1 /*!
2  * \file        sccp_channel.c
3  * \brief       SCCP Channel Class
4  * \author      Sergio Chersovani <mlists [at] c-net.it>
5  * \date
6  * \note        Reworked, but based on chan_sccp code.
7  *              The original chan_sccp driver that was made by Zozo which itself was derived from the chan_skinny driver.
8  *              Modified by Jan Czmok and Julien Goodwin
9  * \note        This program is free software and may be modified and distributed under the terms of the GNU Public License.
10  *              See the LICENSE file at the top of the source tree.
11  *
12  */
13 #include "config.h"
14 #include "common.h"
15 #include "sccp_channel.h"
16 
17 SCCP_FILE_VERSION(__FILE__, "");
18 
19 /*!
20  * \remarks
21  * Purpose:     SCCP Channels
22  * When to use: Only methods directly related to sccp channels should be stored in this source file.
23  * Relations:   SCCP Channels connect Asterisk Channels to SCCP Lines
24  */
25 #include "sccp_device.h"
26 #include "sccp_pbx.h"
27 #include "sccp_conference.h"
28 #include "sccp_atomic.h"
29 #include "sccp_feature.h"
30 #include "sccp_indicate.h"
31 #include "sccp_line.h"
32 #include "sccp_linedevice.h"
33 #include "sccp_rtp.h"
34 #include "sccp_netsock.h"
35 #include "sccp_utils.h"
36 #include "sccp_labels.h"
37 #include "sccp_threadpool.h"
38 #include <asterisk/callerid.h>			// sccp_channel, sccp_callinfo
39 #include <asterisk/pbx.h>			// AST_EXTENSION_NOT_INUSE
40 
41 static uint32_t callCount = 1;
42 int __sccp_channel_destroy(const void * data);
43 
44 /* Lock Macro for Sessions */
45 #define sccp_channel_lock(x)    pbx_mutex_lock(&(x)->lock)
46 #define sccp_channel_unlock(x)  pbx_mutex_unlock(&(x)->lock)
47 #define sccp_channel_trylock(x) pbx_mutex_trylock(&(x)->lock)
48 //#define SCOPED_SESSION(x)       SCOPED_MUTEX(channellock, (ast_mutex_t *)&(x)->lock);
49 /* */
50 
51 AST_MUTEX_DEFINE_STATIC(callCountLock);
52 
53 /*!
54  * \brief Private Channel Data Structure
55  */
56 struct sccp_private_channel_data {
57 	devicePtr device;                                        //! \todo use lineDevicePtr instead;
58 	lineDevicePtr ld;
59 	sccp_callinfo_t * callInfo;
60 	SCCP_LIST_HEAD (, sccp_threadpool_job_t) cleanup_jobs;
61 	boolean_t microphone;					/*!< Flag to mute the microphone when calling a baby phone */
62 	boolean_t isAnswering;
63 	struct {
64 		skinny_tone_t active;
65 		skinny_toneDirection_t direction;
66 	} tone;
67 	boolean_t firewall_holepunch;
68 };
69 
70 /*!
71  * \brief Set Microphone State
72  * \param channel SCCP Channel
73  * \param enabled Enabled as Boolean
74  */
setMicrophoneState(channelPtr c,boolean_t enabled)75 static void setMicrophoneState(channelPtr c, boolean_t enabled)
76 {
77 	AUTO_RELEASE(sccp_device_t, d, sccp_channel_getDevice(c));
78 	if (!d) {
79 		return;
80 	}
81 
82 	c->privateData->microphone = enabled;
83 
84 	if (enabled) {
85 		c->isMicrophoneEnabled = sccp_always_true;
86 		if(sccp_rtp_getState(&c->rtp.audio, SCCP_RTP_TRANSMISSION)) {
87 			sccp_dev_set_microphone(d, SKINNY_STATIONMIC_ON);
88 		}
89 	} else {
90 		c->isMicrophoneEnabled = sccp_always_false;
91 		if(sccp_rtp_getState(&c->rtp.audio, SCCP_RTP_TRANSMISSION)) {
92 			sccp_dev_set_microphone(d, SKINNY_STATIONMIC_OFF);
93 		}
94 	}
95 }
96 
97 /*
98  * \brief statemachine to Start/Stop device tone generation
99  */
setToneWithoutLineDevice(constChannelPtr c,skinny_tone_t tone,skinny_toneDirection_t direction)100 static void setToneWithoutLineDevice(constChannelPtr c, skinny_tone_t tone, skinny_toneDirection_t direction)
101 {
102 	pbx_assert(c);
103 	AUTO_RELEASE(sccp_device_t, d, sccp_channel_getDevice(c));
104 	if(!d) {
105 		pbx_log(LOG_NOTICE, "%s: (%s) No device attached to this channel\n", c->designator, __func__);
106 		return;
107 	}
108 	sccp_dev_stoptone(d, 0, c->callid);
109 	if(tone != SKINNY_TONE_SILENCE) {
110 		sccp_dev_starttone(d, tone, 0, c->callid, direction);
111 	}
112 }
113 
114 /*
115  * \brief statemachine to Start/Stop device tone generation
116  */
setTone(constChannelPtr c,skinny_tone_t tone,skinny_toneDirection_t direction)117 static void setTone(constChannelPtr c, skinny_tone_t tone, skinny_toneDirection_t direction)
118 {
119 	pbx_assert(c && c->privateData && c->privateData->ld);
120 	if(c->privateData->tone.active == tone && c->privateData->tone.direction == direction) {
121 		return;
122 	}
123 	sccp_linedevice_t * ld = c->privateData->ld;
124 	if(c->privateData->tone.active) {
125 		sccp_dev_stoptone(ld->device, ld->lineInstance, c->callid);
126 	}
127 	if(tone != SKINNY_TONE_SILENCE) {
128 		if(c->state == SCCP_CHANNELSTATE_ONHOOK || c->state == SCCP_CHANNELSTATE_DOWN) {
129 			sccp_dev_starttone(ld->device, tone, 0, 0, direction);
130 		} else {
131 			sccp_dev_starttone(ld->device, tone, ld->lineInstance, c->callid, direction);
132 		}
133 	}
134 	c->privateData->tone.active = tone;
135 	c->privateData->tone.direction = direction;
136 }
137 
setEarlyRTP(channelPtr c,boolean_t state)138 static void setEarlyRTP(channelPtr c, boolean_t state)
139 {
140 	pbx_assert(c != NULL);
141 	sccp_log(DEBUGCAT_RTP)(VERBOSE_PREFIX_3 "%s: (%s) %s\n", c->designator, __func__, state ? "ON" : "OFF");
142 	c->wantsEarlyRTP = state ? sccp_always_true : sccp_always_false;
143 }
144 
makeProgress(channelPtr c)145 static void makeProgress(channelPtr c)
146 {
147 	pbx_assert(c != NULL);
148 	if(c->wantsEarlyRTP() && c->progressSent == sccp_always_false) {
149 		sccp_log(DEBUGCAT_RTP)(VERBOSE_PREFIX_3 "%s: (%s)\n", c->designator, __func__);
150 		if(!sccp_rtp_getState(&c->rtp.audio, SCCP_RTP_RECEPTION)) {
151 			sccp_channel_openReceiveChannel(c);
152 		}
153 #if CS_SCCP_VIDEO
154 		if(!sccp_rtp_getState(&c->rtp.video, SCCP_RTP_RECEPTION) && sccp_channel_getVideoMode(c) != SCCP_VIDEO_MODE_OFF) {
155 			sccp_channel_openMultiMediaReceiveChannel(c);
156 		}
157 #endif
158 		c->progressSent = sccp_always_true;
159 	}
160 }
161 
sccp_channel_isAnswering(constChannelPtr c)162 boolean_t sccp_channel_isAnswering(constChannelPtr c)
163 {
164 	return c && c->privateData ? c->privateData->isAnswering : TRUE;
165 }
166 
167 /*!
168  * \brief Allocate SCCP Channel on Device
169  * \param l SCCP Line
170  * \param device SCCP Device (optional)
171  * \return a *retained* SCCP Channel
172  *
173  * \callgraph
174  * \callergraph
175  *
176  * \lock
177  *  - callCountLock
178  */
sccp_channel_allocate(constLinePtr l,constDevicePtr device)179 channelPtr sccp_channel_allocate(constLinePtr l, constDevicePtr device)
180 {
181 	/* this just allocate a sccp channel (not the asterisk channel, for that look at sccp_pbx_channel_allocate) */
182 	sccp_channel_t *channel = NULL;
183 	struct sccp_private_channel_data *private_data = NULL;
184 	sccp_line_t *refLine = sccp_line_retain(l);
185 
186 	if (!refLine) {
187 		pbx_log(LOG_ERROR, "SCCP: Could not retain line to create a channel on it, giving up!\n");
188 		return NULL;
189 	}
190 	if (sccp_strlen_zero(refLine->name) || sccp_strlen_zero(refLine->context) || !pbx_context_find(refLine->context)) {
191 		pbx_log(LOG_ERROR, "SCCP: line with empty name, empty context or non-existent context provided, aborting creation of new channel\n");
192 		return NULL;
193 	}
194 	if (device && !device->session) {
195 		pbx_log(LOG_ERROR, "SCCP: Tried to open channel on device %s without a session\n", device->id);
196 		return NULL;
197 	}
198 
199 	int32_t callid = 0;
200 	char designator[32];
201 	sccp_mutex_lock(&callCountLock);
202 	if (callCount < 0xFFFFFFFF) {						/* callcount limit should be reset at his upper limit :) */
203 		callid = callCount++;
204 	} else {
205 		pbx_log(LOG_NOTICE, "%s: CallId re-starting at 00000001\n", device->id);
206 		callCount = 1;
207 		callid = callCount;
208 	}
209 	snprintf(designator, 32, "SCCP/%s-%08X", refLine->name, callid);
210 	uint8_t callInstance = refLine->statistic.numberOfActiveChannels + refLine->statistic.numberOfHeldChannels + 1;
211 	sccp_mutex_unlock(&callCountLock);
212 	do {
213 		/* allocate new channel */
214 		channel = (sccp_channel_t *) sccp_refcount_object_alloc(sizeof(sccp_channel_t), SCCP_REF_CHANNEL, designator, __sccp_channel_destroy);
215 		if (!channel) {
216 			pbx_log(LOG_ERROR, "%s: No memory to allocate channel on line %s\n", l->id, l->name);
217 			break;
218 		}
219 		pbx_mutex_init(&channel->lock);
220 #if CS_REFCOUNT_DEBUG
221 		sccp_refcount_addRelationship(refLine, channel);
222 #endif
223 		/* allocate resources */
224 		private_data = (struct sccp_private_channel_data *)sccp_calloc(sizeof *private_data, 1);
225 		if (!private_data) {
226 			pbx_log(LOG_ERROR, "%s: No memory to allocate channel private data on line %s\n", l->id, l->name);
227 			break;
228 		}
229 
230 		/* assign private_data default values */
231 		private_data->microphone = TRUE;
232 		private_data->callInfo = iCallInfo.Constructor(callInstance, designator);
233 		private_data->isAnswering = FALSE;
234 		SCCP_LIST_HEAD_INIT(&private_data->cleanup_jobs);
235 		if (!private_data->callInfo) {
236 			break;
237 		}
238 
239 		/* assigning immutable values */
240 		*(struct sccp_private_channel_data **)&channel->privateData = private_data;
241 		*(uint32_t *)&channel->callid = callid;
242 		*(uint32_t *)&channel->passthrupartyid = callid ^ 0xFFFFFFFF;
243 		*(sccp_line_t **)&channel->line = refLine;
244 		*(char **)&channel->musicclass = pbx_strdup(
245 							!sccp_strlen_zero(refLine->musicclass) ? refLine->musicclass :
246 							!sccp_strlen_zero(GLOB(musicclass)) ? GLOB(musicclass) :
247 							"default"
248 						);
249 		*(char **)&channel->designator = pbx_strdup(designator);
250 
251 		/* assign default values */
252 		channel->ringermode = GLOB(ringtype);
253 		channel->calltype = SKINNY_CALLTYPE_INBOUND;
254 		channel->answered_elsewhere = FALSE;
255 		channel->peerIsSCCP = 0;
256 		// channel->maxBitRate = 15000;
257 		channel->maxBitRate = 3200;
258 		iPbx.set_owner(channel, NULL);
259 
260 		/* this is for dialing scheduler */
261 		channel->scheduler.digittimeout_id = -1;
262 		channel->scheduler.hangup_id = -1;
263 		channel->scheduler.cfwd_noanswer_id = -1;
264 		channel->enbloc.digittimeout = GLOB(digittimeout);
265 #ifndef SCCP_ATOMIC
266 		pbx_mutex_init(&channel->scheduler.lock);
267 #endif
268 		/* assign virtual functions */
269 		channel->getDevice = sccp_channel_getDevice;
270 		channel->getLineDevice = sccp_channel_getLineDevice;
271 		channel->setDevice = sccp_channel_setDevice;
272 		channel->isMicrophoneEnabled = sccp_always_true;
273 		channel->isHangingUp = FALSE;
274 		channel->isRunningPbxThread = FALSE;
275 		channel->wantsEarlyRTP = sccp_always_false;
276 		channel->setEarlyRTP = setEarlyRTP;
277 		channel->progressSent = sccp_always_false;
278 		channel->makeProgress = makeProgress;
279 		channel->setMicrophone = setMicrophoneState;
280 		channel->hangupRequest = sccp_astgenwrap_requestQueueHangup;
281 		//channel->privacy = (device && (device->privacyFeature.status & SCCP_PRIVACYFEATURE_CALLPRESENT)) ? TRUE : FALSE;
282 		if (device) {
283 			channel->dtmfmode = device->getDtmfMode(device);
284 			channel->setTone = setTone;
285 		} else {
286 			channel->dtmfmode = SCCP_DTMFMODE_RFC2833;
287 			channel->setTone = setToneWithoutLineDevice;
288 		}
289 
290 		if (l->preferences_set_on_line_level) {
291 			memcpy(&channel->preferences.audio, &l->preferences.audio, sizeof channel->preferences.audio);
292 			memcpy(&channel->preferences.video, &l->preferences.video, sizeof channel->preferences.video);
293 			if (device) {
294 				memcpy(&channel->capabilities.audio, &device->capabilities.audio, sizeof channel->capabilities.audio);
295 				memcpy(&channel->capabilities.video, &device->capabilities.video, sizeof channel->capabilities.video);
296 			}
297 		}
298 		channel->videomode = l->videomode;
299 
300 		/* run setters */
301 		sccp_line_addChannel(l, channel);
302 		if (refLine->capabilities.audio[0] == SKINNY_CODEC_NONE) {
303 			sccp_line_updateCapabilitiesFromDevicesToLine(refLine);			// bit of a hack, UpdateCapabilties is done (long) after device registration
304 		}
305 		channel->setDevice(channel, device, FALSE);
306 
307 		/* return new channel */
308 		sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "%s: New channel number: %d on line %s\n", l->id, channel->callid, l->name);
309 		return channel;
310 	} while (0);
311 
312 	/* something went wrong, cleaning up */
313 	if (private_data) {
314 		if (private_data->callInfo) {
315 			iCallInfo.Destructor(&private_data->callInfo);
316 		}
317 		SCCP_LIST_HEAD_DESTROY(&(private_data->cleanup_jobs));
318 		sccp_free(private_data);
319 	}
320 	if (channel) {
321 		sccp_channel_release(&channel);							// explicit release
322 	}
323 	if (refLine) {
324 		sccp_line_release(&refLine);							// explicit release
325 	}
326 	return NULL;
327 }
328 
329 /*!
330  * \brief Retrieve Device from Channels->Private Channel Data
331  * \param channel SCCP Channel
332  * \return SCCP Device
333  */
sccp_channel_getDevice(constChannelPtr channel)334 devicePtr sccp_channel_getDevice(constChannelPtr channel)
335 {
336 	pbx_assert(channel != NULL);
337 	if (channel->privateData && channel->privateData->device) {
338 		return sccp_device_retain(channel->privateData->device);
339 	}
340 	return NULL;
341 }
342 
343 /*!
344  * \brief Retrieve LineDevice from Channels->Private Channel Data
345  * \param channel SCCP Channel
346  * \return SCCP LineDevice
347  */
sccp_channel_getLineDevice(constChannelPtr channel)348 lineDevicePtr sccp_channel_getLineDevice(constChannelPtr channel)
349 {
350 	pbx_assert(channel != NULL);
351 	if(channel->privateData && channel->privateData->ld) {
352 		return sccp_linedevice_retain(channel->privateData->ld);
353 	}
354 	return NULL;
355 }
356 /*!
357  * \brief Set Device in Channels->Private Channel Data
358  * \param channel SCCP Channel
359  * \param device SCCP Device
360  */
sccp_channel_setDevice(channelPtr channel,constDevicePtr device,boolean_t activate)361 void sccp_channel_setDevice(channelPtr channel, constDevicePtr device, boolean_t activate)
362 {
363 	if (!channel || !channel->privateData) {
364 		return;
365 	}
366 
367 	/** for previous device,set active channel to null */
368 	if (!device) {
369 		sccp_linedevice_refreplace(&channel->privateData->ld, NULL);
370 		if (!channel->privateData->device) {
371 			/* channel->privateData->device was already set to NULL */
372 			goto EXIT;
373 		}
374 		sccp_device_setActiveChannel(channel->privateData->device, NULL);
375 	}
376 #if CS_REFCOUNT_DEBUG
377 	if (device || channel->privateData->device) {
378 		sccp_refcount_removeRelationship(channel->privateData->device ? channel->privateData->device : device, channel);
379 	}
380 #endif
381 	sccp_device_refreplace(&channel->privateData->device, (sccp_device_t *) device);
382 
383 	if (device) {
384 		sccp_device_setActiveChannel(device, channel);
385 #if CS_REFCOUNT_DEBUG
386 		sccp_refcount_addRelationship(device, channel);
387 #endif
388 	}
389 
390 	if (channel->privateData && channel->privateData->device) {
391 		{
392 			AUTO_RELEASE(sccp_linedevice_t, ld, sccp_linedevice_find(channel->privateData->device, channel->line));
393 			sccp_linedevice_refreplace(&channel->privateData->ld, ld);
394 		}
395 		/*! \todo: Check/Fix codec selection on hold/resume */
396 		if(channel->preferences.audio[0] == SKINNY_CODEC_NONE || channel->capabilities.audio[0] == SKINNY_CODEC_NONE) {
397 			sccp_line_copyCodecSetsFromLineToChannel(channel->line, channel->privateData->device, channel);
398 		}
399 #if CS_SCCP_VIDEO
400 		if (!channel->line->preferences_set_on_line_level && channel->preferences.video[0] == SKINNY_CODEC_NONE) {
401 			memcpy(&channel->preferences.video, &channel->privateData->device->preferences.video, sizeof(channel->preferences.video));
402 		}
403 		if (channel->capabilities.video[0] == SKINNY_CODEC_NONE) {
404 			memcpy(&channel->capabilities.video, &channel->privateData->device->capabilities.video, sizeof(channel->capabilities.video));
405 		}
406 #endif
407 		sccp_copy_string(channel->currentDeviceId, channel->privateData->device->id, sizeof(char[StationMaxDeviceNameSize]));
408 		channel->dtmfmode = channel->privateData->device->getDtmfMode(channel->privateData->device);
409 		channel->setEarlyRTP(channel, channel->privateData->device->earlyrtp);
410 		channel->setTone = setTone;
411 		return;
412 	}
413 EXIT:
414 	/*! \todo: Check/Fix codec selection on hold/resume */
415 	if (channel->preferences.audio[0] == SKINNY_CODEC_NONE || channel->capabilities.audio[0] == SKINNY_CODEC_NONE) {
416 		sccp_line_copyCodecSetsFromLineToChannel(channel->line, NULL, channel);
417 	}
418 
419 	sccp_linedevice_refreplace(&channel->privateData->ld, NULL);
420 	/* \todo we should use */
421 	// sccp_line_copyMinimumCodecSetFromLineToChannel(l, c);
422 	sccp_copy_string(channel->currentDeviceId, "SCCP", sizeof(char[StationMaxDeviceNameSize]));
423 	channel->dtmfmode = SCCP_DTMFMODE_RFC2833;
424 	channel->setEarlyRTP(channel, FALSE);
425 	channel->setTone = setToneWithoutLineDevice;
426 }
427 
sccp_getCallCount(constLineDevicePtr ld)428 int sccp_getCallCount(constLineDevicePtr ld)
429 {
430 	int calls = 0;
431 	constLinePtr l = ld->line;
432 	constDevicePtr d = ld->device;
433 	sccp_channel_t * channel = NULL;
434 	SCCP_LIST_LOCK(&l->channels);
435 	if(l->isShared) {
436 		// shared channels are only included if it's assigned device equals the device we are looking for.
437 		SCCP_LIST_TRAVERSE(&l->channels, channel, list) {
438 			if(!d || !channel->privateData->device || d == channel->privateData->device) {
439 				calls++;
440 			}
441 		}
442 	} else {
443 		// all single channels for this line are included in the count
444 		SCCP_LIST_TRAVERSE(&l->channels, channel, list) {
445 			calls++;
446 		}
447 	}
448 	SCCP_LIST_UNLOCK(&l->channels);
449 	return calls;
450 }
451 
sccp_channel_recalculateAudioCodecFormat(channelPtr channel)452 static void sccp_channel_recalculateAudioCodecFormat(channelPtr channel)
453 {
454 	char s1[512];
455 
456 	char s2[512];
457 
458 	char s3[512];
459 
460 	char s4[512];
461 	skinny_codec_t joint = channel->rtp.audio.reception.format;
462 	skinny_capabilities_t *preferences = &(channel->preferences);
463 	sccp_rtp_t * audio = (sccp_rtp_t *)&(channel->rtp.audio);
464 
465 	if(iPbx.retrieve_remote_capabilities && channel->remoteCapabilities.audio[0] == SKINNY_CODEC_NONE) {
466 		iPbx.retrieve_remote_capabilities(channel);
467 	}
468 	if(sccp_rtp_areBothInvalid(audio)) {
469 		if(channel->privateData->device && !channel->line->preferences_set_on_line_level) {
470 			preferences = &(channel->privateData->device->preferences);
471 			sccp_codec_reduceSet(preferences->audio, channel->privateData->device->capabilities.audio);
472 		}
473 		sccp_codec_reduceSet(preferences->audio, channel->capabilities.audio);
474 		joint = sccp_codec_findBestJoint(channel, preferences->audio, channel->remoteCapabilities.audio, TRUE);
475 		if (SKINNY_CODEC_NONE == joint) {
476 			joint = preferences->audio[0] ? preferences->audio[0] : SKINNY_CODEC_WIDEBAND_256K;
477 		}
478 		if (channel->rtp.audio.instance) {                      // Fix nativeAudioFormats
479 			skinny_codec_t codecs[SKINNY_MAX_CAPABILITIES] = { joint, SKINNY_CODEC_NONE};
480 			iPbx.set_nativeAudioFormats(channel, codecs);
481 		}
482 	}
483 	if (SKINNY_CODEC_NONE != joint) {
484 		if(!sccp_rtp_getState(audio, SCCP_RTP_RECEPTION)) {
485 			channel->rtp.audio.reception.format = joint;
486 			iPbx.rtp_setWriteFormat(channel, joint);
487 			channel->rtp.audio.transmission.format = joint;
488 			iPbx.rtp_setReadFormat(channel, joint);
489 		}
490 	}
491 	sccp_log((DEBUGCAT_CODEC + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3
492 		"%s - %s: (recalculateAudioCodecformat) \n\t"
493 		"channel capabilities: %s\n\t"
494 		"%s preferences %s\n\t"
495 		"%s preferences: %s\n\t"
496 		"remote caps: %s\n\t"
497 		"Format:%s\n",
498 		channel->currentDeviceId, channel->designator,
499 		sccp_codec_multiple2str(s1, sizeof(s1) - 1, channel->capabilities.audio, ARRAY_LEN(channel->capabilities.audio)),
500 		(SCCP_LIST_GETSIZE(&channel->line->devices) > 1) ? "shared" : "channel",
501 		sccp_codec_multiple2str(s2, sizeof(s2) - 1, channel->preferences.audio, ARRAY_LEN(channel->preferences.audio)),
502 		channel->line->preferences_set_on_line_level ? "line" : "device",
503 		channel->line->preferences_set_on_line_level ? sccp_codec_multiple2str(s3, sizeof(s3) - 1, channel->line->preferences.audio, ARRAY_LEN(channel->line->preferences.audio)) : ((channel->privateData->device) ? sccp_codec_multiple2str(s3, sizeof(s3) - 1, channel->privateData->device->preferences.audio, ARRAY_LEN(channel->privateData->device->preferences.audio)) : ""),
504 		sccp_codec_multiple2str(s4, sizeof(s4) - 1, channel->remoteCapabilities.audio, ARRAY_LEN(channel->remoteCapabilities.audio)),
505 		codec2name(joint)
506 	);
507 }
508 
sccp_channel_recalculateVideoCodecFormat(channelPtr channel)509 static boolean_t sccp_channel_recalculateVideoCodecFormat(channelPtr channel)
510 {
511 	char s1[512];
512 
513 	char s2[512];
514 
515 	char s3[512];
516 
517 	char s4[512];
518 	skinny_codec_t joint = channel->rtp.video.reception.format;
519 	skinny_capabilities_t *preferences = &(channel->preferences);
520 	sccp_rtp_t * video = (sccp_rtp_t *)&(channel->rtp.video);
521 
522 	if(sccp_rtp_areBothInvalid(video)) {
523 		if(channel->privateData->device && !channel->line->preferences_set_on_line_level) {
524 			preferences = &(channel->privateData->device->preferences);
525 			sccp_codec_reduceSet(preferences->video, channel->privateData->device->capabilities.video);
526 		}
527 		sccp_codec_reduceSet(preferences->video, channel->capabilities.video);
528 		joint = sccp_codec_findBestJoint(channel, preferences->video, channel->remoteCapabilities.video, FALSE);
529 		if (joint == SKINNY_CODEC_NONE) {
530 			if(channel->state > SCCP_GROUPED_CHANNELSTATE_DIALING) {
531 				sccp_channel_setVideoMode(channel, "off");
532 			}
533 			return FALSE;
534 		}
535 		//if (channel->rtp.video.instance) {
536 		skinny_codec_t codecs[SKINNY_MAX_CAPABILITIES] = { joint, SKINNY_CODEC_NONE};
537 		iPbx.set_nativeVideoFormats(channel, codecs);
538 		//}
539 		channel->rtp.video.reception.format = joint;
540 		channel->rtp.video.transmission.format = joint;
541 		iPbx.rtp_setWriteFormat(channel, joint);
542 		iPbx.rtp_setReadFormat(channel, joint);
543 	}
544 	sccp_log((DEBUGCAT_CODEC + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3
545 		"%s - %s: (recalculateVideoCodecformat) \n\t"
546 		"channel capabilities: %s\n\t"
547 		"%s preferences %s\n\t"
548 		"%s preferences: %s\n\t"
549 		"remote caps: %s\n\t"
550 		"Format:%s\n",
551 		channel->currentDeviceId, channel->designator,
552 		sccp_codec_multiple2str(s1, sizeof(s1) - 1, channel->capabilities.video, ARRAY_LEN(channel->capabilities.video)),
553 		(SCCP_LIST_GETSIZE(&channel->line->devices) > 1) ? "shared" : "channel",
554 		sccp_codec_multiple2str(s2, sizeof(s2) - 1, channel->preferences.video, ARRAY_LEN(channel->preferences.video)),
555 		channel->line->preferences_set_on_line_level ? "line" : "device",
556 		channel->line->preferences_set_on_line_level ? sccp_codec_multiple2str(s3, sizeof(s3) - 1, channel->line->preferences.video, ARRAY_LEN(channel->line->preferences.video)) : ((channel->privateData->device) ? sccp_codec_multiple2str(s3, sizeof(s3) - 1, channel->privateData->device->preferences.video, ARRAY_LEN(channel->privateData->device->preferences.video)) : ""),
557 		sccp_codec_multiple2str(s4, sizeof(s4) - 1, channel->remoteCapabilities.video, ARRAY_LEN(channel->remoteCapabilities.video)),
558 		codec2name(joint)
559 	);
560 	return TRUE;
561 }
562 
563 /*!
564  * \brief Update Channel Capability
565  * \param channel a *retained* SCCP Channel
566  */
sccp_channel_updateChannelCapability(channelPtr channel)567 void sccp_channel_updateChannelCapability(channelPtr channel)
568 {
569 	sccp_channel_recalculateAudioCodecFormat(channel);
570 #if CS_SCCP_VIDEO
571 	sccp_channel_recalculateVideoCodecFormat(channel);
572 #endif
573 }
574 
575 /*!
576  * \brief Get const pointer to channels private callinfo
577  */
sccp_channel_getCallInfo(constChannelPtr channel)578 sccp_callinfo_t * const __PURE__ sccp_channel_getCallInfo(constChannelPtr channel)
579 {
580 	return channel->privateData->callInfo; /* discard const because callinfo has a private implementation anyway */
581 }
582 
583 /*!
584  * \brief Send Call Information to Device/Channel
585  *
586  * Wrapper function that calls sccp_channel_send_staticCallinfo or sccp_channel_send_dynamicCallinfo
587  *
588  * \param device SCCP Device
589  * \param channel SCCP Channel
590  *
591  * \callgraph
592  * \callergraph
593  *
594  * \todo find a difference solution for sccp_conference callinfo update
595  */
sccp_channel_send_callinfo(constDevicePtr device,constChannelPtr channel)596 void sccp_channel_send_callinfo(constDevicePtr device, constChannelPtr channel)
597 {
598 	uint8_t lineInstance = 0;
599 
600 	if (device && channel && channel->callid) {
601 		lineInstance = sccp_device_find_index_for_line(device, channel->line->name);
602 		sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "%s: send callInfo on %s with lineInstance: %d\n", device->id, channel->designator, lineInstance);
603 		iCallInfo.Send(channel->privateData->callInfo, channel->callid, channel->calltype, lineInstance, device, FALSE);
604 	}
605 
606 }
607 
608 /*!
609  * \brief Send Dialed Number to SCCP Channel device
610  * \param channel SCCP Channel
611  *
612  * \callgraph
613  * \callergraph
614  */
sccp_channel_send_callinfo2(constChannelPtr channel)615 void sccp_channel_send_callinfo2(constChannelPtr channel)
616 {
617 	pbx_assert(channel != NULL);
618 
619 	AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(channel));
620 	AUTO_RELEASE(sccp_line_t, line , sccp_line_retain(channel->line));
621 
622 	if (d) {
623 		sccp_channel_send_callinfo(d, channel);
624 	} else if (line) {
625 		sccp_linedevice_t * ld = NULL;
626 
627 		SCCP_LIST_LOCK(&line->devices);
628 		SCCP_LIST_TRAVERSE(&line->devices, ld, list) {
629 			AUTO_RELEASE(sccp_device_t, device, sccp_device_retain(ld->device));
630 
631 			sccp_channel_send_callinfo(device, channel);
632 		}
633 		SCCP_LIST_UNLOCK(&line->devices);
634 	}
635 }
636 
637 /*!
638  * \brief Set Call State for SCCP Channel sccp_channel, and Send this State to SCCP Device d.
639  * \param channel SCCP Channel
640  * \param state channel state
641  *
642  * \callgraph
643  * \callergraph
644  */
sccp_channel_setChannelstate(channelPtr channel,sccp_channelstate_t state)645 void sccp_channel_setChannelstate(channelPtr channel, sccp_channelstate_t state)
646 {
647 	channel->previousChannelState = channel->state;
648 	channel->state = state;
649 }
650 
651 /*!
652  * \brief Set CallingParty on SCCP Channel c
653  * \param channel SCCP Channel
654  *
655  * \callgraph
656  * \callergraph
657  */
sccp_channel_display_callInfo(constChannelPtr channel)658 void sccp_channel_display_callInfo(constChannelPtr channel)
659 {
660 	if ((GLOB(debug) & (DEBUGCAT_CHANNEL)) != 0) {
661 		iCallInfo.Print2log(channel->privateData->callInfo, channel->designator);
662 	}
663 }
664 
665 /*!
666  * \brief Set CallingParty on SCCP Channel c
667  * \param channel SCCP Channel
668  * \param name Name as char
669  * \param number Number as char
670  *
671  * \callgraph
672  * \callergraph
673  */
sccp_channel_set_callingparty(constChannelPtr channel,const char * name,const char * number)674 void sccp_channel_set_callingparty(constChannelPtr channel, const char *name, const char *number)
675 {
676 	if (!channel) {
677 		return;
678 	}
679 	iCallInfo.SetCallingParty(channel->privateData->callInfo, name, number, NULL);
680 	sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "%s: (sccp_channel_set_callingparty) Set callingParty Name '%s', Number '%s' on channel %s\n", channel->currentDeviceId, name, number, channel->designator);
681 }
682 
683 /*!
684  * \brief Set Original Calling Party on SCCP Channel c (Used during Forward)
685  * \param channel SCCP Channel * \param name Name as char
686  * \param number Number as char
687  * \return TRUE/FALSE - TRUE if info changed
688  *
689  * \callgraph
690  * \callergraph
691  */
sccp_channel_set_originalCallingparty(constChannelPtr channel,char * name,char * number)692 boolean_t sccp_channel_set_originalCallingparty(constChannelPtr channel, char * name, char * number)
693 {
694 	boolean_t changed = FALSE;
695 
696 	if (!channel) {
697 		return FALSE;
698 	}
699 
700 	changed = iCallInfo.SetOrigCallingParty(channel->privateData->callInfo, name, number);
701 	sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "%s: (sccp_channel_set_originalCallingparty) Set originalCallingparty Name '%s', Number '%s' on channel %s\n", channel->currentDeviceId, name, number, channel->designator);
702 	return changed;
703 }
704 
705 /*!
706  * \brief Set CalledParty on SCCP Channel c
707  * \param channel SCCP Channel
708  * \param name Called Party Name
709  * \param number Called Party Number
710  *
711  * \callgraph
712  * \callergraph
713  */
sccp_channel_set_calledparty(constChannelPtr channel,const char * name,const char * number)714 void sccp_channel_set_calledparty(constChannelPtr channel, const char * name, const char * number)
715 {
716 	if (!channel || sccp_strequals(number, "s") /* skip update for immediate earlyrtp + s-extension */ ) {
717 		return;
718 	}
719 	iCallInfo.SetCalledParty(channel->privateData->callInfo, name, number, NULL);
720 }
721 
722 /*!
723  * \brief Set Original CalledParty on SCCP Channel c (Used during Forward)
724  * \param channel SCCP Channel
725  * \param name Name as char
726  * \param number Number as char
727  *
728  * \callgraph
729  * \callergraph
730  */
sccp_channel_set_originalCalledparty(constChannelPtr channel,char * name,char * number)731 boolean_t sccp_channel_set_originalCalledparty(constChannelPtr channel, char * name, char * number)
732 {
733 	boolean_t changed = FALSE;
734 
735 	if (!channel) {
736 		return FALSE;
737 	}
738 	changed = iCallInfo.SetOrigCalledParty(channel->privateData->callInfo, name, number, NULL, 4);
739 	sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "%s: (sccp_channel_set_originalCalledparty) Set originalCalledparty Name '%s', Number '%s' on channel %s\n", channel->currentDeviceId, name, number, channel->designator);
740 	return changed;
741 
742 }
743 
744 /*!
745  * \brief Request Call Statistics for SCCP Channel
746  * \param channel SCCP Channel
747  */
sccp_channel_StatisticsRequest(constChannelPtr channel)748 void sccp_channel_StatisticsRequest(constChannelPtr channel)
749 {
750 	pbx_assert(channel != NULL);
751 	AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(channel));
752 
753 	if (!d) {
754 		return;
755 	}
756 	sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_DEVICE))(VERBOSE_PREFIX_3 "%s: Device is Requesting Connections Statistics And Clear\n", d->id);
757 	d->protocol->sendConnectionStatisticsReq(d, channel, SKINNY_STATSPROCESSING_CLEAR);
758 }
759 
760 /*
761  * \brief a simple way to punch a whole in the firewall by sending a short burst of packets during progress
762  * transmission will be stopped again as soon as the first packet has been received from the device in astwrap_rtp_read
763  */
sccp_channel_startHolePunch(constChannelPtr c)764 static void sccp_channel_startHolePunch(constChannelPtr c)
765 {
766 	pbx_assert(c != NULL && c->privateData && !c->privateData->firewall_holepunch);
767 	sccp_rtp_t * audio = (sccp_rtp_t *)&(c->rtp.audio);
768 	/*! \todo
769 		// punching is only necessary if the rtp-instance ip-address+mask differs from the rtp->phone+mask
770 		// ie: they are in different networks and there is a potential firewall in between
771 		sccp_rtp_t * audio = (sccp_rtp_t *)&(c->rtp.audio);
772 		apply_netmask()
773 		if (sccp_netsock_cmp_addr(&audio->phone, &audio->phone_remote)) {
774 	*/
775 	if(!sccp_rtp_getState(audio, SCCP_RTP_TRANSMISSION) && pbx_channel_state(c->owner) != AST_STATE_UP && c->wantsEarlyRTP()) {
776 		sccp_log(DEBUGCAT_RTP)(VERBOSE_PREFIX_3 "%s: (%s) start Punching a hole through the firewall (if necessary)\n", c->designator, __func__);
777 		c->privateData->firewall_holepunch = TRUE;
778 		sccp_channel_startMediaTransmission(c);
779 	}
780 }
781 
sccp_channel_finishHolePunch(constChannelPtr c)782 boolean_t sccp_channel_finishHolePunch(constChannelPtr c)
783 {
784 	pbx_assert(c != NULL && c->privateData);
785 	if(pbx_channel_state(c->owner) == AST_STATE_UP) {
786 		c->privateData->firewall_holepunch = FALSE;
787 		return FALSE;
788 	}
789 	sccp_rtp_t * audio = (sccp_rtp_t *)&(c->rtp.audio);
790 	if(c->privateData->firewall_holepunch && ((sccp_rtp_getState(audio, SCCP_RTP_TRANSMISSION) & SCCP_RTP_STATUS_ACTIVE) == SCCP_RTP_STATUS_ACTIVE)) {
791 		sccp_log(DEBUGCAT_RTP)(VERBOSE_PREFIX_3 "%s: (%s) stop punching a hole through the firewall\n", c->designator, __func__);
792 		sccp_channel_stopMediaTransmission(c, TRUE);
793 		c->privateData->firewall_holepunch = FALSE;
794 	}
795 	return c->privateData->firewall_holepunch;
796 }
797 
798 /*!
799  * \brief Tell Device to Open a RTP Receive Channel
800  *
801  * At this point we choose the codec for receive channel and tell them to device.
802  * We will get a OpenReceiveChannelAck message that includes all information.
803  *
804  */
sccp_channel_openReceiveChannel(constChannelPtr channel)805 void sccp_channel_openReceiveChannel(constChannelPtr channel)
806 {
807 	pbx_assert(channel != NULL);
808 	pbx_assert(channel->line != NULL); /* should not be possible, but received a backtrace / report */
809 	sccp_rtp_t * audio = (sccp_rtp_t *)&(channel->rtp.audio);
810 
811 	if(channel->isHangingUp || !channel->owner || pbx_check_hangup_locked(channel->owner)) {
812 		pbx_log(LOG_ERROR, "%s: (%s) Channel already hanging up\n", channel->designator, __func__);
813 		return;
814 	}
815 
816 	if(sccp_rtp_getState(audio, SCCP_RTP_RECEPTION)) {
817 		sccp_log(DEBUGCAT_RTP)(VERBOSE_PREFIX_3 "%s: (%s) Already pending\n", channel->designator, __func__);
818 		return;
819 	}
820 
821 	AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(channel));
822 	if (!d) {
823 		pbx_log(LOG_ERROR, "%s: (%s) Could not retrieve device from channel\n", channel->designator, __func__);
824 		return;
825 	}
826 
827 	/* Mute mic feature: If previously set, mute the microphone prior receiving media is already open. */
828 	/* This must be done in this exact order to work on popular phones like the 7975. It must also be done in other places for other phones. */
829 	if (!channel->isMicrophoneEnabled()) {
830 		sccp_dev_set_microphone(d, SKINNY_STATIONMIC_OFF);
831 	}
832 
833 	/* create the rtp stuff. It must be create before setting the channel AST_STATE_UP. otherwise no audio will be played */
834 	if (!channel->rtp.audio.instance && !sccp_rtp_createServer(d, (channelPtr)channel, SCCP_RTP_AUDIO)) {			// discard const
835 		pbx_log(LOG_WARNING, "%s: Error opening RTP for channel %s\n", d->id, channel->designator);
836 		channel->setTone(channel, SKINNY_TONE_REORDERTONE, SKINNY_TONEDIRECTION_USER);
837 		return;
838 	}
839 
840 	if (channel->owner && channel->rtp.audio.reception.format == SKINNY_CODEC_NONE) {
841 		sccp_channel_recalculateAudioCodecFormat((channelPtr)channel);                                        // discard const
842 	}
843 
844 	sccp_log((DEBUGCAT_RTP + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "%s, OpenReceiveChannel with format %s, payload %d, echocancel: %s, passthrupartyid: %u, pbx_channel_name: %s\n",
845 			channel->designator, codec2str(audio->reception.format), audio->reception.format,
846 			channel->line ? (channel->line->echocancel ? "YES" : "NO") : "(nil)>",
847 			channel->passthrupartyid, iPbx.getChannelName(channel)
848 		);
849 
850 	sccp_rtp_setState(audio, SCCP_RTP_RECEPTION, SCCP_RTP_STATUS_PROGRESS);
851 	if (d->nat >= SCCP_NAT_ON) {												// device is natted
852 		sccp_rtp_updateNatRemotePhone(channel, audio);
853 	}
854 
855 	d->protocol->sendOpenReceiveChannel(d, channel);                                        // extra channel retain, released when receive channel is closed
856 }
857 
sccp_channel_receiveChannelOpen(sccp_device_t * d,sccp_channel_t * c)858 int sccp_channel_receiveChannelOpen(sccp_device_t *d, sccp_channel_t *c)
859 {
860 	pbx_assert(d != NULL && c != NULL);
861 	sccp_rtp_t * audio = &(c->rtp.audio);
862 
863 	// check channel state
864 	if (!audio->instance) {
865 		pbx_log(LOG_ERROR, "%s: Channel has no rtp instance!\n", d->id);
866 		sccp_channel_endcall(c);											// FS - 350
867 		return SCCP_RTP_STATUS_INACTIVE;
868 	}
869 
870 	c->setTone(c, SKINNY_TONE_SILENCE, SKINNY_TONEDIRECTION_USER);
871 	if(c->isHangingUp || !c->owner || pbx_check_hangup_locked(c->owner) || SCCP_CHANNELSTATE_Idling(c->state) || SCCP_CHANNELSTATE_IsTerminating(c->state)) {
872 		if (c->state == SCCP_CHANNELSTATE_INVALIDNUMBER || c->state == SCCP_CHANNELSTATE_CONGESTION) {
873 			return SCCP_RTP_STATUS_ACTIVE;
874 		}
875 		sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_RTP))(VERBOSE_PREFIX_3 "%s: (receiveChannelOpen) Channel is already terminating. Giving up... (%s)\n", DEV_ID_LOG(d), sccp_channelstate2str(c->state));
876 		return SCCP_RTP_STATUS_ACTIVE;
877 	}
878 
879 	sccp_log((DEBUGCAT_RTP))(VERBOSE_PREFIX_3 "%s: Opened Receive Channel (State: %s[%d])\n", d->id, sccp_channelstate2str(c->state), c->state);
880 	//sccp_rtp_set_phone(c, &c->rtp.audio, &sas);
881 	sccp_channel_send_callinfo(d, c);
882 	sccp_rtp_appendState(audio, SCCP_RTP_RECEPTION, SCCP_RTP_STATUS_ACTIVE);
883 
884 	if(c->owner && !pbx_check_hangup_locked(c->owner)) {
885 		sccp_rtp_runCallback(audio, SCCP_RTP_RECEPTION, c);
886 		if(c->calltype != SKINNY_CALLTYPE_INBOUND) {
887 			if(d->nat >= SCCP_NAT_ON) {
888 				sccp_channel_startHolePunch(c);
889 			}
890 			iPbx.queue_control(c->owner, (enum ast_control_frame_type)-1);						// 'PROD' the remote side to let them know
891 																// we can receive inband signalling from this
892 																// moment onwards -> inband signalling required
893 		}
894 	}
895 	return sccp_rtp_getState(audio, SCCP_RTP_RECEPTION);
896 }
897 
898 /*!
899  * \brief Tell Device to Close an RTP Receive Channel and Stop Media Transmission
900  * \param channel SCCP Channel
901  * \param KeepPortOpen Boolean
902  * \note sccp_channel_stopMediaTransmission is explicit call within this function!
903  *
904  */
sccp_channel_closeReceiveChannel(constChannelPtr channel,boolean_t KeepPortOpen)905 void sccp_channel_closeReceiveChannel(constChannelPtr channel, boolean_t KeepPortOpen)
906 {
907 	sccp_msg_t *msg = NULL;
908 
909 	pbx_assert(channel != NULL);
910 	sccp_rtp_t *audio = (sccp_rtp_t *) &(channel->rtp.audio);
911 	AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(channel));
912 
913 	if (!d) {
914 		pbx_log(LOG_ERROR, "%s: (closeReceiveChannel) Could not retrieve device from channel\n", channel->designator);
915 		return;
916 	}
917 	// stop transmitting before closing receivechannel (\note maybe we should not be doing this here)
918 	//sccp_channel_stopMediaTransmission(channel, KeepPortOpen);
919 	//sccp_rtp_stop(channel);
920 
921 	if(sccp_rtp_getState(audio, SCCP_RTP_RECEPTION)) {
922 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_3 "%s: Close receivechannel on device %s (KeepPortOpen: %s)\n", channel->designator, d->id, KeepPortOpen ? "YES" : "NO");
923 		REQ(msg, CloseReceiveChannel);
924 		msg->data.CloseReceiveChannel.lel_conferenceId = htolel(channel->callid);
925 		msg->data.CloseReceiveChannel.lel_passThruPartyId = htolel(channel->passthrupartyid);
926 		msg->data.CloseReceiveChannel.lel_callReference = htolel(channel->callid);
927 		msg->data.CloseReceiveChannel.lel_portHandlingFlag = htolel(KeepPortOpen);
928 		sccp_dev_send(d, msg);
929 		sccp_rtp_setState(audio, SCCP_RTP_RECEPTION, SCCP_RTP_STATUS_INACTIVE);
930 	}
931 }
932 
933 #if UNUSEDCODE // 2015-11-01
sccp_channel_updateReceiveChannel(constChannelPtr channel)934 void sccp_channel_updateReceiveChannel(constChannelPtr channel)
935 {
936 	/* \todo possible to skip the closing of the receive channel (needs testing) */
937 	/* \todo if this works without closing, this would make changing codecs on the fly possible */
938 	if(sccp_rtp_getState(&channel->rtp.audio, SCCP_RTP_RECEPTION)) {
939 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_2 "%s: (sccp_channel_updateReceiveChannel) Close Receive Channel on channel %d\n", channel->currentDeviceId, channel->callid);
940 		sccp_channel_closeReceiveChannel(channel, TRUE);
941 	}
942 	if(!sccp_rtp_getState(&channel->rtp.audio, SCCP_RTP_RECEPTION)) {
943 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_2 "%s: (sccp_channel_updateReceiveChannel) Open Receive Channel on channel %d\n", channel->currentDeviceId, channel->callid);
944 		sccp_channel_openReceiveChannel(channel);
945 	}
946 }
947 #endif
948 
949 /*!
950  * \brief Tell a Device to Start Media Transmission.
951  *
952  * We choose codec according to sccp_channel->format.
953  *
954  * \param channel SCCP Channel
955  * \note rtp should be started before, otherwise we do not start transmission
956  */
sccp_channel_startMediaTransmission(constChannelPtr channel)957 void sccp_channel_startMediaTransmission(constChannelPtr channel)
958 {
959 	pbx_assert(channel != NULL);
960 	pbx_assert(channel->line != NULL); /* should not be possible, but received a backtrace / report */
961 	sccp_rtp_t *audio = (sccp_rtp_t *) &(channel->rtp.audio);
962 
963 	if(channel->isHangingUp || !channel->owner || pbx_check_hangup_locked(channel->owner)) {
964 		pbx_log(LOG_ERROR, "%s: (%s) Channel already hanging up\n", channel->designator, __func__);
965 		return;
966 	}
967 
968 	if(sccp_rtp_getState(audio, SCCP_RTP_TRANSMISSION)) {
969 		sccp_log(DEBUGCAT_RTP)(VERBOSE_PREFIX_3 "%s: (%s) Already pending\n", channel->designator, __func__);
970 		return;
971 	}
972 
973 	AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(channel));
974 	if (!d) {
975 		pbx_log(LOG_ERROR, "%s: (%s) Could not retrieve device from channel\n", channel->designator, __func__);
976 		sccp_channel_closeReceiveChannel(channel, FALSE);
977 		return;
978 	}
979 
980 	if(!audio->instance || !sccp_rtp_getState(audio, SCCP_RTP_RECEPTION)) {
981 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_3 "%s: can't start rtp media transmission, maybe channel is down %s\n", channel->currentDeviceId, channel->designator);
982 		sccp_channel_closeReceiveChannel(channel, FALSE);
983 		return;
984 	}
985 
986 	sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_3 "%s: Starting Phone RTP/UDP Transmission (State: %s[%d])\n", d->id, sccp_channelstate2str(channel->state), channel->state);
987 	/* Mute mic feature: If previously set, mute the microphone after receiving of media is already open, but before starting to send to rtp. */
988 	/* This must be done in this exact order to work also on newer phones like the 8945. It must also be done in other places for other phones. */
989 	if (!channel->isMicrophoneEnabled()) {
990 		sccp_dev_set_microphone(d, SKINNY_STATIONMIC_OFF);
991 	}
992 
993 	if (d->nat >= SCCP_NAT_ON) {
994 		sccp_rtp_updateNatRemotePhone(channel, audio);
995 	}
996 
997 	if (audio->transmission.format == SKINNY_CODEC_NONE) {
998 		if (audio->reception.format == SKINNY_CODEC_NONE) {
999 			sccp_channel_recalculateAudioCodecFormat((channelPtr)channel);                                        // discard const
1000 		} else {
1001 			audio->transmission.format = audio->reception.format;
1002 		}
1003 	}
1004 	sccp_rtp_appendState(audio, SCCP_RTP_TRANSMISSION, SCCP_RTP_STATUS_PROGRESS);
1005 	d->protocol->sendStartMediaTransmission(d, channel);                                        // extra channel retain, released when media transmission is closed
1006 
1007 	char buf1[NI_MAXHOST + NI_MAXSERV];
1008 	char buf2[NI_MAXHOST + NI_MAXSERV];
1009 	sccp_copy_string(buf1, sccp_netsock_stringify(&audio->phone), sizeof(buf1));
1010 	sccp_copy_string(buf2, sccp_netsock_stringify(&audio->phone_remote), sizeof(buf2));
1011 	sccp_log(DEBUGCAT_RTP) (VERBOSE_PREFIX_3 "%s: Tell Phone to send RTP/UDP media from %s to %s (NAT: %s)\n", d->id, buf1, buf2, sccp_nat2str(d->nat));
1012 	sccp_log(DEBUGCAT_RTP) (VERBOSE_PREFIX_3 "%s: Using codec:%s(%d), TOS:%d, Silence Suppression:%s for call with PassThruId:%u and CallID:%u\n", d->id, codec2str(audio->transmission.format), audio->transmission.format, d->audio_tos, channel->line->silencesuppression ? "ON" : "OFF", channel->passthrupartyid, channel->callid);
1013 }
1014 
sccp_channel_mediaTransmissionStarted(devicePtr d,channelPtr c)1015 int sccp_channel_mediaTransmissionStarted(devicePtr d, channelPtr c)
1016 {
1017 	pbx_assert(d != NULL && c != NULL);
1018 	sccp_rtp_t * audio = &(c->rtp.audio);
1019 	// check channel state
1020 	if (!audio->instance) {
1021 		pbx_log(LOG_ERROR, "%s: Channel has no rtp instance!\n", d->id);
1022 		sccp_channel_endcall(c);											// FS - 350
1023 		return SCCP_RTP_STATUS_INACTIVE;
1024 	}
1025 
1026 	if(c->isHangingUp || !c->owner || pbx_check_hangup_locked(c->owner) || SCCP_CHANNELSTATE_Idling(c->state) || SCCP_CHANNELSTATE_IsTerminating(c->state)) {
1027 		if (c->state == SCCP_CHANNELSTATE_INVALIDNUMBER || c->state == SCCP_CHANNELSTATE_CONGESTION) {
1028 			sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_RTP)) (VERBOSE_PREFIX_3 "%s: Stop Tone %s\n", DEV_ID_LOG(d), sccp_channelstate2str(c->state));
1029 			c->setTone(c, SKINNY_TONE_SILENCE, SKINNY_TONEDIRECTION_USER);
1030 			return SCCP_RTP_STATUS_ACTIVE;
1031 		}
1032 		sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_RTP))(VERBOSE_PREFIX_3 "%s: (mediaTransmissionStarted) Channel is already terminating. Giving up... (%s)\n", DEV_ID_LOG(d), sccp_channelstate2str(c->state));
1033 		return SCCP_RTP_STATUS_ACTIVE;
1034 	}
1035 
1036 	sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_3 "%s: Media Transmission Started (State: %s[%d])\n", d->id, sccp_channelstate2str(c->state), c->state);
1037 	sccp_rtp_appendState(audio, SCCP_RTP_TRANSMISSION, SCCP_RTP_STATUS_ACTIVE);
1038 	return SCCP_RTP_STATUS_ACTIVE;
1039 }
1040 
1041 /*!
1042  * \brief Tell device to Stop Media Transmission.
1043  *
1044  * Also RTP will be Stopped/Destroyed and Call Statistic is requested.
1045  * \param channel SCCP Channel
1046  * \param KeepPortOpen Boolean
1047  *
1048  */
sccp_channel_stopMediaTransmission(constChannelPtr channel,boolean_t KeepPortOpen)1049 void sccp_channel_stopMediaTransmission(constChannelPtr channel, boolean_t KeepPortOpen)
1050 {
1051 	sccp_msg_t *msg = NULL;
1052 	pbx_assert(channel != NULL);
1053 	sccp_rtp_t *audio = (sccp_rtp_t *) &(channel->rtp.audio);
1054 
1055 	AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(channel));
1056 	if (!d) {
1057 		pbx_log(LOG_ERROR, "%s: (stopMediaTransmission) Could not retrieve device from channel\n", channel->designator);
1058 		return;
1059 	}
1060 	// stopping phone rtp
1061 	if(sccp_rtp_getState(audio, SCCP_RTP_TRANSMISSION)) {
1062 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_3 "%s: Stop mediatransmission on device %s (KeepPortOpen: %s)\n", channel->designator, d->id, KeepPortOpen ? "YES" : "NO");
1063 		REQ(msg, StopMediaTransmission);
1064 		msg->data.StopMediaTransmission.lel_conferenceId = htolel(channel->callid);
1065 		msg->data.StopMediaTransmission.lel_passThruPartyId = htolel(channel->passthrupartyid);
1066 		msg->data.StopMediaTransmission.lel_callReference = htolel(channel->callid);
1067 		msg->data.StopMediaTransmission.lel_portHandlingFlag = htolel(KeepPortOpen);
1068 		sccp_dev_send(d, msg);
1069 		sccp_rtp_setState(audio, SCCP_RTP_TRANSMISSION, SCCP_RTP_STATUS_INACTIVE);
1070 #ifdef CS_EXPERIMENTAL
1071 		if (!KeepPortOpen) {
1072 			d->protocol->sendPortClose(d, channel, SKINNY_MEDIA_TYPE_AUDIO);
1073 		}
1074 #endif
1075 	}
1076 }
1077 
sccp_channel_updateMediaTransmission(constChannelPtr channel)1078 void sccp_channel_updateMediaTransmission(constChannelPtr channel)
1079 {
1080 	/* \note apparently startmediatransmission allows us to change the ip-information midflight without stopping mediatransmission beforehand */
1081 	/* \note this would indicate that it should also be possible to change codecs midflight ! */
1082 	/* \test should be able to do without this block to stopmediatransmission (Sometimes results in "OpenIngressChan: Potential buffer leak" (phone log) */
1083 	if(sccp_rtp_getState(&channel->rtp.audio, SCCP_RTP_TRANSMISSION)) {
1084 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_2 "%s: (updateMediaTransmission) Stop media transmission on channel %d\n", channel->currentDeviceId, channel->callid);
1085 		sccp_channel_stopMediaTransmission(channel, TRUE);
1086 	}
1087 	if(!sccp_rtp_getState(&channel->rtp.audio, SCCP_RTP_TRANSMISSION)) {
1088 		/*! \todo we should wait for the acknowledgement to get back. We don't have a function/procedure in place to do this at this moment in time (sccp_dev_send_wait) */
1089 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_2 "%s: (updateMediaTransmission) Start/Update media transmission on channel %d\n", channel->currentDeviceId, channel->callid);
1090 		sccp_channel_startMediaTransmission(channel);
1091 	}
1092 }
1093 
1094 /*!
1095  * \brief Open Multi Media Channel (Video) on Channel
1096  * \param channel SCCP Channel
1097  */
sccp_channel_openMultiMediaReceiveChannel(constChannelPtr channel)1098 void sccp_channel_openMultiMediaReceiveChannel(constChannelPtr channel)
1099 {
1100 	int payloadType = 0;
1101 	uint8_t lineInstance = 0;
1102 	// int bitRate = 1500;
1103 	int bitRate = channel->maxBitRate;
1104 
1105 	pbx_assert(channel != NULL);
1106 	pbx_assert(channel->line != NULL); /* should not be possible, but received a backtrace / report */
1107 	sccp_rtp_t *video = (sccp_rtp_t *) &(channel->rtp.video);
1108 
1109 	if(channel->isHangingUp || !channel->owner || pbx_check_hangup_locked(channel->owner)) {
1110 		pbx_log(LOG_ERROR, "%s: (%s) Channel already hanging up\n", channel->designator, __func__);
1111 		return;
1112 	}
1113 
1114 	if(sccp_rtp_getState(video, SCCP_RTP_RECEPTION)) {
1115 		sccp_log(DEBUGCAT_RTP)(VERBOSE_PREFIX_3 "%s: (%s) Already pending\n", channel->designator, __func__);
1116 		return;
1117 	}
1118 
1119 	AUTO_RELEASE(sccp_device_t, d, sccp_channel_getDevice(channel));
1120 	if(!d) {
1121 		pbx_log(LOG_ERROR, "%s: (%s) Could not retrieve device from channel\n", channel->designator, __func__);
1122 		return;
1123 	}
1124 
1125 	if (sccp_channel_getVideoMode(channel) == SCCP_VIDEO_MODE_OFF || !sccp_device_isVideoSupported(d)) {
1126 		pbx_log(LOG_WARNING, "%s: (openMultiMediaReceiveChannel) No video supported on device:%s or turning off. returning.\n", channel->designator, d->id);
1127 		return;
1128 	}
1129 
1130 	if (!video->instance && !sccp_rtp_createServer(d, (channelPtr)channel, SCCP_RTP_VIDEO)) {				// discard const
1131 		pbx_log(LOG_WARNING, "%s: (openMultiMediaReceiveChannel) Could not start vrtp on device:%s. returning\n", channel->designator, d->id);
1132 		sccp_channel_setVideoMode((channelPtr)channel, "off");								// discard const
1133 		return;
1134 	}
1135 
1136 	if(SKINNY_CODEC_NONE == video->reception.format && !sccp_channel_recalculateVideoCodecFormat((channelPtr)channel)) {
1137 		return;
1138 	}
1139 
1140 	//if (d->nat >= SCCP_NAT_ON) {
1141 	//	sccp_rtp_updateNatRemotePhone(channel, video);
1142 	//}
1143 	sccp_rtp_setState(video, SCCP_RTP_RECEPTION, SCCP_RTP_STATUS_PROGRESS);
1144 
1145 	payloadType = sccp_rtp_get_payloadType(&channel->rtp.video, video->reception.format);
1146 	lineInstance = sccp_device_find_index_for_line(d, channel->line->name);
1147 
1148 	d->protocol->sendOpenMultiMediaChannel(d, channel, video->reception.format, payloadType, lineInstance, bitRate);                                        // extra receive channel retension
1149 
1150 	sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_3 "%s: Open receive multimedia channel with format %s[%d], payload %d\n", d->id,
1151 		codec2str(video->reception.format), video->reception.format, payloadType);
1152 }
1153 
sccp_channel_receiveMultiMediaChannelOpen(constDevicePtr d,channelPtr c)1154 int sccp_channel_receiveMultiMediaChannelOpen(constDevicePtr d, channelPtr c)
1155 {
1156 	pbx_assert(d != NULL && c != NULL);
1157 	sccp_rtp_t * video = &(c->rtp.video);
1158 	// check channel state
1159 	if (!video->instance) {
1160 		pbx_log(LOG_ERROR, "%s: Channel has no rtp instance!\n", d->id);
1161 		sccp_channel_endcall(c);											// FS - 350
1162 		return SCCP_RTP_STATUS_INACTIVE;
1163 	}
1164 
1165 	if(c->isHangingUp || !c->owner || pbx_check_hangup_locked(c->owner) || SCCP_CHANNELSTATE_Idling(c->state) || SCCP_CHANNELSTATE_IsTerminating(c->state)) {
1166 		if (c->state == SCCP_CHANNELSTATE_INVALIDNUMBER || c->state == SCCP_CHANNELSTATE_CONGESTION) {
1167 			sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_RTP)) (VERBOSE_PREFIX_3 "%s: Stop Tone %s\n", DEV_ID_LOG(d), sccp_channelstate2str(c->state));
1168 			c->setTone(c, SKINNY_TONE_SILENCE, SKINNY_TONEDIRECTION_USER);
1169 			return SCCP_RTP_STATUS_ACTIVE;
1170 		}
1171 		sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_RTP))(VERBOSE_PREFIX_3 "%s: (receiveMultiMediaChannelOpen) Channel is already terminating. Giving up... (%s)\n", DEV_ID_LOG(d), sccp_channelstate2str(c->state));
1172 		return SCCP_RTP_STATUS_ACTIVE;
1173 	}
1174 
1175 	sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_3 "%s: Opened MultiMedia Receive Channel (State: %s[%d])\n", d->id, sccp_channelstate2str(c->state), c->state);
1176 	sccp_rtp_appendState(video, SCCP_RTP_RECEPTION, SCCP_RTP_STATUS_ACTIVE);
1177 
1178 	if (c->owner && (c->state == SCCP_CHANNELSTATE_CONNECTED || c->state == SCCP_CHANNELSTATE_CONNECTEDCONFERENCE)) {
1179 		if(sccp_rtp_getState(video, SCCP_RTP_TRANSMISSION) & SCCP_RTP_STATUS_ACTIVE) {
1180 			d->protocol->sendMultiMediaCommand(d, c, SKINNY_MISCCOMMANDTYPE_VIDEOFASTUPDATEPICTURE);
1181 			//msg_out = sccp_build_packet(FlowControlNotifyMessage, sizeof(msg_out->data.FlowControlNotifyMessage));
1182 			//msg_out->data.FlowControlNotifyMessage.lel_conferenceID         = htolel(c->callid);
1183 			//msg_out->data.FlowControlNotifyMessage.lel_passThruPartyId      = htolel(c->passthrupartyid);
1184 			//msg_out->data.FlowControlNotifyMessage.lel_callReference        = htolel(c->callid);
1185 			//msg_out->data.FlowControlNotifyMessage.lel_maxBitRate           = htolel(500000);
1186 		} else if(sccp_channel_getVideoMode(c) == SCCP_VIDEO_MODE_AUTO) {
1187 			sccp_channel_startMultiMediaTransmission(c);
1188 		}
1189 		iPbx.queue_control(c->owner, AST_CONTROL_VIDUPDATE);
1190 	}
1191 	return SCCP_RTP_STATUS_ACTIVE;
1192 }
1193 
1194 /*!
1195  * \brief Open Multi Media Channel (Video) on Channel
1196  * \param channel SCCP Channel
1197  * \param KeepPortOpen Boolean
1198  */
sccp_channel_closeMultiMediaReceiveChannel(constChannelPtr channel,boolean_t KeepPortOpen)1199 void sccp_channel_closeMultiMediaReceiveChannel(constChannelPtr channel, boolean_t KeepPortOpen)
1200 {
1201 	sccp_msg_t *msg = NULL;
1202 	pbx_assert(channel != NULL);
1203 	sccp_rtp_t *video = (sccp_rtp_t *) &(channel->rtp.video);
1204 
1205 	AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(channel));
1206 	if (!d) {
1207 		pbx_log(LOG_ERROR, "%s: (closeMultiMediaReceiveChannel) Could not retrieve device from channel\n", channel->designator);
1208 		return;
1209 	}
1210 	// stop transmitting before closing receivechannel (\note maybe we should not be doing this here)
1211 	sccp_channel_stopMediaTransmission(channel, KeepPortOpen);
1212 
1213 	if(sccp_rtp_getState(video, SCCP_RTP_RECEPTION)) {
1214 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_3 "%s: Close multimedia receive channel on device %s (KeepPortOpen: %s)\n", channel->designator, d->id, KeepPortOpen ? "YES" : "NO");
1215 		REQ(msg, CloseMultiMediaReceiveChannel);
1216 		msg->data.CloseMultiMediaReceiveChannel.lel_conferenceId = htolel(channel->callid);
1217 		msg->data.CloseMultiMediaReceiveChannel.lel_passThruPartyId = htolel(channel->passthrupartyid);
1218 		msg->data.CloseMultiMediaReceiveChannel.lel_callReference = htolel(channel->callid);
1219 		msg->data.CloseMultiMediaReceiveChannel.lel_portHandlingFlag = htolel(KeepPortOpen);
1220 		sccp_dev_send(d, msg);
1221 		sccp_rtp_setState(video, SCCP_RTP_RECEPTION, SCCP_RTP_STATUS_INACTIVE);
1222 #ifdef CS_EXPERIMENTAL
1223 		if (!KeepPortOpen) {
1224 			d->protocol->sendPortClose(d, channel, SKINNY_MEDIA_TYPE_MAIN_VIDEO);
1225 		}
1226 #endif
1227 	}
1228 	((channelPtr)channel)->videomode = channel->line->videomode;								// discard const
1229 }
1230 
1231 #if UNUSEDCODE // 2015-11-01
sccp_channel_updateMultiMediaReceiveChannel(constChannelPtr channel)1232 void sccp_channel_updateMultiMediaReceiveChannel(constChannelPtr channel)
1233 {
1234 	if(sccp_rtp_getState(&channel->rtp.video, SCCP_RTP_RECEPTION)) {
1235 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_2 "%s: (sccp_channel_updateMultiMediaReceiveChannel) Stop multimedia transmission on channel %d\n", channel->currentDeviceId, channel->callid);
1236 		sccp_channel_closeMultiMediaReceiveChannel(channel, TRUE);
1237 	}
1238 	if(!sccp_rtp_getState(&channel.rtp.video, SCCP_RTP_RECEPTION)) {
1239 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_2 "%s: (sccp_channel_updateMultiMediaReceiveChannel) Start media transmission on channel %d\n", channel->currentDeviceId, channel->callid);
1240 		sccp_channel_openMultiMediaReceiveChannel(channel);
1241 	}
1242 }
1243 #endif
1244 
1245 /*!
1246  * \brief Start Multi Media Transmission (Video) on Channel
1247  * \param channel SCCP Channel
1248  */
sccp_channel_startMultiMediaTransmission(constChannelPtr channel)1249 void sccp_channel_startMultiMediaTransmission(constChannelPtr channel)
1250 {
1251 	int payloadType = 0;
1252 	int bitRate = channel->maxBitRate;
1253 
1254 	pbx_assert(channel != NULL);
1255 	pbx_assert(channel->line != NULL); /* should not be possible, but received a backtrace / report */
1256 	sccp_rtp_t *video = (sccp_rtp_t *) &(channel->rtp.video);
1257 
1258 	if(channel->isHangingUp || !channel->owner || pbx_check_hangup_locked(channel->owner)) {
1259 		pbx_log(LOG_ERROR, "%s: (%s) Channel already hanging up\n", channel->designator, __func__);
1260 		return;
1261 	}
1262 
1263 	if(sccp_rtp_getState(video, SCCP_RTP_TRANSMISSION)) {
1264 		sccp_log(DEBUGCAT_RTP)(VERBOSE_PREFIX_3 "%s: (%s) Already pending\n", channel->designator, __func__);
1265 		return;
1266 	}
1267 
1268 	AUTO_RELEASE(sccp_device_t, d, sccp_channel_getDevice(channel));
1269 	if(!d) {
1270 		pbx_log(LOG_ERROR, "%s: (%s) Could not retrieve device from channel\n", channel->designator, __func__);
1271 		sccp_channel_closeMultiMediaReceiveChannel(channel, FALSE);
1272 		return;
1273 	}
1274 
1275 	if (sccp_channel_getVideoMode(channel) == SCCP_VIDEO_MODE_OFF || !sccp_device_isVideoSupported(d)) {
1276 		pbx_log(LOG_WARNING, "%s: (openMultiMediaTransmission) No video supported on device:%s or turning off. returning.\n", channel->designator, d->id);
1277 		return;
1278 	}
1279 
1280 	if (!video->instance) {
1281 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_3 "%s: can't start vrtp media transmission, maybe channel is down %s\n", channel->currentDeviceId, channel->designator);
1282 		sccp_channel_setVideoMode((channelPtr)channel, "off");								// discard const
1283 		return;
1284 	}
1285 	//if (d->nat >= SCCP_NAT_ON) {												/* device is natted */
1286 	//	sccp_rtp_updateNatRemotePhone(channel, video);
1287 	//}
1288 
1289 	sccp_rtp_setState(video, SCCP_RTP_TRANSMISSION, SCCP_RTP_STATUS_PROGRESS);
1290 
1291 	/* lookup payloadType */
1292 	payloadType = sccp_rtp_get_payloadType(&channel->rtp.video, video->transmission.format);
1293 
1294 	d->protocol->sendStartMultiMediaTransmission(d, channel, payloadType, bitRate);                                        // extra mediatransmission channel retension
1295 
1296 	char buf1[NI_MAXHOST + NI_MAXSERV];
1297 	char buf2[NI_MAXHOST + NI_MAXSERV];
1298 	sccp_copy_string(buf1, sccp_netsock_stringify(&video->phone), sizeof(buf1));
1299 	sccp_copy_string(buf2, sccp_netsock_stringify(&video->phone_remote), sizeof(buf2));
1300 	sccp_log(DEBUGCAT_RTP) (VERBOSE_PREFIX_3 "%s: (startMultiMediaTransmission) Tell Phone to send VRTP/UDP media from %s to %s (NAT: %s)\n", d->id, buf1, buf2, sccp_nat2str(d->nat));
1301 	sccp_log(DEBUGCAT_RTP) (VERBOSE_PREFIX_3 "%s: (StartMultiMediaTransmission) Using format: %s(%d), payload:%d, TOS %d for call with PassThruId: %u and CallID: %u\n", d->id,
1302 		codec2str(video->transmission.format), video->transmission.format, payloadType, d->video_tos, channel->passthrupartyid, channel->callid);
1303 
1304 	iPbx.queue_control(channel->owner, AST_CONTROL_VIDUPDATE);
1305 }
1306 
sccp_channel_multiMediaTransmissionStarted(constDevicePtr d,channelPtr c)1307 int sccp_channel_multiMediaTransmissionStarted(constDevicePtr d, channelPtr c)
1308 {
1309 	//pbx_builtin_setvar_helper(c->owner, "_SCCP_VIDEO_MODE", sccp_video_mode2str(sccp_channel_getVideoMode(c)));
1310 	//iPbx.queue_control(c->owner, AST_CONTROL_VIDUPDATE);
1311 	//return SCCP_RTP_STATUS_ACTIVE;
1312 	pbx_assert(d != NULL && c != NULL);
1313 	sccp_rtp_t * video = &(c->rtp.video);
1314 	// check channel state
1315 	if (!video->instance) {
1316 		pbx_log(LOG_ERROR, "%s: Channel has no vrtp instance!\n", d->id);
1317 		sccp_channel_endcall(c);											// FS - 350
1318 		return SCCP_RTP_STATUS_INACTIVE;
1319 	}
1320 
1321 	if(c->isHangingUp || !c->owner || pbx_check_hangup_locked(c->owner) || SCCP_CHANNELSTATE_Idling(c->state) || SCCP_CHANNELSTATE_IsTerminating(c->state)) {
1322 		if (c->state == SCCP_CHANNELSTATE_INVALIDNUMBER || c->state == SCCP_CHANNELSTATE_CONGESTION) {
1323 			sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_RTP)) (VERBOSE_PREFIX_3 "%s: Stop Tone %s\n", DEV_ID_LOG(d), sccp_channelstate2str(c->state));
1324 			c->setTone(c, SKINNY_TONE_SILENCE, SKINNY_TONEDIRECTION_USER);
1325 			return SCCP_RTP_STATUS_ACTIVE;
1326 		}
1327 		sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_RTP))(VERBOSE_PREFIX_3 "%s: (multiMediaTransmissionStarted) Channel is already terminating. Giving up... (%s)\n", DEV_ID_LOG(d), sccp_channelstate2str(c->state));
1328 		return SCCP_RTP_STATUS_ACTIVE;
1329 	}
1330 
1331 	sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_3 "%s: Multi Media Transmission Started (State: %s[%d])\n", d->id, sccp_channelstate2str(c->state), c->state);
1332 
1333 	sccp_rtp_appendState(video, SCCP_RTP_TRANSMISSION, SCCP_RTP_STATUS_ACTIVE);
1334 	if (c->owner) {
1335 		iPbx.queue_control(c->owner, AST_CONTROL_VIDUPDATE);
1336 	}
1337 	return SCCP_RTP_STATUS_ACTIVE;
1338 }
1339 
1340 /*!
1341  * \brief Stop Multi Media Transmission (Video) on Channel
1342  * \param channel SCCP Channel
1343  * \param KeepPortOpen Boolean
1344  */
sccp_channel_stopMultiMediaTransmission(constChannelPtr channel,boolean_t KeepPortOpen)1345 void sccp_channel_stopMultiMediaTransmission(constChannelPtr channel, boolean_t KeepPortOpen)
1346 {
1347 	sccp_msg_t *msg = NULL;
1348 
1349 	pbx_assert(channel != NULL);
1350 	sccp_rtp_t *video = (sccp_rtp_t *) &(channel->rtp.video);
1351 
1352 	AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(channel));
1353 	if (!d) {
1354 		pbx_log(LOG_ERROR, "%s: (stopMultiMediaReceiveChannel) Could not retrieve device from channel\n", channel->designator);
1355 		return;
1356 	}
1357 	// stopping phone vrtp
1358 	if(sccp_rtp_getState(video, SCCP_RTP_TRANSMISSION)) {
1359 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_3 "%s: Stop multimediatransmission on device %s (KeepPortOpen: %s)\n", channel->designator, d->id, KeepPortOpen ? "YES" : "NO");
1360 		REQ(msg, StopMultiMediaTransmission);
1361 		msg->data.StopMultiMediaTransmission.lel_conferenceId = htolel(channel->callid);
1362 		msg->data.StopMultiMediaTransmission.lel_passThruPartyId = htolel(channel->passthrupartyid);
1363 		msg->data.StopMultiMediaTransmission.lel_callReference = htolel(channel->callid);
1364 		msg->data.StopMultiMediaTransmission.lel_portHandlingFlag = htolel(KeepPortOpen);
1365 		sccp_dev_send(d, msg);
1366 		sccp_rtp_setState(video, SCCP_RTP_TRANSMISSION, SCCP_RTP_STATUS_INACTIVE);
1367 	}
1368 }
1369 
1370 #if UNUSEDCODE // 2015-11-01
sccp_channel_updateMultiMediaTransmission(constChannelPtr channel)1371 void sccp_channel_updateMultiMediaTransmission(constChannelPtr channel)
1372 {
1373 	if(sccp_rtp_getState(&channel->rtp.video, SCCP_RTP_TRANSMISSION)) {
1374 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_2 "%s: (updateMultiMediaTransmission) Stop multiemedia transmission on channel %d\n", channel->currentDeviceId, channel->callid);
1375 		sccp_channel_stopMultiMediaTransmission(channel, TRUE);
1376 	}
1377 	if(!sccp_rtp_getState(&channel->rtp.video, SCCP_RTP_TRANSMISSION)) {
1378 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_2 "%s: (updateMultiMediaTransmission) Start multimedia transmission on channel %d\n", channel->currentDeviceId, channel->callid);
1379 		sccp_channel_startMultiMediaTransmission(channel);
1380 	}
1381 }
1382 #endif
1383 
sccp_channel_closeAllMediaTransmitAndReceive(constChannelPtr channel)1384 sccp_rtp_status_t sccp_channel_closeAllMediaTransmitAndReceive(constChannelPtr channel)
1385 {
1386 	//! \todo This is what we should check, need to cover all calling paths though
1387 	// pbx_assert(channel != NULL && d != NULL);
1388 	// for now only check channel and skip otherwise (dangerous)
1389 	pbx_assert(channel != NULL);
1390 	sccp_rtp_status_t res = SCCP_RTP_STATUS_ACTIVE;
1391 	sccp_rtp_t * audio = (sccp_rtp_t *)&(channel->rtp.audio);
1392 	sccp_rtp_t * video = (sccp_rtp_t *)&(channel->rtp.video);
1393 
1394 	sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_2 "%s: (sccp_channel_closeAllMediaTransmitAndReceive) Stop All Media Reception and Transmission on device %s\n", channel->designator, channel->currentDeviceId);
1395 	if(sccp_rtp_getState(audio, SCCP_RTP_RECEPTION)) {
1396 		sccp_channel_closeReceiveChannel(channel, FALSE);
1397 	}
1398 	if(sccp_rtp_getState(video, SCCP_RTP_RECEPTION)) {
1399 		sccp_channel_closeMultiMediaReceiveChannel(channel, FALSE);
1400 	}
1401 	if(sccp_rtp_getState(audio, SCCP_RTP_TRANSMISSION)) {
1402 		sccp_channel_stopMediaTransmission(channel, FALSE);
1403 	}
1404 	if(sccp_rtp_getState(video, SCCP_RTP_TRANSMISSION)) {
1405 		sccp_channel_stopMultiMediaTransmission(channel, FALSE);
1406 	}
1407 	res = SCCP_RTP_STATUS_INACTIVE;
1408 	if (channel->rtp.audio.instance || channel->rtp.video.instance) {
1409 		sccp_rtp_stop(channel);
1410 	}
1411 	return res;
1412 }
1413 
1414 /*
1415  * \brief Check if we are in the middle of a transfer and if transfer on hangup is wanted, function is only called by sccp_handle_onhook for now
1416  */
sccp_channel_transfer_on_hangup(constChannelPtr channel)1417 boolean_t sccp_channel_transfer_on_hangup(constChannelPtr channel)
1418 {
1419 	boolean_t result = FALSE;
1420 	if (!channel || !GLOB(transfer_on_hangup)) {
1421 		return result;
1422 	}
1423 	AUTO_RELEASE(sccp_device_t, d , channel->privateData->device ? sccp_device_retain(channel->privateData->device) : NULL);
1424 
1425 	if (d && (SCCP_CHANNELSTATE_IsSettingUp(channel->state) || SCCP_CHANNELSTATE_IsConnected(channel->state))) {	/* Complete transfer when one is in progress */
1426 		sccp_channel_t *transferee = d->transferChannels.transferee;
1427 		sccp_channel_t *transferer = d->transferChannels.transferer;
1428 
1429 		if ((transferee && transferer) && (channel == transferer) && (pbx_channel_state(transferer->owner) == AST_STATE_UP || pbx_channel_state(transferer->owner) == AST_STATE_RING)
1430 		    ) {
1431 			sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: In the middle of a Transfer. Going to transfer completion (channel_name: %s, transferee_name: %s, transferer_name: %s, transferer_state: %d)\n", channel->designator, pbx_channel_name(channel->owner), pbx_channel_name(transferee->owner), pbx_channel_name(transferer->owner), pbx_channel_state(transferer->owner));
1432 			sccp_channel_transfer_complete(transferer);
1433 			result = TRUE;
1434 		}
1435 	}
1436 	return result;
1437 }
1438 
1439 /*
1440  * \brief End all forwarding parent channels
1441  */
sccp_channel_end_forwarding_channel(channelPtr orig_channel)1442 void sccp_channel_end_forwarding_channel(channelPtr orig_channel)
1443 {
1444 	sccp_channel_t *c = NULL;
1445 
1446 	if (!orig_channel || !orig_channel->line) {
1447 		return;
1448 	}
1449 
1450 	SCCP_LIST_TRAVERSE_SAFE_BEGIN(&orig_channel->line->channels, c, list) {
1451 		if (c->parentChannel == orig_channel) {
1452 			sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "%s: (sccp_channel_end_forwarding_channel) Send Hangup to CallForwarding Channel:%s\n", orig_channel->designator, c->designator);
1453 			sccp_channel_release(&c->parentChannel);				/* explicit release refcounted parentChannel */
1454 			/* make sure a ZOMBIE channel is hungup using requestHangup if it is still available after the masquerade */
1455 			c->hangupRequest = sccp_astgenwrap_requestHangup;
1456 			/* need to use scheduled hangup, so that we clear any outstanding locks (during masquerade) before calling hangup */
1457 			c->isHangingUp = TRUE;
1458 			if (ATOMIC_FETCH(&c->scheduler.deny, &c->scheduler.lock) == 0) {
1459 				sccp_channel_stop_and_deny_scheduled_tasks(c);
1460 			}
1461 			c->hangupRequest(c);
1462 			//sccp_channel_schedule_hangup(c, SCCP_HANGUP_TIMEOUT);
1463 
1464 			orig_channel->answered_elsewhere = TRUE;
1465 		}
1466 	}
1467 	SCCP_LIST_TRAVERSE_SAFE_END;
1468 }
1469 
1470 /*!
1471  * \brief Scheduled Hangup for a channel channel (Used by invalid number)
1472  */
_sccp_channel_sched_endcall(const void * data)1473 static int _sccp_channel_sched_endcall(const void *data)
1474 {
1475 	AUTO_RELEASE(sccp_channel_t, channel, sccp_channel_retain(data));
1476 	if(channel) {
1477 		channel->scheduler.hangup_id = -3;
1478 		sccp_log(DEBUGCAT_CHANNEL) ("%s: Scheduled Hangup\n", channel->designator);
1479 		if (ATOMIC_FETCH(&channel->scheduler.deny, &channel->scheduler.lock) == 0) {			/* we cancelled all scheduled tasks, so we should not be hanging up this channel anymore */
1480 			sccp_channel_stop_and_deny_scheduled_tasks(channel);
1481 			sccp_channel_endcall(channel);
1482 		}
1483 		sccp_channel_release((sccp_channel_t **)&data);							// release channel retained in scheduled event
1484 	}
1485 	return 0;												// return 0 to release schedule !
1486 }
1487 
1488 /*
1489  * Remove Schedule digittimeout
1490  */
sccp_channel_stop_schedule_digittimout(constChannelPtr channel)1491 gcc_inline void sccp_channel_stop_schedule_digittimout(constChannelPtr channel)
1492 {
1493 	AUTO_RELEASE(sccp_channel_t, c , sccp_channel_retain(channel));
1494 
1495 	if (c && c->scheduler.digittimeout_id > -1) {
1496 		//sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: stop schedule digittimeout %d\n", c->designator, c->scheduler.digittimeout_id);
1497 		iPbx.sched_del_ref(&c->scheduler.digittimeout_id, c);
1498 	}
1499 }
1500 
1501 /*
1502  * Schedule hangup if allowed and not already scheduled
1503  * \note needs to take retain on channel to pass it on the the scheduled hangup
1504  */
sccp_channel_schedule_hangup(constChannelPtr channel,int timeout)1505 gcc_inline void sccp_channel_schedule_hangup(constChannelPtr channel, int timeout)
1506 {
1507 	AUTO_RELEASE(sccp_channel_t, c , sccp_channel_retain(channel));
1508 	int res = 0;
1509 
1510 	/* only schedule if allowed and not already scheduled */
1511 	if (c && c->scheduler.hangup_id == -1 && !ATOMIC_FETCH(&c->scheduler.deny, &c->scheduler.lock)) {
1512 		res = iPbx.sched_add_ref(&c->scheduler.hangup_id, timeout, _sccp_channel_sched_endcall, c);
1513 		if (res < 0) {
1514 			pbx_log(LOG_NOTICE, "%s: Unable to schedule dialing in '%d' ms\n", c->designator, timeout);
1515 		}
1516 	}
1517 }
1518 
1519 /*
1520  * Schedule digittimeout if allowed
1521  * Release any previously scheduled digittimeout
1522  */
sccp_channel_schedule_digittimeout(constChannelPtr channel,int timeout)1523 gcc_inline void sccp_channel_schedule_digittimeout(constChannelPtr channel, int timeout)
1524 {
1525 	sccp_channel_t *c = sccp_channel_retain(channel);
1526 
1527 	/* only schedule if allowed and not already scheduled */
1528 	if (c && c->scheduler.hangup_id == -1 && !ATOMIC_FETCH(&c->scheduler.deny, &c->scheduler.lock)) {
1529 		sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: schedule digittimeout %d\n", c->designator, timeout);
1530 		if (c->scheduler.digittimeout_id == -1) {
1531 			iPbx.sched_add_ref(&c->scheduler.digittimeout_id, timeout * 1000, sccp_pbx_sched_dial, c);
1532 		} else {
1533 			iPbx.sched_replace_ref(&c->scheduler.digittimeout_id, timeout * 1000, sccp_pbx_sched_dial, c);
1534 		}
1535 		sccp_channel_release(&c);
1536 	}
1537 }
1538 
sccp_channel_stop_and_deny_scheduled_tasks(constChannelPtr channel)1539 void sccp_channel_stop_and_deny_scheduled_tasks(constChannelPtr channel)
1540 {
1541 	AUTO_RELEASE(sccp_channel_t, c , sccp_channel_retain(channel));
1542 	if (c) {
1543 		(void) ATOMIC_INCR(&c->scheduler.deny, TRUE, &c->scheduler.lock);
1544 		sccp_log(DEBUGCAT_CHANNEL)(VERBOSE_PREFIX_3 "%s: Disabling scheduler / Removing Scheduled tasks (digittimeout_id:%d) (hangup_id:%d) (cfwd_noanswer_id:%d)\n", c->designator, c->scheduler.digittimeout_id,
1545 					   c->scheduler.hangup_id, c->scheduler.cfwd_noanswer_id);
1546 		if (c->scheduler.digittimeout_id > -1) {
1547 			iPbx.sched_del_ref(&c->scheduler.digittimeout_id, c);
1548 		}
1549 		if (c->scheduler.hangup_id > -1) {
1550 			iPbx.sched_del_ref(&c->scheduler.hangup_id, c);
1551 		}
1552 		if(c->scheduler.cfwd_noanswer_id > -1) {
1553 			iPbx.sched_del_ref(&c->scheduler.cfwd_noanswer_id, c);
1554 		}
1555 	}
1556 }
1557 
sccp_channel_schedule_cfwd_noanswer(constChannelPtr channel,int timeout)1558 gcc_inline void sccp_channel_schedule_cfwd_noanswer(constChannelPtr channel, int timeout)
1559 {
1560 	sccp_channel_t * c = sccp_channel_retain(channel);
1561 	/* only schedule if allowed and not already scheduled */
1562 	if(c && c->scheduler.cfwd_noanswer_id == -1 && !ATOMIC_FETCH(&c->scheduler.deny, &c->scheduler.lock)) {
1563 		sccp_log((DEBUGCAT_CORE))(VERBOSE_PREFIX_3 "%s: schedule cfwd_noanswer %d\n", c->designator, timeout);
1564 		if(c->scheduler.cfwd_noanswer_id == -1) {
1565 			iPbx.sched_add_ref(&c->scheduler.cfwd_noanswer_id, timeout * 1000, sccp_pbx_cfwdnoanswer_cb, c);
1566 		}
1567 		sccp_channel_release(&c);
1568 	}
1569 }
1570 
sccp_channel_stop_schedule_cfwd_noanswer(constChannelPtr channel)1571 gcc_inline void sccp_channel_stop_schedule_cfwd_noanswer(constChannelPtr channel)
1572 {
1573 	AUTO_RELEASE(sccp_channel_t, c, sccp_channel_retain(channel));
1574 
1575 	if (c && c->scheduler.cfwd_noanswer_id > -1) {
1576 		sccp_log((DEBUGCAT_CORE))(VERBOSE_PREFIX_3 "%s: stop schedule cfwd_noanswer_id %d\n", c->designator, c->scheduler.cfwd_noanswer_id);
1577 		iPbx.sched_del_ref(&c->scheduler.cfwd_noanswer_id, c);
1578 	}
1579 }
1580 
1581 /*!
1582  * \brief Hangup this channel.
1583  * \param channel *retained* SCCP Channel
1584  *
1585  * \callgraph
1586  * \callergraph
1587  */
sccp_channel_endcall(channelPtr channel)1588 void sccp_channel_endcall(channelPtr channel)
1589 {
1590 	if (!channel || !channel->line) {
1591 		pbx_log(LOG_WARNING, "No channel or line or device to hangup\n");
1592 		return;
1593 	}
1594 	channel->isHangingUp = TRUE;
1595 	if (ATOMIC_FETCH(&channel->scheduler.deny, &channel->scheduler.lock) == 0) {
1596 		sccp_channel_stop_and_deny_scheduled_tasks(channel);
1597 	}
1598 	/* end all call forwarded channels (our children) */
1599 	sccp_channel_end_forwarding_channel(channel);
1600 
1601 	/* this is a station active endcall or onhook */
1602 	AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(channel));
1603 
1604 	if (d) {
1605 		sccp_log((DEBUGCAT_CORE + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_2 "%s: Ending call %s (state:%s)\n", d->id, channel->designator, sccp_channelstate2str(channel->state));
1606 		if (d->transferChannels.transferee != channel) {
1607 			sccp_channel_transfer_cancel(d, channel);
1608 		}
1609 	}
1610 	if (channel->owner) {
1611 		sccp_log((DEBUGCAT_CORE + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "%s: Sending hangupRequest to Call %s (state: %s)\n", DEV_ID_LOG(d), channel->designator, sccp_channelstate2str(channel->state));
1612 		channel->hangupRequest(channel);
1613 	} else {
1614 		sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_DEVICE)) (VERBOSE_PREFIX_3 "%s: No Asterisk channel to hangup for sccp channel %s\n", DEV_ID_LOG(d), channel->designator);
1615 	}
1616 }
1617 
1618 /*!
1619  * \brief get an SCCP Channel
1620  * Retrieve unused or allocate a new channel
1621  */
sccp_channel_getEmptyChannel(constLinePtr l,constDevicePtr d,channelPtr maybe_c,skinny_calltype_t calltype,PBX_CHANNEL_TYPE * parentChannel,const void * ids)1622 channelPtr sccp_channel_getEmptyChannel(constLinePtr l, constDevicePtr d, channelPtr maybe_c, skinny_calltype_t calltype, PBX_CHANNEL_TYPE * parentChannel, const void *ids)
1623 {
1624 	pbx_assert(l != NULL && d != NULL);
1625 	sccp_log(DEBUGCAT_CORE)("%s: (getEmptyChannel) on line:%s, maybe_c:%s\n", d->id, l->name, maybe_c ? maybe_c->designator : "");
1626 	sccp_channel_t *channel = NULL;
1627 	{
1628 		AUTO_RELEASE(sccp_channel_t, c, maybe_c ? sccp_channel_retain(maybe_c) : sccp_device_getActiveChannel(d));
1629 		if (c) {
1630 			sccp_log(DEBUGCAT_CORE)("%s: (getEmptyChannel) got channel already.\n", d->id);
1631 			AUTO_RELEASE(const sccp_device_t, call_associated_device, c->getDevice(c));
1632 			if (c->state == SCCP_CHANNELSTATE_OFFHOOK && sccp_strlen_zero(c->dialedNumber)) {		// reuse unused channel
1633 				sccp_log(DEBUGCAT_CORE)("%s: (getEmptyChannel) channel not in use -> reuse it.\n", d->id);
1634 				c->setTone(c, SKINNY_TONE_SILENCE, SKINNY_TONEDIRECTION_USER);
1635 				channel = sccp_channel_retain(c);
1636 				channel->calltype = calltype;
1637 				return channel;
1638 			} else if (call_associated_device && call_associated_device == d && !sccp_channel_hold(c)) {
1639 				pbx_log(LOG_ERROR, "%s: Putting Active Channel %s OnHold failed -> Cancelling new CaLL\n", d->id, c->designator);
1640 				return NULL;
1641 			}
1642 		}
1643 	}
1644 	if (!channel && !(channel = sccp_channel_allocate(l, d))) {
1645 		pbx_log(LOG_ERROR, "%s: Can't allocate SCCP channel for line %s\n", d->id, l->name);
1646 		return NULL;
1647 	}
1648 	channel->calltype = calltype;
1649 	if(sccp_pbx_channel_allocate(channel, ids, parentChannel)) {
1650 		return channel;
1651 	}
1652 	return NULL;
1653 }
1654 
1655 /*!
1656  * \brief Allocate a new Outgoing Channel.
1657  *
1658  * \param l SCCP Line that owns this channel
1659  * \param device SCCP Device that owns this channel
1660  * \param dial Dialed Number as char
1661  * \param calltype Calltype as int
1662  * \param parentChannel SCCP Channel for which the channel was created
1663  * \param ids Optional Linked Channel ID's (> asterisk-1.8)
1664  * \return a *retained* SCCP Channel or NULL if something is wrong
1665  *
1666  * \callgraph
1667  * \callergraph
1668  *
1669  */
sccp_channel_newcall(constLinePtr l,constDevicePtr device,const char * dial,skinny_calltype_t calltype,PBX_CHANNEL_TYPE * parentChannel,const void * ids)1670 channelPtr sccp_channel_newcall(constLinePtr l, constDevicePtr device, const char *dial, skinny_calltype_t calltype, PBX_CHANNEL_TYPE * parentChannel, const void *ids)
1671 {
1672 	/* handle outgoing calls */
1673 	if (!l || !device) {
1674 		pbx_log(LOG_ERROR, "SCCP: Can't allocate SCCP channel if device or line is not defined!\n");
1675 		return NULL;
1676 	}
1677 
1678 	sccp_channel_t * const channel = sccp_channel_getEmptyChannel(l, device, NULL, calltype, parentChannel, ids);
1679 	if (!channel) {
1680 		pbx_log(LOG_ERROR, "%s: Can't allocate SCCP channel for line %s\n", device->id, l->name);
1681 		return NULL;
1682 	}
1683 
1684 	channel->softswitch_action = SCCP_SOFTSWITCH_DIAL;							/* softswitch will catch the number to be dialed */
1685 	channel->ss_data = 0;											/* nothing to pass to action */
1686 
1687 	/* copy the number to dial in the ast->exten */
1688 	iPbx.set_callstate(channel, AST_STATE_OFFHOOK);
1689 	if (dial) {
1690 		sccp_indicate(device, channel, SCCP_CHANNELSTATE_SPEEDDIAL);
1691 		sccp_copy_string(channel->dialedNumber, dial, sizeof(channel->dialedNumber));
1692 		sccp_pbx_softswitch(channel);									/* we know the number to dial -> softswitch */
1693 	} else {
1694 		sccp_indicate(device, channel, SCCP_CHANNELSTATE_OFFHOOK);
1695 		sccp_channel_schedule_digittimeout(channel, GLOB(firstdigittimeout));
1696 	}
1697 
1698 	return channel;
1699 }
1700 
1701 /*! \internal
1702  *
1703  * \brief Locks both sccp_channel and sccp_channel owner if owner is present.
1704  *
1705  * \note This function gives a ref to sccp_channel->owner if it is present and locked.
1706  *       This reference must be decremented after sccp_channel->owner is unlocked.
1707  *
1708  * \note If the function exists early (ie: no c->owner set), the sccp_channel returned will be locked.
1709  *
1710  * \pre sccp_channel is not locked
1711  * \post sccp_channel is always locked
1712  * \post sccp_channel->owner is locked and its reference count is increased (if sccp_channel->owner is not NULL)
1713  *
1714  * \returns a pointer to the locked and reffed sccp_channel->owner channel if it exists.
1715  */
sccp_channel_lock_full(channelPtr c,boolean_t retry_indefinitely)1716 PBX_CHANNEL_TYPE * sccp_channel_lock_full(channelPtr c, boolean_t retry_indefinitely)
1717 {
1718 	PBX_CHANNEL_TYPE * pbx_channel = NULL;
1719 
1720 	/* Locking is simple when it is done right.  If you see a deadlock resulting
1721 	 * in this function, it is not this function's fault, Your problem exists elsewhere.
1722 	 * This function is perfect... seriously. */
1723 	do {
1724 		/* First, get the pbx_channel and grab a reference to it */
1725 		sccp_channel_lock(c);
1726 		pbx_channel = c->owner;
1727 		if(pbx_channel) {
1728 			/* The pbx_channel can not go away while we hold the c lock.
1729 			 * Give the pbx_channel a ref so it will not go away after we let
1730 			 * the c lock go. */
1731 			pbx_channel_ref(pbx_channel);
1732 		} else {
1733 			/* no pbx_channel, return c locked */
1734 			return NULL;
1735 		}
1736 		/* We had to hold the c lock while getting a ref to the owner pbx_channel
1737 		 * but now we have to let this lock go in order to preserve proper
1738 		 * locking order when grabbing the pbx_channel lock */
1739 		sccp_channel_unlock(c);
1740 
1741 		/* Look, no deadlock avoidance, hooray! */
1742 		pbx_channel_lock(pbx_channel);
1743 		sccp_channel_lock(c);
1744 		if(c->owner == pbx_channel) {
1745 			/* done */
1746 			break;
1747 		}
1748 
1749 		/* If the owner changed while everything was unlocked, no problem,
1750 		 * just start over and everthing will work.  This is rare, do not be
1751 		 * confused by this loop and think this it is an expensive operation.
1752 		 * The majority of the calls to this function will never involve multiple
1753 		 * executions of this loop. */
1754 		sccp_channel_unlock(c);
1755 		pbx_channel_unlock(pbx_channel);
1756 		pbx_channel_unref(pbx_channel);
1757 	} while(retry_indefinitely);
1758 
1759 	/* If owner exists, it is locked and reffed */
1760 	return pbx_channel;
1761 }
1762 
1763 /*!
1764  * \brief Complete Answer an Incoming Call via Callback when receiveChannelOpen finished.
1765  * \param channel incoming *retained* SCCP channel
1766  *
1767  * \callgraph
1768  * \callergraph
1769  *
1770  * Steps (sccp_channel_answer):
1771  * 1. Lock the pbx_channel and sccp_channel in orderly fashion
1772  * 2. Set callback to finish the answer sequence
1773  * 3. Start openReceiveChannel
1774  * 4. when receiveChannelOpen returns it will call the callback
1775  *
1776  * During callback (channel_answer_completion):
1777  * 1. Regaing the pbx_channel and sccp_channel lock
1778  * 2. send AST_CONTROL_ANSWER
1779  * 3. pbx::app_dial will terminate any other competetitors trying to answer this channel (astwrap_hangup -> sccp_pbx_remote_hangup)
1780  * 4. startMediaTransmission
1781  * 5. Indicate SCCP_CHANNELSTATE_CONNECTED
1782  */
channel_answer_completion(constChannelPtr channel)1783 static void channel_answer_completion(constChannelPtr channel)
1784 {
1785 	pbx_assert(channel && channel->owner);
1786 	AUTO_RELEASE(sccp_channel_t, c, sccp_channel_retain(channel));
1787 	AUTO_RELEASE(sccp_device_t, d, sccp_channel_getDevice(c));
1788 	if(c && d && c->privateData->isAnswering) {
1789 		PBX_CHANNEL_TYPE * pbx_channel = NULL;
1790 		if((pbx_channel = sccp_channel_lock_full(c, TRUE))) {
1791 			if(!pbx_check_hangup_locked(pbx_channel)) {
1792 				sccp_log((DEBUGCAT_CORE))(VERBOSE_PREFIX_3 "%s: (%s) Answering Call: %s (state:%s)\n", d->id, __func__, c->designator, ast_state2str(ast_channel_state(pbx_channel)));
1793 				sccp_channel_startMediaTransmission(c);
1794 				if(ast_channel_state(pbx_channel) != AST_STATE_UP) {
1795 					iPbx.queue_control(pbx_channel, AST_CONTROL_ANSWER);
1796 				}
1797 #ifdef CS_SCCP_VIDEO
1798 				if(sccp_channel_getVideoMode(c) != SCCP_VIDEO_MODE_OFF && sccp_device_isVideoSupported(d)) {
1799 					sccp_channel_openMultiMediaReceiveChannel(c);
1800 				}
1801 #endif
1802 				/*
1803 								AUTO_RELEASE(sccp_line_t, l, sccp_line_retain(c->line));
1804 								if (l && SCCP_LIST_GETSIZE(&l->devices) > 1) {
1805 									sccp_linedevice_t * ld = NULL;
1806 									SCCP_LIST_LOCK(&l->devices);
1807 									SCCP_LIST_TRAVERSE(&l->devices, ld, list) {
1808 										sccp_device_t *otherdevice = ld->device;
1809 										if (otherdevice != d) {
1810 											sccp_log((DEBUGCAT_CORE))(VERBOSE_PREFIX_3 "%s: (%s) Hangingup up sharing subscribers\n", DEV_ID_LOG(otherdevice), __func__);
1811 											otherdevice->indicate->callhistory(otherdevice, ld->lineInstance, c->callid, otherdevice->callhistory_answered_elsewhere);
1812 											sccp_dev_displayprompt(otherdevice, ld->lineInstance, c->callid, SKINNY_DISP_IN_USE_REMOTE, GLOB(digittimeout));
1813 											otherdevice->indicate->onhook(otherdevice, ld->lineInstance, c->callid);
1814 										}
1815 									}
1816 									SCCP_LIST_UNLOCK(&l->devices);
1817 								}
1818 				*/
1819 				/** check for monitor request */
1820 				if((d->monitorFeature.status & SCCP_FEATURE_MONITOR_STATE_REQUESTED) && !(d->monitorFeature.status & SCCP_FEATURE_MONITOR_STATE_ACTIVE)) {
1821 					pbx_log(LOG_NOTICE, "%s: request monitor\n", d->id);
1822 					sccp_feat_monitor(d, NULL, 0, c);
1823 				}
1824 				c->subscribers = 1;
1825 				sccp_indicate(d, c, SCCP_CHANNELSTATE_CONNECTED);
1826 #ifdef CS_MANAGER_EVENTS
1827 				if(GLOB(callevents)) {
1828 					char tmpCallingNumber[StationMaxDirnumSize] = { 0 };
1829 					char tmpCallingName[StationMaxNameSize] = { 0 };
1830 					char tmpOrigCallingName[StationMaxNameSize] = { 0 };
1831 					char tmpLastRedirectingName[StationMaxNameSize] = { 0 };
1832 					iCallInfo.Getter(channel->privateData->callInfo, SCCP_CALLINFO_CALLINGPARTY_NUMBER, &tmpCallingNumber, SCCP_CALLINFO_CALLINGPARTY_NAME, &tmpCallingName,
1833 							 SCCP_CALLINFO_ORIG_CALLINGPARTY_NUMBER, &tmpOrigCallingName, SCCP_CALLINFO_LAST_REDIRECTINGPARTY_NAME, &tmpLastRedirectingName, SCCP_CALLINFO_KEY_SENTINEL);
1834 					manager_event(EVENT_FLAG_CALL, "CallAnswered",
1835 						      "Channel: %s\r\n"
1836 						      "SCCPLine: %s\r\n"
1837 						      "SCCPDevice: %s\r\n"
1838 						      "Uniqueid: %s\r\n"
1839 						      "CallingPartyNumber: %s\r\n"
1840 						      "CallingPartyName: %s\r\n"
1841 						      "originalCallingParty: %s\r\n"
1842 						      "lastRedirectingParty: %s\r\n",
1843 						      c->designator, c->line->name, d->id, iPbx.getChannelUniqueID(c), tmpCallingNumber, tmpCallingName, tmpOrigCallingName, tmpLastRedirectingName);
1844 				}
1845 #endif
1846 				sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_CORE))(VERBOSE_PREFIX_3 "%s: (%s) Answered channel %s\n", d->id, __func__, c->designator);
1847 			} else {
1848 				pbx_log(LOG_WARNING, "%s: (%s) Attempted to answer channel '%s' but someone else beat us to it (actual state:%s)\n", DEV_ID_LOG(d), __func__, c->designator,
1849 					pbx_state2str(ast_channel_state(pbx_channel)));
1850 			}
1851 			pbx_channel_unref(pbx_channel);                                         // reffed by sccp_channel_lock_full
1852 			pbx_channel_unlock(pbx_channel);                                        // locked by sccp_channel_lock_full
1853 		}
1854 		sccp_channel_unlock(c);                                        // locked by sccp_channel_lock_full
1855 	}
1856 }
1857 
1858 /*!
1859  * \brief Answer an Incoming Call.
1860  * \param device SCCP Device who answers
1861  * \param channel incoming *retained* SCCP channel
1862  * \todo handle codec choose
1863  *
1864  * \callgraph
1865  * \callergraph
1866  *
1867  * Steps (sccp_channel_answer):
1868  * 1. Lock the pbx_channel and sccp_channel in orderly fashion
1869  * 2. Set callback to finish the answer sequence
1870  * 3. Start openReceiveChannel
1871  * 4. when receiveChannelOpen returns it will call the callback
1872  *
1873  * During callback (channel_answer_completion):
1874  * 1. Regaing the pbx_channel and sccp_channel lock
1875  * 2. send AST_CONTROL_ANSWER
1876  * 3. pbx::app_dial will terminate any other competetitors trying to answer this channel (astwrap_hangup -> sccp_pbx_remote_hangup)
1877  * 4. startMediaTransmission
1878  * 5. Indicate SCCP_CHANNELSTATE_CONNECTED
1879  */
sccp_channel_answer(constDevicePtr device,channelPtr channel)1880 void sccp_channel_answer(constDevicePtr device, channelPtr channel)
1881 {
1882 	if(!channel || !channel->line || !channel->owner || !device) {
1883 		pbx_log(LOG_ERROR, "%s: (%s) Answering on unknown channel/device\n", (channel ? channel->designator : 0), __func__);
1884 		return;
1885 	}
1886 	sccp_log(DEBUGCAT_CHANNEL)(VERBOSE_PREFIX_1 "%s (sccp_channel_answer) processing answer.\n", channel->designator);
1887 
1888 	sccp_channel_stop_schedule_cfwd_noanswer(channel);
1889 	sccp_channel_end_forwarding_channel(channel);
1890 
1891 	AUTO_RELEASE(sccp_channel_t, previous_channel, sccp_device_getActiveChannel(device));
1892 	if(previous_channel && previous_channel != channel && !sccp_channel_hold(previous_channel)) {
1893 		pbx_log(LOG_ERROR, "%s: Putting Active Channel:%s OnHold failed -> While trying to answer incoming call:%s. Skipping answer!\n", device->id, previous_channel->designator, channel->designator);
1894 		return;
1895 	}
1896 
1897 	PBX_CHANNEL_TYPE * pbx_channel = NULL;
1898 	if((pbx_channel = sccp_channel_lock_full(channel, TRUE))) {
1899 		if(pbx_channel_state(pbx_channel) == AST_STATE_RINGING && !pbx_check_hangup_locked(pbx_channel) && !channel->privateData->isAnswering) {
1900 			channel->privateData->isAnswering = TRUE;
1901 			channel->setDevice(channel, device, TRUE);
1902 			uint16_t lineInstance = sccp_device_find_index_for_line(device, channel->line->name);
1903 			if (channel->state != SCCP_CHANNELSTATE_OFFHOOK) {	/* 7911 need to have callstate offhook, before connected, to transmit audio */
1904 				sccp_device_sendcallstate(device, lineInstance, channel->callid, SKINNY_CALLSTATE_OFFHOOK, SKINNY_CALLPRIORITY_LOW, SKINNY_CALLINFO_VISIBILITY_DEFAULT);
1905 				sccp_dev_set_cplane(device, lineInstance, 1);
1906 				channel->setTone(channel, SKINNY_TONE_SILENCE, SKINNY_TONEDIRECTION_USER);
1907 			}
1908 			pbx_setstate(pbx_channel, AST_STATE_OFFHOOK);
1909 			sccp_device_sendcallstate(device, lineInstance, channel->callid, SKINNY_CALLSTATE_CONNECTED, SKINNY_CALLPRIORITY_LOW,
1910 						  SKINNY_CALLINFO_VISIBILITY_DEFAULT);	// send connected, so it is not listed as missed call on device that fail the answer first
1911 			sccp_rtp_setCallback(&channel->rtp.audio, SCCP_RTP_RECEPTION, channel_answer_completion);
1912 			sccp_channel_openReceiveChannel(channel);
1913 
1914 			AUTO_RELEASE(sccp_line_t, l, sccp_line_retain(channel->line));
1915 			if(l && SCCP_LIST_GETSIZE(&l->devices) > 1) {
1916 				sccp_linedevice_t * ld = NULL;
1917 				SCCP_LIST_LOCK(&l->devices);
1918 				SCCP_LIST_TRAVERSE(&l->devices, ld, list) {
1919 					sccp_device_t * otherdevice = ld->device;
1920 					if(otherdevice != device) {
1921 						sccp_log((DEBUGCAT_CORE))(VERBOSE_PREFIX_3 "%s: (%s) Hanging up sharing subscribers\n", DEV_ID_LOG(otherdevice), __func__);
1922 						otherdevice->indicate->callhistory(otherdevice, ld->lineInstance, channel->callid, otherdevice->callhistory_answered_elsewhere);
1923 						sccp_dev_displayprompt(otherdevice, ld->lineInstance, channel->callid, SKINNY_DISP_IN_USE_REMOTE, GLOB(digittimeout));
1924 						otherdevice->indicate->onhook(otherdevice, ld->lineInstance, channel->callid);
1925 					}
1926 				}
1927 				SCCP_LIST_UNLOCK(&l->devices);
1928 			}
1929 		} else {
1930 			pbx_log(LOG_WARNING, "%s: (%s) Attempted to answer channel '%s' but someone else beat us to it (actual state:%s)\n", DEV_ID_LOG(device), __func__, channel->designator,
1931 				pbx_state2str(ast_channel_state(pbx_channel)));
1932 		}
1933 		pbx_channel_unref(pbx_channel);                                         // reffed by sccp_channel_lock_full
1934 		pbx_channel_unlock(pbx_channel);                                        // locked by sccp_channel_lock_full
1935 	}
1936 	sccp_channel_unlock(channel);							// locked by sccp_channel_lock_full
1937 }
1938 
1939 /*!
1940  * \brief Put channel on Hold.
1941  *
1942  * \param channel *retained* SCCP Channel
1943  * \return Status as in (0 if something was wrong, otherwise 1)
1944  *
1945  * \callgraph
1946  * \callergraph
1947  */
sccp_channel_hold(channelPtr channel)1948 int sccp_channel_hold(channelPtr channel)
1949 {
1950 	uint16_t instance = 0;
1951 
1952 	if (!channel || !channel->line) {
1953 		pbx_log(LOG_WARNING, "SCCP: weird error. No channel provided to put on hold\n");
1954 		return FALSE;
1955 	}
1956 
1957 	AUTO_RELEASE(sccp_line_t, l , sccp_line_retain(channel->line));
1958 	if (!l) {
1959 		pbx_log(LOG_WARNING, "SCCP: weird error. The channel %s has no line attached to it\n", channel->designator);
1960 		return FALSE;
1961 	}
1962 
1963 	AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(channel));
1964 	if (!d) {
1965 		pbx_log(LOG_WARNING, "SCCP: weird error. The channel %s has no device attached to it\n", channel->designator);
1966 		return FALSE;
1967 	}
1968 
1969 	if (channel->state == SCCP_CHANNELSTATE_HOLD) {
1970 		pbx_log(LOG_WARNING, "SCCP: Channel already on hold\n");
1971 		return FALSE;
1972 	}
1973 
1974 	instance = sccp_device_find_index_for_line(d, l->name);
1975 	/* put on hold an active call */
1976 	if (channel->state != SCCP_CHANNELSTATE_CONNECTED && channel->state != SCCP_CHANNELSTATE_CONNECTEDCONFERENCE && channel->state != SCCP_CHANNELSTATE_PROCEED) {	// TOLL FREE NUMBERS STAYS ALWAYS IN CALL PROGRESS STATE
1977 		/* something wrong on the code let's notify it for a fix */
1978 		sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "%s can't put on hold an inactive channel %s with state %s (%d)... cancelling hold action.\n", d->id, channel->designator, sccp_channelstate2str(channel->state), channel->state);
1979 		/* hard button phones need it */
1980 		sccp_dev_displayprompt(d, instance, channel->callid, SKINNY_DISP_KEY_IS_NOT_ACTIVE, SCCP_DISPLAYSTATUS_TIMEOUT);
1981 		return FALSE;
1982 	}
1983 
1984 	if (d->useHookFlash() && d->transfer && d->transferChannels.transferer == channel) {	// deal with single line phones like 6901, which do not have softkeys
1985 												// 6901 is cancelling the transfer by pressing the hold key on the transferer
1986 		sccp_log((DEBUGCAT_ACTION)) (VERBOSE_PREFIX_3 "%s: We are the middle of a transfer, pressed hold on the transferer channel(%s) -> cancel transfer\n", d->id, channel->designator);
1987 		AUTO_RELEASE(sccp_channel_t, resumeChannel, sccp_channel_retain(d->transferChannels.transferee));
1988 		if (resumeChannel) {
1989 			sccp_channel_endcall(d->transferChannels.transferer);
1990 			sccp_channel_resume(d, resumeChannel, FALSE);
1991 		}
1992 		return TRUE;
1993 	}
1994 
1995 	sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: Hold the channel %s\n", d->id, channel->designator);
1996 
1997 #ifdef CS_SCCP_CONFERENCE
1998 	if (channel->conference) {
1999 		sccp_conference_hold(channel->conference);
2000 	} else
2001 #endif
2002 	{
2003 		if (channel->owner) {
2004 			iPbx.queue_control_data(channel->owner, AST_CONTROL_HOLD, channel->musicclass, sccp_strlen(channel->musicclass) + 1);
2005 		}
2006 	}
2007 	//sccp_rtp_stop(channel);
2008 	sccp_dev_setActiveLine(d, NULL);
2009 	sccp_indicate(d, channel, SCCP_CHANNELSTATE_HOLD);							// this will also close (but not destroy) the RTP stream
2010 	sccp_channel_setDevice(channel, NULL, FALSE);
2011 
2012 #ifdef CS_MANAGER_EVENTS
2013 	if (GLOB(callevents)) {
2014 		manager_event(EVENT_FLAG_CALL, "Hold", "Status: On\r\n" "Channel: %s\r\n" "Uniqueid: %s\r\n", iPbx.getChannelName(channel), iPbx.getChannelUniqueID(channel));
2015 	}
2016 #endif
2017 
2018 	if (l) {
2019 		l->statistic.numberOfHeldChannels++;
2020 	}
2021 
2022 	sccp_log_and((DEBUGCAT_CHANNEL + DEBUGCAT_HIGH)) (VERBOSE_PREFIX_3 "C partyID: %u state: %d\n", channel->passthrupartyid, channel->state);
2023 	return TRUE;
2024 }
2025 
2026 /*!
2027  * \brief Actual Resume Implementation
2028  *
2029  * This will run while channel and pbx_channel are locked and we hold a reference, so that it cannot escape us
2030  *
2031  * \callgraph
2032  * \callergraph
2033  *
2034  */
channel_resume_locked(devicePtr d,linePtr l,channelPtr channel,boolean_t swap_channels)2035 static int channel_resume_locked(devicePtr d, linePtr l, channelPtr channel, boolean_t swap_channels)
2036 {
2037 	uint16_t instance = 0;
2038 
2039 	/* look if we have a call to put on hold */
2040 	if (swap_channels) {
2041 		AUTO_RELEASE(sccp_channel_t, sccp_active_channel , sccp_device_getActiveChannel(d));
2042 
2043 		/* there is an active call, if offhook channelstate then hangup else put it on hold */
2044 		if (sccp_active_channel && sccp_active_channel != channel) {
2045 			if (sccp_active_channel->state <= SCCP_CHANNELSTATE_OFFHOOK) {
2046 				sccp_log(DEBUGCAT_CHANNEL)(VERBOSE_PREFIX_3 "%s: active channel is brand new and unused, hanging it up before resuming another\n", sccp_active_channel->designator);
2047 				sccp_channel_endcall(sccp_active_channel);
2048 			} else if (!(sccp_channel_hold(sccp_active_channel))) {				// hold failed, give up
2049 				pbx_log(LOG_WARNING, "%s: swap_channels failed to put channel on hold. exiting\n", sccp_active_channel->designator);
2050 				return FALSE;
2051 			}
2052 		}
2053 	}
2054 
2055 	if (channel->state == SCCP_CHANNELSTATE_CONNECTED || channel->state == SCCP_CHANNELSTATE_CONNECTEDCONFERENCE || channel->state == SCCP_CHANNELSTATE_PROCEED) {
2056 		if (!(sccp_channel_hold(channel))) {
2057 			pbx_log(LOG_WARNING, "%s: channel still connected before resuming, put on hold failed. exiting\n", channel->designator);
2058 			return FALSE;
2059 		}
2060 	}
2061 
2062 	instance = sccp_device_find_index_for_line(d, l->name);
2063 	/* resume an active call */
2064 	if (channel->state != SCCP_CHANNELSTATE_HOLD && channel->state != SCCP_CHANNELSTATE_CALLTRANSFER && channel->state != SCCP_CHANNELSTATE_CALLCONFERENCE) {
2065 		/* something wrong in the code let's notify it for a fix */
2066 		pbx_log(LOG_ERROR, "%s can't resume the channel %s. Not on hold\n", d->id, channel->designator);
2067 		sccp_dev_displayprompt(d, instance, channel->callid, SKINNY_DISP_NO_ACTIVE_CALL_TO_PUT_ON_HOLD, SCCP_DISPLAYSTATUS_TIMEOUT);
2068 		return FALSE;
2069 	}
2070 
2071 	if (d->transferChannels.transferee != channel) {
2072 		sccp_channel_transfer_release(d, channel);			/* explicitly release transfer if we are in the middle of a transfer */
2073 	}
2074 
2075 	sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: Resume the channel %s\n", d->id, channel->designator);
2076 	sccp_channel_setDevice(channel, d, TRUE);
2077 
2078 #if ASTERISK_VERSION_GROUP >= 111
2079 	// update callgroup / pickupgroup
2080 	ast_channel_callgroup_set(channel->owner, l->callgroup);
2081 #if CS_SCCP_PICKUP
2082 	ast_channel_pickupgroup_set(channel->owner, l->pickupgroup);
2083 #endif
2084 #else
2085 	channel->owner->callgroup = l->callgroup;
2086 #if CS_SCCP_PICKUP
2087 	channel->owner->pickupgroup = l->pickupgroup;
2088 #endif
2089 #endif														// ASTERISK_VERSION_GROUP >= 111
2090 
2091 #ifdef CS_SCCP_CONFERENCE
2092 	if (channel->conference) {
2093 		sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: Resume Conference on the channel %s\n", d->id, channel->designator);
2094 		sccp_conference_resume(channel->conference);
2095 		sccp_dev_set_keyset(d, instance, channel->callid, KEYMODE_CONNCONF);
2096 	} else
2097 #endif
2098 	{
2099 		if (channel->owner) {
2100 			iPbx.queue_control(channel->owner, AST_CONTROL_UNHOLD);
2101 		}
2102 	}
2103 
2104 	channel->state = SCCP_CHANNELSTATE_HOLD;
2105 #ifdef CS_AST_CONTROL_SRCUPDATE
2106 	iPbx.queue_control(channel->owner, AST_CONTROL_SRCUPDATE);						// notify changes e.g codec
2107 #endif
2108 #ifdef CS_SCCP_CONFERENCE
2109 	if (channel->conference) {
2110 		sccp_indicate(d, channel, SCCP_CHANNELSTATE_CONNECTEDCONFERENCE);				// this will also reopen the RTP stream
2111 	} else
2112 #endif
2113 	{
2114 		sccp_indicate(d, channel, SCCP_CHANNELSTATE_CONNECTED);						// this will also reopen the RTP stream
2115 	}
2116 
2117 #ifdef CS_SCCP_VIDEO
2118 	if(channel->rtp.video.instance && sccp_channel_getVideoMode(channel) != SCCP_VIDEO_MODE_OFF && sccp_device_isVideoSupported(d)) {
2119 		if(!sccp_rtp_getState(&channel->rtp.video, SCCP_RTP_RECEPTION)) {
2120 			sccp_channel_openMultiMediaReceiveChannel(channel);
2121 		} else if((sccp_rtp_getState(&channel->rtp.video, SCCP_RTP_RECEPTION) & SCCP_RTP_STATUS_ACTIVE) && !sccp_rtp_getState(&channel->rtp.video, SCCP_RTP_TRANSMISSION)) {
2122 			sccp_channel_startMultiMediaTransmission(channel);
2123 		}
2124 	}
2125 #endif
2126 
2127 #ifdef CS_MANAGER_EVENTS
2128 	if (GLOB(callevents)) {
2129 		manager_event(EVENT_FLAG_CALL, "Hold", "Status: Off\r\n" "Channel: %s\r\n" "Uniqueid: %s\r\n", iPbx.getChannelName(channel), iPbx.getChannelUniqueID(channel));
2130 	}
2131 #endif
2132 
2133 	/* state of channel is set down from the remoteDevices, so correct channel state */
2134 	if (channel->conference) {
2135 		channel->state = SCCP_CHANNELSTATE_CONNECTEDCONFERENCE;
2136 	} else {
2137 		channel->state = SCCP_CHANNELSTATE_CONNECTED;
2138 	}
2139 	l->statistic.numberOfHeldChannels--;
2140 
2141 	/** set called party name */
2142 	{
2143 		AUTO_RELEASE(sccp_linedevice_t, ld, sccp_linedevice_find(d, l));
2144 
2145 		if(ld) {
2146 			char tmpNumber[StationMaxDirnumSize] = {0};
2147 			char tmpName[StationMaxNameSize] = {0};
2148 			if(!sccp_strlen_zero(ld->subscriptionId.number)) {
2149 				snprintf(tmpNumber, StationMaxDirnumSize, "%s%s", channel->line->cid_num, ld->subscriptionId.number);
2150 			} else {
2151 				snprintf(tmpNumber, StationMaxDirnumSize, "%s%s", channel->line->cid_num, channel->line->defaultSubscriptionId.number);
2152 			}
2153 
2154 			if(!sccp_strlen_zero(ld->subscriptionId.name)) {
2155 				snprintf(tmpName, StationMaxNameSize, "%s%s", channel->line->cid_name, ld->subscriptionId.name);
2156 			} else {
2157 				snprintf(tmpName, StationMaxNameSize, "%s%s", channel->line->cid_name, channel->line->defaultSubscriptionId.name);
2158 			}
2159 			if(channel->calltype == SKINNY_CALLTYPE_OUTBOUND) {
2160 				iCallInfo.SetCallingParty(channel->privateData->callInfo, tmpNumber, tmpName, NULL);
2161 				sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: Set callingPartyNumber '%s' callingPartyName '%s'\n", d->id, tmpNumber, tmpName);
2162 			} else if(channel->calltype == SKINNY_CALLTYPE_INBOUND) {
2163 				iCallInfo.SetCalledParty(channel->privateData->callInfo, tmpNumber, tmpName, NULL);
2164 				sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: Set calledPartyNumber '%s' calledPartyName '%s'\n", d->id, tmpNumber, tmpName);
2165 			}
2166 			iPbx.set_connected_line(channel, tmpNumber, tmpName, AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER);
2167 		}
2168 	}
2169 	/* */
2170 
2171 	sccp_log_and((DEBUGCAT_CHANNEL + DEBUGCAT_HIGH)) (VERBOSE_PREFIX_3 "C partyID: %u state: %d\n", channel->passthrupartyid, channel->state);
2172 	return TRUE;
2173 }
2174 
2175 /*!
2176  * \brief Resume a channel that is on hold.
2177  * \param device device who resumes the channel
2178  * \param channel channel
2179  * \param swap_channels Swap Channels as Boolean
2180  * \return 0 if something was wrong, otherwise 1
2181  *
2182  * \callgraph
2183  * \callergraph
2184  *
2185  */
sccp_channel_resume(constDevicePtr device,channelPtr channel,boolean_t swap_channels)2186 int sccp_channel_resume(constDevicePtr device, channelPtr channel, boolean_t swap_channels)
2187 {
2188 	uint16_t instance = 0;
2189 	PBX_CHANNEL_TYPE * pbx_channel = NULL;
2190 	if(!channel || !channel->owner || !channel->line) {
2191 		pbx_log(LOG_WARNING, "SCCP: weird error. No channel provided to resume\n");
2192 		return FALSE;
2193 	}
2194 	AUTO_RELEASE(sccp_channel_t, c, sccp_channel_retain(channel));
2195 	if(!c) {
2196 		pbx_log(LOG_WARNING, "SCCP: weird error. The channel could not be retained.\n");
2197 		return FALSE;
2198 	}
2199 	AUTO_RELEASE(sccp_device_t, d, sccp_device_retain(device));
2200 	AUTO_RELEASE(sccp_line_t, l, sccp_line_retain(c->line));
2201 	if(!d || !l) {
2202 		pbx_log(LOG_WARNING, "%s: weird error. The channel has no line or device\n", c->designator);
2203 		return FALSE;
2204 	}
2205 
2206 	if((pbx_channel = sccp_channel_lock_full(channel, FALSE))) {
2207 		instance = channel_resume_locked(d, l, channel, swap_channels);
2208 		pbx_channel_unref(pbx_channel);                                         // reffed by sccp_channel_lock_full
2209 		pbx_channel_unlock(pbx_channel);                                        // locked by sccp_channel_lock_full
2210 	} else {
2211 		pbx_log(LOG_WARNING, "%s: weird error. We could not get a reference to the pbx_channel, skipping resume.\n", c->designator);
2212 	}
2213 	sccp_channel_unlock(channel);                                        // locked by sccp_channel_lock_full
2214 	return instance;
2215 }
2216 
sccp_channel_addCleanupJob(channelPtr c,void * (* function_p)(void *),void * arg_p)2217 void sccp_channel_addCleanupJob(channelPtr c, void *(*function_p) (void *), void *arg_p)
2218 {
2219 	if (!c) {
2220 		return;
2221 	}
2222 	sccp_threadpool_job_t * newJob = NULL;
2223 	if (!(newJob = (sccp_threadpool_job_t *) sccp_calloc(sizeof *newJob, 1))) {
2224 		pbx_log(LOG_ERROR, SS_Memory_Allocation_Error, "SCCP");
2225 		exit(1);
2226 	}
2227 
2228 	/* add function and argument */
2229 	newJob->function = function_p;
2230 	newJob->arg = arg_p;
2231 
2232 	/* add job to cleanup jobqueue */
2233 	SCCP_LIST_LOCK(&(c->privateData->cleanup_jobs));
2234 	SCCP_LIST_INSERT_TAIL(&(c->privateData->cleanup_jobs), newJob, list);
2235 	SCCP_LIST_UNLOCK(&(c->privateData->cleanup_jobs));
2236 }
2237 
2238 /*!
2239  * \brief Cleanup Channel before Free.
2240  * \param channel SCCP Channel
2241  *
2242  * \callgraph
2243  * \callergraph
2244  *
2245  */
sccp_channel_clean(channelPtr channel)2246 void sccp_channel_clean(channelPtr channel)
2247 {
2248 	sccp_selectedchannel_t * sccp_selected_channel = NULL;
2249 
2250 	if (!channel) {
2251 		pbx_log(LOG_ERROR, "SCCP:No channel provided to clean\n");
2252 		return;
2253 	}
2254 
2255 	AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(channel));
2256 
2257 	// l = channel->line;
2258 	sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: Cleaning channel %s\n", channel->designator);
2259 
2260 	if (ATOMIC_FETCH(&channel->scheduler.deny, &channel->scheduler.lock) == 0) {
2261 		sccp_channel_stop_and_deny_scheduled_tasks(channel);
2262 	}
2263 
2264 	/* mark the channel DOWN so any pending thread will terminate */
2265 	if (channel->owner) {
2266 		pbx_setstate(channel->owner, AST_STATE_DOWN);
2267 		/* postponing ast_channel_unref to sccp_channel destructor */
2268 		//iPbx.set_owner(channel, NULL);
2269 	}
2270 
2271 	if (channel->state != SCCP_CHANNELSTATE_ONHOOK && channel->state != SCCP_CHANNELSTATE_DOWN) {
2272 		iPbx.set_callstate(channel, AST_STATE_DOWN);
2273 		sccp_indicate(d, channel, SCCP_CHANNELSTATE_ONHOOK);
2274 	}
2275 
2276 	if (d) {
2277 		/* make sure all rtp stuff is closed and destroyed */
2278 		if (channel->rtp.audio.instance || channel->rtp.video.instance) {
2279 			sccp_channel_closeAllMediaTransmitAndReceive(channel);
2280 		}
2281 
2282 		/* deactive the active call if needed */
2283 		if (d->active_channel == channel) {
2284 			sccp_device_setActiveChannel(d, NULL);
2285 		}
2286 		sccp_channel_transfer_release(d, channel);										/* explicitly release transfer when cleaning up channel */
2287 #ifdef CS_SCCP_CONFERENCE
2288 		if (d->conference && d->conference == channel->conference) {
2289 			sccp_conference_release(&d->conference);									/* explicit release of conference */
2290 		}
2291 		if (channel->conference) {
2292 			sccp_conference_release(&channel->conference);									/* explicit release of conference */
2293 		}
2294 #endif
2295 		if (channel->privacy) {
2296 			channel->privacy = FALSE;
2297 			d->privacyFeature.status = SCCP_PRIVACYFEATURE_OFF;
2298 			sccp_feat_changed(d, NULL, SCCP_FEATURE_PRIVACY);
2299 		}
2300 
2301 		if ((sccp_selected_channel = sccp_device_find_selectedchannel(d, channel))) {
2302 			SCCP_LIST_LOCK(&d->selectedChannels);
2303 			sccp_selected_channel = SCCP_LIST_REMOVE(&d->selectedChannels, sccp_selected_channel, list);
2304 			SCCP_LIST_UNLOCK(&d->selectedChannels);
2305 			sccp_channel_release(&sccp_selected_channel->channel);
2306 			sccp_free(sccp_selected_channel);
2307 		}
2308 		sccp_dev_setActiveLine(d, NULL);
2309 		sccp_dev_check_displayprompt(d);
2310 	}
2311 	if (channel->privateData) {
2312 		if (channel->privateData->device) {
2313 			sccp_channel_setDevice(channel, NULL, FALSE);
2314 		}
2315 
2316 		if(channel->privateData->ld) {
2317 			sccp_linedevice_release(&channel->privateData->ld);
2318 		}
2319 
2320 		sccp_threadpool_job_t * job = NULL;
2321 		SCCP_LIST_LOCK(&channel->privateData->cleanup_jobs);
2322 		while ((job = SCCP_LIST_REMOVE_HEAD(&channel->privateData->cleanup_jobs, list))) {
2323 			SCCP_LIST_UNLOCK(&channel->privateData->cleanup_jobs);
2324 			sccp_threadpool_jobqueue_add(GLOB(general_threadpool), job);
2325 			SCCP_LIST_LOCK(&channel->privateData->cleanup_jobs);
2326 		}
2327 		SCCP_LIST_UNLOCK(&channel->privateData->cleanup_jobs);
2328 	}
2329 }
2330 
2331 /*!
2332  * \brief Destroy Channel
2333  * \param channel SCCP Channel
2334  *
2335  * \callgraph
2336  * \callergraph
2337  *
2338  * \warning
2339  *  - line->channels is not always locked
2340  */
__sccp_channel_destroy(const void * data)2341 int __sccp_channel_destroy(const void * data)
2342 {
2343 	sccp_channel_t * channel = (sccp_channel_t *) data;
2344 	if (!channel) {
2345 		pbx_log(LOG_NOTICE, "SCCP: channel destructor called with NULL pointer\n");
2346 		return -1;
2347 	}
2348 	sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "Destroying channel %s\n", channel->designator);
2349 
2350 	sccp_channel_lock(channel);
2351 
2352 	if (channel->rtp.audio.instance || channel->rtp.video.instance) {
2353 		sccp_channel_closeAllMediaTransmitAndReceive(channel);
2354 		sccp_rtp_stop(channel);
2355 		sccp_rtp_destroy(channel);
2356 	}
2357 
2358 	if (channel->privateData->callInfo) {
2359 		iCallInfo.Destructor(&channel->privateData->callInfo);
2360 	}
2361 
2362 #if ASTERISK_VERSION_GROUP >= 113
2363 	if (channel->caps) {
2364 		ao2_t_cleanup(channel->caps, "sccp_channel_caps cleanup");
2365 	}
2366 #endif
2367 
2368 	if (channel->owner) {
2369 		if (iPbx.removeTimingFD) {
2370 			iPbx.removeTimingFD(channel->owner);
2371 		}
2372 		iPbx.set_owner(channel, NULL);
2373 	}
2374 
2375 	/* destroy immutables, by casting away const */
2376 	sccp_free(*(char **)&channel->musicclass);
2377 	sccp_free(*(char **)&channel->designator);
2378 	SCCP_LIST_HEAD_DESTROY(&(channel->privateData->cleanup_jobs));
2379 	sccp_free(*(struct sccp_private_channel_data **)&channel->privateData);
2380 	sccp_line_release((sccp_line_t **)&channel->line);
2381 	/* */
2382 
2383 #ifndef SCCP_ATOMIC
2384 	pbx_mutex_destroy(&channel->scheduler.lock);
2385 #endif
2386 	sccp_channel_unlock(channel);
2387 	pbx_mutex_destroy(&channel->lock);
2388 	return 0;
2389 }
2390 
2391 /*!
2392  * \brief Handle Transfer Request (Pressing the Transfer Softkey)
2393  * \param channel *retained* SCCP Channel
2394  * \param device *retained* SCCP Device
2395  *
2396  * \callgraph
2397  * \callergraph
2398  */
sccp_channel_transfer(channelPtr channel,constDevicePtr device)2399 void sccp_channel_transfer(channelPtr channel, constDevicePtr device)
2400 {
2401 	sccp_channelstate_t prev_channel_state = SCCP_CHANNELSTATE_ZOMBIE;
2402 	uint32_t blindTransfer = 0;
2403 	uint16_t instance = 0;
2404 	PBX_CHANNEL_TYPE * pbx_channel_owner = NULL;
2405 	PBX_CHANNEL_TYPE * pbx_channel_bridgepeer = NULL;
2406 
2407 	if (!channel) {
2408 		return;
2409 	}
2410 
2411 	if (!(channel->line)) {
2412 		pbx_log(LOG_WARNING, "SCCP: weird error. The channel has no line on channel %d\n", channel->callid);
2413 		sccp_dev_displayprompt(device, 0, channel->callid, SKINNY_DISP_NO_LINE_TO_TRANSFER, GLOB(digittimeout));
2414 		return;
2415 	}
2416 
2417 	AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(channel));
2418 
2419 	if (!d) {
2420 		/* transfer was pressed on first (transferee) channel, check if is our transferee channel and continue with d <= device */
2421 		if (channel == device->transferChannels.transferee && device->transferChannels.transferer) {
2422 			d = sccp_device_retain(device) /*ref_replace*/;
2423 		} else if (channel->state == SCCP_CHANNELSTATE_HOLD) {
2424 			if (SCCP_LIST_GETSIZE(&channel->line->devices) == 1) {
2425 				d = sccp_device_retain(device) /*ref_replace*/;
2426 			} else {
2427 				pbx_log(LOG_WARNING, "%s: The channel %s is not attached to a particular device (hold on shared line, resume first)\n", DEV_ID_LOG(device), channel->designator);
2428 				instance = sccp_device_find_index_for_line(device, channel->line->name);
2429 				sccp_dev_displayprompt(device, instance, channel->callid, SKINNY_DISP_NO_LINE_TO_TRANSFER, GLOB(digittimeout));
2430 				return;
2431 			}
2432 		} else {
2433 			pbx_log(LOG_WARNING, "%s: The channel %s state is unclear. giving up\n", DEV_ID_LOG(device), channel->designator);
2434 			instance = sccp_device_find_index_for_line(device, channel->line->name);
2435 			sccp_dev_displayprompt(device, instance, channel->callid, SKINNY_DISP_NO_LINE_TO_TRANSFER, GLOB(digittimeout));
2436 			return;
2437 		}
2438 	}
2439 	instance = sccp_device_find_index_for_line(d, channel->line->name);
2440 
2441 	if (!d->transfer || !channel->line->transfer) {
2442 		sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: Transfer disabled on device or line\n", d->id);
2443 		sccp_dev_displayprompt(device, instance, channel->callid, SKINNY_DISP_KEY_IS_NOT_ACTIVE, GLOB(digittimeout));
2444 		return;
2445 	}
2446 
2447 	/* are we in the middle of a transfer? */
2448 	if (d->transferChannels.transferee && d->transferChannels.transferer) {
2449 		sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: In the middle of a Transfer. Going to transfer completion\n", d->id);
2450 		sccp_channel_transfer_complete(d->transferChannels.transferer);
2451 		return;
2452 	}
2453 	/* exceptional case, we need to release half transfer before retaking, should never occur */
2454 	/* \todo check out if this should be reactiveated or removed */
2455 	// if (d->transferChannels.transferee && !d->transferChannels.transferer) {
2456 	// sccp_channel_release(&d->transferChannels.transferee);						/* explicit release */
2457 	// }
2458 	if (!d->transferChannels.transferee && d->transferChannels.transferer) {
2459 		sccp_channel_release(&d->transferChannels.transferer);						/* explicit release */
2460 	}
2461 
2462 	if ((d->transferChannels.transferee = sccp_channel_retain(channel))) {					/** channel to be transfered */
2463 		sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: Transfer request from line channel %s\n", d->id, channel->designator);
2464 
2465 		prev_channel_state = channel->state;
2466 
2467 		if (channel->state == SCCP_CHANNELSTATE_HOLD) {							/* already put on hold manually */
2468 			channel->channelStateReason = SCCP_CHANNELSTATEREASON_TRANSFER;
2469 			// sccp_indicate(d, channel, SCCP_CHANNELSTATE_HOLD);                      		/* do we need to reindicate ? */
2470 		}
2471 		if ((channel->state != SCCP_CHANNELSTATE_OFFHOOK && channel->state != SCCP_CHANNELSTATE_HOLD && channel->state != SCCP_CHANNELSTATE_CALLTRANSFER)) {
2472 			channel->channelStateReason = SCCP_CHANNELSTATEREASON_TRANSFER;
2473 
2474 			if (!sccp_channel_hold(channel)) {							/* hold failed, restore */
2475 				channel->channelStateReason = SCCP_CHANNELSTATEREASON_NORMAL;
2476 				sccp_channel_release(&d->transferChannels.transferee);				/* explicit release */
2477 				return;
2478 			}
2479 		}
2480 
2481 		if ((pbx_channel_owner = pbx_channel_ref(channel->owner))) {
2482 			if (channel->state != SCCP_CHANNELSTATE_CALLTRANSFER) {
2483 				sccp_indicate(d, channel, SCCP_CHANNELSTATE_CALLTRANSFER);
2484 			}
2485 			AUTO_RELEASE(sccp_channel_t, sccp_channel_new , sccp_channel_newcall(channel->line, d, NULL, SKINNY_CALLTYPE_OUTBOUND, pbx_channel_owner, NULL));
2486 
2487 			if (sccp_channel_new && (pbx_channel_bridgepeer = iPbx.get_bridged_channel(pbx_channel_owner))) {
2488 				pbx_builtin_setvar_helper(sccp_channel_new->owner, "TRANSFEREE", pbx_channel_name(pbx_channel_bridgepeer));
2489 
2490 				instance = sccp_device_find_index_for_line(d, sccp_channel_new->line->name);
2491 				sccp_device_setLamp(d, SKINNY_STIMULUS_LINE, instance, SKINNY_LAMP_ON);
2492 				sccp_dev_set_keyset(d, instance, sccp_channel_new->callid, KEYMODE_OFFHOOKFEAT);
2493 				sccp_dev_displayprompt(d, instance, sccp_channel_new->callid, SKINNY_DISP_ENTER_NUMBER, SCCP_DISPLAYSTATUS_TIMEOUT);
2494 				sccp_device_setLamp(d, SKINNY_STIMULUS_TRANSFER, instance, SKINNY_LAMP_FLASH);
2495 
2496 				/* set a var for BLINDTRANSFER. It will be removed if the user manually answers the call Otherwise it is a real BLINDTRANSFER */
2497 #if 0
2498 				if (blindTransfer || (sccp_channel_new && sccp_channel_new->owner && pbx_channel_owner && pbx_channel_bridgepeer)) {
2499 					//! \todo use pbx impl
2500 					pbx_builtin_setvar_helper(sccp_channel_new->owner, "BLINDTRANSFER", pbx_channel_name(pbx_channel_bridgepeer));
2501 					pbx_builtin_setvar_helper(pbx_channel_bridgepeer, "BLINDTRANSFER", pbx_channel_name(sccp_channel_new->owner));
2502 				}
2503 #else
2504 				if (blindTransfer || (sccp_channel_new && sccp_channel_new->owner && pbx_channel_owner && pbx_channel_bridgepeer)) {
2505 					pbx_builtin_setvar_helper(sccp_channel_new->owner, "BLINDTRANSFER", pbx_channel_name(channel->owner));
2506 				}
2507 #endif
2508 				// should go on, even if there is no bridged channel (yet/anymore) ?
2509 				d->transferChannels.transferer = sccp_channel_retain(sccp_channel_new);
2510 				pbx_channel_unref(pbx_channel_bridgepeer);
2511 			} else if (sccp_channel_new && (pbx_channel_appl(pbx_channel_owner) != NULL)) {
2512 				// giving up
2513 				sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_DEVICE + DEBUGCAT_LINE)) (VERBOSE_PREFIX_3 "%s: Cannot transfer a dialplan application, bridged channel is required on %s\n", d->id, channel->designator);
2514 				sccp_dev_displayprompt(d, instance, channel->callid, SKINNY_DISP_CAN_NOT_COMPLETE_TRANSFER, SCCP_DISPLAYSTATUS_TIMEOUT);
2515 				channel->channelStateReason = SCCP_CHANNELSTATEREASON_NORMAL;
2516 				sccp_indicate(d, channel, SCCP_CHANNELSTATE_CONGESTION);
2517 				sccp_channel_release(&d->transferChannels.transferee);				/* explicit release */
2518 			} else {
2519 				// giving up
2520 				if (!sccp_channel_new) {
2521 					sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_DEVICE + DEBUGCAT_LINE)) (VERBOSE_PREFIX_3 "%s: New channel could not be created to complete transfer for %s\n", d->id, channel->designator);
2522 				} else {
2523 					sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_DEVICE + DEBUGCAT_LINE)) (VERBOSE_PREFIX_3 "%s: No bridged channel or application on %s\n", d->id, channel->designator);
2524 				}
2525 				sccp_dev_displayprompt(d, instance, channel->callid, SKINNY_DISP_CAN_NOT_COMPLETE_TRANSFER, SCCP_DISPLAYSTATUS_TIMEOUT);
2526 				channel->channelStateReason = SCCP_CHANNELSTATEREASON_NORMAL;
2527 				sccp_indicate(d, channel, SCCP_CHANNELSTATE_CONGESTION);
2528 				sccp_channel_release(&d->transferChannels.transferee);				/* explicit release */
2529 			}
2530 			pbx_channel_owner = pbx_channel_unref(pbx_channel_owner);
2531 		} else {
2532 			// giving up
2533 			sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_DEVICE + DEBUGCAT_LINE)) (VERBOSE_PREFIX_3 "%s: No pbx channel owner to transfer %s\n", d->id, channel->designator);
2534 			sccp_dev_displayprompt(d, instance, channel->callid, SKINNY_DISP_CAN_NOT_COMPLETE_TRANSFER, SCCP_DISPLAYSTATUS_TIMEOUT);
2535 			channel->channelStateReason = SCCP_CHANNELSTATEREASON_NORMAL;
2536 			sccp_indicate(d, channel, prev_channel_state);
2537 			sccp_channel_release(&d->transferChannels.transferee);					/* explicit release */
2538 		}
2539 	}
2540 }
2541 
2542 /*!
2543  * \brief Release Transfer Variables
2544  */
sccp_channel_transfer_release(devicePtr d,channelPtr c)2545 void sccp_channel_transfer_release(devicePtr d, channelPtr c)
2546 {
2547 	if (!d || !c) {
2548 		return;
2549 	}
2550 
2551 	if ((d->transferChannels.transferee && c == d->transferChannels.transferee) || (d->transferChannels.transferer && c == d->transferChannels.transferer)) {
2552 		if (d->transferChannels.transferee) {
2553 			sccp_channel_release(&d->transferChannels.transferee);					/* explicit release */
2554 		}
2555 		if (d->transferChannels.transferer) {
2556 			sccp_channel_release(&d->transferChannels.transferer);					/* explicit release */
2557 		}
2558 		sccp_log_and((DEBUGCAT_CHANNEL + DEBUGCAT_HIGH)) (VERBOSE_PREFIX_3 "%s: Transfer on the channel %s released\n", d->id, c->designator);
2559 	}
2560 	c->channelStateReason = SCCP_CHANNELSTATEREASON_NORMAL;
2561 }
2562 
2563 /*!
2564  * \brief Cancel Transfer
2565  */
sccp_channel_transfer_cancel(devicePtr d,channelPtr c)2566 void sccp_channel_transfer_cancel(devicePtr d, channelPtr c)
2567 {
2568 	if (!d || !c || !d->transferChannels.transferee) {
2569 		return;
2570 	}
2571 
2572 	/**
2573 	 * workaround to fix issue with 7960 and protocol version != 6
2574 	 * 7960 loses callplane when cancel transfer (end call on other channel).
2575 	 * This script sets the hold state for transfered channel explicitly -MC
2576 	 */
2577 	AUTO_RELEASE(sccp_channel_t, transferee , d->transferChannels.transferee ? sccp_channel_retain(d->transferChannels.transferee) : NULL);
2578 	if (transferee && transferee != c) {
2579 		sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: (sccp_channel_transfer_cancel) Denied Receipt of Transferee %d %s by the Receiving Party. Cancelling Transfer and Putting transferee channel on Hold.\n", d->id, transferee->callid, transferee->line->name);
2580 		transferee->channelStateReason = SCCP_CHANNELSTATEREASON_NORMAL;
2581 		sccp_channel_closeAllMediaTransmitAndReceive(c);
2582 		sccp_dev_setActiveLine(d, NULL);
2583 		sccp_indicate(d, transferee, SCCP_CHANNELSTATE_HOLD);
2584 		sccp_channel_setDevice(transferee, NULL, FALSE);
2585 #if ASTERISK_VERSION_GROUP >= 108
2586 		enum ast_control_transfer control_transfer_message = AST_TRANSFER_FAILED;
2587 		iPbx.queue_control_data(c->owner, AST_CONTROL_TRANSFER, &control_transfer_message, sizeof(control_transfer_message));
2588 #endif
2589 		sccp_channel_transfer_release(d, transferee);			/* explicit release */
2590 	} else {
2591 		pbx_log(LOG_WARNING, "%s: (sccp_channel_transfer_cancel) Could not retain the transferee channel, giving up.\n", d->id);
2592 	}
2593 }
2594 
2595 /*!
2596  * \brief Bridge Two Channels
2597  * \param sccp_destination_local_channel Local Destination SCCP Channel
2598  * \todo Find a way solve the chan->state problem
2599  *
2600  * \callgraph
2601  * \callergraph
2602  */
sccp_channel_transfer_complete(channelPtr sccp_destination_local_channel)2603 void sccp_channel_transfer_complete(channelPtr sccp_destination_local_channel)
2604 {
2605 	PBX_CHANNEL_TYPE * pbx_source_local_channel = NULL;
2606 	PBX_CHANNEL_TYPE * pbx_source_remote_channel = NULL;
2607 	PBX_CHANNEL_TYPE * pbx_destination_local_channel = NULL;
2608 	PBX_CHANNEL_TYPE * pbx_destination_remote_channel = NULL;
2609 	boolean_t result = FALSE;
2610 #if ASTERISK_VERSION_GROUP >= 108
2611 	enum ast_control_transfer control_transfer_message = AST_TRANSFER_FAILED;
2612 #endif
2613 	uint16_t instance = 0;
2614 
2615 	if (!sccp_destination_local_channel) {
2616 		return;
2617 	}
2618 	// Obtain the device from which the transfer was initiated
2619 	AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(sccp_destination_local_channel));
2620 
2621 	if (!d) {
2622 		pbx_log(LOG_WARNING, "SCCP: weird error. The channel has no device on channel %d\n", sccp_destination_local_channel->callid);
2623 		return;
2624 	}
2625 	if (!sccp_destination_local_channel->line) {
2626 		pbx_log(LOG_WARNING, "SCCP: weird error. The channel has no line on channel %d\n", sccp_destination_local_channel->callid);
2627 		sccp_dev_displayprompt(d, instance, sccp_destination_local_channel->callid, SKINNY_DISP_NO_LINE_TO_TRANSFER, GLOB(digittimeout));
2628 		return;
2629 	}
2630 	// Obtain the source channel on that device
2631 	AUTO_RELEASE(sccp_channel_t, sccp_source_local_channel , sccp_channel_retain(d->transferChannels.transferee));
2632 
2633 	sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: Complete transfer from %s\n", d->id, sccp_destination_local_channel->designator);
2634 	instance = sccp_device_find_index_for_line(d, sccp_destination_local_channel->line->name);
2635 
2636 	if (sccp_destination_local_channel->state != SCCP_CHANNELSTATE_RINGOUT && sccp_destination_local_channel->state != SCCP_CHANNELSTATE_CONNECTED && sccp_destination_local_channel->state != SCCP_CHANNELSTATE_PROGRESS) {
2637 		pbx_log(LOG_WARNING, "SCCP: Failed to complete transfer. The channel is not ringing or connected. ChannelState: %s (%d)\n", sccp_channelstate2str(sccp_destination_local_channel->state), sccp_destination_local_channel->state);
2638 		goto EXIT;
2639 	}
2640 
2641 	if (!sccp_destination_local_channel->owner || !sccp_source_local_channel || !sccp_source_local_channel->owner) {
2642 		sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: Transfer error, no PBX channel for %s\n",
2643 			d->id,
2644 			!sccp_destination_local_channel->owner ? sccp_destination_local_channel->designator :
2645 			sccp_source_local_channel ? sccp_source_local_channel->designator :
2646 			"source_local == <null>");
2647 		goto EXIT;
2648 	}
2649 
2650 	pbx_source_local_channel = sccp_source_local_channel->owner;
2651 	pbx_source_remote_channel = iPbx.get_bridged_channel(sccp_source_local_channel->owner);
2652 	pbx_destination_remote_channel = iPbx.get_bridged_channel(sccp_destination_local_channel->owner);
2653 	pbx_destination_local_channel = sccp_destination_local_channel->owner;
2654 
2655 	sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: pbx_source_local_channel       %s\n", d->id, pbx_source_local_channel ? pbx_channel_name(pbx_source_local_channel) : "NULL");
2656 	sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: pbx_source_remote_channel      %s\n\n", d->id, pbx_source_remote_channel ? pbx_channel_name(pbx_source_remote_channel) : "NULL");
2657 
2658 	sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: pbx_destination_local_channel  %s\n", d->id, pbx_destination_local_channel ? pbx_channel_name(pbx_destination_local_channel) : "NULL");
2659 	sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: pbx_destination_remote_channel %s\n\n", d->id, pbx_destination_remote_channel ? pbx_channel_name(pbx_destination_remote_channel) : "NULL");
2660 
2661 	sccp_source_local_channel->channelStateReason = SCCP_CHANNELSTATEREASON_NORMAL;
2662 
2663 	if (!(pbx_source_remote_channel && pbx_destination_local_channel)) {
2664 		pbx_log(LOG_WARNING, "SCCP: Failed to complete transfer. Missing asterisk transferred or transferee channel\n");
2665 		goto EXIT;
2666 	}
2667 
2668 	{
2669 		int connectedLineUpdateReason = (sccp_destination_local_channel->state == SCCP_CHANNELSTATE_RINGOUT) ? AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING : AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
2670 
2671 		char calling_number[StationMaxDirnumSize] = { 0 };
2672 
2673 		char called_number[StationMaxDirnumSize] = { 0 };
2674 
2675 		char orig_number[StationMaxDirnumSize] = { 0 };
2676 		char calling_name[StationMaxNameSize] = { 0 };
2677 
2678 		char called_name[StationMaxNameSize] = { 0 };
2679 
2680 		char orig_name[StationMaxNameSize] = { 0 };
2681 
2682 		iCallInfo.Getter(sccp_channel_getCallInfo(sccp_destination_local_channel),
2683 			SCCP_CALLINFO_CALLINGPARTY_NAME, &calling_name,
2684 			SCCP_CALLINFO_CALLINGPARTY_NUMBER, &calling_number,
2685 			SCCP_CALLINFO_CALLEDPARTY_NAME, &called_name,
2686 			SCCP_CALLINFO_CALLEDPARTY_NUMBER, &called_number,
2687 			SCCP_CALLINFO_KEY_SENTINEL);
2688 
2689 		if (sccp_source_local_channel->calltype == SKINNY_CALLTYPE_INBOUND) {
2690 			iCallInfo.Getter(sccp_channel_getCallInfo(sccp_source_local_channel),
2691 				SCCP_CALLINFO_CALLINGPARTY_NAME, &orig_name,
2692 				SCCP_CALLINFO_CALLINGPARTY_NUMBER, &orig_number,
2693 				SCCP_CALLINFO_KEY_SENTINEL);
2694 		} else {
2695 			iCallInfo.Getter(sccp_channel_getCallInfo(sccp_source_local_channel),
2696 				SCCP_CALLINFO_CALLEDPARTY_NAME, &orig_name,
2697 				SCCP_CALLINFO_CALLEDPARTY_NUMBER, &orig_number,
2698 				SCCP_CALLINFO_KEY_SENTINEL);
2699 		}
2700 
2701 		/* update our source part */
2702 		iCallInfo.Setter(sccp_channel_getCallInfo(sccp_source_local_channel),
2703 			SCCP_CALLINFO_LAST_REDIRECTINGPARTY_NAME, calling_name,
2704 			SCCP_CALLINFO_LAST_REDIRECTINGPARTY_NUMBER, calling_number,
2705 			SCCP_CALLINFO_KEY_SENTINEL);
2706 		sccp_channel_display_callInfo(sccp_source_local_channel);
2707 
2708 		/* update our destination part */
2709 		iCallInfo.Setter(sccp_channel_getCallInfo(sccp_destination_local_channel),
2710 			SCCP_CALLINFO_LAST_REDIRECTINGPARTY_NAME, calling_name,
2711 			SCCP_CALLINFO_LAST_REDIRECTINGPARTY_NUMBER, calling_number,
2712 			SCCP_CALLINFO_KEY_SENTINEL);
2713 		sccp_destination_local_channel->calltype = SKINNY_CALLTYPE_FORWARD;
2714 		sccp_channel_display_callInfo(sccp_destination_local_channel);
2715 
2716 		/* update transferee */
2717 		iPbx.set_connected_line(sccp_source_local_channel, called_number, called_name, connectedLineUpdateReason);
2718 #if ASTERISK_VERSION_GROUP > 106										/*! \todo change to SCCP_REASON Codes, using mapping table */
2719 		if (iPbx.sendRedirectedUpdate) {
2720 			iPbx.sendRedirectedUpdate(sccp_source_local_channel, calling_number, calling_name, called_number, called_name, AST_REDIRECTING_REASON_UNCONDITIONAL);
2721 		}
2722 #endif
2723 		/* update ring-in channel directly */
2724 		iPbx.set_connected_line(sccp_destination_local_channel, orig_number, orig_name, connectedLineUpdateReason);
2725 #if ASTERISK_VERSION_GROUP > 106										/*! \todo change to SCCP_REASON Codes, using mapping table */
2726 //		if (iPbx.sendRedirectedUpdate) {
2727 //			iPbx.sendRedirectedUpdate(sccp_destination_local_channel, calling_number, calling_name, called_number, called_name, AST_REDIRECTING_REASON_UNCONDITIONAL);
2728 //		}
2729 #endif
2730 	}
2731 
2732 	if (sccp_destination_local_channel->state == SCCP_CHANNELSTATE_RINGOUT) {
2733 		sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: Blind transfer. Signalling ringing state to %s\n", d->id, pbx_channel_name(pbx_source_remote_channel));
2734 		pbx_indicate(pbx_source_remote_channel, AST_CONTROL_RINGING);					// Shouldn't this be ALERTING?
2735 
2736 		sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: (Ringing within Transfer %s)\n", pbx_channel_name(pbx_source_remote_channel));
2737 		sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: (Transfer destination %s)\n", pbx_channel_name(pbx_destination_local_channel));
2738 
2739 		if (GLOB(blindtransferindication) == SCCP_BLINDTRANSFER_RING) {
2740 			sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: (sccp_channel_transfer_complete) Send ringing indication to %s\n", pbx_channel_name(pbx_source_remote_channel));
2741 			pbx_indicate(pbx_source_remote_channel, AST_CONTROL_RINGING);
2742 		} else if (GLOB(blindtransferindication) == SCCP_BLINDTRANSFER_MOH) {
2743 			sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: (sccp_channel_transfer_complete) Started music on hold for channel %s\n", pbx_channel_name(pbx_source_remote_channel));
2744 			iPbx.moh_start(pbx_source_remote_channel, NULL, NULL);					//! \todo use pbx impl
2745 		}
2746 	}
2747 
2748 	sccp_channel_transfer_release(d, d->transferChannels.transferee);					/* explicit release */
2749 	if (!iPbx.attended_transfer(sccp_destination_local_channel, sccp_source_local_channel)) {
2750 		pbx_log(LOG_WARNING, "SCCP: Failed to masquerade %s into %s\n", pbx_channel_name(pbx_destination_local_channel), pbx_channel_name(pbx_source_remote_channel));
2751 		goto EXIT;
2752 	}
2753 
2754 	if (GLOB(transfer_tone) && sccp_destination_local_channel->state == SCCP_CHANNELSTATE_CONNECTED) {
2755 		/* while connected not all the tones can be played */
2756 		sccp_destination_local_channel->setTone(sccp_destination_local_channel, GLOB(autoanswer_tone), SKINNY_TONEDIRECTION_USER);
2757 	}
2758 
2759 #if ASTERISK_VERSION_GROUP >= 108
2760 	control_transfer_message = AST_TRANSFER_SUCCESS;
2761 #endif
2762 	result = TRUE;
2763 EXIT:
2764 	if (pbx_source_remote_channel) {
2765 		pbx_channel_unref(pbx_source_remote_channel);
2766 	}
2767 	if (pbx_destination_remote_channel) {
2768 		pbx_channel_unref(pbx_destination_remote_channel);
2769 	}
2770 	if (result == FALSE) {
2771 		sccp_dev_starttone(d, SKINNY_TONE_BEEPBONK, instance, sccp_destination_local_channel->callid, SKINNY_TONEDIRECTION_USER);
2772 		sccp_dev_displayprompt(d, instance, sccp_destination_local_channel->callid, SKINNY_DISP_CAN_NOT_COMPLETE_TRANSFER, SCCP_DISPLAYSTATUS_TIMEOUT);
2773 	} else {
2774 		sccp_source_local_channel->line->statistic.numberOfHeldChannels--;
2775 	}
2776 	if (!sccp_source_local_channel || !sccp_source_local_channel->owner) {
2777 		sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "SCCP: Peer owner disappeared! Can't free resources\n");
2778 		return;
2779 	}
2780 #if ASTERISK_VERSION_GROUP >= 108
2781 	iPbx.queue_control_data(sccp_source_local_channel->owner, AST_CONTROL_TRANSFER, &control_transfer_message, sizeof(control_transfer_message));
2782 #endif
2783 }
2784 
2785 /*!
2786  * \brief Set Caller Id Presentation
2787  * \param channel SCCP Channel
2788  * \param presentation SCCP CallerID Presentation ENUM
2789  */
sccp_channel_set_calleridPresentation(constChannelPtr channel,sccp_callerid_presentation_t presentation)2790 void sccp_channel_set_calleridPresentation(constChannelPtr channel, sccp_callerid_presentation_t presentation)
2791 {
2792 	iCallInfo.Setter(channel->privateData->callInfo, SCCP_CALLINFO_PRESENTATION, presentation, SCCP_CALLINFO_KEY_SENTINEL);
2793 	if (iPbx.set_callerid_presentation) {
2794 		iPbx.set_callerid_presentation(channel->owner, presentation);
2795 	}
2796 }
2797 
2798 /*!
2799  * \brief Forward a Channel
2800  * \param sccp_channel_parent SCCP parent channel
2801  * \param lineDevice SCCP LineDevice
2802  * \param fwdNumber fwdNumber as char *
2803  *
2804  * \callgraph
2805  * \callergraph
2806  */
sccp_channel_forward(constChannelPtr sccp_channel_parent,constLineDevicePtr ld,const char * fwdNumber)2807 int sccp_channel_forward(constChannelPtr sccp_channel_parent, constLineDevicePtr ld, const char * fwdNumber)
2808 {
2809 	char dialedNumber[256];
2810 	if (!sccp_channel_parent) {
2811 		pbx_log(LOG_ERROR, "We can not forward a call without parent channel\n");
2812 		return -1;
2813 	}
2814 
2815 	sccp_copy_string(dialedNumber, fwdNumber, sizeof(dialedNumber));
2816 	AUTO_RELEASE(sccp_channel_t, sccp_forwarding_channel , sccp_channel_allocate(sccp_channel_parent->line, NULL));
2817 
2818 	if (!sccp_forwarding_channel) {
2819 		pbx_log(LOG_ERROR, "%s: Can't allocate SCCP channel\n", ld->device->id);
2820 		return -1;
2821 	}
2822 	sccp_forwarding_channel->parentChannel = sccp_channel_retain(sccp_channel_parent);
2823 	sccp_forwarding_channel->softswitch_action = SCCP_SOFTSWITCH_DIAL;					/* softswitch will catch the number to be dialed */
2824 	sccp_forwarding_channel->ss_data = 0;									// nothing to pass to action
2825 	sccp_forwarding_channel->calltype = SKINNY_CALLTYPE_FORWARD;
2826 
2827 	char calling_name[StationMaxNameSize] = {0};
2828 	char calling_num[StationMaxDirnumSize] = {0};
2829 	char called_name[StationMaxNameSize] = {0};
2830 	char called_num[StationMaxDirnumSize] = {0};
2831 	iCallInfo.Getter(sccp_channel_getCallInfo(sccp_channel_parent),
2832 		SCCP_CALLINFO_CALLINGPARTY_NAME, &calling_name,
2833 		SCCP_CALLINFO_CALLINGPARTY_NUMBER, &calling_num,
2834 		SCCP_CALLINFO_CALLEDPARTY_NAME, &called_name,
2835 		SCCP_CALLINFO_CALLEDPARTY_NUMBER, &called_num,
2836 		SCCP_CALLINFO_KEY_SENTINEL);
2837 
2838 	/* copy the number to dial in the ast->exten */
2839 	sccp_copy_string(sccp_forwarding_channel->dialedNumber, dialedNumber, sizeof(sccp_forwarding_channel->dialedNumber));
2840 	sccp_log((DEBUGCAT_CHANNEL))(VERBOSE_PREFIX_3 "Incoming: %s (%s) Forwarded By: %s (%s) Forwarded To: %s\n", calling_name, calling_num, ld->line->cid_name, ld->line->cid_num, dialedNumber);
2841 
2842 	/* Copy Channel Capabilities From Predecessor */
2843 	memset(&sccp_forwarding_channel->remoteCapabilities.audio, 0, sizeof(sccp_forwarding_channel->remoteCapabilities.audio));
2844 	memcpy(&sccp_forwarding_channel->remoteCapabilities.audio, sccp_channel_parent->remoteCapabilities.audio, sizeof(sccp_forwarding_channel->remoteCapabilities.audio));
2845 	memset(&sccp_forwarding_channel->preferences.audio, 0, sizeof(sccp_forwarding_channel->preferences.audio));
2846 	memcpy(&sccp_forwarding_channel->preferences.audio, sccp_channel_parent->preferences.audio, sizeof(sccp_channel_parent->preferences.audio));
2847 
2848 	/* ok the number exist. allocate the asterisk channel */
2849 	if (!sccp_pbx_channel_allocate(sccp_forwarding_channel, NULL, sccp_channel_parent->owner))
2850 	{
2851 		return -1;
2852 	}
2853 	/* Update rtp setting to match predecessor */
2854 	skinny_codec_t codecs[] = { SKINNY_CODEC_WIDEBAND_256K, SKINNY_CODEC_NONE };
2855 	iPbx.set_nativeAudioFormats(sccp_forwarding_channel, codecs);
2856 	iPbx.rtp_setWriteFormat(sccp_forwarding_channel, SKINNY_CODEC_WIDEBAND_256K);
2857 	iPbx.rtp_setReadFormat(sccp_forwarding_channel, SKINNY_CODEC_WIDEBAND_256K);
2858 	sccp_channel_updateChannelCapability(sccp_forwarding_channel);
2859 
2860 	char newcalling_name[StationMaxNameSize] = {0};
2861 	char newcalling_num[StationMaxDirnumSize] = {0};
2862 	iCallInfo.Getter(sccp_channel_getCallInfo(sccp_forwarding_channel),
2863 		SCCP_CALLINFO_CALLINGPARTY_NAME, &newcalling_name,
2864 		SCCP_CALLINFO_CALLINGPARTY_NUMBER, &newcalling_num,
2865 		SCCP_CALLINFO_KEY_SENTINEL);
2866 
2867 	iCallInfo.Setter(sccp_channel_getCallInfo(sccp_forwarding_channel),
2868 		SCCP_CALLINFO_CALLINGPARTY_NAME, &calling_name,
2869 		SCCP_CALLINFO_CALLINGPARTY_NUMBER, &calling_num,
2870 		SCCP_CALLINFO_CALLEDPARTY_NUMBER, &dialedNumber,
2871 		SCCP_CALLINFO_ORIG_CALLEDPARTY_NAME, &newcalling_name,
2872 		SCCP_CALLINFO_ORIG_CALLEDPARTY_NUMBER, &newcalling_num,
2873 		SCCP_CALLINFO_ORIG_CALLEDPARTY_REDIRECT_REASON, 4,
2874 		SCCP_CALLINFO_KEY_SENTINEL);
2875 
2876 	/* setting callerid */
2877 	if (iPbx.set_callerid_number) {
2878 		iPbx.set_callerid_number(sccp_forwarding_channel->owner, calling_num);
2879 	}
2880 
2881 	if (iPbx.set_callerid_name) {
2882 		iPbx.set_callerid_name(sccp_forwarding_channel->owner, calling_name);
2883 	}
2884 
2885 	if (iPbx.set_callerid_ani) {
2886 		iPbx.set_callerid_ani(sccp_forwarding_channel->owner, dialedNumber);
2887 	}
2888 
2889 	if (iPbx.set_callerid_dnid) {
2890 		iPbx.set_callerid_dnid(sccp_forwarding_channel->owner, dialedNumber);
2891 	}
2892 
2893 	if (iPbx.set_callerid_redirectedParty) {
2894 		iPbx.set_callerid_redirectedParty(sccp_forwarding_channel->owner, called_num, called_name);
2895 	}
2896 
2897 	if (iPbx.set_callerid_redirectingParty) {
2898 		iPbx.set_callerid_redirectingParty(sccp_forwarding_channel->owner, newcalling_num, newcalling_name);
2899 	}
2900 
2901 	/* dial sccp_forwarding_channel */
2902 	iPbx.setChannelExten(sccp_forwarding_channel, dialedNumber);
2903 
2904 	/* \todo copy device line setvar variables from parent channel to forwarder->owner */
2905 	iPbx.set_callstate(sccp_forwarding_channel, AST_STATE_OFFHOOK);
2906 	if (!sccp_strlen_zero(dialedNumber)
2907 	    && iPbx.checkhangup(sccp_forwarding_channel)
2908 	    && pbx_exists_extension(sccp_forwarding_channel->owner, sccp_forwarding_channel->line->context ? sccp_forwarding_channel->line->context : "", dialedNumber, 1, sccp_forwarding_channel->line->cid_num)) {
2909 		/* found an extension, let's dial it */
2910 		pbx_log(LOG_NOTICE, "%s: (sccp_channel_forward) channel %s is dialing number %s\n", sccp_forwarding_channel->currentDeviceId, sccp_forwarding_channel->designator, dialedNumber);
2911 		/* Answer dialplan command works only when in RINGING OR RING ast_state */
2912 		iPbx.set_callstate(sccp_forwarding_channel, AST_STATE_RING);
2913 
2914 		pbx_channel_call_forward_set(sccp_forwarding_channel->owner, dialedNumber);
2915 #if CS_AST_CONTROL_REDIRECTING
2916 		iPbx.queue_control(sccp_forwarding_channel->owner, AST_CONTROL_REDIRECTING);
2917 #endif
2918 		if (pbx_pbx_start(sccp_forwarding_channel->owner)) {
2919 			pbx_log(LOG_WARNING, "%s: invalid number\n", "SCCP");
2920 		}
2921 		return 0;
2922 	}
2923 	pbx_log(LOG_NOTICE, "%s: (sccp_channel_forward) channel %s cannot dial this number %s\n", sccp_forwarding_channel->currentDeviceId, sccp_forwarding_channel->designator, dialedNumber);
2924 	sccp_channel_release(&sccp_forwarding_channel->parentChannel);						/* explicit release */
2925 	sccp_channel_endcall(sccp_forwarding_channel);
2926 	return -1;
2927 }
2928 
2929 #ifdef CS_SCCP_PARK
2930 /*!
2931  * \brief Park an SCCP Channel
2932  * \param channel SCCP Channel
2933  */
sccp_channel_park(constChannelPtr channel)2934 void sccp_channel_park(constChannelPtr channel)
2935 {
2936 	sccp_parkresult_t result = 0;
2937 
2938 	if (!iPbx.feature_park) {
2939 		pbx_log(LOG_WARNING, "SCCP, parking feature not implemented\n");
2940 		return;
2941 	}
2942 
2943 	/* let the pbx implementation do the rest */
2944 	result = iPbx.feature_park(channel);
2945 	if (PARK_RESULT_SUCCESS != result) {
2946 		AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(channel));
2947 		if (d) {
2948 			uint16_t lineInstance = sccp_device_find_index_for_line (d, channel->line->name);
2949 			sccp_dev_displayprompt (d, lineInstance, channel->callid, SKINNY_DISP_TEMP_FAIL " " SKINNY_DISP_PARK, SCCP_DISPLAYSTATUS_TIMEOUT);
2950 			channel->setTone (channel, SKINNY_TONE_BEEPBONK, SKINNY_TONEDIRECTION_USER);
2951 		}
2952 	}
2953 }
2954 #endif
2955 
2956 /*!
2957  * \brief Set Preferred Codec on Channel
2958  * \param c SCCP Channel
2959  * \param data Stringified Skinny Codec ShortName
2960  * \return Success as Boolean
2961  */
sccp_channel_setPreferredCodec(channelPtr c,const char * data)2962 boolean_t sccp_channel_setPreferredCodec(channelPtr c, const char * data)
2963 {
2964 	if (!data || !c) {
2965 		return FALSE;
2966 	}
2967 
2968 	skinny_codec_t new_codecs[SKINNY_MAX_CAPABILITIES] = { SKINNY_CODEC_NONE};
2969 	skinny_codec_t audio_prefs[ARRAY_LEN(c->preferences.audio)] = {SKINNY_CODEC_NONE};
2970 	skinny_codec_t video_prefs[ARRAY_LEN(c->preferences.video)] = {SKINNY_CODEC_NONE};
2971 
2972 	char text[64] = { '\0' };
2973 	sccp_copy_string(text, data, sizeof(text));
2974 	sccp_codec_parseAllowDisallow(new_codecs, text, 1 /*allow*/);
2975 	if (new_codecs[0] != SKINNY_CODEC_NONE) {
2976 		sccp_get_codecs_bytype(new_codecs, audio_prefs, SKINNY_CODEC_TYPE_AUDIO);
2977 		sccp_get_codecs_bytype(new_codecs, video_prefs, SKINNY_CODEC_TYPE_VIDEO);
2978 	}
2979 	if (audio_prefs[0] != SKINNY_CODEC_NONE) {
2980 		memcpy(c->preferences.audio, audio_prefs, sizeof c->preferences.audio);
2981 	}
2982 	if (video_prefs[0] != SKINNY_CODEC_NONE) {
2983 		memcpy(c->preferences.video, video_prefs, sizeof c->preferences.video);
2984 	}
2985 
2986 	if(c->line) {
2987 		c->line->preferences_set_on_line_level = TRUE;
2988 	}
2989 
2990 	sccp_channel_updateChannelCapability(c);
2991 
2992 	return TRUE;
2993 }
2994 
sccp_channel_getVideoMode(constChannelPtr c)2995 sccp_video_mode_t sccp_channel_getVideoMode(constChannelPtr c)
2996 {
2997 #if CS_SCCP_VIDEO
2998 	// sccp_log(DEBUGCAT_CHANNEL)(VERBOSE_PREFIX_3 "%s: (getVideoMode) current video mode:%s\n", c->designator, sccp_video_mode2str(c->videomode));
2999 	return c->videomode;
3000 #else
3001 	return FALSE;
3002 #endif
3003 }
3004 
sccp_channel_setVideoMode(channelPtr c,const char * data)3005 boolean_t sccp_channel_setVideoMode(channelPtr c, const char *data)
3006 {
3007 	boolean_t res = FALSE;
3008 #if CS_SCCP_VIDEO
3009 	if (c) {
3010 		sccp_video_mode_t newval = c->videomode = sccp_video_mode_str2val(data);
3011 		if (newval == SCCP_VIDEO_MODE_SENTINEL) {
3012 			return res;
3013 		}
3014 		sccp_rtp_t * video = (sccp_rtp_t *)&(c->rtp.video);
3015 		sccp_log((DEBUGCAT_CHANNEL | DEBUGCAT_RTP))(VERBOSE_PREFIX_2 "%s: (setVideoMode) Setting Video Mode to %s\n", c->designator, sccp_video_mode2str(newval));
3016 		if (c->state >= SCCP_GROUPED_CHANNELSTATE_SETUP && newval == SCCP_VIDEO_MODE_AUTO && !c->isHangingUp) {
3017 			if(!c->rtp.video.instance || !sccp_rtp_getState(video, SCCP_RTP_RECEPTION)) {
3018 				sccp_channel_openMultiMediaReceiveChannel(c);
3019 			}
3020 			if((sccp_rtp_getState(video, SCCP_RTP_RECEPTION) & SCCP_RTP_STATUS_ACTIVE) && !sccp_rtp_getState(video, SCCP_RTP_TRANSMISSION)) {
3021 				sccp_channel_startMultiMediaTransmission(c);
3022 			}
3023 		}
3024 		if (newval == SCCP_VIDEO_MODE_OFF) {
3025 			if (c->rtp.video.instance) {
3026 				if(sccp_rtp_getState(video, SCCP_RTP_RECEPTION)) {
3027 					sccp_channel_closeMultiMediaReceiveChannel(c, TRUE);
3028 				}
3029 				if(sccp_rtp_getState(video, SCCP_RTP_TRANSMISSION)) {
3030 					sccp_channel_stopMultiMediaTransmission(c, TRUE);
3031 				}
3032 				if(video->instance && video->instance_active) {
3033 					iPbx.rtp_stop(video->instance);
3034 					video->instance_active = FALSE;
3035 				}
3036 			}
3037 		}
3038 		c->videomode = newval;
3039 		if (c->owner) {
3040 			pbx_builtin_setvar_helper(c->owner, "_SCCP_VIDEO_MODE", sccp_video_mode2str(c->videomode));
3041 		}
3042 		return TRUE;
3043 	}
3044 #endif
3045 	{
3046 		return res;
3047 	}
3048 }
3049 
3050 /*!
3051  * \brief Send callwaiting tone to device multiple times
3052  */
sccp_channel_callwaiting_tone_interval(constDevicePtr device,constChannelPtr channel)3053 int sccp_channel_callwaiting_tone_interval(constDevicePtr device, constChannelPtr channel)
3054 {
3055 	if (GLOB(callwaiting_tone)) {
3056 		AUTO_RELEASE(sccp_device_t, d , sccp_device_retain(device));
3057 
3058 		if (d) {
3059 			AUTO_RELEASE(sccp_channel_t, c , sccp_channel_retain(channel));
3060 
3061 			if (c) {
3062 				pbx_assert(c->line != NULL);
3063 				sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: Handle Callwaiting Tone on channel %d\n", c->callid);
3064 				if (c && c->owner && (SCCP_CHANNELSTATE_CALLWAITING == c->state || SCCP_CHANNELSTATE_RINGING == c->state)) {
3065 					sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "%s: Sending Call Waiting Tone \n", d->id);
3066 					c->setTone(c, GLOB(callwaiting_tone), SKINNY_TONEDIRECTION_USER);
3067 					return 0;
3068 				}
3069 				sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: (sccp_channel_callwaiting_tone_interval) channel has been hungup or pickuped up by another phone\n");
3070 				return -1;
3071 			}
3072 		}
3073 		sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: (sccp_channel_callwaiting_tone_interval) No valid device/channel to handle callwaiting\n");
3074 	} else {
3075 		sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: (sccp_channel_callwaiting_tone_interval) No callwaiting_tone set\n");
3076 	}
3077 	return -1;
3078 }
3079 
3080 /*=================================================================================== FIND FUNCTIONS ==============*/
3081 /*!
3082  * \brief Find Channel by ID, using a specific line
3083  *
3084  * \callgraph
3085  * \callergraph
3086  *
3087  * \param l     SCCP Line
3088  * \param id    channel ID as int
3089  * \return *refcounted* SCCP Channel (can be null)
3090  * \todo rename function to include that it checks the channelstate != DOWN
3091  */
sccp_find_channel_on_line_byid(constLinePtr l,uint32_t id)3092 channelPtr sccp_find_channel_on_line_byid(constLinePtr l, uint32_t id)
3093 {
3094 	sccp_channel_t *c = NULL;
3095 
3096 	//sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: Looking for channel on line by id %u\n", id);
3097 
3098 	SCCP_LIST_LOCK(&(((linePtr)l)->channels));
3099 	c = SCCP_LIST_FIND(&l->channels, sccp_channel_t, tmpc, list, (tmpc->callid == id && tmpc->state != SCCP_CHANNELSTATE_DOWN), TRUE, __FILE__, __LINE__, __PRETTY_FUNCTION__);
3100 	SCCP_LIST_UNLOCK(&(((linePtr)l)->channels));
3101 	return c;
3102 }
3103 
3104 /*!
3105  * Find channel by lineId and CallId, connected to a particular device;
3106  * \return *refcounted* SCCP Channel (can be null)
3107  */
sccp_find_channel_by_buttonIndex_and_callid(constDevicePtr d,const uint32_t buttonIndex,const uint32_t callid)3108 channelPtr sccp_find_channel_by_buttonIndex_and_callid(constDevicePtr d, const uint32_t buttonIndex, const uint32_t callid)
3109 {
3110 	sccp_channel_t *c = NULL;
3111 
3112 	if (!d || !buttonIndex || !callid) {
3113 		return NULL;
3114 	}
3115 
3116 	AUTO_RELEASE(sccp_line_t, l , sccp_line_find_byButtonIndex((sccp_device_t *) d, buttonIndex));
3117 	if (l) {
3118 		SCCP_LIST_LOCK(&l->channels);
3119 		c = SCCP_LIST_FIND(&l->channels, sccp_channel_t, tmpc, list, (tmpc->callid == callid), TRUE, __FILE__, __LINE__, __PRETTY_FUNCTION__);
3120 		SCCP_LIST_UNLOCK(&l->channels);
3121 	}
3122 	if (!c) {
3123 		sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "%s: Could not find channel for lineInstance:%u and callid:%d on device\n", d->id, buttonIndex, callid);
3124 	}
3125 	return c;
3126 }
3127 
3128 /*!
3129  * Find channel by lineInstance and CallId, connected to a particular device;
3130  * \return *refcounted* SCCP Channel (can be null)
3131  */
sccp_find_channel_by_lineInstance_and_callid(const sccp_device_t * d,const uint32_t lineInstance,const uint32_t callid)3132 channelPtr sccp_find_channel_by_lineInstance_and_callid(const sccp_device_t * d, const uint32_t lineInstance, const uint32_t callid)
3133 {
3134 	sccp_channel_t *c = NULL;
3135 
3136 	if (!d || !lineInstance || !callid) {
3137 		return NULL;
3138 	}
3139 
3140 	AUTO_RELEASE(sccp_line_t, l , sccp_line_find_byid((sccp_device_t *) d, lineInstance));
3141 
3142 	if (l) {
3143 		SCCP_LIST_LOCK(&l->channels);
3144 		c = SCCP_LIST_FIND(&l->channels, sccp_channel_t, tmpc, list, (tmpc->callid == callid), TRUE, __FILE__, __LINE__, __PRETTY_FUNCTION__);
3145 		SCCP_LIST_UNLOCK(&l->channels);
3146 	}
3147 	if (!c) {
3148 		sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "%s: Could not find channel for lineInstance:%u and callid:%d on device\n", d->id, lineInstance, callid);
3149 	}
3150 	return c;
3151 }
3152 
3153 /*!
3154  * \brief Find Line by ID
3155  *
3156  * \callgraph
3157  * \callergraph
3158  *
3159  * \param callid Call ID as uint32_t
3160  * \return *refcounted* SCCP Channel (can be null)
3161  *
3162  * \todo rename function to include that it checks the channelstate != DOWN (sccp_find_channel_on_line_byid)
3163  */
sccp_channel_find_byid(uint32_t callid)3164 channelPtr sccp_channel_find_byid(uint32_t callid)
3165 {
3166 	sccp_channel_t *channel = NULL;
3167 	sccp_line_t *l = NULL;
3168 
3169 	sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: Looking for channel by id %u\n", callid);
3170 
3171 	SCCP_RWLIST_RDLOCK(&GLOB(lines));
3172 	SCCP_RWLIST_TRAVERSE(&GLOB(lines), l, list) {
3173 		channel = sccp_find_channel_on_line_byid(l, callid);
3174 		if (channel) {
3175 			break;
3176 		}
3177 	}
3178 	SCCP_RWLIST_UNLOCK(&GLOB(lines));
3179 	if (!channel) {
3180 		sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: Could not find channel for callid:%d on device\n", callid);
3181 	}
3182 	return channel;
3183 }
3184 
3185 /*!
3186  * \brief Find Channel by Pass Through Party ID
3187  * We need this to start the correct rtp stream.
3188  *
3189  * \note Does check that channel state not is DOWN.
3190  *
3191  * \callgraph
3192  * \callergraph
3193  *
3194  * \param passthrupartyid Party ID
3195  * \return *refcounted* SCCP Channel - cann bee NULL if no channel with this id was found
3196  */
sccp_channel_find_bypassthrupartyid(uint32_t passthrupartyid)3197 channelPtr sccp_channel_find_bypassthrupartyid(uint32_t passthrupartyid)
3198 {
3199 	sccp_channel_t *c = NULL;
3200 	sccp_line_t *l = NULL;
3201 
3202 	sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: Looking for channel by PassThruId %u\n", passthrupartyid);
3203 
3204 	SCCP_RWLIST_RDLOCK(&GLOB(lines));
3205 	SCCP_RWLIST_TRAVERSE(&GLOB(lines), l, list) {
3206 		SCCP_LIST_LOCK(&l->channels);
3207 		c = SCCP_LIST_FIND(&l->channels, sccp_channel_t, tmpc, list, (tmpc->passthrupartyid == passthrupartyid && tmpc->state != SCCP_CHANNELSTATE_DOWN), TRUE, __FILE__, __LINE__, __PRETTY_FUNCTION__);
3208 		SCCP_LIST_UNLOCK(&l->channels);
3209 		if (c) {
3210 			break;
3211 		}
3212 	}
3213 	SCCP_RWLIST_UNLOCK(&GLOB(lines));
3214 
3215 	if (!c) {
3216 		sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: Could not find active channel with Passthrupartyid %u\n", passthrupartyid);
3217 	}
3218 	return c;
3219 }
3220 
3221 /*!
3222  * \brief Find Channel by Pass Through Party ID on a line connected to device provided
3223  * We need this to start the correct rtp stream.
3224  *
3225  * \param d SCCP Device
3226  * \param passthrupartyid Party ID
3227  * \return retained SCCP Channel - can be NULL if no channel with this id was found.
3228  *
3229  * \note does not take channel state into account, this need to be asserted in the calling function
3230  * \note this is different from the sccp_channel_find_bypassthrupartyid behaviour
3231  *
3232  * \callgraph
3233  * \callergraph
3234  *
3235  */
sccp_channel_find_on_device_bypassthrupartyid(constDevicePtr d,uint32_t passthrupartyid)3236 channelPtr sccp_channel_find_on_device_bypassthrupartyid(constDevicePtr d, uint32_t passthrupartyid)
3237 {
3238 	sccp_channel_t *c = NULL;
3239 
3240 	if (!d) {
3241 		sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_RTP)) (VERBOSE_PREFIX_3 "SCCP: No device provided to look for %u\n", passthrupartyid);
3242 		return NULL;
3243 	}
3244 	uint8_t instance = 0;
3245 
3246 	sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_RTP + DEBUGCAT_HIGH)) (VERBOSE_PREFIX_3 "SCCP: Looking for channel on device by PassThruId %u on device %s\n", passthrupartyid, d->id);
3247 	for (instance = SCCP_FIRST_LINEINSTANCE; instance < d->lineButtons.size; instance++) {
3248 		if (d->lineButtons.instance[instance]) {
3249 			AUTO_RELEASE(sccp_line_t, l , sccp_line_retain(d->lineButtons.instance[instance]->line));
3250 
3251 			if (l) {
3252 				sccp_log((DEBUGCAT_CHANNEL + DEBUGCAT_RTP + DEBUGCAT_HIGH)) (VERBOSE_PREFIX_3 "%s: Found line: '%s'\n", d->id, l->name);
3253 				SCCP_LIST_LOCK(&l->channels);
3254 				c = SCCP_LIST_FIND(&l->channels, sccp_channel_t, tmpc, list, (tmpc->passthrupartyid == passthrupartyid), TRUE, __FILE__, __LINE__, __PRETTY_FUNCTION__);
3255 				SCCP_LIST_UNLOCK(&l->channels);
3256 
3257 				if (c) {
3258 					break;
3259 				}
3260 			}
3261 		}
3262 	}
3263 	if (!c) {
3264 		sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "%s: Could not find active channel with Passthrupartyid %u on device\n", d->id, passthrupartyid);
3265 	}
3266 
3267 	return c;
3268 }
3269 
3270 /*!
3271  * \brief Find Channel by State on Line
3272  * \return *refcounted* SCCP Channel
3273  *
3274  * \callgraph
3275  * \callergraph
3276  *
3277  * \param l SCCP Line
3278  * \param state State
3279  * \return *refcounted* SCCP Channel
3280  */
sccp_channel_find_bystate_on_line(constLinePtr l,sccp_channelstate_t state)3281 channelPtr sccp_channel_find_bystate_on_line(constLinePtr l, sccp_channelstate_t state)
3282 {
3283 	sccp_channel_t *c = NULL;
3284 
3285 	sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: Looking for channel by state '%d'\n", state);
3286 
3287 	SCCP_LIST_LOCK(&(((linePtr)l)->channels));
3288 	c = SCCP_LIST_FIND(&l->channels, sccp_channel_t, tmpc, list, (tmpc->state == state), TRUE, __FILE__, __LINE__, __PRETTY_FUNCTION__);
3289 	SCCP_LIST_UNLOCK(&(((linePtr)l)->channels));
3290 
3291 	if (!c) {
3292 		sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "%s: Could not find active channel with state %s(%u) on line\n", l->id, sccp_channelstate2str(state), state);
3293 	}
3294 
3295 	return c;
3296 }
3297 
3298 /*!
3299  * \brief Find Channel by State on Device
3300  *
3301  * \callgraph
3302  * \callergraph
3303  *
3304  * \param device SCCP Device
3305  * \param state State as int
3306  * \return *refcounted* SCCP Channel
3307  */
sccp_channel_find_bystate_on_device(constDevicePtr device,sccp_channelstate_t state)3308 channelPtr sccp_channel_find_bystate_on_device(constDevicePtr device, sccp_channelstate_t state)
3309 {
3310 	sccp_channel_t *c = NULL;
3311 
3312 	sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: Looking for channel by state '%d' on device: %s\n", state, device->id);
3313 
3314 	AUTO_RELEASE(sccp_device_t, d , sccp_device_retain(device));
3315 
3316 	if (!d) {
3317 		return NULL;
3318 	}
3319 	uint8_t instance = 0;
3320 
3321 	for (instance = SCCP_FIRST_LINEINSTANCE; instance < d->lineButtons.size; instance++) {
3322 		if (d->lineButtons.instance[instance]) {
3323 			AUTO_RELEASE(sccp_line_t, l , sccp_line_retain(d->lineButtons.instance[instance]->line));
3324 
3325 			if (l) {
3326 				sccp_log((DEBUGCAT_DEVICE + DEBUGCAT_BUTTONTEMPLATE + DEBUGCAT_CHANNEL + DEBUGCAT_LINE)) (VERBOSE_PREFIX_3 "%s: line: '%s'\n", d->id, l->name);
3327 				SCCP_LIST_LOCK(&l->channels);
3328 				c = SCCP_LIST_FIND(&l->channels, sccp_channel_t, tmpc, list, (tmpc->state == state && sccp_util_matchSubscriptionId(tmpc, d->lineButtons.instance[instance]->subscriptionId.number)), TRUE, __FILE__, __LINE__, __PRETTY_FUNCTION__);
3329 				SCCP_LIST_UNLOCK(&l->channels);
3330 				if (c) {
3331 					break;
3332 				}
3333 			}
3334 		}
3335 	}
3336 	if (!c) {
3337 		sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "%s: Could not find active channel with state %s(%u) on device\n", d->id, sccp_channelstate2str(state), state);
3338 	}
3339 	return c;
3340 }
3341 
3342 /*!
3343  * \brief Find Selected Channel by Device
3344  * \param d SCCP Device
3345  * \param channel channel
3346  * \return x SelectedChannel
3347  *
3348  * \callgraph
3349  * \callergraph
3350  *
3351  * \todo Currently this returns the selectedchannel unretained (there is no retain/release for selectedchannel at the moment)
3352  */
sccp_device_find_selectedchannel(constDevicePtr d,constChannelPtr channel)3353 sccp_selectedchannel_t *sccp_device_find_selectedchannel(constDevicePtr d, constChannelPtr channel)
3354 {
3355 	if (!d) {
3356 		return NULL;
3357 	}
3358 	sccp_selectedchannel_t *sc = NULL;
3359 
3360 	sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "%s: Looking for selected channel (%d)\n", d->id, channel->callid);
3361 
3362 	SCCP_LIST_LOCK(&(((devicePtr)d)->selectedChannels));
3363 	sc = SCCP_LIST_FIND(&d->selectedChannels, sccp_selectedchannel_t, tmpsc, list, (tmpsc->channel == channel), FALSE, __FILE__, __LINE__, __PRETTY_FUNCTION__);
3364 	SCCP_LIST_UNLOCK(&(((devicePtr)d)->selectedChannels));
3365 	return sc;
3366 }
3367 
3368 /*!
3369  * \brief Count Selected Channel on Device
3370  * \param device SCCP Device
3371  * \return count Number of Selected Channels
3372  *
3373  */
sccp_device_selectedchannels_count(constDevicePtr device)3374 uint8_t sccp_device_selectedchannels_count(constDevicePtr device)
3375 {
3376 	uint8_t count = 0;
3377 
3378 	sccp_log((DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "%s: Looking for selected channels count\n", device->id);
3379 	SCCP_LIST_LOCK(&(((devicePtr)device)->selectedChannels));
3380 	count = SCCP_LIST_GETSIZE(&device->selectedChannels);
3381 	SCCP_LIST_UNLOCK(&(((devicePtr)device)->selectedChannels));
3382 
3383 	return count;
3384 }
3385 // kate: indent-width 8; replace-tabs off; indent-mode cstyle; auto-insert-doxygen on; line-numbers on; tab-indents on; keep-extra-spaces off; auto-brackets off;
3386