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