1 /*!
2  * \file        sccp_pbx.c
3  * \brief       SCCP PBX Asterisk Wrapper Class
4  * \author      Diederik de Groot <ddegroot [at] users.sourceforge.net>
5  * \note        Reworked, but based on chan_sccp code.
6  *              The original chan_sccp driver that was made by Zozo which itself was derived from the chan_skinny driver.
7  *              Modified by Jan Czmok and Julien Goodwin
8  * \note        This program is free software and may be modified and distributed under the terms of the GNU Public License.
9  *              See the LICENSE file at the top of the source tree.
10  *
11  */
12 #include "config.h"
13 #include "common.h"
14 #include "sccp_pbx.h"
15 #include "sccp_channel.h"
16 #include "sccp_device.h"
17 #include "sccp_conference.h"
18 #include "sccp_feature.h"
19 #include "sccp_line.h"
20 #include "sccp_utils.h"
21 #include "sccp_indicate.h"
22 #include "sccp_linedevice.h"
23 #include "sccp_rtp.h"
24 #include "sccp_netsock.h"
25 #include "sccp_session.h"
26 #include "sccp_atomic.h"
27 #include "sccp_labels.h"
28 #include "sccp_threadpool.h"
29 
30 SCCP_FILE_VERSION(__FILE__, "");
31 
32 #include <asterisk/callerid.h>
33 #include <asterisk/module.h>		// ast_update_use_count
34 #include <asterisk/causes.h>		// AST_CAUSE_NORMAL_CLEARING
35 
36 /*!
37  * \brief SCCP Request Channel
38  * \param lineName              Line Name as Char
39  * \param autoanswer_type       SCCP Auto Answer Type
40  * \param autoanswer_cause      SCCP Auto Answer Cause
41  * \param ringermode            Ringer Mode
42  * \param channel               SCCP Channel
43  * \return SCCP Channel Request Status
44  *
45  * \called_from_asterisk
46  */
sccp_requestChannel(const char * lineName,sccp_autoanswer_t autoanswer_type,uint8_t autoanswer_cause,skinny_ringtype_t ringermode,sccp_channel_t * const * channel)47 sccp_channel_request_status_t sccp_requestChannel(const char * lineName, sccp_autoanswer_t autoanswer_type, uint8_t autoanswer_cause, skinny_ringtype_t ringermode, sccp_channel_t * const * channel)
48 {
49 	if (!lineName) {
50 		return SCCP_REQUEST_STATUS_ERROR;
51 	}
52 
53 	char mainId[SCCP_MAX_EXTENSION];
54 	sccp_subscription_id_t subscriptionId;
55 	if(!sccp_parseComposedId(lineName, 80, &subscriptionId, mainId)) {
56 		sccp_log((DEBUGCAT_CORE))(VERBOSE_PREFIX_3 "Could not parse lineName:%s !\n", lineName);
57 		return SCCP_REQUEST_STATUS_LINEUNKNOWN;
58 	};
59 
60 	AUTO_RELEASE(sccp_line_t, l, sccp_line_find_byname(mainId, FALSE));
61 	if (!l) {
62 		sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "SCCP/%s does not exist!\n", mainId);
63 		return SCCP_REQUEST_STATUS_LINEUNKNOWN;
64 	}
65 	sccp_log_and((DEBUGCAT_CORE + DEBUGCAT_HIGH)) (VERBOSE_PREFIX_1 "[SCCP] in file %s, line %d (%s)\n", __FILE__, __LINE__, __PRETTY_FUNCTION__);
66 	if (SCCP_RWLIST_GETSIZE(&l->devices) == 0) {
67 		sccp_log((DEBUGCAT_DEVICE + DEBUGCAT_LINE)) (VERBOSE_PREFIX_3 "SCCP/%s isn't currently registered anywhere.\n", l->name);
68 		return SCCP_REQUEST_STATUS_LINEUNAVAIL;
69 	}
70 	sccp_log_and((DEBUGCAT_CORE + DEBUGCAT_HIGH)) (VERBOSE_PREFIX_1 "[SCCP] in file %s, line %d (%s)\n", __FILE__, __LINE__, __PRETTY_FUNCTION__);
71 	/* call forward check */
72 
73 	// Allocate a new SCCP channel.
74 	/* on multiline phone we set the line when answering or switching lines */
75 	AUTO_RELEASE(sccp_channel_t, my_sccp_channel, sccp_channel_allocate(l, NULL));
76 	if (!my_sccp_channel) {
77 		return SCCP_REQUEST_STATUS_ERROR;
78 	}
79 
80 	/* set subscriberId for individual device addressing */
81 	if (!sccp_strlen_zero(subscriptionId.number)) {
82 		sccp_copy_string(my_sccp_channel->subscriptionId.number, subscriptionId.number, sizeof(my_sccp_channel->subscriptionId.number));
83 		if (!sccp_strlen_zero(subscriptionId.name)) {
84 			sccp_copy_string(my_sccp_channel->subscriptionId.name, subscriptionId.name, sizeof(my_sccp_channel->subscriptionId.name));
85 		} else {
86 			//pbx_log(LOG_NOTICE, "%s: calling subscriber id=%s\n", l->id, my_sccp_channel->subscriptionId.number);
87 		}
88 	} else {
89 		sccp_copy_string(my_sccp_channel->subscriptionId.number, l->defaultSubscriptionId.number, sizeof(my_sccp_channel->subscriptionId.number));
90 		sccp_copy_string(my_sccp_channel->subscriptionId.name, l->defaultSubscriptionId.name, sizeof(my_sccp_channel->subscriptionId.name));
91 		//pbx_log(LOG_NOTICE, "%s: calling all subscribers\n", l->id);
92 	}
93 
94 	//memset(&channel->preferences.audio, 0, sizeof(channel->preferences.audio));
95 	//memset(&channel->preferences.video, 0, sizeof(channel->preferences.video));
96 
97 	my_sccp_channel->autoanswer_type = autoanswer_type;
98 	my_sccp_channel->autoanswer_cause = autoanswer_cause;
99 	my_sccp_channel->ringermode = ringermode;
100 	my_sccp_channel->hangupRequest = sccp_astgenwrap_requestQueueHangup;
101 	(*(sccp_channel_t **)channel) = sccp_channel_retain(my_sccp_channel);
102 	return SCCP_REQUEST_STATUS_SUCCESS;
103 }
104 
105 /*!
106  * \brief SCCP Structure to pass data to the pbx answer thread
107  */
108 struct sccp_answer_conveyor_struct {
109 	sccp_linedevice_t * ld;
110 	uint32_t callid;
111 };
112 /*!
113  * \brief Call Auto Answer Thead
114  * \param data Data
115  *
116  * The Auto Answer thread is started by ref sccp_pbx_call if necessary
117  */
sccp_pbx_call_autoanswer_thread(void * data)118 static void *sccp_pbx_call_autoanswer_thread(void *data)
119 {
120 	struct sccp_answer_conveyor_struct *conveyor = (struct sccp_answer_conveyor_struct *)data;
121 
122 	sccp_log((DEBUGCAT_PBX))(VERBOSE_PREFIX_3 "SCCP: autoanswer thread started\n");
123 
124 	sleep(GLOB(autoanswer_ring_time));
125 	pthread_testcancel();
126 
127 	if (!conveyor) {
128 		pbx_log(LOG_ERROR, "SCCP: (autoanswer_thread) No conveyor\n");
129 		return NULL;
130 	}
131 	if(!conveyor->ld) {
132 		pbx_log(LOG_ERROR, "SCCP: (autoanswer_thread) No linedevice\n");
133 		goto FINAL;
134 	}
135 
136 	{
137 		AUTO_RELEASE(sccp_device_t, device, sccp_device_retain(conveyor->ld->device));
138 
139 		if (!device) {
140 			pbx_log(LOG_ERROR, "SCCP: (autoanswer_thread) no device\n");
141 			goto FINAL;
142 		}
143 
144 		AUTO_RELEASE(sccp_channel_t, c , sccp_channel_find_byid(conveyor->callid));
145 
146 		if (!c || c->state != SCCP_CHANNELSTATE_RINGING) {
147 			pbx_log(LOG_WARNING, "%s: (autoanswer_thread) %s\n", device->id, c ? "not ringing" : "no channel");
148 			goto FINAL;
149 		}
150 		if (c->pbx_callid) {
151 			pbx_callid_threadassoc_add(c->pbx_callid);
152 		}
153 
154 		sccp_channel_answer(device, c);
155 		c->setTone(c, GLOB(autoanswer_tone), SKINNY_TONEDIRECTION_USER);
156 		if (c->autoanswer_type == SCCP_AUTOANSWER_1W) {
157 			sccp_dev_set_microphone(device, SKINNY_STATIONMIC_OFF);
158 		}
159 		if (c->pbx_callid) {
160 			pbx_callid_threadassoc_remove();
161 		}
162 	}
163 FINAL:
164 	if(conveyor->ld) {
165 		sccp_linedevice_release(&conveyor->ld);                                        // retained in calling thread, explicit release required here
166 	}
167 	sccp_free(conveyor);
168 	return NULL;
169 }
170 
171 /*!
172  * \brief Incoming Calls by Asterisk SCCP_Request
173  * \param c SCCP Channel
174  * \param dest Destination as char
175  * \param timeout Timeout after which incoming call is cancelled as int
176  * \return Success as int
177  *
178  * \todo reimplement DNDMODES, ringermode=urgent, autoanswer
179  *
180  * \callgraph
181  * \callergraph
182  *
183  * \called_from_asterisk
184  *
185  * \note called with c retained
186  */
187 // improved sharedline handling
188 // - calculate c->subscribers correctly			(using when handling sccp_softkey_onhook, to define behaviour)
189 // - handle dnd and callforward after calculating c->subscribers
190 // - use asterisk local channel to resolve forward bei non-shared line, which does evade
191 //   * sccp_channel_callforward
192 //   * sccp_channel_end_forwarding_channel
193 //   * c->parentChannel
194 //   * masquerading in sccp_pbx_answer
195 //   in that case
sccp_pbx_call(channelPtr c,const char * dest,int timeout)196 int sccp_pbx_call(channelPtr c, const char * dest, int timeout)
197 {
198 	if (!c) {
199 		return -1;
200 	}
201 	int res = 0;
202 
203 	AUTO_RELEASE(sccp_line_t, l , sccp_line_retain(c->line));
204 	if (!l) {
205 		pbx_log(LOG_WARNING, "SCCP: The channel %08X has no line. giving up.\n", (c->callid));
206 		return -1;
207 	}
208 
209 	sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: Asterisk request to call %s\n", l->name, iPbx.getChannelName(c));
210 
211 	/* Reinstated this call instead of the following lines */
212 	char cid_name[StationMaxNameSize] = {0};
213 	char cid_num[StationMaxDirnumSize] = {0};
214 	char suffixedNumber[StationMaxDirnumSize] = {0};
215 	sccp_callerid_presentation_t presentation = CALLERID_PRESENTATION_ALLOWED;
216 
217 	sccp_callinfo_t *ci = sccp_channel_getCallInfo(c);
218 	iCallInfo.Getter(ci,
219 		SCCP_CALLINFO_CALLINGPARTY_NAME, &cid_name,
220 		SCCP_CALLINFO_CALLINGPARTY_NUMBER, &cid_num,
221 		SCCP_CALLINFO_PRESENTATION, &presentation,
222 		SCCP_CALLINFO_KEY_SENTINEL);
223 	sccp_copy_string(suffixedNumber, cid_num, sizeof(suffixedNumber));
224 	//! \todo implement dnid, ani, ani2 and rdnis
225 	sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_3 "SCCP: (sccp_pbx_call) asterisk callerid='%s <%s>'\n", cid_name, cid_num);
226 
227 	/* Set the channel callingParty Name and Number, called Party Name and Number, original CalledParty Name and Number, Presentation */
228 	if (GLOB(recorddigittimeoutchar)) {
229 		/* The hack to add the # at the end of the incoming number
230 		   is only applied for numbers beginning with a 0,
231 		   which is appropriate for Germany and other countries using similar numbering plan.
232 		   The option should be generalized, moved to the dialplan, or otherwise be replaced. */
233 		/* Also, we require an option whether to add the timeout suffix to certain
234 		   enbloc dialed numbers (such as via 7970 enbloc dialing) if they match a certain pattern.
235 		   This would help users dial from call history lists on other phones, which do not have enbloc dialing,
236 		   when using shared lines. */
237 		int length = sccp_strlen(cid_num);
238 		if (length && (length + 2  < StationMaxDirnumSize) && ('\0' == cid_num[0])) {
239 			suffixedNumber[length + 0] = GLOB(digittimeoutchar);
240 			suffixedNumber[length + 1] = '\0';
241 		}
242 		/* Set the channel calledParty Name and Number 7910 compatibility */
243 	}
244 	//! \todo implement dnid, ani, ani2 and rdnis
245 	sccp_callerid_presentation_t pbx_presentation = iPbx.get_callerid_presentation ? iPbx.get_callerid_presentation(c->owner) : SCCP_CALLERID_PRESENTATION_SENTINEL;
246 	if (	(!sccp_strequals(suffixedNumber, cid_num)) ||
247 		(pbx_presentation != SCCP_CALLERID_PRESENTATION_SENTINEL && pbx_presentation != presentation)
248 	) {
249 		iCallInfo.Setter(ci,
250 			SCCP_CALLINFO_CALLINGPARTY_NUMBER, (!sccp_strlen_zero(suffixedNumber) ? suffixedNumber : NULL),
251 			SCCP_CALLINFO_PRESENTATION, (pbx_presentation != SCCP_CALLERID_PRESENTATION_SENTINEL) ? pbx_presentation : presentation,
252 			SCCP_CALLINFO_KEY_SENTINEL);
253 	}
254 	sccp_channel_display_callInfo(c);
255 
256 	if (!c->ringermode) {
257 		c->ringermode = GLOB(ringtype);
258 	}
259 	boolean_t isRinging = FALSE;
260 	boolean_t isBusy = FALSE;
261 	boolean_t bypassCallForward = !sccp_strlen_zero(pbx_builtin_getvar_helper(c->owner, "BYPASS_CFWD"));
262 	sccp_linedevice_t * ForwardingLineDevice = NULL;
263 
264 	sccp_linedevice_t * ld = NULL;
265 	sccp_channelstate_t previousstate = c->previousChannelState;
266 
267 	SCCP_LIST_LOCK(&l->devices);
268 	int num_devices = SCCP_LIST_GETSIZE(&l->devices);
269 	c->subscribers = num_devices;
270 
271 	pbx_str_t * cfwds_all = pbx_str_alloca(DEFAULT_PBX_STR_BUFFERSIZE);
272 	pbx_str_t * cfwds_busy = pbx_str_alloca(DEFAULT_PBX_STR_BUFFERSIZE);
273 	pbx_str_t * cfwds_noanswer = pbx_str_alloca(DEFAULT_PBX_STR_BUFFERSIZE);
274 	int cfwd_all = 0;
275 	int cfwd_busy = 0;
276 	int cfwd_noanswer = 0;
277 	SCCP_LIST_TRAVERSE(&l->devices, ld, list) {
278 		AUTO_RELEASE(sccp_channel_t, active_channel, sccp_device_getActiveChannel(ld->device));
279 
280 		// skip incoming call on a shared line from the originator. (sharedline calling same sharedline)
281 		if (active_channel && active_channel != c && sccp_strequals(iPbx.getChannelLinkedId(active_channel), iPbx.getChannelLinkedId(c))) {
282 			sccp_log((DEBUGCAT_PBX))(VERBOSE_PREFIX_3 "SCCP: (sccp_pbx_call) skip ringing on %s\n", ld->device->id);
283 			c->subscribers--;
284 			continue;
285 		}
286 
287 		/* do we have cfwd enabled? */
288 		if(ld->cfwd[SCCP_CFWD_ALL].enabled) {
289 			ast_str_append(&cfwds_all, DEFAULT_PBX_STR_BUFFERSIZE, "%s%s", cfwd_all++ ? "," : "", ld->cfwd[SCCP_CFWD_ALL].number);
290 		}
291 		if(ld->cfwd[SCCP_CFWD_BUSY].enabled) {
292 			ast_str_append(&cfwds_busy, DEFAULT_PBX_STR_BUFFERSIZE, "%s%s", cfwd_busy++ ? "," : "", ld->cfwd[SCCP_CFWD_BUSY].number);
293 		}
294 		if(!bypassCallForward
295 		   && (ld->cfwd[SCCP_CFWD_ALL].enabled || (ld->cfwd[SCCP_CFWD_BUSY].enabled && (sccp_device_getDeviceState(ld->device) != SCCP_DEVICESTATE_ONHOOK || sccp_device_getActiveAccessory(ld->device))))) {
296 			if (num_devices == 1) {
297 				/* when single line -> use asterisk functionality directly, without creating new channel + masquerade */
298 				sccp_log((DEBUGCAT_CORE))(VERBOSE_PREFIX_3 "%s: Call Forward active on line %s\n", ld->device->id, ld->line->name);
299 				ForwardingLineDevice = ld;
300 			} else {
301 				/* shared line -> create a temp channel to call forward destination and tie them together */
302 				pbx_log(LOG_NOTICE, "%s: handle cfwd to %s for line %s\n", ld->device->id, ld->cfwd[SCCP_CFWD_ALL].enabled ? ld->cfwd[SCCP_CFWD_ALL].number : ld->cfwd[SCCP_CFWD_BUSY].number, l->name);
303 				if(sccp_channel_forward(c, ld, ld->cfwd[SCCP_CFWD_ALL].enabled ? ld->cfwd[SCCP_CFWD_ALL].number : ld->cfwd[SCCP_CFWD_BUSY].number) == 0) {
304 					sccp_device_sendcallstate(ld->device, ld->lineInstance, c->callid, SKINNY_CALLSTATE_INTERCOMONEWAY, SKINNY_CALLPRIORITY_NORMAL, SKINNY_CALLINFO_VISIBILITY_DEFAULT);
305 					sccp_channel_send_callinfo(ld->device, c);
306 					isRinging = TRUE;
307 				}
308 			};
309 			c->subscribers--;
310 			continue;
311 		}
312 
313 		if(ld->cfwd[SCCP_CFWD_NOANSWER].enabled && c) {
314 			sccp_channel_schedule_cfwd_noanswer(c, GLOB(cfwdnoanswer_timeout));
315 			ast_str_append(&cfwds_noanswer, DEFAULT_PBX_STR_BUFFERSIZE, "%s%s", cfwd_noanswer++ ? "," : "", ld->cfwd[SCCP_CFWD_NOANSWER].number);
316 		}
317 
318 		if(!ld->device->session) {
319 			sccp_log((DEBUGCAT_CORE))(VERBOSE_PREFIX_3 "%s: line device has no session\n", DEV_ID_LOG(ld->device));
320 			c->subscribers--;
321 			continue;
322 		}
323 		/* check if c->subscriptionId.number is matching deviceSubscriptionID */
324 		/* This means that we call only those devices on a shared line
325 		   which match the specified subscription id in the dial parameters. */
326 		if(!sccp_util_matchSubscriptionId(c, ld->subscriptionId.number)) {
327 			sccp_log((DEBUGCAT_PBX))(VERBOSE_PREFIX_3 "%s: device does not match subscriptionId.number c->subscriptionId.number: '%s', deviceSubscriptionID: '%s'\n", DEV_ID_LOG(ld->device),
328 						 c->subscriptionId.number, ld->subscriptionId.number);
329 			c->subscribers--;
330 			continue;
331 		}
332 		/* reset channel state (because we are offering the same call to multiple (shared) lines)*/
333 		c->previousChannelState = previousstate;
334 
335 		int calls = sccp_getCallCount(ld);
336 		sccp_log((DEBUGCAT_PBX))(VERBOSE_PREFIX_3 "%s: #calls:%d, Incoming calls limit:%d\n", l->name, calls, l->incominglimit);
337 		if(l->incominglimit && calls > l->incominglimit) {
338 			sccp_log((DEBUGCAT_CORE))(VERBOSE_PREFIX_3 "%s: #calls:%d > Incoming calls limit:%d -> returning BUSY\n", l->name, calls, l->incominglimit);
339 			isBusy = TRUE;
340 			c->subscribers--;
341 			continue;
342 		}
343 
344 		if (active_channel) {
345 			sccp_indicate(ld->device, c, SCCP_CHANNELSTATE_CALLWAITING);
346 			/* display the new call on prompt */
347 			AUTO_RELEASE(sccp_linedevice_t, activeChannelLinedevice, active_channel->getLineDevice(active_channel));
348 			if (activeChannelLinedevice) {
349 				char caller[100] = {0};
350 				if(!sccp_strlen_zero(cid_name)) {
351 					if(!sccp_strlen_zero(cid_num)) {
352 						snprintf(caller,sizeof(caller), "%s %s <%s>", SKINNY_DISP_CALL_WAITING, cid_name, cid_num);
353 					} else {
354 						snprintf(caller,sizeof(caller), "%s %s", SKINNY_DISP_CALL_WAITING, cid_name);
355 					}
356 				} else {
357 					if (!sccp_strlen_zero(cid_num)) {
358 						snprintf(caller,sizeof(caller), "%s %s", SKINNY_DISP_CALL_WAITING, cid_num);
359 					} else {
360 						snprintf(caller,sizeof(caller), "%s %s", SKINNY_DISP_CALL_WAITING, SKINNY_DISP_UNKNOWN_NUMBER);
361 					}
362 				}
363 				// snprintf(prompt, sizeof(prompt), "%s: %s: %s", active_channel->line->name, SKINNY_DISP_FROM, cid_num);
364 				// sccp_dev_displayprompt(ld->device, activeChannelLinedevice->lineInstance, active_channel->callid, caller, SCCP_DISPLAYSTATUS_TIMEOUT);
365 				sccp_dev_set_message(ld->device, caller, SCCP_DISPLAYSTATUS_TIMEOUT, FALSE, FALSE);
366 			}
367 			ForwardingLineDevice = NULL;	/* reset cfwd if shared */
368 			isRinging = TRUE;
369 		} else {
370 			/** check if ringermode is not urgent and device enabled dnd in reject mode */
371 			if(SKINNY_RINGTYPE_URGENT != c->ringermode && ld->device->dndFeature.enabled && ld->device->dndFeature.status == SCCP_DNDMODE_REJECT) {
372 				sccp_log((DEBUGCAT_CORE))(VERBOSE_PREFIX_3 "%s: DND active on line %s, returning Busy\n", ld->device->id, ld->line->name);
373 				isBusy = TRUE;
374 				c->subscribers--;
375 				continue;
376 			}
377 			ForwardingLineDevice = NULL;	/* reset cfwd if shared */
378 			sccp_log(DEBUGCAT_PBX)(VERBOSE_PREFIX_3 "%s: Ringing %sLine: %s on device:%s using channel:%s, ringermode:%s\n", ld->device->id, SCCP_LIST_GETSIZE(&l->devices) > 1 ? "Shared" : "", ld->line->name,
379 					       ld->device->id, c->designator, skinny_ringtype2str(c->ringermode));
380 			sccp_indicate(ld->device, c, SCCP_CHANNELSTATE_RINGING);
381 			isRinging = TRUE;
382 			if (c->autoanswer_type) {
383 				struct sccp_answer_conveyor_struct *conveyor = (struct sccp_answer_conveyor_struct *)sccp_calloc(1, sizeof(struct sccp_answer_conveyor_struct));
384 				if (conveyor) {
385 					sccp_log((DEBUGCAT_CORE))(VERBOSE_PREFIX_3 "%s: Running the autoanswer thread on %s\n", DEV_ID_LOG(ld->device), iPbx.getChannelName(c));
386 					conveyor->callid = c->callid;
387 					conveyor->ld = sccp_linedevice_retain(ld);
388 
389 					sccp_threadpool_add_work(GLOB(general_threadpool), sccp_pbx_call_autoanswer_thread, (void *) conveyor);
390 				} else {
391 					pbx_log(LOG_ERROR, SS_Memory_Allocation_Error, c->designator);
392 				}
393 			}
394 		}
395 	}
396 	SCCP_LIST_UNLOCK(&l->devices);
397 
398 	// sccp_log(DEBUGCAT_PBX)(VERBOSE_PREFIX_3 "%s: isRinging:%d, hadDNDParticipant:%d, ForwardingLineDevice:%p\n", c->designator, isRinging, isBusy, ForwardingLineDevice);
399 	if(cfwd_all) {
400 		pbx_builtin_setvar_helper(c->owner, "_CFWD_ALL", pbx_str_buffer(cfwds_all));
401 	}
402 	if(cfwd_busy) {
403 		pbx_builtin_setvar_helper(c->owner, "_CFWD_BUSY", pbx_str_buffer(cfwds_busy));
404 	}
405 	if(cfwd_noanswer) {
406 		pbx_builtin_setvar_helper(c->owner, "_CFWD_NOANSWER", pbx_str_buffer(cfwds_noanswer));
407 	}
408 	if (isRinging) {
409 		sccp_channel_setChannelstate(c, SCCP_CHANNELSTATE_RINGING);
410 		iPbx.set_callstate(c, AST_STATE_RINGING);
411 		iPbx.queue_control(c->owner, AST_CONTROL_RINGING);
412 	} else if (ForwardingLineDevice) {
413 		/* when single line -> use asterisk functionality directly, without creating new channel + masquerade */
414 		pbx_log(LOG_NOTICE, "%s: handle cfwd to %s for line %s\n", ForwardingLineDevice->device->id,
415 			ForwardingLineDevice->cfwd[SCCP_CFWD_ALL].enabled ? ForwardingLineDevice->cfwd[SCCP_CFWD_ALL].number : ForwardingLineDevice->cfwd[SCCP_CFWD_BUSY].number, l->name);
416 #if CS_AST_CONTROL_REDIRECTING
417 		iPbx.queue_control(c->owner, AST_CONTROL_REDIRECTING);
418 #endif
419 		pbx_channel_call_forward_set(c->owner, ForwardingLineDevice->cfwd[SCCP_CFWD_ALL].enabled ? ForwardingLineDevice->cfwd[SCCP_CFWD_ALL].number : ForwardingLineDevice->cfwd[SCCP_CFWD_BUSY].number);
420 		sccp_device_sendcallstate(ForwardingLineDevice->device, ForwardingLineDevice->lineInstance, c->callid, SKINNY_CALLSTATE_INTERCOMONEWAY, SKINNY_CALLPRIORITY_NORMAL, SKINNY_CALLINFO_VISIBILITY_DEFAULT);
421 		sccp_channel_send_callinfo(ForwardingLineDevice->device, c);
422 	} else if(isBusy) {
423 		iPbx.queue_control(c->owner, AST_CONTROL_BUSY);
424 		// iPbx.set_callstate(c, AST_STATE_BUSY);
425 		// pbx_channel_set_hangupcause(c->owner, AST_CAUSE_USER_BUSY);
426 		pbx_channel_set_hangupcause(c->owner, AST_CAUSE_BUSY);
427 		res = 0;
428 	} else {
429 		iPbx.queue_control(c->owner, AST_CONTROL_CONGESTION);
430 		res = -1;
431 	}
432 
433 	/* set linevariables */
434 	PBX_VARIABLE_TYPE *v = l->variables;
435 	while (c->owner && !pbx_check_hangup(c->owner) && l && v) {
436 		pbx_builtin_setvar_helper(c->owner, v->name, v->value);
437 		v = v->next;
438 	}
439 
440 	sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: (sccp_pbx_call) Returning: %d\n", c->designator, res);
441 	return res;
442 }
443 
444 /*!
445  * callback function to handle callforward when recipient does not answer within GLOB(cfwdnoanswer_timeout)
446  *
447  * this callback is scheduled in sccp_pbx_call / sccp_channel_schedule_cfwd_noanswer
448  */
sccp_pbx_cfwdnoanswer_cb(const void * data)449 int sccp_pbx_cfwdnoanswer_cb(const void * data)
450 {
451 	AUTO_RELEASE(sccp_channel_t, c, (channelPtr)data);			// explicitly taken in sccp_channel_schedule_cfwd_noanswer, releasing on exit
452 	if(!c || !c->owner) {
453 		pbx_log(LOG_WARNING, "SCCP: No channel provided.\n");
454 		return -1;
455 	}
456 
457 	if((ATOMIC_FETCH(&c->scheduler.deny, &c->scheduler.lock) == 0)) {
458 		c->scheduler.cfwd_noanswer_id = -3; /* prevent further cfwd_noanswer_id scheduling */
459 	}
460 
461 	AUTO_RELEASE(sccp_line_t, l, sccp_line_retain(c->line));
462 	if(!l) {
463 		pbx_log(LOG_WARNING, "%s: The channel has no line. giving up.\n", c->designator);
464 		return -2;
465 	}
466 
467 	if (sccp_channel_isAnswering(c)) {
468 		sccp_log(DEBUGCAT_CHANNEL)(VERBOSE_PREFIX_2 "%s: The channel is already being answered. canceling forward\n", c->designator);
469 		return -3;
470 	}
471 
472 	pbx_channel_lock(c->owner);
473 	PBX_CHANNEL_TYPE * forwarder = pbx_channel_ref(c->owner);
474 	pbx_channel_unlock(c->owner);
475 
476 	if(!forwarder || c->isHangingUp || pbx_check_hangup_locked(forwarder)) {
477 		pbx_log(LOG_WARNING, "%s: The channel was already hungup. giving up.\n", c->designator);
478 		pbx_channel_unref(forwarder);
479 		return -4;
480 	}
481 
482 	boolean_t bypassCallForward = !sccp_strlen_zero(pbx_builtin_getvar_helper(forwarder, "BYPASS_CFWD"));
483 
484 	sccp_linedevice_t * ld = NULL;
485 	SCCP_LIST_LOCK(&l->devices);
486 	int num_devices = SCCP_LIST_GETSIZE(&l->devices);
487 	SCCP_LIST_TRAVERSE(&l->devices, ld, list) {
488 		/* do we have cfwd enabled? */
489 		if(ld->cfwd[SCCP_CFWD_NOANSWER].enabled && !sccp_strlen_zero(ld->cfwd[SCCP_CFWD_NOANSWER].number) && !bypassCallForward) {
490 			if(num_devices == 1) {
491 				/* when single line -> use asterisk functionality directly, without creating new channel + masquerade */
492 				sccp_log(DEBUGCAT_PBX)("%s: Redirecting call to callforward noanswer:%s\n", c->designator, ld->cfwd[SCCP_CFWD_NOANSWER].number);
493 #if CS_AST_CONTROL_REDIRECTING
494 				iPbx.queue_control(forwarder, AST_CONTROL_REDIRECTING);
495 #endif
496 				pbx_channel_call_forward_set(forwarder, ld->cfwd[SCCP_CFWD_NOANSWER].number);
497 				sccp_device_sendcallstate(ld->device, ld->lineInstance, c->callid, SKINNY_CALLSTATE_INTERCOMONEWAY, SKINNY_CALLPRIORITY_NORMAL, SKINNY_CALLINFO_VISIBILITY_DEFAULT);
498 				sccp_channel_send_callinfo(ld->device, c);
499 				iPbx.set_owner(c, NULL);
500 				break;                                        //! \todo currently using only the first match.
501 			} else {
502 				/* shared line -> create a temp channel to call forward destination and tie them together */
503 				pbx_log(LOG_NOTICE, "%s: handle cfwd to %s for line %s\n", ld->device->id, ld->cfwd[SCCP_CFWD_NOANSWER].number, l->name);
504 				sccp_channel_forward(c, ld, ld->cfwd[SCCP_CFWD_NOANSWER].number);
505 			}
506 		}
507 	}
508 	SCCP_LIST_UNLOCK(&l->devices);
509 	pbx_channel_unref(forwarder);
510 	return 0;
511 }
512 
513 /*!
514  * \brief Handle Hangup Request by Asterisk
515  * \param channel SCCP Channel
516  * \return Success as int
517  *
518  * \callgraph
519  * \callergraph
520  *
521  * \called_from_asterisk via sccp_wrapper_asterisk.._hangup
522  *
523  * \note sccp_channel should be retained in calling function
524  */
525 
sccp_pbx_hangup(constChannelPtr channel)526 channelPtr sccp_pbx_hangup(constChannelPtr channel)
527 {
528 
529 	/* here the ast channel is locked */
530 	// sccp_log((DEBUGCAT_CORE)) (;VERBOSE_PREFIX_3 "SCCP: Asterisk request to hangup channel %s\n", iPbx.getChannelName(c));
531 	(void) ATOMIC_DECR(&GLOB(usecnt), 1, &GLOB(usecnt_lock));
532 
533 	pbx_update_use_count();
534 
535 	AUTO_RELEASE(sccp_channel_t, c , sccp_channel_retain(channel));
536 	if (!c) {
537 		sccp_log_and((DEBUGCAT_PBX + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: Asked to hangup channel. SCCP channel already deleted\n");
538 		return NULL;
539 	}
540 	c->isHangingUp = TRUE;
541 	sccp_log_and((DEBUGCAT_PBX + DEBUGCAT_CHANNEL))(VERBOSE_PREFIX_3 "%s: Asked to hangup channel.\n", c->designator);
542 
543 	AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(c));
544 	if(d && d->session) {
545 		sccp_session_waitForPendingRequests(d->session);
546 		/*		if (
547 					GLOB(remotehangup_tone) &&
548 					SKINNY_DEVICE_RS_OK == sccp_device_getRegistrationState(d) &&
549 					SCCP_DEVICESTATE_OFFHOOK == sccp_device_getDeviceState(d) &&
550 					SCCP_CHANNELSTATE_IsConnected(c->state) &&
551 					c == d->active_channel
552 				) {
553 					c->setTone(c, GLOB(remotehangup_tone), SKINNY_TONEDIRECTION_USER);
554 				}*/
555 	}
556 
557 	AUTO_RELEASE(sccp_line_t, l , sccp_line_retain(c->line));
558 
559 #ifdef CS_SCCP_CONFERENCE
560 	if (c && c->conference) {
561 		sccp_conference_release(&c->conference);								/* explicit release required here */
562 	}
563 	if (d && d->conference) {
564 		sccp_conference_release(&d->conference);								/* explicit release required here */
565 	}
566 #endif														// CS_SCCP_CONFERENCE
567 	if (c->rtp.audio.instance || c->rtp.video.instance) {
568 		sccp_channel_closeAllMediaTransmitAndReceive(c);
569 	}
570 
571 	// removing scheduled dialing
572 	sccp_channel_stop_schedule_digittimout(c);
573 	sccp_channel_stop_schedule_cfwd_noanswer(c);
574 
575 	sccp_log((DEBUGCAT_PBX + DEBUGCAT_CHANNEL))(VERBOSE_PREFIX_3 "%s: Current pbxchannelstate %s(%d)\n", c->designator, sccp_channelstate2str(c->state), c->state);
576 
577 	/* end callforwards */
578 	sccp_channel_end_forwarding_channel(c);
579 
580 	/* cancel transfer if in progress */
581 	if(d) {
582 		sccp_channel_transfer_cancel(d, c);
583 	}
584 
585 	if (l) {
586 		/* remove call from transferee, transferer */
587 		sccp_linedevice_t * ld = NULL;
588 		SCCP_LIST_LOCK(&l->devices);
589 		SCCP_LIST_TRAVERSE(&l->devices, ld, list) {
590 			AUTO_RELEASE(sccp_device_t, tmpDevice, sccp_device_retain(ld->device));
591 			if(!d && tmpDevice && SKINNY_DEVICE_RS_OK == sccp_device_getRegistrationState(tmpDevice)) {
592 				d = sccp_device_retain(tmpDevice);
593 			}
594 			if (tmpDevice) {
595 				sccp_channel_transfer_release(tmpDevice, c); /* explicit release required here */
596 			}
597 		}
598 		SCCP_LIST_UNLOCK(&l->devices);
599 		sccp_line_removeChannel(l, c);
600 	}
601 
602 	if (d) {
603 		if (d->monitorFeature.status & SCCP_FEATURE_MONITOR_STATE_ACTIVE) {
604 			d->monitorFeature.status &= ~SCCP_FEATURE_MONITOR_STATE_ACTIVE;
605 			sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_3 "%s: Reset monitor state after hangup\n", DEV_ID_LOG(d));
606 			sccp_feat_changed(d, NULL, SCCP_FEATURE_MONITOR);
607 		}
608 
609 		if (SCCP_CHANNELSTATE_DOWN != c->state && SCCP_CHANNELSTATE_ONHOOK != c->state) {
610 			sccp_indicate(d, c, SCCP_CHANNELSTATE_ONHOOK);
611 		}
612 
613 		/* requesting statistics */
614 		sccp_channel_StatisticsRequest(c);
615 		sccp_channel_clean(c);
616 		return c;								/* returning unretained so that sccp_wrapper_asterisk113_hangup can clear out the last reference */
617 	}
618 	return NULL;
619 }
620 
621 /*!
622  * \brief Asterisk Channel as been answered by remote
623  * \note we have no bridged channel at this point
624  *
625  * \param channel SCCCP channel
626  * \return Success as int
627  *
628  * \callgraph
629  * \callergraph
630  *
631  * \called_from_asterisk
632  *
633  * \todo masquarade does not succeed when forwarding to a dialplan extension which starts with PLAYBACK (Is this still the case, i think this might have been resolved ?? - DdG -)
634  */
sccp_pbx_remote_answer(constChannelPtr channel)635 int sccp_pbx_remote_answer(constChannelPtr channel)
636 {
637 	int res = -1;
638 
639 	/* \todo perhaps we should lock channel here. */
640 	AUTO_RELEASE(sccp_channel_t, c , sccp_channel_retain(channel));
641 	if(!c || !c->owner) {
642 		return res;
643 	}
644 	sccp_log((DEBUGCAT_PBX))(VERBOSE_PREFIX_2 "%s: (%s) Remote end has answered the call.\n", c->designator, __func__);
645 
646 	sccp_channel_stop_schedule_cfwd_noanswer(c);
647 
648 	// sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_3 "%s: sccp_pbx_answer checking parent channel\n", c->currentDeviceId);
649 	if (c->parentChannel) {										// containing a retained channel, final release at the end
650 		/* we are a forwarded call, bridge me with my parent (the forwarded channel will take the place of the forwarder.) */
651 		sccp_log((DEBUGCAT_PBX))(VERBOSE_PREFIX_3 "%s: (%s) handling forwarded call\n", c->designator, __func__);
652 
653 		pbx_channel_lock(c->parentChannel->owner);
654 		PBX_CHANNEL_TYPE * forwarder = pbx_channel_ref(c->parentChannel->owner);
655 		pbx_channel_unlock(c->parentChannel->owner);
656 
657 		pbx_channel_lock(c->owner);
658 		PBX_CHANNEL_TYPE * tmp_channel = pbx_channel_ref(c->owner);
659 		pbx_channel_unlock(c->owner);
660 
661 		const char * destinationChannelName = pbx_builtin_getvar_helper(tmp_channel, CS_BRIDGEPEERNAME);
662 
663 		PBX_CHANNEL_TYPE * destination = NULL;
664 		if(sccp_strlen_zero(destinationChannelName) || !iPbx.getChannelByName(destinationChannelName, &destination)) {
665 			pbx_log(LOG_NOTICE, "%s: (%s) Could not retrieve channel for destination: %s", c->designator, __func__, destinationChannelName);
666 			return -2;
667 		}
668 		/*
669 		if (iPbx.getChannelAppl(c)) {
670 			sccp_log_and((DEBUGCAT_PBX + DEBUGCAT_HIGH)) (VERBOSE_PREFIX_3 "%s: (sccp_pbx_answer) %s bridging to dialplan application %s\n", c->currentDeviceId, iPbx.getChannelName(c), iPbx.getChannelAppl(c));
671 		}
672 		*/
673 		sccp_log(DEBUGCAT_PBX)(VERBOSE_PREFIX_3 "\n"
674 							"\tendpoint1           | bridge             | endpoint2          | comment\n"
675 							"\t=================== | ================== | ================== | =================\n"
676 							"\t%-20.20s| primary_call       |%20.20s| creates tmp_channel in sccp_pbx_call to call forwarding destination\n"
677 							"\t%-20.20s| temp_bridge        |%20.20s| masquerade on answer of endpoint 2\n"
678 							"\t------------------- | ------------------ | ------------------ | <-- masquerade temp_bridge:endpoint2 -> primary_call:endpoint2\n"
679 							"\t%-20.20s| primary call       |%20.20s| after masquerading, hangup temp_bridge:temp_channel\n",
680 				       "incoming", pbx_channel_name(forwarder), pbx_channel_name(tmp_channel), destinationChannelName, "incoming", destinationChannelName);
681 		do {
682 			// retrieve channel by name which will replace in the forwarded channel
683 			sccp_channel_release(&c->parentChannel);
684 			if(destination) {
685 				sccp_log((DEBUGCAT_PBX))(VERBOSE_PREFIX_3 "%s: (%s) handling forwarded call. Replace %s with %s.\n", c->designator, __func__, pbx_channel_name(forwarder), pbx_channel_name(destination));
686 #if ASTERISK_VERSION_GROUP < 116
687 				/* set the channel and the bridge to state UP to fix problem with fast pickup / autoanswer */
688 				pbx_setstate(tmp_channel, AST_STATE_UP);
689 				pbx_setstate(destination, AST_STATE_UP);
690 #endif
691 				if(!iPbx.masqueradeHelper(destination, forwarder)) {
692 					pbx_log(LOG_ERROR, "%s: (%s) Failed to masquerade bridge into forwarded channel\n", c->designator, __func__);
693 					if(destination) {
694 						pbx_channel_unref(destination);
695 					}
696 					res = -3;
697 					break;
698 				}
699 #if ASTERISK_VERSION_GROUP > 106
700 				// Note: destination has taken the place of forwarder
701 				pbx_indicate(forwarder, AST_CONTROL_CONNECTED_LINE);
702 #endif
703 				sccp_log((DEBUGCAT_PBX))(VERBOSE_PREFIX_4 "%s: (%s) Masqueraded into %s\n", c->designator, __func__, pbx_channel_name(forwarder));
704 				res = 0;
705 			} else {
706 				pbx_log(LOG_ERROR, "%s: (%s) Could not retrieve forwarding channel by name:%s: -> Hangup\n", c->designator, __func__, destinationChannelName);
707 				if(pbx_channel_state(tmp_channel) == AST_STATE_RING && pbx_channel_state(forwarder) == AST_STATE_DOWN && iPbx.getChannelPbx(c)) {
708 					sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_4 "SCCP: Receiver Hungup: (hasPBX: %s)\n", iPbx.getChannelPbx(c) ? "yes" : "no");
709 					pbx_channel_set_hangupcause(forwarder, AST_CAUSE_CALL_REJECTED);
710 				} else {
711 					pbx_log(LOG_ERROR, "%s: (%s) We did not find bridge channel for call forwarding call. Hangup\n", c->currentDeviceId, __func__);
712 					pbx_channel_set_hangupcause(forwarder, AST_CAUSE_REQUESTED_CHAN_UNAVAIL);
713 					sccp_channel_endcall(c);
714 				}
715 				pbx_channel_set_hangupcause(forwarder, AST_CAUSE_REQUESTED_CHAN_UNAVAIL);
716 				pbx_channel_unref(forwarder);
717 				if(destination) {
718 					pbx_channel_unref(destination);
719 				}
720 				res = -4;
721 			}
722 		} while(0);
723 		if(tmp_channel) {
724 			pbx_channel_unref(tmp_channel);
725 		}
726 	} else {
727 		sccp_log((DEBUGCAT_CORE))(VERBOSE_PREFIX_3 "%s: (%s) Outgoing call %s being answered by remote party\n", c->currentDeviceId, __func__, iPbx.getChannelName(c));
728 		AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(c));
729 		if (d) {
730 			const char * application = ast_channel_appl (c->owner);
731 			if (application && sccp_strequals (application, "ParkedCall")) {
732 				sccp_log ((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: !! retrieving parked call !!\n", c->designator);
733 				sccp_channel_setChannelstate (c, SCCP_CHANNELSTATE_CALLPARK);
734 				pbx_builtin_setvar_helper (c->owner, "_PARK_RETRIEVER", c->designator);
735 			}
736 #if CS_SCCP_CONFERENCE
737 			sccp_indicate(d, c, d->conference ? SCCP_CHANNELSTATE_CONNECTEDCONFERENCE : SCCP_CHANNELSTATE_CONNECTED);
738 #else
739 			sccp_indicate(d, c, SCCP_CHANNELSTATE_CONNECTED);
740 #endif
741 			/** check for monitor request */
742 			if((d->monitorFeature.status & SCCP_FEATURE_MONITOR_STATE_REQUESTED) && !(d->monitorFeature.status & SCCP_FEATURE_MONITOR_STATE_ACTIVE)) {
743 				pbx_log(LOG_NOTICE, "%s: (%s) request monitor/record\n", d->id, __func__);
744 				sccp_feat_monitor(d, NULL, 0, c);
745 			}
746 
747 			sccp_log(DEBUGCAT_PBX)(VERBOSE_PREFIX_3 "%s: (%s) Switching to STATE_UP\n", c->designator, __func__);
748 			iPbx.set_callstate(c, AST_STATE_UP);
749 			res = 0;
750 		}
751 
752 		if((sccp_rtp_getState(&c->rtp.video, SCCP_RTP_RECEPTION) & SCCP_RTP_STATUS_ACTIVE)) {
753 			iPbx.queue_control(c->owner, AST_CONTROL_VIDUPDATE);
754 		}
755 	}
756 	return res;
757 }
758 
759 /*!
760  * \brief Allocate an Asterisk Channel
761  * \param channel SCCP Channel
762  * \param ids Void Character Pointer (either Empty / LinkedId / Channel ID, depending on the asterisk version)
763  * \param parentChannel SCCP Channel for which the channel was created
764  * \return 1 on Success as uint8_t
765  *
766  * \callgraph
767  * \callergraph
768  *
769  * \lock
770  *  - usecnt_lock
771  */
sccp_pbx_channel_allocate(constChannelPtr channel,const void * ids,const PBX_CHANNEL_TYPE * parentChannel)772 boolean_t sccp_pbx_channel_allocate(constChannelPtr channel, const void * ids, const PBX_CHANNEL_TYPE * parentChannel)
773 {
774 	PBX_CHANNEL_TYPE * tmp = NULL;
775 	AUTO_RELEASE(sccp_channel_t, c , sccp_channel_retain(channel));
776 	AUTO_RELEASE(sccp_device_t, d , NULL);
777 
778 	if (!c) {
779 		return FALSE;
780 	}
781 	pbx_assert(c->owner == NULL);										// prevent calling this function when the channel already has a pbx channel
782 
783 #ifndef CS_AST_CHANNEL_HAS_CID
784 	char cidtmp[256];
785 
786 	memset(&cidtmp, 0, sizeof(cidtmp));
787 #endif														// CS_AST_CHANNEL_HAS_CID
788 
789 	AUTO_RELEASE(sccp_line_t, l , sccp_line_retain(c->line));
790 	if (!l) {
791 		sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "SCCP: (sccp_pbx_channel_allocate) Unable to find line for channel %s\n", c->designator);
792 		pbx_log(LOG_ERROR, "SCCP: Unable to allocate asterisk channel... returning 0\n");
793 		return FALSE;
794 	}
795 
796 	sccp_log((DEBUGCAT_PBX + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: (pbx_channel_allocate) try to allocate %s channel on line: %s\n", skinny_calltype2str(c->calltype), l->name);
797 	/* Don't hold a sccp pvt lock while we allocate a channel */
798 	char s1[512];
799 
800 	char s2[512];
801 
802 	char cid_name[StationMaxNameSize] = {0};
803 	char cid_num[StationMaxDirnumSize] = {0};
804 	{
805 		sccp_linedevice_t * ld = NULL;
806 		// if ((d = sccp_channel_getDevice(c))) {
807 		d = sccp_channel_getDevice(c) /*ref_replace*/;
808 		if(d) {
809 			SCCP_LIST_LOCK(&l->devices);
810 			SCCP_LIST_TRAVERSE(&l->devices, ld, list) {
811 				if(ld->device == d) {
812 					break;
813 				}
814 			}
815 			SCCP_LIST_UNLOCK(&l->devices);
816 		} else if(SCCP_LIST_GETSIZE(&l->devices) > 0) {
817 			SCCP_LIST_LOCK(&l->devices);
818 			ld = SCCP_LIST_FIRST(&l->devices);
819 			SCCP_LIST_UNLOCK(&l->devices);
820 			if(ld && ld->device) {
821 				d = sccp_device_retain(ld->device) /*ref_replace*/;                                        // ugly hack just picking the first one !
822 			}
823 		}
824 
825 		if(!ld) {
826 			pbx_log(LOG_NOTICE, "%s: Could not find an appropriate ld to assign this channel to. Line:%s exists, but was not assigned to any device (yet). We should give up here.\n", c->designator, l->name);
827 			goto error_exit;
828 		}
829 
830 		sccp_callinfo_t *ci = sccp_channel_getCallInfo(c);
831 		if(ld->subscriptionId.replaceCid) {
832 			snprintf(cid_num, StationMaxDirnumSize, "%s", sccp_strlen_zero(ld->subscriptionId.number) ? l->cid_num : ld->subscriptionId.number);
833 			snprintf(cid_name, StationMaxNameSize, "%s", sccp_strlen_zero(ld->subscriptionId.name) ? l->cid_name : ld->subscriptionId.name);
834 		} else {
835 			snprintf(cid_num, StationMaxDirnumSize, "%s%s", l->cid_num, sccp_strlen_zero(ld->subscriptionId.number) ? "" : ld->subscriptionId.number);
836 			snprintf(cid_name, StationMaxNameSize, "%s%s", l->cid_name, sccp_strlen_zero(ld->subscriptionId.name) ? "" : ld->subscriptionId.name);
837 		}
838 		switch (c->calltype) {
839 			case SKINNY_CALLTYPE_INBOUND:
840 				iCallInfo.Setter(ci, SCCP_CALLINFO_CALLEDPARTY_NAME, &cid_name, SCCP_CALLINFO_CALLEDPARTY_NUMBER, &cid_num, SCCP_CALLINFO_KEY_SENTINEL);
841 				break;
842 			case SKINNY_CALLTYPE_FORWARD:
843 				iCallInfo.Setter(ci,
844 					SCCP_CALLINFO_CALLINGPARTY_NAME, &cid_name,
845 					SCCP_CALLINFO_CALLINGPARTY_NUMBER, &cid_num,
846 					SCCP_CALLINFO_LAST_REDIRECTINGPARTY_NAME, &cid_name,
847 					SCCP_CALLINFO_LAST_REDIRECTINGPARTY_NUMBER, &cid_num,
848 					SCCP_CALLINFO_LAST_REDIRECT_REASON, 4,
849 					SCCP_CALLINFO_KEY_SENTINEL);
850 				break;
851 			case SKINNY_CALLTYPE_OUTBOUND:
852 				iCallInfo.Setter(ci,
853 					SCCP_CALLINFO_CALLINGPARTY_NAME, &cid_name,
854 					SCCP_CALLINFO_CALLINGPARTY_NUMBER, &cid_num,
855 					//SCCP_CALLINFO_ORIG_CALLINGPARTY_NAME, &cid_name,
856 					//SCCP_CALLINFO_ORIG_CALLINGPARTY_NUMBER, &cid_num,
857 					SCCP_CALLINFO_LAST_REDIRECTINGPARTY_NAME, &cid_name,
858 					SCCP_CALLINFO_LAST_REDIRECTINGPARTY_NUMBER, &cid_num,
859 					SCCP_CALLINFO_LAST_REDIRECT_REASON, 0,
860 					SCCP_CALLINFO_KEY_SENTINEL);
861 				break;
862 			case SKINNY_CALLTYPE_SENTINEL:
863 				break;
864 		}
865 
866 		// make sure preferences only contains the codecs that this channel is capable of
867 		if (SCCP_LIST_GETSIZE(&l->devices) == 1 && d) {				// singleline
868 			//sccp_line_copyCodecSetsFromLineToChannel(l, d, c);
869 			sccp_codec_reduceSet(c->preferences.audio, d->capabilities.audio);
870 			sccp_codec_reduceSet(c->preferences.video, d->capabilities.video);
871 		} else {
872 			//sccp_line_copyCodecSetsFromLineToChannel(l, NULL, c);		// sharedline
873 			sccp_codec_reduceSet(c->preferences.audio, c->capabilities.audio);
874 			sccp_codec_reduceSet(c->preferences.video, c->capabilities.video);
875 		}
876 
877 		if (c->preferences.audio[0] == SKINNY_CODEC_NONE || c->capabilities.audio[0] == SKINNY_CODEC_NONE) {
878 			pbx_log(LOG_ERROR, "%s: Expect trouble ahead.\n"
879 				"The audio preferences:%s of this channel have been reduced to nothing.\n"
880 				"Because they are not compatible with this %s capabilities:%s.\n"
881 				"Please fix your config. Ending Call !.\n",
882 				c->designator,
883 				sccp_codec_multiple2str(s1, sizeof(s1) - 1, c->preferences.audio, SKINNY_MAX_CAPABILITIES),
884 				l->preferences_set_on_line_level ? "line's" : "device's",
885 				sccp_codec_multiple2str(s2, sizeof(s2) - 1, c->capabilities.audio, SKINNY_MAX_CAPABILITIES));
886 			goto error_exit;
887 		}
888 	}
889 	sccp_log((DEBUGCAT_PBX + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP:             cid_num: %s\n", cid_num);
890 	sccp_log((DEBUGCAT_PBX + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP:            cid_name: %s\n", cid_name);
891 	sccp_log((DEBUGCAT_PBX + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP:         accountcode: %s\n", l->accountcode);
892 	sccp_log((DEBUGCAT_PBX + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP:               exten: %s\n", c->dialedNumber);
893 	sccp_log((DEBUGCAT_PBX + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP:             context: %s\n", l->context);
894 	sccp_log((DEBUGCAT_PBX + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP:            amaflags: %d\n", (int)l->amaflags);
895 	sccp_log((DEBUGCAT_PBX + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP:           chan/call: %s\n", c->designator);
896 	sccp_log((DEBUGCAT_PBX + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: combined audio caps: %s\n", sccp_codec_multiple2str(s1, sizeof(s1) - 1, c->capabilities.audio, SKINNY_MAX_CAPABILITIES));
897 	sccp_log((DEBUGCAT_PBX + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: reduced audio prefs: %s\n", sccp_codec_multiple2str(s1, sizeof(s1) - 1, c->preferences.audio, SKINNY_MAX_CAPABILITIES));
898 	sccp_log((DEBUGCAT_PBX + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: combined video caps: %s\n", sccp_codec_multiple2str(s1, sizeof(s1) - 1, c->capabilities.video, SKINNY_MAX_CAPABILITIES));
899 	sccp_log((DEBUGCAT_PBX + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP: reduced video prefs: %s\n", sccp_codec_multiple2str(s1, sizeof(s1) - 1, c->preferences.video, SKINNY_MAX_CAPABILITIES));
900 /*
901 	// this should not be done here at this moment, leaving it to alloc_pbxChannel to sort out.
902 	if (c->calltype == SKINNY_CALLTYPE_INBOUND) {
903 		if (c->remoteCapabilities.audio[0] != SKINNY_CODEC_NONE) {
904 			sccp_log((DEBUGCAT_PBX + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP:   remote audio prefs: \"%s\"\n", sccp_codec_multiple2str(s1, sizeof(s1) - 1, c->remoteCapabilities.audio, SKINNY_MAX_CAPABILITIES));
905 			skinny_codec_t ordered_audio_prefs[SKINNY_MAX_CAPABILITIES] = {SKINNY_CODEC_NONE};
906 			memcpy(&ordered_audio_prefs, c->remoteCapabilities.audio, sizeof(ordered_audio_prefs));
907 			sccp_codec_reduceSet(ordered_audio_prefs, c->preferences.audio);
908 			memcpy(&c->preferences.audio, ordered_audio_prefs, sizeof(c->preferences.audio));
909 			sccp_log((DEBUGCAT_PBX + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP:      set audio prefs: \"%s\"\n", sccp_codec_multiple2str(s2, sizeof(s2) - 1, c->preferences.audio, SKINNY_MAX_CAPABILITIES));
910 		}
911 
912 		if (c->remoteCapabilities.video[0] != SKINNY_CODEC_NONE && (d ? sccp_device_isVideoSupported(d) : TRUE)) {
913 			sccp_log((DEBUGCAT_PBX + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP:   remote video prefs: \"%s\"\n", sccp_codec_multiple2str(s1, sizeof(s1) - 1, c->remoteCapabilities.video, SKINNY_MAX_CAPABILITIES));
914 			skinny_codec_t ordered_video_prefs[SKINNY_MAX_CAPABILITIES] = {SKINNY_CODEC_NONE};
915 			memcpy(&ordered_video_prefs, c->remoteCapabilities.video, sizeof(ordered_video_prefs));
916 			sccp_codec_reduceSet(ordered_video_prefs, c->preferences.video);
917 			memcpy(&c->preferences.video, ordered_video_prefs, sizeof(c->preferences.video));
918 			sccp_log((DEBUGCAT_PBX + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "SCCP:      set video prefs: \"%s\"\n", sccp_codec_multiple2str(s2, sizeof(s2) - 1, c->preferences.video, SKINNY_MAX_CAPABILITIES));
919 		}
920 	}
921 */
922 	if (!c->pbx_callid && c->calltype != SKINNY_CALLTYPE_INBOUND) {
923 		c->pbx_callid = pbx_create_callid();
924 	}
925 	/* This should definitely fix CDR */
926 	iPbx.alloc_pbxChannel(c, ids, parentChannel, &tmp);
927 
928 	if (!tmp || !c->owner) {
929 		pbx_log(LOG_ERROR, "%s: Unable to allocate asterisk channel on line %s\n", c->designator, l->name);
930 		goto error_exit;
931 	}
932 	iPbx.setChannelName(c, c->designator);
933 
934 	// \todo: Bridge?
935 	// \todo: Transfer?
936 
937 	(void) ATOMIC_INCR(&GLOB(usecnt), 1, &GLOB(usecnt_lock));
938 
939 	pbx_update_use_count();
940 
941 	if (iPbx.set_callerid_number) {
942 		iPbx.set_callerid_number(c->owner, cid_num);
943 	}
944 	if (iPbx.set_callerid_ani) {
945 		iPbx.set_callerid_ani(c->owner, cid_num);
946 	}
947 	if (iPbx.set_callerid_name) {
948 		iPbx.set_callerid_name(c->owner, cid_name);
949 	}
950 
951 	/* call ast_channel_call_forward_set with the forward destination if this device is forwarded */
952 	if (SCCP_LIST_GETSIZE(&l->devices) == 1) {
953 		sccp_linedevice_t * ld = NULL;
954 
955 		SCCP_LIST_LOCK(&l->devices);
956 		SCCP_LIST_TRAVERSE(&l->devices, ld, list) {
957 			if(ld->line == l) {
958 				if(ld->cfwd[SCCP_CFWD_ALL].enabled) {
959 					sccp_log((DEBUGCAT_PBX))(VERBOSE_PREFIX_3 "%s: ast call forward channel_set: %s\n", c->designator, ld->cfwd[SCCP_CFWD_ALL].number);
960 					iPbx.setChannelCallForward(c, ld->cfwd[SCCP_CFWD_ALL].number);
961 				} else if(ld->cfwd[SCCP_CFWD_BUSY].enabled && (sccp_device_getDeviceState(ld->device) != SCCP_DEVICESTATE_ONHOOK || sccp_device_getActiveAccessory(ld->device))) {
962 					sccp_log((DEBUGCAT_PBX))(VERBOSE_PREFIX_3 "%s: ast call forward channel_set: %s\n", c->designator, ld->cfwd[SCCP_CFWD_BUSY].number);
963 					iPbx.setChannelCallForward(c, ld->cfwd[SCCP_CFWD_BUSY].number);
964 				}
965 				break;
966 			}
967 		}
968 		SCCP_LIST_UNLOCK(&l->devices);
969 	}
970 
971 #if CS_SCCP_VIDEO
972 	const char *VideoStr = pbx_builtin_getvar_helper(c->owner, "SCCP_VIDEO_MODE");
973 	if (VideoStr && !sccp_strlen_zero(VideoStr)) {
974 		sccp_channel_setVideoMode(c, VideoStr);
975 	}
976 #endif
977 	/* asterisk needs the native formats bevore dialout, otherwise the next channel gets the whole AUDIO_MASK as requested format
978 	 * chan_sip dont like this do sdp processing */
979 	//iPbx.set_nativeAudioFormats(c, c->preferences.audio, ARRAY_LEN(c->preferences.audio));
980 
981 	/* start audio rtp server early, to facilitate choosing codecs via sdp */
982 	if (d) {
983 		if (c->calltype == SKINNY_CALLTYPE_OUTBOUND) {
984 			if (!c->rtp.audio.instance && !sccp_rtp_createServer(d, c, SCCP_RTP_AUDIO)) {
985 				pbx_log(LOG_WARNING, "%s: Error opening RTP instance for channel %s\n", d->id, c->designator);
986 				goto error_exit;
987 			}
988 			/*
989 			#if CS_SCCP_VIDEO
990 						if (sccp_channel_getVideoMode(c) != SCCP_VIDEO_MODE_OFF && sccp_device_isVideoSupported(d) && c->preferences.video[0] != SKINNY_CODEC_NONE && !c->rtp.video.instance &&
991 			!sccp_rtp_createServer(d, c, SCCP_RTP_VIDEO)) { pbx_log(LOG_WARNING, "%s: Error opening VRTP instance for channel %s\n", d->id, c->designator); sccp_channel_setVideoMode(c, "off");
992 						}
993 			#endif
994 			*/
995 		}
996 		// export sccp informations in asterisk dialplan
997 		pbx_builtin_setvar_helper(tmp, "SCCP_DEVICE_MAC", d->id);
998 		struct sockaddr_storage sas = { 0 };
999 		sccp_session_getSas(d->session, &sas);
1000 		pbx_builtin_setvar_helper(tmp, "SCCP_DEVICE_IP", d->session ? sccp_netsock_stringify_addr(&sas) : "");
1001 		pbx_builtin_setvar_helper(tmp, "SCCP_DEVICE_TYPE", skinny_devicetype2str(d->skinny_type));
1002 	}
1003 	sccp_log((DEBUGCAT_PBX + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "%s: Allocated asterisk channel %s\n", (l) ? l->id : "(null)", c->designator);
1004 
1005 	return TRUE;
1006 
1007 error_exit:
1008 	if(c) {
1009 		pbx_log(LOG_WARNING, "%s: (pbx_channel_allocate) Unable to allocate a new channel for line %s\n -> Hanging up call.", DEV_ID_LOG(d), l->name);
1010 		if(c->owner) {
1011 			if(d) {
1012 				sccp_indicate(d, c, SCCP_CHANNELSTATE_CONGESTION);
1013 			}
1014 			sccp_channel_endcall(c);
1015 		} else {
1016 			if(d) {
1017 				sccp_indicate(d, channel, SCCP_CHANNELSTATE_ONHOOK);
1018 			}
1019 			if(c->line) {
1020 				sccp_line_removeChannel(c->line, c);
1021 			}
1022 			sccp_channel_clean(c);
1023 			sccp_channel_release(&c);
1024 		}
1025 	}
1026 	return FALSE;
1027 }
1028 
1029 /*!
1030  * \brief Schedule Asterisk Dial
1031  * \param data Data as constant
1032  * \return Success as int
1033  *
1034  * \called_from_asterisk
1035  */
sccp_pbx_sched_dial(const void * data)1036 int sccp_pbx_sched_dial(const void * data)
1037 {
1038 	AUTO_RELEASE(sccp_channel_t, channel, sccp_channel_retain(data));
1039 
1040 	if(channel) {
1041 		if ((ATOMIC_FETCH(&channel->scheduler.deny, &channel->scheduler.lock) == 0) && channel->scheduler.hangup_id == -1) {
1042 			channel->scheduler.digittimeout_id = -3;	/* prevent further digittimeout scheduling */
1043 			if (channel->owner && !iPbx.getChannelPbx(channel) && !sccp_strlen_zero(channel->dialedNumber)) {
1044 				sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_1 "SCCP: Timeout for call '%s'. Going to dial '%s'\n", channel->designator, channel->dialedNumber);
1045 				sccp_pbx_softswitch(channel);
1046 			} else {
1047 				sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_1 "SCCP: Timeout for call '%s'. Nothing to dial -> INVALIDNUMBER\n", channel->designator);
1048 				channel->dialedNumber[0] = '\0';
1049 				sccp_indicate(NULL, channel, SCCP_CHANNELSTATE_INVALIDNUMBER);
1050 			}
1051 		}
1052 		sccp_channel_release((sccp_channel_t **)&data);	// release channel retained in scheduled event
1053 	}
1054 	return 0;						// return 0 to release schedule !
1055 }
1056 
1057 /*!
1058  * \brief Asterisk Helper
1059  * \param c SCCP Channel as sccp_channel_t
1060  * \return Success as int
1061  */
sccp_pbx_helper(constChannelPtr c)1062 sccp_extension_status_t sccp_pbx_helper(constChannelPtr c)
1063 {
1064 	sccp_extension_status_t extensionStatus = 0;
1065 	int dialedLen = sccp_strlen(c->dialedNumber);
1066 
1067 	if (dialedLen > 1) {
1068 		if (GLOB(recorddigittimeoutchar) && GLOB(digittimeoutchar) == c->dialedNumber[dialedLen - 1]) {
1069 			/* we finished dialing with digit timeout char */
1070 			sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_2 "%s: We finished dialing with digit timeout char %s\n", c->designator, c->dialedNumber);
1071 			return SCCP_EXTENSION_EXACTMATCH;
1072 		}
1073 	}
1074 
1075 	if ((c->softswitch_action != SCCP_SOFTSWITCH_GETCBARGEROOM) && (c->softswitch_action != SCCP_SOFTSWITCH_GETMEETMEROOM)
1076 #ifdef CS_SCCP_CONFERENCE
1077 	    && (c->softswitch_action != SCCP_SOFTSWITCH_GETCONFERENCEROOM)
1078 #endif
1079 	    ) {
1080 
1081 		//! \todo check overlap feature status -MC
1082 		extensionStatus = iPbx.extension_status(c);
1083 		AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(c));
1084 
1085 		if (d) {
1086 			if (((d->overlapFeature.enabled && !extensionStatus) || (!d->overlapFeature.enabled && !extensionStatus))) {
1087 				sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: %s Matches More\n", c->designator, c->dialedNumber);
1088 				return SCCP_EXTENSION_MATCHMORE;
1089 			}
1090 			sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: %s Matches %s\n", c->designator, c->dialedNumber, extensionStatus == SCCP_EXTENSION_EXACTMATCH ? "Exactly" : "More");
1091 		}
1092 		return extensionStatus;
1093 	}
1094 	sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_2 "%s: %s Does Exists\n", c->designator, c->dialedNumber);
1095 	return SCCP_EXTENSION_NOTEXISTS;
1096 }
1097 
1098 /*!
1099  * \brief Handle Soft Switch
1100  * \param channel SCCP Channel as sccp_channel_t
1101  * \todo clarify Soft Switch Function
1102  */
sccp_pbx_softswitch(constChannelPtr channel)1103 void * sccp_pbx_softswitch(constChannelPtr channel)
1104 {
1105 	PBX_CHANNEL_TYPE * pbx_channel = NULL;
1106 	PBX_VARIABLE_TYPE * v = NULL;
1107 
1108 	{
1109 		AUTO_RELEASE(sccp_channel_t, c , sccp_channel_retain(channel));
1110 
1111 		if (!c) {
1112 			pbx_log(LOG_ERROR, "SCCP: (sccp_pbx_softswitch) No <channel> available. Returning from dial thread.\n");
1113 			goto EXIT_FUNC;
1114 		}
1115 		sccp_channel_stop_schedule_digittimout(c);
1116 
1117 		/* Reset Enbloc Dial Emulation */
1118 		c->enbloc.deactivate = 0;
1119 		c->enbloc.totaldigittime = 0;
1120 		c->enbloc.totaldigittimesquared = 0;
1121 		c->enbloc.digittimeout = GLOB(digittimeout);
1122 
1123 		/* prevent softswitch from being executed twice (Pavel Troller / 15-Oct-2010) */
1124 		if (iPbx.getChannelPbx(c)) {
1125 			sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "SCCP: (sccp_pbx_softswitch) PBX structure already exists. Dialing instead of starting.\n");
1126 			/* If there are any digits, send them instead of starting the PBX */
1127 			if (!sccp_strlen_zero(c->dialedNumber)) {
1128 				if (iPbx.send_digits) {
1129 					iPbx.send_digits(channel, c->dialedNumber);
1130 				}
1131 				sccp_channel_set_calledparty(c, NULL, c->dialedNumber);
1132 			}
1133 			goto EXIT_FUNC;
1134 		}
1135 
1136 		if (!c->owner) {
1137 			pbx_log(LOG_ERROR, "SCCP: (sccp_pbx_softswitch) No PBX <channel> available. Returning from dial thread.\n");
1138 			goto EXIT_FUNC;
1139 		}
1140 		pbx_channel = pbx_channel_ref(c->owner);
1141 
1142 		/* we should just process outbound calls, let's check calltype */
1143 		if (c->calltype != SKINNY_CALLTYPE_OUTBOUND && c->softswitch_action == SCCP_SOFTSWITCH_DIAL) {
1144 			pbx_log(LOG_ERROR, "SCCP: (sccp_pbx_softswitch) This function is for outbound calls only. Exiting\n");
1145 			goto EXIT_FUNC;
1146 		}
1147 
1148 		/* assume d is the channel's device */
1149 		/* does it exists ? */
1150 		AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(c));
1151 
1152 		if (!d) {
1153 			pbx_log(LOG_ERROR, "SCCP: (sccp_pbx_softswitch) No <device> available. Returning from dial thread. Exiting\n");
1154 			goto EXIT_FUNC;
1155 		}
1156 
1157 		if (pbx_check_hangup(pbx_channel)) {
1158 			pbx_log(LOG_ERROR, "SCCP: (sccp_pbx_softswitch) Channel already hungup, no need to go any further. Exiting\n");
1159 			sccp_indicate(d, c, SCCP_CHANNELSTATE_ONHOOK);
1160 			goto EXIT_FUNC;
1161 		}
1162 
1163 		/* we don't need to check for a device type but just if the device has an id, otherwise back home  -FS */
1164 		if (sccp_strlen_zero(d->id)) {
1165 			pbx_log(LOG_ERROR, "SCCP: (sccp_pbx_softswitch) No <device> identifier available. Returning from dial thread. Exiting\n");
1166 			goto EXIT_FUNC;
1167 		}
1168 
1169 		AUTO_RELEASE(sccp_line_t, l , sccp_line_retain(c->line));
1170 
1171 		if (!l) {
1172 			pbx_log(LOG_ERROR, "SCCP: (sccp_pbx_softswitch) No <line> available. Returning from dial thread. Exiting\n");
1173 			c->hangupRequest(c);
1174 			goto EXIT_FUNC;
1175 		}
1176 		uint8_t instance = sccp_device_find_index_for_line(d, l->name);
1177 
1178 		sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: (sccp_pbx_softswitch) New call on line %s\n", DEV_ID_LOG(d), l->name);
1179 
1180 		/* assign callerid name and number */
1181 		//sccp_channel_set_callingparty(c, l->cid_name, l->cid_num);
1182 
1183 		// we use shortenedNumber but why ???
1184 		// If the timeout digit has been used to terminate the number
1185 		// and this digit shall be included in the phone call history etc (recorddigittimeoutchar is true)
1186 		// we still need to dial the number without the timeout char in the pbx
1187 		// so that we don't dial strange extensions with a trailing characters.
1188 		char shortenedNumber[256] = { '\0' };
1189 		sccp_copy_string(shortenedNumber, c->dialedNumber, sizeof(shortenedNumber));
1190 		unsigned int len = sccp_strlen(shortenedNumber);
1191 
1192 		pbx_assert(sccp_strlen(c->dialedNumber) == len);
1193 
1194 		if (len > 0 && GLOB(digittimeoutchar) == shortenedNumber[len - 1]) {
1195 			shortenedNumber[len - 1] = '\0';
1196 
1197 			// If we don't record the timeoutchar in the logs, we remove it from the sccp channel structure
1198 			// Later, the channel dialed number is used for directories, etc.,
1199 			// and the shortened number is used for dialing the actual call via asterisk pbx.
1200 			if (!GLOB(recorddigittimeoutchar)) {
1201 				c->dialedNumber[len - 1] = '\0';
1202 			}
1203 		}
1204 
1205 		/* This will choose what to do */
1206 		switch (c->softswitch_action) {
1207 			case SCCP_SOFTSWITCH_GETFORWARDEXTEN:
1208 				{
1209 				sccp_cfwd_t type = (sccp_cfwd_t)c->ss_data;
1210 				sccp_log((DEBUGCAT_PBX))(VERBOSE_PREFIX_3 "%s: (sccp_pbx_softswitch) Get Forward %s Extension\n", d->id, sccp_cfwd2str(type));
1211 				if(!sccp_strlen_zero(shortenedNumber)) {
1212 					c->setTone(c, SKINNY_TONE_ZIP, SKINNY_TONEDIRECTION_USER);
1213 					sccp_line_cfwd(l, d, type, shortenedNumber);
1214 				}
1215 					sccp_channel_endcall(c);
1216 					goto EXIT_FUNC;								// leave simple switch without dial
1217 				}
1218 			case SCCP_SOFTSWITCH_ENDCALLFORWARD:
1219 				{
1220 				sccp_cfwd_t type = (sccp_cfwd_t)c->ss_data;
1221 				sccp_log((DEBUGCAT_PBX))(VERBOSE_PREFIX_3 "%s: (sccp_pbx_softswitch) Clear Forward %s\n", d->id, sccp_cfwd2str(type));
1222 				sccp_line_cfwd(l, d, type, NULL);
1223 				switch(type) {
1224 					case SCCP_CFWD_ALL:
1225 						sccp_device_setLamp(d, SKINNY_STIMULUS_FORWARDALL, instance, SKINNY_LAMP_OFF);
1226 						break;
1227 					case SCCP_CFWD_BUSY:
1228 						sccp_device_setLamp(d, SKINNY_STIMULUS_FORWARDBUSY, instance, SKINNY_LAMP_OFF);
1229 						break;
1230 					case SCCP_CFWD_NOANSWER:
1231 						sccp_device_setLamp(d, SKINNY_STIMULUS_FORWARDNOANSWER, instance, SKINNY_LAMP_OFF);
1232 						break;
1233 					case SCCP_CFWD_NONE:
1234 					case SCCP_CFWD_SENTINEL:
1235 					default:
1236 						pbx_log(LOG_ERROR, "%s: (sccp_pbx_softswitch) EndCallForward unknown CFWD_TYPE\n", d->id);
1237 				}
1238 					sccp_channel_endcall(c);
1239 					goto EXIT_FUNC;								// leave simple switch without dial
1240 				}
1241 #ifdef CS_SCCP_PICKUP
1242 			case SCCP_SOFTSWITCH_GETPICKUPEXTEN:
1243 				sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_3 "%s: (sccp_pbx_softswitch) Get Pickup Extension\n", d->id);
1244 				sccp_dev_clearprompt(d, instance, c->callid);
1245 
1246 				if (!sccp_strlen_zero(shortenedNumber)) {
1247  					sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "SCCP: (sccp_pbx_softswitch) Asterisk request to pickup exten '%s'\n", shortenedNumber);
1248 					sccp_dev_displayprompt(d, instance, c->callid, SKINNY_DISP_PICKUP, GLOB(digittimeout));
1249 					if (sccp_feat_directed_pickup(d, c, instance, shortenedNumber) == 0) {
1250 						goto EXIT_FUNC;
1251 					}
1252 				}
1253 				sccp_dev_displayprinotify(d, SKINNY_DISP_NO_CALL_AVAILABLE_FOR_PICKUP, SCCP_MESSAGE_PRIORITY_TIMEOUT, 5);
1254 				if (c->state == SCCP_CHANNELSTATE_ONHOOK || c->state == SCCP_CHANNELSTATE_DOWN) {
1255 					c->setTone(c, SKINNY_TONE_BEEPBONK, SKINNY_TONEDIRECTION_USER);
1256 				}
1257 				sccp_channel_schedule_hangup(c, 500);
1258 				goto EXIT_FUNC;									// leave simpleswitch without dial
1259 #endif														// CS_SCCP_PICKUP
1260 #ifdef CS_SCCP_CONFERENCE
1261 			case SCCP_SOFTSWITCH_GETCONFERENCEROOM:
1262 				sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_3 "%s: (sccp_pbx_softswitch) Conference request\n", d->id);
1263 				if (c->owner && !pbx_check_hangup(c->owner)) {
1264 					sccp_channel_setChannelstate(c, SCCP_CHANNELSTATE_PROCEED);
1265 					iPbx.set_callstate(channel, AST_STATE_UP);
1266 					if (!d->conference) {
1267 						if (!(d->conference = sccp_conference_create(d, c))) {
1268 							goto EXIT_FUNC;
1269 						}
1270 					} else {
1271 						pbx_log(LOG_NOTICE, "%s: There is already a conference running on this device.\n", DEV_ID_LOG(d));
1272 						sccp_channel_endcall(c);
1273 						goto EXIT_FUNC;
1274 					}
1275 					sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: (sccp_pbx_softswitch) Start Conference\n", d->id);
1276 					sccp_feat_conference_start(d, instance, c);
1277 				}
1278 				goto EXIT_FUNC;
1279 #endif														// CS_SCCP_CONFERENCE
1280 			case SCCP_SOFTSWITCH_GETMEETMEROOM:
1281 				sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_3 "%s: (sccp_pbx_softswitch) Meetme request\n", d->id);
1282 				if (!sccp_strlen_zero(shortenedNumber) && !sccp_strlen_zero(c->line->meetmenum)) {
1283 					sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: (sccp_pbx_softswitch) Meetme request for room '%s' on extension '%s'\n", d->id, shortenedNumber, c->line->meetmenum);
1284 					if (c->owner && !pbx_check_hangup(c->owner)) {
1285 						pbx_builtin_setvar_helper(c->owner, "SCCP_MEETME_ROOM", shortenedNumber);
1286 					}
1287 					sccp_copy_string(shortenedNumber, c->line->meetmenum, sizeof(shortenedNumber));
1288 
1289 					//sccp_copy_string(c->dialedNumber, SKINNY_DISP_CONFERENCE, sizeof(c->dialedNumber));
1290 					sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: (sccp_pbx_softswitch) Start Meetme Thread\n", d->id);
1291 					sccp_feat_meetme_start(c);						/* Copied from Federico Santulli */
1292 					sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: (sccp_pbx_softswitch) Meetme Thread Started\n", d->id);
1293 					goto EXIT_FUNC;
1294 				} else {
1295 					// without a number we can also close the call. Isn't it true ?
1296 					sccp_channel_endcall(c);
1297 					goto EXIT_FUNC;
1298 				}
1299 				break;
1300 			case SCCP_SOFTSWITCH_GETBARGEEXTEN:
1301 				sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_3 "%s: (sccp_pbx_softswitch) Get Barge Extension\n", d->id);
1302 				sccp_dev_clearprompt(d, instance, c->callid);
1303 				if (!sccp_strlen_zero(shortenedNumber)) {
1304  					sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "SCCP: (sccp_pbx_softswitch) Asterisk request to barge exten '%s'\n", shortenedNumber);
1305 					sccp_dev_displayprompt(d, instance, c->callid, SKINNY_DISP_BARGE, GLOB(digittimeout));
1306 					if (sccp_feat_singleline_barge(c, shortenedNumber)) {
1307 						//sccp_indicate(d, c, SCCP_CHANNELSTATE_INVALIDNUMBER);
1308 						goto EXIT_FUNC;
1309 					}
1310 				}
1311 				sccp_dev_displayprinotify(d, SKINNY_DISP_FAILED_TO_SETUP_BARGE, SCCP_MESSAGE_PRIORITY_TIMEOUT, 5);
1312 				if (c->state == SCCP_CHANNELSTATE_ONHOOK || c->state == SCCP_CHANNELSTATE_DOWN) {
1313 					c->setTone(c, SKINNY_TONE_BEEPBONK, SKINNY_TONEDIRECTION_USER);
1314 				}
1315 				sccp_channel_endcall(c);
1316 				goto EXIT_FUNC;									// leave simpleswitch without dial
1317 			case SCCP_SOFTSWITCH_GETCBARGEROOM:
1318 				sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_3 "%s: (sccp_pbx_softswitch) Get Conference Barge Extension\n", d->id);
1319 				// like we're dialing but we're not :)
1320 				sccp_indicate(d, c, SCCP_CHANNELSTATE_DIALING);
1321 				sccp_device_sendcallstate(d, instance, c->callid, SKINNY_CALLSTATE_PROCEED, SKINNY_CALLPRIORITY_LOW, SKINNY_CALLINFO_VISIBILITY_DEFAULT);
1322 				sccp_channel_send_callinfo(d, c);
1323 				sccp_dev_clearprompt(d, instance, c->callid);
1324 				sccp_dev_displayprompt(d, instance, c->callid, SKINNY_DISP_CALL_PROCEED, GLOB(digittimeout));
1325 				if (!sccp_strlen_zero(shortenedNumber)) {
1326 					sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: (sccp_pbx_softswitch) Device request to barge conference '%s'\n", d->id, shortenedNumber);
1327 					if (sccp_feat_cbarge(c, shortenedNumber)) {
1328 						sccp_indicate(d, c, SCCP_CHANNELSTATE_INVALIDNUMBER);
1329 					}
1330 				} else {
1331 					// without a number we can also close the call. Isn't it true ?
1332 					sccp_channel_endcall(c);
1333 				}
1334 				goto EXIT_FUNC;									// leave simpleswitch without dial
1335 			case SCCP_SOFTSWITCH_SENTINEL:
1336 				sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_3 "%s: (sccp_pbx_softswitch) Unknown Softswitch Request\n", d->id);
1337 				goto EXIT_FUNC;
1338 			case SCCP_SOFTSWITCH_DIAL:
1339 				sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_3 "%s: (sccp_pbx_softswitch) Dial Extension %s\n", d->id, shortenedNumber);
1340 				sccp_indicate(d, c, SCCP_CHANNELSTATE_DIALING);
1341 				/* fall through */
1342 		}
1343 
1344 		/* set private variable */
1345 		if (pbx_channel && !pbx_check_hangup(pbx_channel)) {
1346 			sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_3 "SCCP: (sccp_pbx_softswitch) set variable SKINNY_PRIVATE to: %s\n", c->privacy ? "1" : "0");
1347 			if (c->privacy) {
1348 				sccp_channel_set_calleridPresentation(c, CALLERID_PRESENTATION_FORBIDDEN);
1349 			}
1350 
1351 			uint32_t result = d->privacyFeature.status & SCCP_PRIVACYFEATURE_CALLPRESENT;
1352 
1353 			result |= c->privacy;
1354 			if (d->privacyFeature.enabled && result) {
1355 				sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_3 "SCCP: (sccp_pbx_softswitch) set variable SKINNY_PRIVATE to: %s\n", "1");
1356 				pbx_builtin_setvar_helper(pbx_channel, "SKINNY_PRIVATE", "1");
1357 			} else {
1358 				sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_3 "SCCP: (sccp_pbx_softswitch) set variable SKINNY_PRIVATE to: %s\n", "0");
1359 				pbx_builtin_setvar_helper(pbx_channel, "SKINNY_PRIVATE", "0");
1360 			}
1361 		}
1362 
1363 		/* set devicevariables */
1364 		v = d->variables;
1365 		while (pbx_channel && !pbx_check_hangup(pbx_channel) && d && v) {
1366 			pbx_builtin_setvar_helper(pbx_channel, v->name, v->value);
1367 			v = v->next;
1368 		}
1369 
1370 		/* set linevariables */
1371 		v = l->variables;
1372 		while (pbx_channel && !pbx_check_hangup(pbx_channel) && l && v) {
1373 			pbx_builtin_setvar_helper(pbx_channel, v->name, v->value);
1374 			v = v->next;
1375 		}
1376 
1377 		iPbx.setChannelExten(c, shortenedNumber);
1378 
1379 		/*! \todo DdG: Extra wait time is incurred when checking pbx_exists_extension, when a wrong number is dialed. storing extension_exists status for sccp_log use */
1380 		int extension_exists = SCCP_EXTENSION_NOTEXISTS;
1381 
1382 		if (!sccp_strlen_zero(shortenedNumber) && ((extension_exists = iPbx.extension_status(c) != SCCP_EXTENSION_NOTEXISTS))
1383 		    ) {
1384 			if (pbx_channel && !pbx_check_hangup(pbx_channel)) {
1385 				/* found an extension, let's dial it */
1386 				sccp_log((DEBUGCAT_PBX + DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_1 "%s: (sccp_pbx_softswitch) channel %s is dialing number %s\n", DEV_ID_LOG(d), c->designator, shortenedNumber);
1387 
1388 				/* Answer dialplan command works only when in RINGING OR RING ast_state */
1389 				iPbx.set_callstate(c, AST_STATE_RING);
1390 
1391 				enum ast_pbx_result pbxStartResult = pbx_pbx_start(pbx_channel);
1392 
1393 				/* \todo replace AST_PBX enum using pbx_impl wrapper enum */
1394 				switch (pbxStartResult) {
1395 					case AST_PBX_FAILED:
1396 						pbx_log(LOG_ERROR, "%s: (sccp_pbx_softswitch) channel %s failed to start new thread to dial %s\n", DEV_ID_LOG(d), c->designator, shortenedNumber);
1397 						/* \todo change indicate to something more suitable */
1398 						sccp_indicate(d, c, SCCP_CHANNELSTATE_CONGESTION);		/* will auto hangup after SCCP_HANGUP_TIMEOUT */
1399 						break;
1400 					case AST_PBX_CALL_LIMIT:
1401 						pbx_log(LOG_WARNING, "%s: (sccp_pbx_softswitch) call limit reached for channel %s-%08x failed to start new thread to dial %s\n", DEV_ID_LOG(d), l->name, c->callid, shortenedNumber);
1402 						sccp_indicate(d, c, SCCP_CHANNELSTATE_CONGESTION);		/* will auto hangup after SCCP_HANGUP_TIMEOUT */
1403 						break;
1404 					case AST_PBX_SUCCESS:
1405 						sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_1 "%s: (sccp_pbx_softswitch) pbx started\n", DEV_ID_LOG(d));
1406 #ifdef CS_MANAGER_EVENTS
1407 						if (GLOB(callevents)) {
1408 							manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", "Channel: %s\r\nUniqueid: %s\r\nChanneltype: %s\r\nSCCPdevice: %s\r\nSCCPline: %s\r\nSCCPcallid: %08X\r\nSCCPCallDesignator: %s\r\n",
1409 								(pbx_channel) ? pbx_channel_name(pbx_channel) : "(null)",
1410 								(pbx_channel) ? pbx_channel_uniqueid(pbx_channel) : "(null)",
1411 								"SCCP",
1412 								(d) ? d->id : "(null)",
1413 								(l) ? l->name : "(null)",
1414 								(c && c->callid) ? c->callid : 0,
1415 								(c) ? c->designator : "(null)");
1416 						}
1417 #endif														// CS_MANAGER_EVENTS
1418 						break;
1419 				}
1420 				AUTO_RELEASE(sccp_linedevice_t, ld, c->getLineDevice(c));
1421 				if(ld) {
1422 					sccp_device_setLastNumberDialed(d, shortenedNumber, ld);
1423 				}
1424 				if(iPbx.set_dialed_number) {
1425 					iPbx.set_dialed_number(c, shortenedNumber);
1426 				}
1427 			} else {
1428 				sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_1 "%s: (sccp_pbx_softswitch) pbx_check_hangup(chan): %d on line %s\n", DEV_ID_LOG(d), (pbx_channel && pbx_check_hangup(pbx_channel)), l->name);
1429 			}
1430 		} else {
1431 			sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_1 "%s: (sccp_pbx_softswitch) channel:%s shortenedNumber:%s, extension exists:%s\n", DEV_ID_LOG(d), c->designator, shortenedNumber, (extension_exists != SCCP_EXTENSION_NOTEXISTS) ? "TRUE" : "FALSE");
1432 			pbx_log(LOG_NOTICE, "%s: Call from '%s' to extension '%s', rejected because the extension could not be found in context '%s'\n", DEV_ID_LOG(d), l->name, shortenedNumber, pbx_channel ? pbx_channel_context(pbx_channel) : "pbx_channel==NULL");
1433 			/* timeout and no extension match */
1434 			if (pbx_channel && !pbx_check_hangup(pbx_channel)) {
1435 				pbx_log(LOG_NOTICE, "%s: Scheduling Hangup of Call: %s\n", DEV_ID_LOG(d), c->designator);
1436 				sccp_indicate(d, c, SCCP_CHANNELSTATE_INVALIDNUMBER);				/* will auto hangup after SCCP_HANGUP_TIMEOUT */
1437 			}
1438 		}
1439 
1440 		sccp_log((DEBUGCAT_PBX + DEBUGCAT_DEVICE)) (VERBOSE_PREFIX_1 "%s: (sccp_pbx_softswitch) finished\n", DEV_ID_LOG(d));
1441 	}
1442 EXIT_FUNC:
1443 	sccp_log((DEBUGCAT_PBX + DEBUGCAT_DEVICE)) (VERBOSE_PREFIX_1 "SCCP: (sccp_pbx_softswitch) exit\n");
1444 	if (pbx_channel) {
1445 		pbx_channel_unref(pbx_channel);
1446 	}
1447 	return NULL;
1448 }
1449 
1450 #if 0
1451 /*!
1452  * \brief Handle Dialplan Transfer
1453  *
1454  * This will allow asterisk to transfer an SCCP Channel via the dialplan transfer function
1455  *
1456  * \param ast Asterisk Channel
1457  * \param dest Destination as char *
1458  * \return result as int
1459  *
1460  * \test Dialplan Transfer Needs to be tested
1461  * \todo pbx_transfer needs to be implemented correctly
1462  *
1463  * \called_from_asterisk
1464  */
1465 int sccp_pbx_transfer(PBX_CHANNEL_TYPE * ast, const char *dest)
1466 {
1467 	int res = 0;
1468 
1469 	if (dest == NULL) {											/* functions below do not take a NULL */
1470 		dest = "";
1471 		return -1;
1472 	}
1473 
1474 	AUTO_RELEASE(sccp_channel_t, c , get_sccp_channel_from_pbx_channel(ast));
1475 
1476 	if (!c) {
1477 		return -1;
1478 	}
1479 
1480 	/*
1481 	   sccp_device_t *d = NULL;
1482 	   sccp_channel_t *newcall = NULL;
1483 	 */
1484 
1485 	sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_1 "Transferring '%s' to '%s'\n", iPbx.getChannelName(c), dest);
1486 	if (pbx_channel_state(ast) == AST_STATE_RING) {
1487 		//! \todo Blindtransfer needs to be implemented correctly
1488 
1489 		/*
1490 		   res = sccp_blindxfer(p, dest);
1491 		 */
1492 		res = -1;
1493 	} else {
1494 		//! \todo Transfer needs to be implemented correctly
1495 
1496 		/*
1497 		   res=sccp_channel_transfer(p,dest);
1498 		 */
1499 		res = -1;
1500 	}
1501 	return res;
1502 }
1503 #endif
1504 
1505 // 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;
1506