1 /*!
2  * \file        ast113.c
3  * \brief       SCCP PBX Asterisk Wrapper Class
4  * \author      Marcello Ceshia
5  * \author      Diederik de Groot <ddegroot [at] users.sourceforge.net>
6  * \note        This program is free software and may be modified and distributed under the terms of the GNU Public License.
7  *              See the LICENSE file at the top of the source tree.
8  */
9 
10 #include "config.h"
11 #include "common.h"
12 #include "chan_sccp.h"
13 #include "sccp_pbx.h"
14 #include "sccp_channel.h"
15 #include "sccp_device.h"
16 #include "sccp_line.h"
17 #include "sccp_linedevice.h"
18 #include "sccp_cli.h"
19 #include "sccp_utils.h"
20 #include "sccp_indicate.h"
21 #include "sccp_hint.h"
22 #include "sccp_appfunctions.h"
23 #include "sccp_management.h"
24 #include "sccp_netsock.h"
25 #include "sccp_rtp.h"
26 #include "sccp_session.h"		// required for sccp_session_getOurIP
27 #include "sccp_labels.h"
28 #include "sccp_enum.h"
29 #include "pbx_impl/ast113/ast113.h"
30 #include "pbx_impl/ast_announce/ast_announce.h"
31 
32 SCCP_FILE_VERSION(__FILE__, "");
33 
34 __BEGIN_C_EXTERN__
35 #ifdef HAVE_PBX_ACL_H
36 #  include <asterisk/acl.h>
37 #endif
38 #include <asterisk/module.h>
39 #include <asterisk/callerid.h>
40 #include <asterisk/causes.h>
41 #include <asterisk/musiconhold.h>
42 #ifdef HAVE_PBX_FEATURES_H
43 #  include <asterisk/features_config.h>
44 #  include <asterisk/features.h>
45 #  include <asterisk/parking.h>
46 #  include <asterisk/pickup.h>
47 #endif
48 #ifdef HAVE_PBX_APP_H
49 #  include <asterisk/app.h>
50 #endif
51 #include <asterisk/translate.h>
52 #include <asterisk/indications.h>
53 #include <asterisk/cel.h>
54 #include <asterisk/netsock2.h>
55 #include <asterisk/pickup.h>
56 #include <asterisk/stasis.h>
57 #include <asterisk/stasis_channels.h>
58 #include <asterisk/stasis_endpoints.h>
59 #include <asterisk/bridge_after.h>
60 #include <asterisk/bridge_channel.h>
61 #include <asterisk/format_cap.h>		// for AST_FORMAT_CAP_NAMES_LEN
62 #include <asterisk/timing.h>
63 #include <asterisk/say.h>                                        // PARKING
64 __END_C_EXTERN__
65 #define pbx_module_info ast_module_info
66 
67 struct ast_sched_context *sched = 0;
68 struct io_context *io = 0;
69 
70 static PBX_CHANNEL_TYPE *sccp_astwrap_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const PBX_CHANNEL_TYPE * requestor, const char *dest, int *cause);
71 static int sccp_astwrap_call(PBX_CHANNEL_TYPE * ast, const char *dest, int timeout);
72 static int sccp_astwrap_answer(PBX_CHANNEL_TYPE * chan);
73 static PBX_FRAME_TYPE *sccp_astwrap_rtp_read(PBX_CHANNEL_TYPE * ast);
74 static int sccp_astwrap_rtp_write(PBX_CHANNEL_TYPE * ast, PBX_FRAME_TYPE * frame);
75 static int sccp_astwrap_indicate(PBX_CHANNEL_TYPE * ast, int ind, const void *data, size_t datalen);
76 static int sccp_astwrap_fixup(PBX_CHANNEL_TYPE * oldchan, PBX_CHANNEL_TYPE * newchan);
77 static void sccp_astwrap_setDialedNumber(constChannelPtr channel, const char *number);
78 //#ifdef CS_AST_RTP_INSTANCE_BRIDGE
79 //static enum ast_bridge_result sccp_astwrap_rtpBridge(PBX_CHANNEL_TYPE * c0, PBX_CHANNEL_TYPE * c1, int flags, PBX_FRAME_TYPE ** fo, PBX_CHANNEL_TYPE ** rc, int timeoutms);
80 //#endif
81 static int sccp_pbx_sendtext(PBX_CHANNEL_TYPE * ast, const char *text);
82 static int sccp_wrapper_recvdigit_begin(PBX_CHANNEL_TYPE * ast, char digit);
83 static int sccp_wrapper_recvdigit_end(PBX_CHANNEL_TYPE * ast, char digit, unsigned int duration);
84 static int sccp_pbx_sendHTML(PBX_CHANNEL_TYPE * ast, int subclass, const char *data, int datalen);
85 int sccp_astwrap_hangup(PBX_CHANNEL_TYPE * ast_channel);
86 int sccp_astwrap_queue_control(const PBX_CHANNEL_TYPE * pbx_channel, enum ast_control_frame_type control);
87 int sccp_astwrap_queue_control_data(const PBX_CHANNEL_TYPE * pbx_channel, enum ast_control_frame_type control, const void *data, size_t datalen);
88 static int sccp_astwrap_devicestate(const char *data);
89 PBX_CHANNEL_TYPE *sccp_astwrap_findPickupChannelByExtenLocked(PBX_CHANNEL_TYPE * chan, const char *exten, const char *context);
90 PBX_CHANNEL_TYPE *sccp_astwrap_findPickupChannelByGroupLocked(PBX_CHANNEL_TYPE * chan);
91 
sccp_astwrap_getSkinnyFormatSingle(struct ast_format_cap * ast_format_capability)92 static inline skinny_codec_t sccp_astwrap_getSkinnyFormatSingle(struct ast_format_cap *ast_format_capability)
93 {
94 	uint formatPosition;
95 	skinny_codec_t codec = SKINNY_CODEC_NONE;
96 	struct ast_format *format;
97 
98 	for (formatPosition = 0; formatPosition < ast_format_cap_count(ast_format_capability); ++formatPosition) {
99 		format = ast_format_cap_get_format(ast_format_capability, formatPosition);
100 		uint64_t ast_codec = ast_format_compatibility_format2bitfield(format);
101 		ao2_ref(format, -1);
102 
103 		if ((codec = pbx_codec2skinny_codec(ast_codec)) != SKINNY_CODEC_NONE) {
104 			break;
105 		}
106 	}
107 
108 	if (codec == SKINNY_CODEC_NONE) {
109 		ast_log(LOG_WARNING, "SCCP: (getSkinnyFormatSingle) No matching codec found");
110 	}
111 	return codec;
112 }
113 
sccp_astwrap_getSkinnyFormatMultiple(struct ast_format_cap * ast_format_capability,skinny_codec_t codecs[],int length)114 static uint8_t sccp_astwrap_getSkinnyFormatMultiple(struct ast_format_cap *ast_format_capability, skinny_codec_t codecs[], int length)
115 {
116 	// struct ast_format tmp_fmt;
117 	uint formatPosition;
118 	skinny_codec_t found = SKINNY_CODEC_NONE;
119 	uint8_t position = 0;
120 	struct ast_format *format;
121 
122 	memset(codecs, 0, length * sizeof(skinny_codec_t));
123 
124 	for (formatPosition = 0; formatPosition < ast_format_cap_count(ast_format_capability); ++formatPosition) {
125 		format = ast_format_cap_get_format(ast_format_capability, formatPosition);
126 		uint64_t ast_codec = ast_format_compatibility_format2bitfield(format);
127 		ao2_ref(format, -1);
128 
129 		if ((found = pbx_codec2skinny_codec(ast_codec)) != SKINNY_CODEC_NONE) {
130 			codecs[position++] = found;
131 		}
132 	}
133 
134 	if (codecs[0] == SKINNY_CODEC_NONE) {
135 		ast_log(LOG_WARNING, "SCCP: (getSkinnyFormatSingle) No matching codecs found");
136 	}
137 
138 	return position;
139 }
140 
sccp_astwrap_skinny2ast_format(skinny_codec_t skinnycodec)141 static struct ast_format *sccp_astwrap_skinny2ast_format(skinny_codec_t skinnycodec)
142 {
143 	switch (skinnycodec) {
144 		case SKINNY_CODEC_WIDEBAND_256K:
145 			return ast_format_slin16;
146 		case SKINNY_CODEC_G711_ALAW_64K:
147 		case SKINNY_CODEC_G711_ALAW_56K:
148 			return ast_format_alaw;
149 		case SKINNY_CODEC_G711_ULAW_64K:
150 		case SKINNY_CODEC_G711_ULAW_56K:
151 			return ast_format_ulaw;
152 		case SKINNY_CODEC_G722_64K:
153 		case SKINNY_CODEC_G722_56K:
154 		case SKINNY_CODEC_G722_48K:
155 			return ast_format_g722;
156 		case SKINNY_CODEC_G723_1:
157 			return ast_format_g723;
158 		case SKINNY_CODEC_G729:
159 			return ast_format_g729;
160 		case SKINNY_CODEC_G729_A:
161 			return ast_format_g729;
162 		case SKINNY_CODEC_G729_B_LOW:
163 			return ast_format_ilbc;
164 //		case SKINNY_CODEC_G729_B:
165 //		case SKINNY_CODEC_G729_ANNEX_B:
166 //		case SKINNY_CODEC_G729_AB:
167 //			return ast_format_g729b;
168 		case SKINNY_CODEC_G726_32K:
169 			return ast_format_g726;
170 		case SKINNY_CODEC_GSM:
171 			return ast_format_gsm;
172 #ifdef AST_FORMAT_OPUS
173 		case SKINNY_CODEC_OPUS:
174 			return ast_format_opus;
175 #endif
176 #ifdef AST_FORMAT_SIREN7
177 		case SKINNY_CODEC_G722_1_24K:
178 			return ast_format_siren7;
179 #endif
180 #ifdef AST_FORMAT_SIREN7
181 		case SKINNY_CODEC_G722_1_32K:
182 			return ast_format_siren14;
183 #endif
184 		case SKINNY_CODEC_H261:
185 			return ast_format_h261;
186 		case SKINNY_CODEC_H263:
187 			return ast_format_h263;
188 		case SKINNY_CODEC_H263P:
189 			return ast_format_h263p;
190 		case SKINNY_CODEC_H264:
191 			return ast_format_h264;
192 		case SKINNY_CODEC_T120:
193 			return ast_format_t140;
194 		default:
195 			return ast_format_none;
196 	}
197 }
198 
pbx_format_cap_append_skinny(struct ast_format_cap * caps,skinny_codec_t codecs[SKINNY_MAX_CAPABILITIES])199 static void pbx_format_cap_append_skinny(struct ast_format_cap *caps, skinny_codec_t codecs[SKINNY_MAX_CAPABILITIES]) {
200 	int i;
201 	for (i=0; i<SKINNY_MAX_CAPABILITIES; i++) {
202 		if (codecs[i] == SKINNY_CODEC_NONE) {
203 			break;
204 		}
205 		struct ast_format *format = sccp_astwrap_skinny2ast_format(codecs[i]);
206 		if (format != ast_format_none && ast_format_cap_iscompatible_format(caps, format) == AST_FORMAT_CMP_NOT_EQUAL) {
207 			unsigned int framing = ast_format_get_default_ms(format);
208 			ast_format_cap_append(caps, format, framing);
209 			//sccp_log(DEBUGCAT_CODEC)(VERBOSE_PREFIX_3 "Added codec:%s\n", codec2str(codecs[i]));
210 		}
211 	}
212 }
213 
214 #if defined(__cplusplus) || defined(c_plusplus)
215 /*!
216  * \brief NULL Tech Structure
217  */
218 static const struct ast_channel_tech null_tech = {
219 type:	"NULL",
220 description:"Null channel (should not see this)",
221 };
222 
223 /*!
224  * \brief SCCP Tech Structure
225  */
226 static struct ast_channel_tech sccp_tech = {
227 	/* *INDENT-OFF* */
228 	type:			SCCP_TECHTYPE_STR,
229 	description:		"Skinny Client Control Protocol (SCCP)",
230 	properties:		AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
231 	requester:		sccp_astwrap_request,
232 	devicestate:		sccp_astwrap_devicestate,
233 	send_digit_begin:	sccp_wrapper_recvdigit_begin,
234 	send_digit_end:		sccp_wrapper_recvdigit_end,
235 	call:			sccp_astwrap_call,
236 	hangup:			sccp_astwrap_hangup,
237 	answer:			sccp_astwrap_answer,
238 	read:			sccp_astwrap_rtp_read,
239 	write:			sccp_astwrap_rtp_write,
240 	send_text:		sccp_pbx_sendtext,
241 	send_image:		NULL,
242 	send_html:		sccp_pbx_sendHTML,
243 	exception:		NULL,
244 //	bridge:			sccp_astwrap_rtpBridge,
245         bridge:			ast_rtp_instance_bridge,
246 	early_bridge:		ast_rtp_instance_early_bridge,
247 	indicate:		sccp_astwrap_indicate,
248 	fixup:			sccp_astwrap_fixup,
249 	setoption:		NULL,
250 	queryoption:		NULL,
251 	transfer:		NULL,
252 	write_video:		sccp_astwrap_rtp_write,
253 	write_text:		NULL,
254 	bridged_channel:	NULL,
255 	func_channel_read:	sccp_astgenwrap_channel_read,
256 	func_channel_write:	sccp_astgenwrap_channel_write,
257 	get_base_channel:	NULL,
258 	set_base_channel:	NULL,
259 	/* *INDENT-ON* */
260 };
261 
262 #else
263 /*!
264  * \brief NULL Tech Structure
265  */
266 static const struct ast_channel_tech null_tech = {
267 	.type = "NULL",
268 	.description = "Null channel (should not see this)",
269 };
270 
271 /*!
272  * \brief SCCP Tech Structure
273  */
274 struct ast_channel_tech sccp_tech = {
275 	/* *INDENT-OFF* */
276 	.type 			= SCCP_TECHTYPE_STR,
277 	.description 		= "Skinny Client Control Protocol (SCCP)",
278 	.properties 		= AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
279 	.requester 		= sccp_astwrap_request,
280 	.devicestate 		= sccp_astwrap_devicestate,
281 	.call 			= sccp_astwrap_call,
282 	.hangup 		= sccp_astwrap_hangup,
283 	.answer 		= sccp_astwrap_answer,
284 	.read 			= sccp_astwrap_rtp_read,
285 	.write 			= sccp_astwrap_rtp_write,
286 	.write_video 		= sccp_astwrap_rtp_write,
287 	.indicate 		= sccp_astwrap_indicate,
288 	.fixup 			= sccp_astwrap_fixup,
289 	//.transfer 		= sccp_pbx_transfer,
290 #ifdef CS_AST_RTP_INSTANCE_BRIDGE
291 	.bridge 		= ast_rtp_instance_bridge,
292 //	.bridge 		= sccp_astwrap_rtpBridge,
293 #endif
294 	// asterisk-13 rtp_engine.h implementation of ast_rtp_instance_early_bridge is actually not fully c++ compatible to their own definition, so a cast is required
295 	.early_bridge		= (enum ast_bridge_result (*)(struct ast_channel *, struct ast_channel *))&ast_rtp_instance_early_bridge,
296 	//.bridged_channel      =
297 
298 	.send_text 		= sccp_pbx_sendtext,
299 	.send_html 		= sccp_pbx_sendHTML,
300 	//.send_image           =
301 
302 	.func_channel_read 	= sccp_astgenwrap_channel_read,
303 	.func_channel_write	= sccp_astgenwrap_channel_write,
304 
305 	.send_digit_begin 	= sccp_wrapper_recvdigit_begin,
306 	.send_digit_end 	= sccp_wrapper_recvdigit_end,
307 
308 	//.write_text           =
309 	//.write_video          =
310 	//.cc_callback          =                                              // ccss, new >1.6.0
311 	//.exception            =                                              // new >1.6.0
312 	//.setoption              = sccp_astwrap_setOption,
313 	//.queryoption          =                                              // new >1.6.0
314 	//.get_pvt_uniqueid     = sccp_pbx_get_callid,                         // new >1.6.0
315 	//.get_base_channel     =
316 	//.set_base_channel     =
317 	/* *INDENT-ON* */
318 };
319 
320 #endif
321 
sccp_astwrap_devicestate(const char * data)322 static int sccp_astwrap_devicestate(const char *data)
323 {
324 	enum ast_device_state res = AST_DEVICE_UNKNOWN;
325 	char *lineName = (char *) data;
326 	char *deviceId = NULL;
327 	sccp_channelstate_t state;
328 
329 	if ((deviceId = strchr(lineName, '@'))) {
330 		*deviceId = '\0';
331 		deviceId++;
332 	}
333 
334 	state = sccp_hint_getLinestate(lineName, deviceId);
335 	sccp_log((DEBUGCAT_HINT)) (VERBOSE_PREFIX_4 "SCCP: (devicestate) sccp_hint returned state:%s for '%s'\n", sccp_channelstate2str(state), lineName);
336 	switch (state) {
337 		case SCCP_CHANNELSTATE_DOWN:
338 		case SCCP_CHANNELSTATE_ONHOOK:
339 			res = AST_DEVICE_NOT_INUSE;
340 			break;
341 		case SCCP_CHANNELSTATE_RINGING:
342 			res = AST_DEVICE_RINGING;
343 			break;
344 		case SCCP_CHANNELSTATE_HOLD:
345 			res = AST_DEVICE_ONHOLD;
346 			break;
347 		case SCCP_CHANNELSTATE_INVALIDNUMBER:
348 		case SCCP_CHANNELSTATE_INVALIDCONFERENCE:
349 			res = AST_DEVICE_INVALID;
350 			break;
351 		case SCCP_CHANNELSTATE_BUSY:
352 		case SCCP_CHANNELSTATE_DND:
353 			res = AST_DEVICE_BUSY;
354 			break;
355 		case SCCP_CHANNELSTATE_CONGESTION:
356 			res = AST_DEVICE_UNAVAILABLE;
357 			break;
358 		case SCCP_CHANNELSTATE_RINGOUT:
359 		case SCCP_CHANNELSTATE_RINGOUT_ALERTING:
360 			res = AST_DEVICE_RINGINUSE;
361 			break;
362 		case SCCP_CHANNELSTATE_DIALING:
363 		case SCCP_CHANNELSTATE_DIGITSFOLL:
364 		case SCCP_CHANNELSTATE_PROGRESS:
365 		case SCCP_CHANNELSTATE_CALLWAITING:
366 		case SCCP_CHANNELSTATE_CONNECTEDCONFERENCE:
367 		case SCCP_CHANNELSTATE_OFFHOOK:
368 		case SCCP_CHANNELSTATE_GETDIGITS:
369 		case SCCP_CHANNELSTATE_CONNECTED:
370 		case SCCP_CHANNELSTATE_PROCEED:
371 		case SCCP_CHANNELSTATE_BLINDTRANSFER:
372 		case SCCP_CHANNELSTATE_CALLTRANSFER:
373 		case SCCP_CHANNELSTATE_CALLCONFERENCE:
374 		case SCCP_CHANNELSTATE_CALLPARK:
375 		case SCCP_CHANNELSTATE_CALLREMOTEMULTILINE:
376 		case SCCP_CHANNELSTATE_SPEEDDIAL:
377 			res = AST_DEVICE_INUSE;
378 			break;
379 		case SCCP_CHANNELSTATE_SENTINEL:
380 		case SCCP_CHANNELSTATE_ZOMBIE:
381 			res = AST_DEVICE_UNKNOWN;
382 			break;
383 	}
384 
385 	sccp_log((DEBUGCAT_HINT)) (VERBOSE_PREFIX_4 "SCCP: (devicestate) PBX requests state for '%s' - state %s\n", lineName, ast_devstate2str(res));
386 	return (int)res;
387 }
388 
389 #define RTP_NEW_SOURCE(_c,_log) 								\
390 	if(c->rtp.audio.instance) { 										\
391 		ast_rtp_new_source(c->rtp.audio.instance); 							\
392 		sccp_log((DEBUGCAT_PBX | DEBUGCAT_INDICATE))(VERBOSE_PREFIX_3 "SCCP: " #_log "\n"); 	\
393 	}
394 
395 #define RTP_CHANGE_SOURCE(_c,_log) 								\
396 	if(c->rtp.audio.instance) {										\
397 		ast_rtp_change_source(c->rtp.audio.instance);						\
398 		sccp_log((DEBUGCAT_PBX | DEBUGCAT_INDICATE))(VERBOSE_PREFIX_3 "SCCP: " #_log "\n"); 	\
399 	}
400 
401 /*! \brief Get the name of a format
402  * \note replacement for ast_getformatname
403  * \param format id of format
404  * \return A static string containing the name of the format or "unknown" if unknown.
405  */
pbx_getformatname(const struct ast_format * format)406 const char *pbx_getformatname(const struct ast_format *format)
407 {
408 	return ast_format_get_codec_name(format);
409 }
410 
411 /*!
412  * \brief Get the names of a set of formats
413  * \note replacement for ast_getformatname_multiple
414  * \param buf a buffer for the output string
415  * \param size size of buf (bytes)
416  * \param format the format (combined IDs of codecs)
417  * Prints a list of readable codec names corresponding to "format".
418  * ex: for format=AST_FORMAT_GSM|AST_FORMAT_SPEEX|AST_FORMAT_ILBC it will return "0x602 (GSM|SPEEX|ILBC)"
419  * \return The return value is buf.
420  */
pbx_getformatname_multiple(char * buf,size_t size,struct ast_format_cap * format)421 const char *pbx_getformatname_multiple(char *buf, size_t size, struct ast_format_cap *format)
422 {
423 	pbx_str_t *codec_buf = pbx_str_alloca(64);
424 	ast_format_cap_get_names(format, &codec_buf);
425 	snprintf(buf, size, "%s", ast_format_cap_get_names(format, &codec_buf));
426 	return buf;
427 }
428 
429 /*!
430  * \brief Find Asterisk/PBX channel by linkid
431  *
432  * \param ast   pbx channel
433  * \param data  linkId as void *
434  *
435  * \return int
436  */
pbx_find_channel_by_linkid(PBX_CHANNEL_TYPE * ast,PBX_CHANNEL_TYPE * remotePeer,const void * data)437 static int pbx_find_channel_by_linkid(PBX_CHANNEL_TYPE * ast, PBX_CHANNEL_TYPE * remotePeer, const void *data)
438 {
439 	const char *linkedId = (char *) data;
440 	const char *remoteLinkedId = ast_channel_linkedid(remotePeer);
441 
442 	if (!linkedId) {
443 		return 0;
444 	}
445 
446 	return remotePeer != ast && remoteLinkedId && (!strcasecmp(linkedId, remoteLinkedId)) && !pbx_channel_masq(remotePeer);
447 }
448 
449 /*! Generic helper function to find the best common codec to use */
__find_joint_capabilities(sccp_channel_t * c,PBX_CHANNEL_TYPE * peer,enum ast_media_type media_type,skinny_codec_t remoteCapabilities[])450 static void __find_joint_capabilities(sccp_channel_t *c, PBX_CHANNEL_TYPE* peer, enum ast_media_type media_type, skinny_codec_t remoteCapabilities[])
451 {
452 	char buf[512];
453 	pbx_str_t *codec_buf = pbx_str_alloca(64);
454 	PBX_CHANNEL_TYPE *owner = c->owner;
455 	RAII(struct ast_format_cap *, caps, ao2_t_bump(c->caps, "sccp_channel_caps"), ao2_cleanup);
456 	RAII(struct ast_format_cap *, payload_caps, ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT), ao2_cleanup);
457 	RAII(struct ast_format_cap *, remote_caps, ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT), ao2_cleanup);
458 	RAII(struct ast_format_cap *, joint, ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT), ao2_cleanup);
459 	struct ast_format *best_fmt_cap = NULL;
460 	struct ast_format *best_fmt_native = NULL;
461 	if (caps && payload_caps && remote_caps && joint && !ast_format_cap_empty(caps)) {
462 		ast_format_cap_append_from_cap(payload_caps, caps, media_type);
463 		ast_channel_lock(peer);
464 		struct ast_format_cap * cap_native_peer = ast_channel_nativeformats(peer);
465 		if (!ast_format_cap_empty(cap_native_peer) && ast_format_cap_has_type(cap_native_peer, media_type)) {
466 			ast_format_cap_append_from_cap(remote_caps, cap_native_peer, media_type);
467 		}
468 		ast_channel_unlock(peer);
469 		if (!ast_format_cap_empty(payload_caps) && !ast_format_cap_empty(remote_caps)) {
470 			sccp_log(DEBUGCAT_CODEC)(VERBOSE_PREFIX_3 "%s: (find_joint_capabilities) native caps:%s (%d)\n", c->designator, ast_format_cap_get_names(caps, &codec_buf), (int)ast_format_cap_count(caps));
471 			sccp_log(DEBUGCAT_CODEC)(VERBOSE_PREFIX_3 "%s: (find_joint_capabilities) %s  payload:%s (%d)\n", c->designator, ast_codec_media_type2str(media_type), ast_format_cap_get_names(payload_caps, &codec_buf),
472 			                         (int)ast_format_cap_count(payload_caps));
473 			sccp_log(DEBUGCAT_CODEC)(VERBOSE_PREFIX_3 "%s: (find_joint_capabilities) %s   remote:%s (%d)\n", c->designator, ast_codec_media_type2str(media_type), ast_format_cap_get_names(remote_caps, &codec_buf),
474 			                         (int)ast_format_cap_count(remote_caps));
475 
476 			// fill c->remoteCapabilities
477 			sccp_astwrap_getSkinnyFormatMultiple(remote_caps, remoteCapabilities, SKINNY_MAX_CAPABILITIES);
478 
479 			sccp_codec_multiple2str(buf, sizeof(buf) - 1, remoteCapabilities, SKINNY_MAX_CAPABILITIES);
480 			sccp_log(DEBUGCAT_CODEC) (VERBOSE_PREFIX_4 "skinny set remote %s caps: %s\n", ast_codec_media_type2str(media_type), buf);
481 
482 			ast_format_cap_get_compatible(payload_caps, remote_caps, joint);
483 
484 			if (!ast_format_cap_empty(joint)) {
485 				best_fmt_native = ast_format_cap_get_best_by_type(joint, media_type);
486 				sccp_log(DEBUGCAT_CODEC) (VERBOSE_PREFIX_4 "%s: (find_joint_capabilities) NOT transcoding, best_native:%s\n", c->designator, ast_format_get_codec_name(best_fmt_native));
487 				if (best_fmt_native) {
488 					ast_format_cap_remove_by_type(caps, media_type);
489 					ast_format_cap_append(caps, best_fmt_native, media_type);
490 				}
491 				ast_format_cap_append_from_cap(caps, joint, media_type);
492 			} else {
493 				ast_translator_best_choice(remote_caps, caps, &best_fmt_cap, &best_fmt_native);
494 				if (best_fmt_native) {
495 					ao2_ref(best_fmt_native, +1);
496 					ast_format_cap_remove_by_type(caps, media_type);
497 					ast_format_cap_append(caps, best_fmt_cap, media_type);
498 				} else {
499 					best_fmt_native = ast_format_cap_get_best_by_type(caps, media_type);
500 				}
501 				ast_format_cap_append_from_cap(caps, payload_caps, media_type);
502 				sccp_log(DEBUGCAT_CODEC) (VERBOSE_PREFIX_3 "%s: pbx_retrieve_remote_capabilities: transcoding, best_cap:%s, best_native:%s\n",
503 					c->designator, ast_format_get_codec_name(best_fmt_cap), best_fmt_native ? ast_format_get_codec_name(best_fmt_native) : "");
504 			}
505 
506 			ast_format_cap_append_from_cap(caps, ast_channel_nativeformats(c->owner), AST_MEDIA_TYPE_UNKNOWN);
507 			if (best_fmt_native) {
508 				if (best_fmt_native != ast_format_none) {
509 					if (!ast_format_cap_empty(caps)) {
510 						ast_channel_lock(owner);
511 						ast_channel_nativeformats_set(c->owner, caps);
512 						ast_channel_unlock(owner);
513 						sccp_log(DEBUGCAT_CODEC) (VERBOSE_PREFIX_4 "%s: (find_joint_capabilities) using: caps:%s, codec:%s\n", c->designator, ast_format_cap_get_names(caps, &codec_buf), ast_format_get_codec_name(best_fmt_native));
514 					}
515 						if (AST_MEDIA_TYPE_AUDIO == media_type) {
516 							ast_channel_set_writeformat(c->owner, best_fmt_native);
517 							ast_channel_set_readformat(c->owner, best_fmt_native);
518 							if (c->rtp.audio.instance) {
519 								ast_channel_set_rawwriteformat(c->owner, best_fmt_native);
520 								ast_channel_set_rawreadformat(c->owner, best_fmt_native);
521 							}
522 							if (c->rtp.audio.instance) {
523 								ast_rtp_instance_set_write_format(c->rtp.audio.instance, best_fmt_native);
524 								ast_rtp_instance_set_read_format(c->rtp.audio.instance, best_fmt_native);
525 							}
526 						} else if (AST_MEDIA_TYPE_VIDEO == media_type && c->rtp.video.instance) {
527 							ast_rtp_instance_set_write_format(c->rtp.video.instance, best_fmt_native);
528 							ast_rtp_instance_set_read_format(c->rtp.video.instance, best_fmt_native);
529 					}
530 				}
531 				ao2_ref(best_fmt_native, -1);
532 			}
533 		}
534 		return;
535 	}
536 }
537 
pbx_retrieve_remote_capabilities(sccp_channel_t * c)538 static void pbx_retrieve_remote_capabilities(sccp_channel_t *c)
539 {
540 	pbx_assert(c != NULL);
541 	PBX_CHANNEL_TYPE *ast = c->owner;
542 	PBX_CHANNEL_TYPE *remotePeer;
543 
544 	struct ast_channel_iterator *iterator = ast_channel_iterator_all_new();
545 	((struct ao2_iterator *) iterator)->flags |= AO2_ITERATOR_DONTLOCK;
546 
547 	//! \todo handle multiple remotePeers i.e. DIAL(SCCP/400&SIP/300), find smallest common codecs, what order to use ?
548 	for (; (remotePeer = ast_channel_iterator_next(iterator)); pbx_channel_unref(remotePeer)) {
549 		if (pbx_find_channel_by_linkid(ast, remotePeer, (void *) ast_channel_linkedid(ast))) {
550 			__find_joint_capabilities(c, remotePeer, AST_MEDIA_TYPE_AUDIO, c->remoteCapabilities.audio);
551 #if CS_SCCP_VIDEO
552 			__find_joint_capabilities(c, remotePeer, AST_MEDIA_TYPE_VIDEO, c->remoteCapabilities.video);
553 #endif
554 			break;
555 		}
556 	}
557 	ast_channel_iterator_destroy(iterator);
558 }
559 
560 
asterisk_indication2str(int ind)561 static const char *asterisk_indication2str(int ind)
562 {
563 	switch (ind) {
564 		case AST_CONTROL_HANGUP: return "AST_CONTROL_HANGUP: Other end has hungup";
565 		case AST_CONTROL_RING: return "AST_CONTROL_RING: Local ring";
566 		case AST_CONTROL_RINGING: return "AST_CONTROL_RINGING: Remote end is ringing";
567 		case AST_CONTROL_ANSWER: return "AST_CONTROL_ANSWER: Remote end has answered";
568 		case AST_CONTROL_BUSY: return "AST_CONTROL_BUSY: Remote end is busy";
569 		case AST_CONTROL_TAKEOFFHOOK: return "AST_CONTROL_TAKEOFFHOOK: Make it go off hook";
570 		case AST_CONTROL_OFFHOOK: return "AST_CONTROL_OFFHOOK: Line is off hook";
571 		case AST_CONTROL_CONGESTION: return "AST_CONTROL_CONGESTION: Congestion (circuits busy)";
572 		case AST_CONTROL_FLASH: return "AST_CONTROL_FLASH: Flash hook";
573 		case AST_CONTROL_WINK: return "AST_CONTROL_WINK: Wink";
574 		case AST_CONTROL_OPTION: return "AST_CONTROL_OPTION: Set a low-level option";
575 		case AST_CONTROL_RADIO_KEY: return "AST_CONTROL_RADIO_KEY: Key Radio";
576 		case AST_CONTROL_RADIO_UNKEY: return "AST_CONTROL_RADIO_UNKEY: Un-Key Radio";
577 		case AST_CONTROL_PROGRESS: return "AST_CONTROL_PROGRESS: Indicate PROGRESS";
578 		case AST_CONTROL_PROCEEDING: return "AST_CONTROL_PROCEEDING: Indicate CALL PROCEEDING";
579 		case AST_CONTROL_HOLD: return "AST_CONTROL_HOLD: Indicate call is placed on hold";
580 		case AST_CONTROL_UNHOLD: return "AST_CONTROL_UNHOLD: Indicate call left hold";
581 		case AST_CONTROL_VIDUPDATE: return "AST_CONTROL_VIDUPDATE: Indicate video frame update";
582 		case _XXX_AST_CONTROL_T38: return "_XXX_AST_CONTROL_T38: T38 state change request/notification. Deprecated This is no longer supported. Use AST_CONTROL_T38_PARAMETERS instead.";
583 		case AST_CONTROL_SRCUPDATE: return "AST_CONTROL_SRCUPDATE: Indicate source of media has changed";
584 		case AST_CONTROL_TRANSFER: return "AST_CONTROL_TRANSFER: Indicate status of a transfer request";
585 		case AST_CONTROL_CONNECTED_LINE: return "AST_CONTROL_CONNECTED_LINE: Indicate connected line has changed";
586 		case AST_CONTROL_REDIRECTING: return "AST_CONTROL_REDIRECTING: Indicate redirecting id has changed";
587 		case AST_CONTROL_T38_PARAMETERS: return "AST_CONTROL_T38_PARAMETERS: T38 state change request/notification with parameters";
588 		case AST_CONTROL_CC: return "AST_CONTROL_CC: Indication that Call completion service is possible";
589 		case AST_CONTROL_SRCCHANGE: return "AST_CONTROL_SRCCHANGE: Media source has changed and requires a new RTP SSRC";
590 		case AST_CONTROL_READ_ACTION: return "AST_CONTROL_READ_ACTION: Tell ast_read to take a specific action";
591 		case AST_CONTROL_AOC: return "AST_CONTROL_AOC: Advice of Charge with encoded generic AOC payload";
592 		case AST_CONTROL_END_OF_Q: return "AST_CONTROL_END_OF_Q: Indicate that this position was the end of the channel queue for a softhangup.";
593 		case AST_CONTROL_INCOMPLETE: return "AST_CONTROL_INCOMPLETE: Indication that the extension dialed is incomplete";
594 		case AST_CONTROL_MCID: return "AST_CONTROL_MCID: Indicate that the caller is being malicious.";
595 		case AST_CONTROL_UPDATE_RTP_PEER: return "AST_CONTROL_UPDATE_RTP_PEER: Interrupt the bridge and have it update the peer";
596 		case AST_CONTROL_PVT_CAUSE_CODE: return "AST_CONTROL_PVT_CAUSE_CODE: Contains an update to the protocol-specific cause-code stored for branching dials";
597 		case AST_CONTROL_MASQUERADE_NOTIFY: return "AST_CONTROL_MASQUERADE_NOTIFY: A masquerade is about to begin/end."; // Never sent as a frame but directly with ast_indicate_data()
598 		case -1: return "AST_CONTROL_PROD: Kick remote channel";
599 	}
600 	return "Unknown/Unhandled/IAX Indication";
601 }
602 
sccp_astwrap_indicate(PBX_CHANNEL_TYPE * ast,int ind,const void * data,size_t datalen)603 static int sccp_astwrap_indicate(PBX_CHANNEL_TYPE * ast, int ind, const void *data, size_t datalen)
604 {
605 	int res = 0;	/* indication supported */
606 
607 	AUTO_RELEASE(sccp_channel_t, c , get_sccp_channel_from_pbx_channel(ast));
608 	if (!c) {
609 		sccp_log((DEBUGCAT_PBX | DEBUGCAT_CHANNEL | DEBUGCAT_INDICATE)) (VERBOSE_PREFIX_3 "SCCP: (pbx_indicate) no sccp channel yet\n");
610 		return -1;
611 	}
612 	sccp_log((DEBUGCAT_PBX | DEBUGCAT_CHANNEL | DEBUGCAT_INDICATE)) (VERBOSE_PREFIX_3 "%s: (pbx_indicate) start indicate '%s'\n", c->designator, asterisk_indication2str(ind));
613 
614 	AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(c));
615 	if (!d || c->state == SCCP_CHANNELSTATE_DOWN) {
616 		//sccp_log((DEBUGCAT_PBX | DEBUGCAT_CHANNEL | DEBUGCAT_INDICATE)) (VERBOSE_PREFIX_3 "SCCP: (pbx_indicate) no sccp device yet\n");
617 		switch (ind) {
618 			case AST_CONTROL_CONNECTED_LINE:
619 				sccp_astwrap_connectedline(c, data, datalen);
620 				break;
621 			case AST_CONTROL_REDIRECTING:
622 				sccp_astwrap_redirectedUpdate(c, data, datalen);
623 				break;
624 			default:
625 				res = -1;	/* this indication is not supported */
626 				break;
627 		}
628 		return res;
629 	}
630 
631 	sccp_log((DEBUGCAT_PBX | DEBUGCAT_CHANNEL
632 		  | DEBUGCAT_INDICATE))(VERBOSE_PREFIX_1 "%s: (pbx_indicate) start indicate '%s' (%d) condition on channel %s (rtp_instance:%s, reception.state:%d/%s, transmission.state:%d/%s)\n", DEV_ID_LOG(d),
633 					asterisk_indication2str(ind), ind, pbx_channel_name(ast), c->rtp.audio.instance ? "yes" : "no", sccp_rtp_getState(&c->rtp.audio, SCCP_RTP_RECEPTION),
634 					codec2str(c->rtp.audio.reception.format), sccp_rtp_getState(&c->rtp.audio, SCCP_RTP_TRANSMISSION), codec2str(c->rtp.audio.transmission.format));
635 
636 	boolean_t inband_if_receivechannel = FALSE;
637 	switch (ind) {
638 		case AST_CONTROL_RINGING:
639 			if (SKINNY_CALLTYPE_OUTBOUND == c->calltype) {
640 				if (pbx_channel_state (c->owner) != AST_STATE_UP) {
641 					if (c->remoteCapabilities.audio[0] == SKINNY_CODEC_NONE) {
642 						pbx_retrieve_remote_capabilities (c);
643 					}
644 					// Allow signalling of RINGOUT only on outbound calls.
645 					// Otherwise, there are some issues with late arrival of ringing
646 					// indications on ISDN calls (chan_lcr, chan_dahdi) (-DD).
647 					iPbx.set_callstate (c, AST_STATE_RING);
648 				} else {
649 					iPbx.set_callstate (c, AST_STATE_RINGING);
650 				}
651 				sccp_indicate(d, c, SCCP_CHANNELSTATE_RINGOUT);
652 			}
653 			inband_if_receivechannel = TRUE;
654 			break;
655 
656 		case AST_CONTROL_BUSY:
657 			sccp_indicate(d, c, SCCP_CHANNELSTATE_BUSY);
658 			iPbx.set_callstate(c, AST_STATE_BUSY);
659 			inband_if_receivechannel = TRUE;
660 			break;
661 
662 		case AST_CONTROL_CONGESTION:
663 			sccp_indicate(d, c, SCCP_CHANNELSTATE_CONGESTION);
664 			inband_if_receivechannel = TRUE;
665 			break;
666 
667 		case AST_CONTROL_PROGRESS:
668 			if (c->remoteCapabilities.audio[0] == SKINNY_CODEC_NONE) {
669 				pbx_retrieve_remote_capabilities(c);
670 			}
671 			sccp_indicate(d, c, SCCP_CHANNELSTATE_PROGRESS);
672 			/*
673 			if (c->state != SCCP_CHANNELSTATE_CONNECTED && c->previousChannelState != SCCP_CHANNELSTATE_CONNECTED) {
674 				sccp_indicate(d, c, SCCP_CHANNELSTATE_PROGRESS);
675 			} else {
676 				// ORIGINATE() to SIP indicates PROGRESS after CONNECTED, causing issues with transfer
677 				sccp_indicate(d, c, SCCP_CHANNELSTATE_CONNECTED);
678 			}*/
679 			inband_if_receivechannel = TRUE;
680 			break;
681 
682 		case AST_CONTROL_PROCEEDING:
683 			sccp_indicate(d, c, SCCP_CHANNELSTATE_PROCEED);
684 			//inband_if_receivechannel = TRUE;
685 			break;
686 
687 		case AST_CONTROL_SRCCHANGE:									/* ask our channel's remote source address to update */
688 			if (c->rtp.audio.instance) {
689 				ast_rtp_instance_change_source(c->rtp.audio.instance);
690 			}
691 			break;
692 
693 		case AST_CONTROL_SRCUPDATE:									/* semd control bit to force other side to update, their source address */
694 			/* Source media has changed. */
695 			sccp_log((DEBUGCAT_PBX | DEBUGCAT_INDICATE)) (VERBOSE_PREFIX_3 "SCCP: Source UPDATE request\n");
696 
697 			if (c->rtp.audio.instance) {
698 				ast_rtp_instance_update_source(c->rtp.audio.instance);
699 			}
700 			break;
701 
702 		case AST_CONTROL_HOLD:										/* when the bridged channel hold/unhold the call we are notified here */
703 			if (c->rtp.audio.instance) {
704 				ast_rtp_instance_update_source(c->rtp.audio.instance);
705 			}
706 #ifdef CS_SCCP_VIDEO
707 			if (c->rtp.video.instance && d && sccp_device_isVideoSupported(d) && sccp_channel_getVideoMode(c) != SCCP_VIDEO_MODE_OFF) {
708 				d->protocol->sendMultiMediaCommand(d, c, SKINNY_MISCCOMMANDTYPE_VIDEOFREEZEPICTURE);
709 				if(sccp_rtp_getState(&c->rtp.video, SCCP_RTP_TRANSMISSION)) {
710 					sccp_channel_stopMultiMediaTransmission(c, TRUE);
711 				}
712 				ast_rtp_instance_update_source(c->rtp.video.instance);
713 			}
714 #endif
715 			sccp_astwrap_moh_start(ast, (const char *) data, c->musicclass);
716 			sccp_dev_set_message(d, SKINNY_DISP_CALL_ON_HOLD, SCCP_MESSAGE_PRIORITY_TIMEOUT, FALSE, FALSE);
717 			break;
718 
719 		case AST_CONTROL_UNHOLD:
720 			if (c->rtp.audio.instance) {
721 				ast_rtp_instance_update_source(c->rtp.audio.instance);
722 			}
723 #ifdef CS_SCCP_VIDEO
724 			if(c->rtp.video.instance && d && sccp_device_isVideoSupported(d) && sccp_channel_getVideoMode(c) != SCCP_VIDEO_MODE_OFF) {
725 				ast_rtp_instance_update_source(c->rtp.video.instance);
726 				if(!sccp_rtp_getState(&c->rtp.video, SCCP_RTP_RECEPTION)) {
727 					sccp_channel_openMultiMediaReceiveChannel(c);
728 				} else if((sccp_rtp_getState(&c->rtp.video, SCCP_RTP_RECEPTION) & SCCP_RTP_STATUS_ACTIVE) && !sccp_rtp_getState(&c->rtp.video, SCCP_RTP_TRANSMISSION)) {
729 					sccp_channel_startMultiMediaTransmission(c);
730 				}
731 				ast_rtp_instance_update_source(c->rtp.video.instance);
732 			}
733 #endif
734 			sccp_astwrap_moh_stop(ast);
735 			sccp_dev_clear_message(d, FALSE);
736 			break;
737 
738 		case AST_CONTROL_CONNECTED_LINE:
739 			/* remarking out this code, as it is causing issues with callforward + FREEPBX,  the calling party will not hear the remote end ringing
740 			 this patch was added to suppress 'double callwaiting tone', but channel PROD(-1) below is taking care of that already
741 			*/
742 			//if (c->calltype == SKINNY_CALLTYPE_OUTBOUND && c->rtp.audio.reception.state == SCCP_RTP_STATUS_INACTIVE && c->state > SCCP_CHANNELSTATE_DIALING) {
743 			//	sccp_channel_openReceiveChannel(c);
744 			//}
745 			sccp_astwrap_connectedline(c, data, datalen);
746 			inband_if_receivechannel = TRUE;
747 			break;
748 
749 		case AST_CONTROL_TRANSFER:
750 			ast_log(LOG_NOTICE, "%s: Ast Control Transfer: %d", c->designator, *(int *)data);
751 			//sccp_astwrap_connectedline(c, data, datalen);
752 			res = -1;
753 			break;
754 
755 		case AST_CONTROL_REDIRECTING:
756 			sccp_astwrap_redirectedUpdate(c, data, datalen);
757 			sccp_indicate(d, c, c->state);
758 			break;
759 
760 		case AST_CONTROL_VIDUPDATE:									/* Request a video frame update */
761 #ifdef CS_SCCP_VIDEO
762 			if (c->rtp.video.instance && d && sccp_device_isVideoSupported(d) && sccp_channel_getVideoMode(c) != SCCP_VIDEO_MODE_OFF) {
763 				d->protocol->sendMultiMediaCommand(d, c, SKINNY_MISCCOMMANDTYPE_VIDEOFASTUPDATEPICTURE);
764 			} else
765 #endif
766 			{
767 				res = -1;	/* this indication is not supported */
768 			}
769 			break;
770 
771 #ifdef CS_AST_CONTROL_INCOMPLETE
772 		case AST_CONTROL_INCOMPLETE:									/*!< Indication that the extension dialed is incomplete */
773 			/* \todo implement dial continuation by:
774 			 *  - display message incomplete number
775 			 *  - adding time to channel->scheduler.digittimeout
776 			 *  - rescheduling sccp_pbx_sched_dial
777 			 */
778 			inband_if_receivechannel = TRUE;
779 			res = -1;
780 			break;
781 #endif
782 
783 		case AST_CONTROL_PVT_CAUSE_CODE:
784 			{
785 				/*! \todo This would also be a good moment to update the c->requestHangup to requestQueueHangup */
786 				// int hangupcause = ast_channel_hangupcause(ast);
787 				// sccp_log((DEBUGCAT_PBX | DEBUGCAT_INDICATE)) (VERBOSE_PREFIX_3 "%s: hangup cause set: %d\n", c->designator, hangupcause);
788 				// res = -1;
789 				inband_if_receivechannel = TRUE;
790 			}
791 			break;
792 
793 		case AST_CONTROL_MASQUERADE_NOTIFY:
794 			res = -1;										// Return -1 so that asterisk core will correctly set up hangupcauses.
795 			break;
796 
797 		case -1:											// Asterisk prod the channel /* STOP_TONE */
798 			if (	c->line &&
799 				c->state > SCCP_GROUPED_CHANNELSTATE_DIALING &&
800 				c->calltype == SKINNY_CALLTYPE_OUTBOUND &&
801 				!ast_channel_hangupcause(ast)
802 			) {
803 				if(!sccp_rtp_getState(&c->rtp.audio, SCCP_RTP_RECEPTION)) {
804 					sccp_channel_openReceiveChannel(c);
805 				}
806 			}
807 			inband_if_receivechannel = TRUE;
808 			break;
809 
810 		default:
811 			sccp_log((DEBUGCAT_PBX | DEBUGCAT_INDICATE)) (VERBOSE_PREFIX_3 "%s: (pbx_indicate) Don't know how to indicate condition '%s' (%d)\n", DEV_ID_LOG(d), asterisk_indication2str(ind), ind);
812 			res = -1;	/* this indication is not supported */
813 			break;
814 	}
815 	if(inband_if_receivechannel && sccp_rtp_getState(&c->rtp.audio, SCCP_RTP_RECEPTION)) {
816 		res = -1;
817 	}
818 	sccp_log((DEBUGCAT_PBX | DEBUGCAT_INDICATE)) (VERBOSE_PREFIX_2 "%s: (pbx_indicate) finish: send indication (res:%d)\n", DEV_ID_LOG(d), res);
819 	return res;
820 }
821 
822 /*!
823  * \brief Read from an Asterisk Channel
824  * \param ast Asterisk Channel as ast_channel
825  *
826  * \called_from_asterisk
827  *
828  * \note not following the refcount rules... channel is already retained
829  */
sccp_astwrap_rtp_read(PBX_CHANNEL_TYPE * ast)830 static PBX_FRAME_TYPE *sccp_astwrap_rtp_read(PBX_CHANNEL_TYPE * ast)
831 {
832 	//AUTO_RELEASE(sccp_channel_t, c , NULL);									// not following the refcount rules... channel is already retained
833 	sccp_channel_t *c = NULL;
834 	PBX_FRAME_TYPE *frame = &ast_null_frame;
835 
836 	if (!(c = CS_AST_CHANNEL_PVT(ast))) {									// not following the refcount rules... channel is already retained
837 		pbx_log(LOG_ERROR, "SCCP: (rtp_read) no channel pvt\n");
838 		goto EXIT_FUNC;
839 	}
840 
841 	if (!c->rtp.audio.instance) {
842 		pbx_log(LOG_NOTICE, "SCCP: (rtp_read) no rtp stream yet. skip\n");
843 		goto EXIT_FUNC;
844 	}
845 
846 	switch (ast_channel_fdno(ast)) {
847 
848 		case 0:
849 			frame = ast_rtp_instance_read(c->rtp.audio.instance, 0);					/* RTP Audio */
850 			break;
851 		case 1:
852 			frame = ast_rtp_instance_read(c->rtp.audio.instance, 1);					/* RTCP Control Channel */
853 			break;
854 		case 2:
855 #ifdef CS_SCCP_VIDEO
856 			frame = ast_rtp_instance_read(c->rtp.video.instance, 0);					/* RTP Video */
857 #else
858 			pbx_log(LOG_NOTICE, "SCCP: (rtp_read) Cannot handle video rtp stream.\n");
859 #endif
860 			break;
861 		case 3:
862 #ifdef CS_SCCP_VIDEO
863 			frame = ast_rtp_instance_read(c->rtp.video.instance, 1);					/* RTCP Control Channel for video */
864 #else
865 			pbx_log(LOG_NOTICE, "SCCP: (rtp_read) Cannot handle video rtcp stream.\n");
866 #endif
867 			break;
868 		default:
869 			// pbx_log(LOG_NOTICE, "%s: (rtp_read) Unknown Frame Type (%d). Skipping\n", c->designator, ast_channel_fdno(ast));
870 			goto EXIT_FUNC;
871 	}
872 	//sccp_log((DEBUGCAT_CORE))(VERBOSE_PREFIX_3 "%s: read format: ast->fdno: %d, frametype: %d, %s(%d)\n", DEV_ID_LOG(c->device), ast_channel_fdno(ast), frame->frametype, pbx_getformatname(frame->subclass), frame->subclass);
873 	if(frame && frame != &ast_null_frame && frame->frametype == AST_FRAME_VOICE) {
874 #ifdef CS_SCCP_CONFERENCE
875 		if (c->conference && (!ast_format_cache_is_slinear(ast_channel_readformat(ast)))) {
876 			ast_set_read_format(ast, ast_format_slin96);
877 		} else
878 #endif
879 		{
880 			if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(ast), frame->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
881 				struct ast_format_cap *caps;
882 				sccp_log(DEBUGCAT_CODEC)(VERBOSE_PREFIX_3 "%s: (rtp_read) Format changed to %s\n", c->designator, ast_format_get_name(frame->subclass.format));
883 				caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
884 				if (caps) {
885 					ast_format_cap_append(caps, frame->subclass.format, 0);
886 					ast_channel_nativeformats_set(ast, caps);
887 					ao2_cleanup(caps);
888 				}
889 				ast_set_read_format(ast, ast_channel_readformat(ast));
890 				ast_set_write_format(ast, ast_channel_writeformat(ast));
891 			}
892 		}
893 	}
894 
895 	/* Only allow audio through if they sent progress, or if the channel is actually answered */
896 	/* removed causing one way audio trouble, needs more research */
897 	if(c->calltype != SKINNY_CALLTYPE_INBOUND && pbx_channel_state(ast) != AST_STATE_UP && c->wantsEarlyRTP() && c->progressSent() && (frame == &ast_null_frame || !sccp_channel_finishHolePunch(c))) {
898 		// if hole punch is not active and the channel is not active either, we transmit null packets in the meantime
899 		// Only allow audio through if they sent progress
900 		ast_frfree(frame);
901 		frame = &ast_null_frame;
902 	}
903 EXIT_FUNC:
904 	return frame;
905 }
906 
907 /*!
908  * \brief Write to an Asterisk Channel
909  * \param ast Channel as ast_channel
910  * \param frame Frame as ast_frame
911  *
912  * \called_from_asterisk
913  *
914  * \note not following the refcount rules... channel is already retained
915  */
sccp_astwrap_rtp_write(PBX_CHANNEL_TYPE * ast,PBX_FRAME_TYPE * frame)916 static int sccp_astwrap_rtp_write(PBX_CHANNEL_TYPE * ast, PBX_FRAME_TYPE * frame)
917 {
918 	//AUTO_RELEASE(sccp_channel_t, c , NULL);								// not following the refcount rules... channel is already retained
919 	sccp_channel_t *c = NULL;
920 
921 	int res = 0;
922 
923 	if (!(c = CS_AST_CHANNEL_PVT(ast))) {									// not following the refcount rules... channel is already retained
924 		return -1;
925 	}
926 
927 	switch (frame->frametype) {
928 		case AST_FRAME_VOICE:
929 			// checking for samples to transmit
930 			if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(ast), frame->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
931 				pbx_str_t *codec_buf = pbx_str_alloca(64);
932 				sccp_log(DEBUGCAT_CODEC)(VERBOSE_PREFIX_3 "%s: (rtp_write) Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
933 					c->designator,
934 					ast_format_get_name(frame->subclass.format),
935 					ast_format_cap_get_names(ast_channel_nativeformats(ast), &codec_buf),
936 					ast_channel_readformat(ast) ? ast_format_get_name(ast_channel_readformat(ast)) : "",
937 					ast_channel_writeformat(ast) ? ast_format_get_name(ast_channel_writeformat(ast)) : ""
938 				);
939 				//return -1;
940 			}
941 			if(pbx_channel_state(ast) != AST_STATE_UP && c->state > SCCP_GROUPED_CHANNELSTATE_DIALING && c->wantsEarlyRTP() && !c->progressSent()) {
942 				sccp_log(DEBUGCAT_RTP)(VERBOSE_PREFIX_3 "%s: (rtp_write) device requested earlyRtp and we received an incoming audio packet calling makeProgress\n", c->designator);
943 				c->makeProgress(c);
944 			}
945 			if (!frame->samples) {
946 				if(!strcasecmp(frame->src, "ast_prod")) {
947 					sccp_log((DEBUGCAT_PBX | DEBUGCAT_CHANNEL)) (VERBOSE_PREFIX_3 "%s: Asterisk prodded channel %s.\n", c->currentDeviceId, pbx_channel_name(ast));
948 				} else {
949 					pbx_log(LOG_NOTICE, "%s: Asked to transmit frame type %d ('%s') with no samples.\n", c->currentDeviceId, (int)frame->frametype, frame->src);
950 				}
951 				break;
952 			}
953 			if(c->rtp.audio.instance && (sccp_rtp_getState(&c->rtp.audio, SCCP_RTP_RECEPTION) & SCCP_RTP_STATUS_ACTIVE) != 0) {
954 				res = ast_rtp_instance_write(c->rtp.audio.instance, frame);
955 			}
956 			break;
957 		case AST_FRAME_IMAGE:
958 		case AST_FRAME_VIDEO:
959 #ifdef CS_SCCP_VIDEO
960 			if(sccp_channel_getVideoMode(c) != SCCP_VIDEO_MODE_OFF && c->state != SCCP_CHANNELSTATE_HOLD) {
961 				if(ast_format_cmp(ast_format_h264, frame->subclass.format) != AST_FORMAT_CMP_EQUAL) {
962 					sccp_channel_closeMultiMediaReceiveChannel(c, TRUE);
963 					sccp_channel_stopMultiMediaTransmission(c, TRUE);
964 					sccp_channel_setVideoMode(c, "off");
965 					return -1;
966 				}
967 				sccp_rtp_status_t receptionstate = sccp_rtp_getState(&c->rtp.video, SCCP_RTP_RECEPTION);
968 				if(pbx_channel_state(ast) != AST_STATE_UP && c->state > SCCP_GROUPED_CHANNELSTATE_DIALING) {
969 					if(c->wantsEarlyRTP() && !c->progressSent()) {
970 						sccp_log(DEBUGCAT_RTP)(VERBOSE_PREFIX_3 "%s: (rtp_write) device requested earlyRtp and we received an incoming video packet calling makeProgress\n", c->designator);
971 						c->makeProgress(c);
972 					}
973 				} else if(!receptionstate) {
974 					sccp_log((DEBUGCAT_RTP))(VERBOSE_PREFIX_3 "%s: got first video frame %s\n", c->currentDeviceId, "H264");
975 					sccp_channel_openMultiMediaReceiveChannel(c);
976 				}
977 				if(receptionstate & SCCP_RTP_STATUS_ACTIVE) {
978 					res = ast_rtp_instance_write(c->rtp.video.instance, frame);
979 				}
980 			}
981 #endif
982 			break;
983 		case AST_FRAME_TEXT:
984 		case AST_FRAME_MODEM:
985 		default:
986 			pbx_log(LOG_WARNING, "%s: Can't send %d type frames with SCCP write on channel %s\n", c->currentDeviceId, frame->frametype, pbx_channel_name(ast));
987 			break;
988 	}
989 
990 	return res;
991 }
992 
sccp_astwrap_setDialedNumber(const sccp_channel_t * channel,const char * number)993 static void sccp_astwrap_setDialedNumber(const sccp_channel_t *channel, const char *number)
994 {
995 	PBX_CHANNEL_TYPE *pbx_channel = channel->owner;
996 	if (pbx_channel && number) {
997 		struct ast_party_dialed dialed;
998 		ast_party_dialed_init(&dialed);
999 		dialed.number.str = pbx_strdupa(number);
1000 		ast_trim_blanks(dialed.number.str);
1001 		ast_party_dialed_set(ast_channel_dialed(pbx_channel), &dialed);
1002 	}
1003 }
1004 
sccp_astwrap_setCalleridPresentation(PBX_CHANNEL_TYPE * pbx_channel,sccp_callerid_presentation_t presentation)1005 static void sccp_astwrap_setCalleridPresentation(PBX_CHANNEL_TYPE *pbx_channel, sccp_callerid_presentation_t presentation)
1006 {
1007 	if (pbx_channel && CALLERID_PRESENTATION_FORBIDDEN == presentation) {
1008 		ast_channel_caller(pbx_channel)->id.name.presentation |= AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
1009 		ast_channel_caller(pbx_channel)->id.number.presentation |= AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
1010 	}
1011 }
1012 
sccp_astwrap_setNativeAudioFormats(constChannelPtr channel,skinny_codec_t codecs[])1013 static int sccp_astwrap_setNativeAudioFormats(constChannelPtr channel, skinny_codec_t codecs[])
1014 {
1015 	if (!channel || !channel->owner || !ast_channel_nativeformats(channel->owner)) {
1016 		pbx_log(LOG_ERROR, "SCCP: (setNativeAudioFormats) no channel provided!\n");
1017 		return 0;
1018 	}
1019 	PBX_CHANNEL_TYPE *ast = channel->owner;
1020 
1021 	struct ast_format_cap *caps = ao2_t_bump((struct ast_format_cap *)channel->caps, "sccp_channel_caps");
1022 	if (!caps) {
1023         	return 0;
1024 	}
1025 	ast_format_cap_append_from_cap(caps, ast_channel_nativeformats(ast), AST_MEDIA_TYPE_UNKNOWN);
1026 	ast_format_cap_remove_by_type(caps, AST_MEDIA_TYPE_AUDIO);
1027 	pbx_format_cap_append_skinny(caps, codecs);
1028 
1029 	ast_channel_lock(ast);
1030 	ast_channel_nativeformats_set(ast, caps);
1031 	ast_channel_unlock(ast);
1032 	ao2_t_ref(caps, -1, "sccp_channel_caps");
1033 
1034 	pbx_str_t *codec_buf = pbx_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1035 	sccp_log((DEBUGCAT_RTP | DEBUGCAT_CODEC)) (VERBOSE_PREFIX_3 "%s: (setNativeAudioFormats) %s\n", channel->designator, ast_format_cap_get_names(ast_channel_nativeformats(ast), &codec_buf));
1036 
1037 	return 1;
1038 }
1039 
sccp_astwrap_setNativeVideoFormats(constChannelPtr channel,skinny_codec_t codecs[])1040 static int sccp_astwrap_setNativeVideoFormats(constChannelPtr channel, skinny_codec_t codecs[])
1041 {
1042 	if (!channel || !channel->owner || !ast_channel_nativeformats(channel->owner)) {
1043 		pbx_log(LOG_ERROR, "SCCP: (setNativeVideoFormats) no channel provided!\n");
1044 		return 0;
1045 	}
1046 	PBX_CHANNEL_TYPE *ast = channel->owner;
1047 
1048 	struct ast_format_cap *caps = ao2_t_bump((struct ast_format_cap *)channel->caps, "sccp_channel_caps");
1049 	if (!caps) {
1050         	return 0;
1051 	}
1052 	ast_format_cap_append_from_cap(caps, ast_channel_nativeformats(ast), AST_MEDIA_TYPE_UNKNOWN);
1053 	ast_format_cap_remove_by_type(caps, AST_MEDIA_TYPE_VIDEO);
1054 	pbx_format_cap_append_skinny(caps, codecs);
1055 
1056 	ast_channel_lock(ast);
1057 	ast_channel_nativeformats_set(ast, caps);
1058 	ast_channel_unlock(ast);
1059 	ao2_t_ref(caps, -1, "sccp_channel_caps");
1060 
1061 	pbx_str_t *codec_buf = pbx_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1062 	sccp_log((DEBUGCAT_RTP | DEBUGCAT_CODEC)) (VERBOSE_PREFIX_3 "%s: (setNativeVideoFormats) %s\n", channel->designator, ast_format_cap_get_names(ast_channel_nativeformats(ast), &codec_buf));
1063 
1064 	return 1;
1065 }
1066 
sccp_astwrap_setWriteFormat(constChannelPtr channel,skinny_codec_t codec)1067 static boolean_t sccp_astwrap_setWriteFormat(constChannelPtr channel, skinny_codec_t codec)
1068 {
1069 	if (!channel) {
1070 		return FALSE;
1071 	}
1072 	sccp_log((DEBUGCAT_RTP | DEBUGCAT_CODEC)) (VERBOSE_PREFIX_3 "%s: (setWriteFormat) %s)\n", channel->designator, codec2str(codec));
1073 
1074 	struct ast_format *ast_format = sccp_astwrap_skinny2ast_format(codec);
1075 	if (ast_format == ast_format_none)
1076 		return FALSE;
1077 
1078 	if (channel->rtp.audio.instance) {
1079 		ast_channel_set_rawwriteformat(channel->owner, ast_format);
1080 		ast_rtp_instance_set_write_format(channel->rtp.audio.instance, ast_format);
1081 	}
1082 	ast_channel_set_writeformat(channel->owner, ast_format);
1083 	return TRUE;
1084 }
1085 
sccp_astwrap_setReadFormat(constChannelPtr channel,skinny_codec_t codec)1086 static boolean_t sccp_astwrap_setReadFormat(constChannelPtr channel, skinny_codec_t codec)
1087 {
1088 	if (!channel) {
1089 		return FALSE;
1090 	}
1091 
1092 	sccp_log((DEBUGCAT_RTP | DEBUGCAT_CODEC)) (VERBOSE_PREFIX_3 "%s: (setReadFormat) %s)\n", channel->designator, codec2str(codec));
1093 
1094 	struct ast_format *ast_format = sccp_astwrap_skinny2ast_format(codec);
1095 	if (ast_format == ast_format_none)
1096 		return FALSE;
1097 
1098 	if (channel->rtp.audio.instance) {
1099 		ast_channel_set_rawreadformat(channel->owner, ast_format);
1100 		ast_rtp_instance_set_read_format(channel->rtp.audio.instance, ast_format);
1101 	}
1102 	ast_channel_set_readformat(channel->owner, ast_format);
1103 	return TRUE;
1104 }
1105 
sccp_astwrap_removeTimingFD(PBX_CHANNEL_TYPE * ast)1106 static void sccp_astwrap_removeTimingFD(PBX_CHANNEL_TYPE *ast)
1107 {
1108 	if (ast) {
1109 		struct ast_timer *timer=ast_channel_timer(ast);
1110 		if (timer) {
1111 			//ast_log(LOG_NOTICE, "%s: (clean_timer_fds) timername: %s, fd:%d\n", ast_channel_name(ast), ast_timer_get_name(timer), ast_timer_fd(timer));
1112 			ast_timer_disable_continuous(timer);
1113 			ast_timer_close(timer);
1114 			ast_channel_set_fd(ast, AST_TIMING_FD, -1);
1115 			ast_channel_timingfd_set(ast, -1);
1116 			ast_channel_timer_set(ast, NULL);
1117 		}
1118 	}
1119 }
1120 
sccp_astwrap_setOwner(sccp_channel_t * channel,PBX_CHANNEL_TYPE * pbx_channel)1121 static void sccp_astwrap_setOwner(sccp_channel_t * channel, PBX_CHANNEL_TYPE * pbx_channel)
1122 {
1123 	PBX_CHANNEL_TYPE *prev_owner = channel->owner;
1124 
1125 	if (pbx_channel) {
1126 		channel->owner = pbx_channel_ref(pbx_channel);
1127 		ast_module_ref(ast_module_info->self);
1128 	} else {
1129 		channel->owner = NULL;
1130 	}
1131 	if (prev_owner) {
1132 		pbx_channel_unref(prev_owner);
1133 		ast_module_unref(ast_module_info->self);
1134 	}
1135 	if (channel->rtp.audio.instance) {
1136 		ast_rtp_instance_set_channel_id(channel->rtp.audio.instance, pbx_channel ? ast_channel_uniqueid(pbx_channel) : "");
1137 	}
1138 	if (channel->rtp.video.instance) {
1139 		ast_rtp_instance_set_channel_id(channel->rtp.video.instance, pbx_channel ? ast_channel_uniqueid(pbx_channel) : "");
1140 	}
1141 }
1142 
__sccp_astwrap_updateConnectedLine(PBX_CHANNEL_TYPE * pbx_channel,const char * number,const char * name,uint8_t reason)1143 static void __sccp_astwrap_updateConnectedLine(PBX_CHANNEL_TYPE *pbx_channel, const char *number, const char *name, uint8_t reason)
1144 {
1145 	if (!pbx_channel) {
1146 		return;
1147 	}
1148 
1149 	struct ast_party_connected_line connected;
1150 	struct ast_set_party_connected_line update_connected = {{0}};
1151 
1152 	ast_party_connected_line_init(&connected);
1153 	if (number) {
1154 		update_connected.id.number = 1;
1155 		connected.id.number.valid = 1;
1156 		connected.id.number.str = pbx_strdupa(number);
1157 		connected.id.number.presentation = AST_PRES_ALLOWED_NETWORK_NUMBER;
1158 	}
1159 	if (name) {
1160 		update_connected.id.name = 1;
1161 		connected.id.name.valid = 1;
1162 		connected.id.name.str = pbx_strdupa(name);
1163 		connected.id.name.presentation = AST_PRES_ALLOWED_NETWORK_NUMBER;
1164 	}
1165 	if (update_connected.id.number || update_connected.id.name) {
1166 		ast_set_party_id_all(&update_connected.priv);
1167 		// connected.id.tag = NULL;
1168 		connected.source = reason;
1169 		ast_channel_queue_connected_line_update(pbx_channel, &connected, &update_connected);
1170 		sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_3 "SCCP: do connected line for line '%s', name: %s ,num: %s\n", pbx_channel_name(pbx_channel), name ? name : "(NULL)", number ? number : "(NULL)");
1171 	}
1172 }
1173 
sccp_astwrap_allocPBXChannel(sccp_channel_t * channel,const void * ids,const PBX_CHANNEL_TYPE * pbxSrcChannel,PBX_CHANNEL_TYPE ** _pbxDstChannel)1174 static boolean_t sccp_astwrap_allocPBXChannel(sccp_channel_t * channel, const void *ids, const PBX_CHANNEL_TYPE * pbxSrcChannel, PBX_CHANNEL_TYPE ** _pbxDstChannel)
1175 {
1176 	const struct ast_assigned_ids *assignedids = NULL;
1177 	PBX_CHANNEL_TYPE *pbxDstChannel = NULL;
1178 	if (!channel || !channel->line) {
1179 		return FALSE;
1180 	}
1181 	AUTO_RELEASE(sccp_line_t, line , sccp_line_retain(channel->line));
1182 	if (!line) {
1183 		return FALSE;
1184 	}
1185 
1186 	channel->caps = ast_t_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT, "sccp_channel_caps");			/* cleanup in channel destructor */
1187 	if (!channel->caps) {
1188 		ao2_cleanup(channel->caps);
1189 		return FALSE;
1190 	}
1191 	struct ast_format_cap *caps = ao2_t_bump(channel->caps, "sccp_channel_caps");
1192 
1193 	if (ids) {
1194 		assignedids = (const struct ast_assigned_ids *)ids;
1195 	}
1196 
1197 	sccp_log(DEBUGCAT_CHANNEL)(VERBOSE_PREFIX_3 "SCCP: (allocPBXChannel) Create New Channel with name: SCCP/%s-%08X\n", line->name, channel->callid);
1198 	pbxDstChannel = ast_channel_alloc(0, AST_STATE_DOWN, line->cid_num, line->cid_name, line->accountcode, line->name, line->context, assignedids, pbxSrcChannel, line->amaflags, "%s", channel->designator);
1199 	if (pbxDstChannel == NULL) {
1200 		pbx_log(LOG_ERROR, "SCCP: (allocPBXChannel) ast_channel_alloc failed\n");
1201 		ao2_cleanup(caps);
1202 		return FALSE;
1203 	}
1204 
1205 	ast_channel_stage_snapshot(pbxDstChannel);
1206 	if (channel->callid) {
1207 		pbx_channel_callid_set(pbxDstChannel, channel->pbx_callid);
1208 	}
1209 
1210 	ast_channel_tech_set(pbxDstChannel, &sccp_tech);
1211 	ast_channel_tech_pvt_set(pbxDstChannel, sccp_channel_retain(channel));
1212 
1213 	pbx_str_t *codec_buf = pbx_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1214 	//pbx_log(LOG_NOTICE, "allocPBXChannel: tmp->nativeformats=%s\n", ast_format_cap_get_names(ast_channel_nativeformats(pbxDstChannel), &codec_buf));
1215 
1216 	pbx_format_cap_append_skinny(caps, channel->preferences.audio);
1217 #ifdef CS_SCCP_VIDEO
1218 	pbx_format_cap_append_skinny(caps, channel->preferences.video);
1219 #endif
1220 	struct ast_format_cap *joint = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
1221 	if (!joint) {
1222 		ao2_cleanup(pbxDstChannel);
1223 		ao2_cleanup(caps);
1224 		return FALSE;
1225 	}
1226 	struct ast_format_cap *what = NULL;
1227 	if (pbxSrcChannel && ast_format_cap_count(ast_channel_nativeformats(pbxSrcChannel)) > 0) {
1228 		sccp_log(DEBUGCAT_CODEC)(VERBOSE_PREFIX_3 "allocPBXChannel: new->nativeformats=%s based on audio preferences\n", ast_format_cap_get_names(caps, &codec_buf));
1229 
1230 		ast_format_cap_get_compatible(caps, ast_channel_nativeformats(pbxSrcChannel /*requestor*/), joint);
1231 		sccp_log(DEBUGCAT_CODEC)(VERBOSE_PREFIX_3  "allocPBXChannel: requestor->nativeformats=%s\n", ast_format_cap_get_names( ast_channel_nativeformats(pbxSrcChannel /*requestor*/), &codec_buf));
1232 		sccp_log(DEBUGCAT_CODEC)(VERBOSE_PREFIX_3 "allocPBXChannel: joint formats=%s\n", ast_format_cap_get_names(joint, &codec_buf));
1233 	}
1234 	if (ast_format_cap_count(joint) > 0) {
1235 		what = joint;
1236 	} else if (ast_format_cap_count(caps)) {
1237 		what = caps;
1238 	} else {
1239 		what = (&sccp_tech)->capabilities;
1240 	}
1241 	ast_format_cap_append_from_cap(caps, what, AST_MEDIA_TYPE_UNKNOWN);
1242 
1243 	struct ast_format *fmt = ast_format_cap_get_best_by_type(what, AST_MEDIA_TYPE_AUDIO); /* get the best audio format */
1244 	if (fmt) {
1245 		ast_format_cap_remove_by_type(caps, AST_MEDIA_TYPE_AUDIO); /* remove only the other audio formats */
1246 		ast_format_cap_append(caps, fmt, 0); /* add our best choice back */
1247 	} else {
1248 		/* If we don't have an audio format, try to get something */
1249 		fmt = ast_format_cap_get_format(caps, 0);
1250 		if (!fmt) {
1251 			ast_log(LOG_WARNING, "No compatible formats could be found for %s\n", ast_channel_name(pbxDstChannel));
1252 			ao2_cleanup(caps);
1253 			ast_channel_stage_snapshot_done(pbxDstChannel);
1254 			ast_hangup(pbxDstChannel);
1255 			return FALSE;
1256 		}
1257 	}
1258 	ast_channel_nativeformats_set(pbxDstChannel, caps);
1259 	ao2_cleanup(joint);
1260 	ao2_t_ref(caps, -1, "sccp_channel_caps");	/* see:bump */
1261 
1262 	sccp_log(DEBUGCAT_CODEC)(VERBOSE_PREFIX_3 "allocPBXChannel: using nativeformats=%s fmt=%s\n", ast_format_cap_get_names(ast_channel_nativeformats(pbxDstChannel), &codec_buf), ast_format_get_name(fmt));
1263 
1264 	ast_channel_set_writeformat(pbxDstChannel, fmt);
1265 	ast_channel_set_rawwriteformat(pbxDstChannel, fmt);
1266 	ast_channel_set_readformat(pbxDstChannel, fmt);
1267 	ast_channel_set_rawreadformat(pbxDstChannel, fmt);
1268 	ao2_ref(fmt, -1);
1269 	/* EndCodec */
1270 
1271 	sccp_astwrap_setOwner(channel, pbxDstChannel);
1272 
1273 	ast_channel_context_set(pbxDstChannel, line->context);
1274 	ast_channel_exten_set(pbxDstChannel, line->name);
1275 	ast_channel_priority_set(pbxDstChannel, 1);
1276 	ast_channel_adsicpe_set(pbxDstChannel, AST_ADSI_UNAVAILABLE);
1277 
1278 	if (!sccp_strlen_zero(line->language)) {
1279 		ast_channel_language_set(pbxDstChannel, line->language);
1280 	}
1281 
1282 	if (!sccp_strlen_zero(line->accountcode)) {
1283 		ast_channel_accountcode_set(pbxDstChannel, line->accountcode);
1284 	}
1285 
1286 	if (!sccp_strlen_zero(line->musicclass)) {
1287 		ast_channel_musicclass_set(pbxDstChannel, line->musicclass);
1288 	}
1289 
1290 	if (line->amaflags) {
1291 		ast_channel_amaflags_set(pbxDstChannel, line->amaflags);
1292 	}
1293 	if (line->callgroup) {
1294 		ast_channel_callgroup_set(pbxDstChannel, line->callgroup);
1295 	}
1296 
1297 	ast_channel_callgroup_set(pbxDstChannel, line->callgroup);						// needed for ast_pickup_call
1298 #if CS_SCCP_PICKUP
1299 	if (line->pickupgroup) {
1300 		ast_channel_pickupgroup_set(pbxDstChannel, line->pickupgroup);
1301 	}
1302 #if CS_AST_HAS_NAMEDGROUP
1303 	if (!sccp_strlen_zero(line->namedcallgroup)) {
1304 		ast_channel_named_callgroups_set(pbxDstChannel, ast_get_namedgroups(line->namedcallgroup));
1305 	}
1306 
1307 	if (!sccp_strlen_zero(line->namedpickupgroup)) {
1308 		ast_channel_named_pickupgroups_set(pbxDstChannel, ast_get_namedgroups(line->namedpickupgroup));
1309 	}
1310 #	endif
1311 #endif
1312 	if (!sccp_strlen_zero(line->parkinglot)) {
1313 		ast_channel_parkinglot_set(pbxDstChannel, line->parkinglot);
1314 	}
1315 
1316 	/** the the tonezone using language information */
1317 	if (!sccp_strlen_zero(line->language) && ast_get_indication_zone(line->language)) {
1318 		ast_channel_zone_set(pbxDstChannel, ast_get_indication_zone(line->language));			/* this will core asterisk on hangup */
1319 	}
1320 
1321 	ast_channel_stage_snapshot_done(pbxDstChannel);
1322 	ast_channel_unlock(pbxDstChannel);
1323 
1324 	(*_pbxDstChannel) = pbxDstChannel;
1325 
1326 	return TRUE;
1327 }
1328 
1329 /*!
1330  * \brief Uses ast_channel_move instead of the old masquerade procedure to force a channel into a bridge and hangup the peer channel
1331  */
sccp_astwrap_masqueradeHelper(PBX_CHANNEL_TYPE * pbxChannel,PBX_CHANNEL_TYPE * pbxTmpChannel)1332 static boolean_t sccp_astwrap_masqueradeHelper(PBX_CHANNEL_TYPE * pbxChannel, PBX_CHANNEL_TYPE * pbxTmpChannel)
1333 {
1334 	boolean_t res = FALSE;
1335 	pbx_log(LOG_NOTICE, "SCCP: (masqueradeHelper) answer temp: %s\n", ast_channel_name(pbxTmpChannel));
1336 
1337 	ast_channel_ref(pbxChannel);
1338 	if(ast_answer(pbxChannel) == 0) {
1339 		pbx_log(LOG_NOTICE, "SCCP: (masqueradeHelper) replace pbxTmpChannel: %s with %s (move)\n", ast_channel_name(pbxTmpChannel), ast_channel_name(pbxChannel));
1340 		if(ast_channel_move(pbxTmpChannel, pbxChannel)) {
1341 			pbx_log(LOG_ERROR, "SCCP: (masqueradeHelper) move failed. Hanging up tmp channel: %s\n", ast_channel_name(pbxTmpChannel));
1342 			ast_hangup(pbxTmpChannel);
1343 		} else {
1344 			pbx_log(LOG_NOTICE, "SCCP: (masqueradeHelper) move succeeded. Hanging up orphan: %s\n", ast_channel_name(pbxChannel));
1345 			ast_hangup(pbxChannel);
1346 			pbx_channel_set_hangupcause(pbxTmpChannel, AST_CAUSE_REDIRECTED_TO_NEW_DESTINATION);
1347 			res = TRUE;
1348 		}
1349 		pbx_channel_unref(pbxTmpChannel);
1350 	}
1351 	pbx_channel_unref(pbxChannel);
1352 	return res;
1353 }
1354 
sccp_astwrap_allocTempPBXChannel(PBX_CHANNEL_TYPE * pbxSrcChannel,PBX_CHANNEL_TYPE ** _pbxDstChannel)1355 static boolean_t sccp_astwrap_allocTempPBXChannel(PBX_CHANNEL_TYPE * pbxSrcChannel, PBX_CHANNEL_TYPE ** _pbxDstChannel)
1356 {
1357 	PBX_CHANNEL_TYPE *pbxDstChannel = NULL;
1358 	struct ast_assigned_ids assignedids = {NULL, NULL};
1359 
1360 	if (!pbxSrcChannel) {
1361 		pbx_log(LOG_ERROR, "SCCP: (allocTempPBXChannel) no pbx channel provided\n");
1362 		return FALSE;
1363 	}
1364 	struct ast_format_cap *caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
1365 	if (!caps) {
1366 		return FALSE;
1367 	}
1368 
1369 /*
1370 	assignedids.uniqueid = ast_channel_uniqueid(pbxSrcChannel);
1371 	{
1372 		char *uniqueid2;
1373 		uniqueid2 = ast_alloca(strlen(assignedids.uniqueid) + 3);
1374 		strcpy(uniqueid2, assignedids.uniqueid);
1375 		strcat(uniqueid2, ";2");
1376 		assignedids.uniqueid2 = uniqueid2;
1377 	}
1378 */
1379 
1380 	ast_channel_lock(pbxSrcChannel);
1381 	pbxDstChannel = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, ast_channel_accountcode(pbxSrcChannel), pbx_channel_exten(pbxSrcChannel), pbx_channel_context(pbxSrcChannel), &assignedids, pbxSrcChannel, ast_channel_amaflags(pbxSrcChannel), "%s-TMP", ast_channel_name(pbxSrcChannel));
1382 	if (pbxDstChannel == NULL) {
1383 		pbx_log(LOG_ERROR, "SCCP: (allocTempPBXChannel) ast_channel_alloc failed\n");
1384 		ao2_cleanup(caps);
1385 		return FALSE;
1386 	}
1387 
1388 	ast_channel_stage_snapshot(pbxDstChannel);
1389 	//sccp_astwrap_setOwner(channel, pbxDstChannel);
1390 
1391 	ast_channel_tech_set(pbxDstChannel, &null_tech);							// USE null_tech to prevent fixup issues. Channel is only used to masquerade a channel out of a running bridge.
1392 	//ast_channel_tech_pvt_set(pbxDstChannel, sccp_channel_retain(channel));
1393 
1394 	// if (ast_format_cap_is_empty(pbx_channel_nativeformats(pbxSrcChannel))) {
1395 	if (ast_format_cap_count(ast_channel_nativeformats(pbxSrcChannel)) > 0) {
1396 		ast_format_cap_append_from_cap(caps, ast_channel_nativeformats(pbxSrcChannel), AST_MEDIA_TYPE_UNKNOWN);
1397 	} else {
1398 		struct ast_format *ast_format = ast_format_slin16;
1399 		unsigned int framing = ast_format_get_default_ms(ast_format);
1400 		ast_format_cap_append(caps, ast_format, framing);
1401 	}
1402 	ast_channel_nativeformats_set(pbxDstChannel, caps);
1403 	struct ast_format *tmpfmt = ast_format_cap_get_format(caps, 0);
1404 	ast_channel_set_writeformat(pbxDstChannel, tmpfmt);
1405 	ast_channel_set_rawwriteformat(pbxDstChannel, tmpfmt);
1406 	ast_channel_set_readformat(pbxDstChannel, tmpfmt);
1407 	ast_channel_set_rawreadformat(pbxDstChannel, tmpfmt);
1408 
1409 	//pbx_str_t *codec_buf = pbx_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1410 	//pbx_log(LOG_NOTICE, "allocPBXChannel: tmp->nativeformats=%s fmt=%s\n", ast_format_cap_get_names(ast_channel_nativeformats(pbxDstChannel), &codec_buf), ast_format_get_name(tmpfmt));
1411 
1412 	ao2_ref(tmpfmt, -1);
1413 	ao2_ref(caps, -1);
1414 	//ao2_cleanup(caps);
1415 	/* EndCodec */
1416 
1417 	ast_channel_context_set(pbxDstChannel, ast_channel_context(pbxSrcChannel));
1418 	ast_channel_exten_set(pbxDstChannel, ast_channel_exten(pbxSrcChannel));
1419 	ast_channel_priority_set(pbxDstChannel, ast_channel_priority(pbxSrcChannel));
1420 	ast_channel_adsicpe_set(pbxDstChannel, AST_ADSI_UNAVAILABLE);
1421 	ast_channel_stage_snapshot_done(pbxDstChannel);
1422 	ast_channel_unlock(pbxSrcChannel);
1423 	ast_channel_unlock(pbxDstChannel);
1424 
1425 	(*_pbxDstChannel) = pbxDstChannel;
1426 	//pbx_channel_ref(pbxDstChannel);
1427 
1428 	return TRUE;
1429 }
1430 
sccp_astwrap_requestAnnouncementChannel(pbx_format_type format_type,const PBX_CHANNEL_TYPE * requestor,void * data)1431 static PBX_CHANNEL_TYPE *sccp_astwrap_requestAnnouncementChannel(pbx_format_type format_type, const PBX_CHANNEL_TYPE * requestor, void *data)
1432 {
1433 	PBX_CHANNEL_TYPE *chan;
1434 	int cause;
1435 	struct ast_format_cap *cap;
1436 	struct ast_format *ast_format;
1437 	unsigned int framing;
1438 
1439 	cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
1440 	if (!cap) {
1441 		return NULL;
1442 	}
1443 	// TODO(dkgroot): convert format_type to ast_format
1444 	ast_format = ast_format_alaw;
1445 	framing = ast_format_get_default_ms(ast_format);
1446 
1447 	ast_format_cap_append(cap, ast_format, framing);
1448 	chan = ast_request("SCCPCBAnn", cap, NULL, NULL, (char *) data, &cause);
1449 	ao2_ref(cap, -1);
1450 
1451 	if (!chan) {
1452 		pbx_log(LOG_ERROR, "SCCP: Requested Unreal channel could not be created, cause: %d\n", cause);
1453 	 	return NULL;
1454 	}
1455 	/* To make sure playback_chan has the same language of that profile */
1456 	if (requestor) {
1457 		ast_channel_lock(chan);
1458 		ast_channel_language_set(chan, ast_channel_language(requestor));
1459 		ast_channel_unlock(chan);
1460 	}
1461 
1462 	ast_debug(1, "Created Unreal channel '%s' related to '%s'\n", ast_channel_name(chan), (char *) data);
1463 	return chan;
1464 }
1465 
1466 
sccp_astwrap_hangup(PBX_CHANNEL_TYPE * ast_channel)1467 int sccp_astwrap_hangup(PBX_CHANNEL_TYPE * ast_channel)
1468 {
1469 	// ast_channel_stage_snapshot(ast_channel);
1470 	AUTO_RELEASE(sccp_channel_t, c , get_sccp_channel_from_pbx_channel(ast_channel));
1471 	int res = -1;
1472 
1473 	if (c) {
1474 		sccp_mutex_lock(&c->lock);
1475 		if (pbx_channel_hangupcause(ast_channel) == AST_CAUSE_ANSWERED_ELSEWHERE) {
1476 			sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "SCCP: This call was answered elsewhere\n");
1477 			c->answered_elsewhere = TRUE;
1478 		}
1479 		/* postponing pbx_channel_unref to sccp_channel destructor */
1480 		AUTO_RELEASE(sccp_channel_t, channel , sccp_pbx_hangup(c));					/* explicit release from unretained channel returned by sccp_pbx_hangup */
1481 		(void) channel;											// suppress unused variable warning
1482 		sccp_mutex_unlock(&c->lock);
1483 		ast_channel_tech_pvt_set(ast_channel, NULL);
1484 	} else {												// after this moment c might have gone already
1485 		ast_channel_tech_pvt_set(ast_channel, NULL);
1486 		pbx_channel_unref(ast_channel);									// strange unknown channel, why did we get called to hang it up ?
1487 	}
1488 	return res;
1489 }
1490 
parking_event_cb(void * data,struct stasis_subscription * sub,struct stasis_message * message)1491 static void parking_event_cb (void * data, struct stasis_subscription * sub, struct stasis_message * message)
1492 {
1493 	struct ast_parked_call_payload * parked_payload = stasis_message_data (message);
1494 	AUTO_RELEASE (sccp_channel_t, parker, sccp_channel_retain ((sccp_channel_t *)data));
1495 	if (!parker) {
1496 		pbx_log (LOG_ERROR, "No Parker provided\n");
1497 		return;
1498 	}
1499 
1500 	RAII (struct ast_channel *, parker_chan, ast_channel_ref (parker->owner), ao2_cleanup);
1501 	if (!parker_chan) {
1502 		pbx_log (LOG_ERROR, "%s: No Park Owner set\n", parker->designator);
1503 		return;
1504 	}
1505 
1506 	if (stasis_subscription_final_message (sub, message)) {
1507 		// pbx_log(LOG_NOTICE, "%s: (parking_event_cb) Final Message", parker->designator);
1508 		return;
1509 	}
1510 
1511 	switch (parked_payload->event_type) {
1512 		case PARKED_CALL: {
1513 			sccp_log (DEBUGCAT_CHANNEL) (VERBOSE_PREFIX_3 "%s Parked call to parkingspace:%d@%s\n", ast_channel_name (parker_chan), parked_payload->parkingspace, parked_payload->parkinglot);
1514 			char parkingspace[16];
1515 			snprintf (parkingspace, sizeof (parkingspace), "%d", parked_payload->parkingspace);
1516 			AUTO_RELEASE (sccp_device_t, d, sccp_channel_getDevice (parker));
1517 			if (d) {
1518 				char extstr[20] = "";
1519 				snprintf (extstr, sizeof (extstr), "%c%c %s", 128, SKINNY_LBL_CALL_PARK_AT, parkingspace);
1520 				sccp_dev_displayprinotify (d, extstr, SCCP_MESSAGE_PRIORITY_TIMEOUT, 20);
1521 			}
1522 			RAII (struct ast_bridge *, bridge, ast_channel_get_bridge (parker_chan), ao2_cleanup);
1523 			if (bridge) {
1524 				ast_bridge_suspend (bridge, parker_chan);
1525 				ast_channel_lock (parker_chan);
1526 				ast_channel_ref (parker_chan);
1527 				ast_channel_unlock (parker_chan);
1528 				ast_say_digit_str (parker_chan, parkingspace, "", ast_channel_language (parker_chan));
1529 				ast_bridge_unsuspend (bridge, parker_chan);
1530 				ast_channel_unref (parker_chan);
1531 			} else {
1532 				parker->setTone (parker, SKINNY_TONE_CONFIRMATIONTONE, SKINNY_TONEDIRECTION_USER);
1533 			}
1534 			sccp_astgenwrap_requestHangup (parker);
1535 		} break;
1536 		case PARKED_CALL_FAILED: {
1537 			pbx_log (LOG_ERROR, "%s Parked failed\n", ast_channel_name (parker_chan));
1538 			AUTO_RELEASE (sccp_device_t, d, sccp_channel_getDevice (parker));
1539 			if (d) {
1540 				sccp_dev_displayprinotify (d, SKINNY_DISP_TEMP_FAIL, SCCP_MESSAGE_PRIORITY_TIMEOUT, GLOB (digittimeout));
1541 			}
1542 			parker->setTone (parker, SKINNY_TONE_REORDERTONE, SKINNY_TONEDIRECTION_USER);
1543 			sccp_astgenwrap_requestHangup (parker);
1544 		} break;
1545 		default:
1546 			break;
1547 	}
1548 }
1549 
parking_subscriptionCleanup(void * data)1550 static void * parking_subscriptionCleanup (void * data)
1551 {
1552 	AUTO_RELEASE (sccp_channel_t, hostChannel, (sccp_channel_t *)data);
1553 	if (hostChannel && hostChannel->parking_sub) {
1554 		hostChannel->parking_sub = stasis_unsubscribe_and_join (hostChannel->parking_sub);
1555 	}
1556 	return NULL;
1557 }
1558 
1559 /*!
1560  * \brief Parking Thread Arguments Structure
1561  */
1562 
1563 /*!
1564  * \brief Park the bridge channel of hostChannel
1565  * This function prepares the host and the bridged channel to be ready for parking.
1566  * It clones the pbx channel of both sides forward them to the park_thread
1567  *
1568  * \param hostChannel initial channel that request the parking
1569  * \todo we have a codec issue after unpark a call
1570  * \todo copy connected line info
1571  *
1572  */
sccp_astwrap_park(constChannelPtr hostChannel)1573 static sccp_parkresult_t sccp_astwrap_park(constChannelPtr hostChannel)
1574 {
1575 	sccp_parkresult_t res = PARK_RESULT_FAIL;
1576 	RAII (struct ast_channel *, parker_chan, ast_channel_ref (hostChannel->owner), ast_channel_cleanup);
1577 	RAII(struct ast_bridge_channel *, bridge_channel, NULL, ao2_cleanup);
1578 
1579 	if (!ast_parking_provider_registered()) {
1580 		return res;
1581 	}
1582 
1583 	do {
1584 		AUTO_RELEASE (sccp_device_t, device, sccp_channel_getDevice (hostChannel));
1585 		sccp_log (DEBUGCAT_CHANNEL) (VERBOSE_PREFIX_3 "%s: Handling Park\n", hostChannel->designator);
1586 		if (device && (ast_channel_state (parker_chan) == AST_STATE_UP)) {
1587 			ast_channel_lock (parker_chan); /* we have to lock our channel, otherwise asterisk crashes internally */
1588 			bridge_channel = ast_channel_get_bridge_channel (parker_chan);
1589 			ast_channel_unlock (parker_chan);
1590 			if (!bridge_channel) {
1591 				pbx_log (LOG_ERROR, "Park action failed\n");
1592 				break;
1593 			}
1594 			if (!hostChannel->parking_sub) {
1595 				// pbx_log(LOG_NOTICE, "%s: Subscribing to park topic\n", hostChannel->designator);
1596 				channelPtr c = (channelPtr)hostChannel;                                        // casting away const
1597 				c->parking_sub = stasis_subscribe (ast_parking_topic(), parking_event_cb, (void *)c);
1598 #if CS_AST_HAS_STASIS_SUBSCRIPTION_SET_FILTER
1599 				stasis_subscription_accept_message_type (c->parking_sub, ast_parked_call_type());
1600 				stasis_subscription_set_filter (c->parking_sub, STASIS_SUBSCRIPTION_FILTER_SELECTIVE);
1601 #endif
1602 				// pbx_log(LOG_NOTICE, "%s: Added cleaning job\n", hostChannel->designator);
1603 				sccp_channel_addCleanupJob (c, &parking_subscriptionCleanup, (void *)sccp_channel_retain (c));
1604 			}
1605 			if (bridge_channel) {
1606 				RAII (struct ast_channel *, other_chan, NULL, ast_channel_cleanup);
1607 				ast_bridge_channel_lock_bridge (bridge_channel);
1608 				uint8_t peer_count = bridge_channel->bridge->num_channels;
1609 				if (peer_count == 2) {
1610 					struct ast_bridge_channel * other = ast_bridge_channel_peer (bridge_channel);
1611 					other_chan = other->chan;
1612 					ast_channel_ref (other_chan);
1613 				}
1614 				ast_bridge_unlock (bridge_channel->bridge);
1615 				if (!other_chan) {
1616 					pbx_log (LOG_WARNING, "%s: Remote channel is missing, giving up (connected to application?)\n", hostChannel->designator);
1617 					break;
1618 				}
1619 				pbx_builtin_setvar_helper (other_chan, "_PARKED_BY_CHANNEL", ast_channel_name (parker_chan));
1620 				pbx_builtin_setvar_helper (other_chan, "_PARKED_BY_UNIQUEID", ast_channel_uniqueid (parker_chan));
1621 
1622 				sccp_log (DEBUGCAT_CHANNEL) (VERBOSE_PREFIX_3 "%s: Parking %s\n", hostChannel->designator, ast_channel_name (other_chan));
1623 				const char * parkinglot = ast_channel_parkinglot (bridge_channel->chan);
1624 				char app_data[256];
1625 				snprintf (app_data, 256, "%s,%s", parkinglot, "s");
1626 				if (ast_bridge_channel_write_park (bridge_channel, ast_channel_uniqueid (other_chan), ast_channel_uniqueid (bridge_channel->chan), app_data) != 0) {
1627 					pbx_log (LOG_ERROR, "%s: Parking bridge_channel failed\n", hostChannel->designator);
1628 					break;
1629 				}
1630 
1631 				AUTO_RELEASE (sccp_channel_t, remote, get_sccp_channel_from_pbx_channel (other_chan));
1632 				if (remote) {
1633 					sccp_indicate (NULL, remote, SCCP_CHANNELSTATE_CALLPARK);
1634 				}
1635 
1636 				pbx_channel_set_hangupcause (parker_chan, AST_CAUSE_REDIRECTED_TO_NEW_DESTINATION);
1637 				sccp_channel_schedule_hangup (hostChannel, SCCP_HANGUP_TIMEOUT);
1638 
1639 				res = PARK_RESULT_SUCCESS;
1640 			}
1641 		}
1642 	} while (0);
1643 	return res;
1644 }
1645 
sccp_astwrap_getFeatureExtension(constChannelPtr channel,const char * featureName,char extension[SCCP_MAX_EXTENSION])1646 static boolean_t sccp_astwrap_getFeatureExtension(constChannelPtr channel, const char *featureName, char extension[SCCP_MAX_EXTENSION])
1647 {
1648 	int feat_res = ast_get_feature(channel->owner, featureName, extension, SCCP_MAX_EXTENSION);
1649 	return feat_res ? FALSE : TRUE;
1650 }
1651 
sccp_astwrap_getPickupExtension(constChannelPtr channel,char extension[SCCP_MAX_EXTENSION])1652 static boolean_t sccp_astwrap_getPickupExtension(constChannelPtr channel, char extension[SCCP_MAX_EXTENSION])
1653 {
1654 	boolean_t res = FALSE;
1655 	struct ast_features_pickup_config *pickup_cfg = NULL;
1656 
1657 	if (channel->owner) {
1658 		pbx_channel_lock(channel->owner);
1659 		pickup_cfg = ast_get_chan_features_pickup_config(channel->owner);
1660 		if (!pickup_cfg) {
1661 			ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
1662 		} else {
1663 			if (!sccp_strlen_zero(pickup_cfg->pickupexten)) {
1664 				sccp_copy_string(extension, pickup_cfg->pickupexten, SCCP_MAX_EXTENSION);
1665 				res = TRUE;
1666 			}
1667 			pbx_channel_unref(pickup_cfg);
1668 		}
1669 		pbx_channel_unlock(channel->owner);
1670 	}
1671 	return res;
1672 }
1673 
sccp_astwrap_get_payloadType(const struct sccp_rtp * rtp,skinny_codec_t codec)1674 static uint8_t sccp_astwrap_get_payloadType(const struct sccp_rtp *rtp, skinny_codec_t codec)
1675 {
1676 	struct ast_format *astCodec = sccp_astwrap_skinny2ast_format(codec);
1677 	if (astCodec != ast_format_none) {
1678 		return ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(rtp->instance), 1, astCodec, 0);
1679 	}
1680 	return 0;
1681 }
1682 
sccp_astwrap_get_sampleRate(skinny_codec_t codec)1683 static int sccp_astwrap_get_sampleRate(skinny_codec_t codec)
1684 {
1685 	struct ast_format *astCodec = sccp_astwrap_skinny2ast_format(codec);
1686 	if (astCodec != ast_format_none) {
1687 		return ast_rtp_lookup_sample_rate2(1, astCodec, 0);
1688 	}
1689 	return 0;
1690 }
1691 
sccp_astwrap_extensionStatus(constChannelPtr channel)1692 static sccp_extension_status_t sccp_astwrap_extensionStatus(constChannelPtr channel)
1693 {
1694 	PBX_CHANNEL_TYPE *pbx_channel = channel->owner;
1695 
1696 	if (!pbx_channel || !pbx_channel_context(pbx_channel)) {
1697 		pbx_log(LOG_ERROR, "%s: (extension_status) Either no pbx_channel or no valid context provided to lookup number\n", channel->designator);
1698 		return SCCP_EXTENSION_NOTEXISTS;
1699 	}
1700 	int ignore_pat = ast_ignore_pattern(pbx_channel_context(pbx_channel), channel->dialedNumber);
1701 	int ext_exist = ast_exists_extension(pbx_channel, pbx_channel_context(pbx_channel), channel->dialedNumber, 1, channel->line->cid_num);
1702 	int ext_canmatch = ast_canmatch_extension(pbx_channel, pbx_channel_context(pbx_channel), channel->dialedNumber, 1, channel->line->cid_num);
1703 	int ext_matchmore = ast_matchmore_extension(pbx_channel, pbx_channel_context(pbx_channel), channel->dialedNumber, 1, channel->line->cid_num);
1704 
1705 	// RAII(struct ast_features_pickup_config *, pickup_cfg, ast_get_chan_features_pickup_config(pbx_channel), ao2_cleanup);
1706 	// const char *pickupexten = (pickup_cfg) ? pickup_cfg->pickupexten : "-";
1707 
1708 	/* if we dialed the pickup extention, mark this as exact match */
1709 	const char *pickupexten = "";
1710 	struct ast_features_pickup_config *pickup_cfg = NULL;
1711 
1712 	if (channel->owner) {
1713 		pbx_channel_lock(channel->owner);
1714 		pickup_cfg = ast_get_chan_features_pickup_config(channel->owner);
1715 		if (!pickup_cfg) {
1716 			ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
1717 			pickupexten = "";
1718 		} else {
1719 			pickupexten = pbx_strdupa(pickup_cfg->pickupexten);
1720 			pbx_channel_unref(pickup_cfg);
1721 		}
1722 		pbx_channel_unlock(channel->owner);
1723 	}
1724 	if (!sccp_strlen_zero(pickupexten) && sccp_strcaseequals(pickupexten, channel->dialedNumber)) {
1725 		sccp_log(DEBUGCAT_CORE) (VERBOSE_PREFIX_3 "SCCP: pbx extension matcher found pickup extension %s matches dialed number %s\n", channel->dialedNumber, pickupexten);
1726 		ext_exist = 1;
1727 		ext_canmatch = 1;
1728 		ext_matchmore = 0;
1729 	}
1730 
1731 	sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "+- pbx extension matcher (%-15s): ---+\n" VERBOSE_PREFIX_3 "|ignore     |exists     |can match  |match more|\n" VERBOSE_PREFIX_3 "|%3s        |%3s        |%3s        |%3s       |\n" VERBOSE_PREFIX_3 "+----------------------------------------------+\n", channel->dialedNumber, ignore_pat ? "yes" : "no", ext_exist ? "yes" : "no", ext_canmatch ? "yes" : "no", ext_matchmore ? "yes" : "no");
1732 
1733 	if (ignore_pat) {
1734 		return SCCP_EXTENSION_NOTEXISTS;
1735 	}
1736 	if (ext_exist) {
1737 		if (ext_canmatch && !ext_matchmore) {
1738 			return SCCP_EXTENSION_EXACTMATCH;
1739 		}
1740 		return SCCP_EXTENSION_MATCHMORE;
1741 	}
1742 
1743 	return SCCP_EXTENSION_NOTEXISTS;
1744 }
1745 
sccp_astwrap_request(const char * type,struct ast_format_cap * cap,const struct ast_assigned_ids * assignedids,const struct ast_channel * requestor,const char * dest,int * cause)1746 static PBX_CHANNEL_TYPE *sccp_astwrap_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *dest, int *cause)
1747 {
1748 	sccp_channel_request_status_t requestStatus;
1749 	PBX_CHANNEL_TYPE *result_ast_channel = NULL;
1750 	pbx_str_t *codec_buf = pbx_str_alloca(64);
1751 #if !defined(CS_AST_CHANNEL_CALLID_TYPEDEF)
1752 	struct ast_callid *callid = NULL;
1753 #else
1754 	ast_callid callid = 0;
1755 #endif
1756 	skinny_codec_t audioCapabilities[SKINNY_MAX_CAPABILITIES] = {SKINNY_CODEC_NONE};
1757 	skinny_codec_t videoCapabilities[SKINNY_MAX_CAPABILITIES] = {SKINNY_CODEC_NONE};
1758 
1759 	//! \todo parse request
1760 	char *lineName;
1761 	skinny_codec_t audio_codec = SKINNY_CODEC_WIDEBAND_256K;
1762 #if CS_SCCP_VIDEO
1763 	skinny_codec_t video_codec = SKINNY_CODEC_NONE;
1764 #endif
1765 	sccp_autoanswer_t autoanswer_type = SCCP_AUTOANSWER_NONE;
1766 	uint8_t autoanswer_cause = AST_CAUSE_NOTDEFINED;
1767 	skinny_ringtype_t ringermode = GLOB(ringtype);
1768 
1769 	if (!(ast_format_cap_has_type(cap, AST_MEDIA_TYPE_AUDIO))) {
1770 		ast_log(LOG_NOTICE, "Asked to get a channel with an unsupported format '%s'\n", ast_format_cap_get_names(cap, &codec_buf));
1771 	}
1772 
1773 	*cause = AST_CAUSE_NOTDEFINED;
1774 	if (!type) {
1775 		pbx_log(LOG_NOTICE, "Attempt to call with unspecified type of channel\n");
1776 		*cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
1777 		return NULL;
1778 	}
1779 
1780 	if (!dest) {
1781 		pbx_log(LOG_NOTICE, "Attempt to call SCCP/ failed\n");
1782 		*cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
1783 		return NULL;
1784 	}
1785 	/* we leave the data unchanged */
1786 	lineName = pbx_strdupa((const char *) dest);
1787 
1788 	/* parsing options string */
1789 	char *options = NULL;
1790 	if ((options = strchr(lineName, '/'))) {
1791 		*options = '\0';
1792 		options++;
1793 	}
1794 	// sccp_log(DEBUGCAT_CHANNEL) (VERBOSE_PREFIX_3 "SCCP: Asterisk asked us to create a channel with type=%s, format=" UI64FMT ", lineName=%s, options=%s\n", type, (uint64_t) ast_format_compatibility_codec2bitfield(cap), lineName, (options) ? options : "");
1795 	sccp_log(DEBUGCAT_CHANNEL) (VERBOSE_PREFIX_3 "SCCP: Asterisk asked us to create a channel with type=%s, format=%s, lineName=%s, options=%s\n", type, ast_format_cap_get_names(cap, &codec_buf), lineName, (options) ? options : "");
1796 	if (requestor) {							/* get ringer mode from ALERT_INFO */
1797 		sccp_parse_alertinfo((PBX_CHANNEL_TYPE *)requestor, &ringermode);
1798 	}
1799 	sccp_parse_dial_options(options, &autoanswer_type, &autoanswer_cause, &ringermode);
1800 	if (autoanswer_cause) {
1801 		*cause = autoanswer_cause;
1802 	}
1803 	sccp_parse_auto_answer((PBX_CHANNEL_TYPE *)requestor, &autoanswer_type);
1804 
1805 	/** getting remote capabilities */
1806 	if (requestor) {
1807 		struct ast_format_cap *acaps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
1808 		if (acaps) {
1809 			ast_format_cap_append_from_cap(acaps, cap, AST_MEDIA_TYPE_AUDIO);								// Add Resquested
1810 			if (ast_format_cap_count(acaps)) {
1811 				audio_codec = sccp_astwrap_getSkinnyFormatSingle(acaps);									// Is it compatible
1812 				ast_format_cap_append_from_cap(acaps, ast_channel_nativeformats(requestor), AST_MEDIA_TYPE_AUDIO);				// Add rest
1813 				sccp_astwrap_getSkinnyFormatMultiple(acaps, audioCapabilities, ARRAY_LEN(audioCapabilities));
1814 				if (audio_codec == SKINNY_CODEC_NONE && (audio_codec = audioCapabilities[0]) == SKINNY_CODEC_NONE) {
1815 					pbx_log(LOG_NOTICE, "SCCP: remote native audio formats are not compatible with any skinny format. Transcoding required\n");
1816 					audioCapabilities[0] = SKINNY_CODEC_WIDEBAND_256K;
1817 					audio_codec  =SKINNY_CODEC_WIDEBAND_256K;
1818 				}
1819 			}
1820 			ao2_cleanup(acaps);
1821 		}
1822 #if CS_SCCP_VIDEO
1823 		struct ast_format_cap *vcaps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
1824 		if (vcaps) {
1825 			ast_format_cap_append_from_cap(vcaps, cap, AST_MEDIA_TYPE_VIDEO);								// Add Resquested
1826 			if (ast_format_cap_count(vcaps)) {
1827 				video_codec = sccp_astwrap_getSkinnyFormatSingle(vcaps);								// Is it compatible
1828 				ast_format_cap_append_from_cap(vcaps, ast_channel_nativeformats(requestor), AST_MEDIA_TYPE_VIDEO);			// Add rest
1829 				sccp_astwrap_getSkinnyFormatMultiple(vcaps, videoCapabilities, ARRAY_LEN(videoCapabilities));
1830 				if (video_codec == SKINNY_CODEC_NONE && (video_codec = videoCapabilities[0]) == SKINNY_CODEC_NONE) {
1831 					pbx_log(LOG_NOTICE, "SCCP: remote native video formats are not compatible with any skinny format. Deny video\n");
1832 					videoCapabilities[0] = SKINNY_CODEC_NONE;
1833 					video_codec = SKINNY_CODEC_NONE;
1834 				}
1835 			}
1836 			ao2_cleanup(vcaps);
1837 		}
1838 #endif
1839 	}
1840 
1841 	char cap_buf[512];
1842 	sccp_codec_multiple2str(cap_buf, sizeof(cap_buf) - 1, audioCapabilities, ARRAY_LEN(audioCapabilities));
1843 	sccp_log(DEBUGCAT_CODEC) (VERBOSE_PREFIX_4 "remote audio caps: %s\n", cap_buf);
1844 
1845 	sccp_codec_multiple2str(cap_buf, sizeof(cap_buf) - 1, videoCapabilities, ARRAY_LEN(videoCapabilities));
1846 	sccp_log(DEBUGCAT_CODEC) (VERBOSE_PREFIX_4 "remote video caps: %s\n", cap_buf);
1847 
1848 	//sccp_log(DEBUGCAT_CODEC) (VERBOSE_PREFIX_4 "SCCP: requestedCodec in Skinny Format: audio:%s (video:%s)\n", codec2name(audio_codec), codec2name(video_codec));
1849 	/** done getting remote capabilities */
1850 
1851 	callid = ast_read_threadstorage_callid();
1852 
1853 	AUTO_RELEASE(sccp_channel_t, channel , NULL);
1854 	requestStatus = sccp_requestChannel(lineName, autoanswer_type, autoanswer_cause, ringermode, &channel);
1855 	switch (requestStatus) {
1856 		case SCCP_REQUEST_STATUS_SUCCESS:								// everything is fine
1857 			break;
1858 		case SCCP_REQUEST_STATUS_LINEUNKNOWN:
1859 			sccp_log(DEBUGCAT_CORE) (VERBOSE_PREFIX_4 "SCCP: sccp_requestChannel returned Line %s Unknown -> Not Successfull\n", lineName);
1860 			*cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
1861 			goto EXITFUNC;
1862 		case SCCP_REQUEST_STATUS_LINEUNAVAIL:
1863 			sccp_log(DEBUGCAT_CORE) (VERBOSE_PREFIX_4 "SCCP: sccp_requestChannel returned Line %s not currently registered -> Try again later\n", lineName);
1864 			*cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
1865 			goto EXITFUNC;
1866 		case SCCP_REQUEST_STATUS_ERROR:
1867 			pbx_log(LOG_ERROR, "SCCP: sccp_requestChannel returned Status Error for lineName: %s\n", lineName);
1868 			*cause = AST_CAUSE_UNALLOCATED;
1869 			goto EXITFUNC;
1870 		default:
1871 			pbx_log(LOG_ERROR, "SCCP: sccp_requestChannel returned Status Error for lineName: %s\n", lineName);
1872 			*cause = AST_CAUSE_UNALLOCATED;
1873 			goto EXITFUNC;
1874 	}
1875 #ifdef CS_SCCP_VIDEO
1876 	memset(&channel->remoteCapabilities.video, 0, sizeof(channel->remoteCapabilities.video));
1877 	if (videoCapabilities[0] != SKINNY_CODEC_NONE) {
1878 		memcpy(channel->remoteCapabilities.video, videoCapabilities, ARRAY_LEN(videoCapabilities));
1879 	} else if (video_codec) {
1880 		channel->remoteCapabilities.video[0] = video_codec;
1881 	}
1882 #endif
1883 	if (callid) {
1884 		channel->pbx_callid = (pbx_callid_t)callid;
1885 	}
1886 
1887 	if (!sccp_pbx_channel_allocate(channel, assignedids, requestor)) {
1888 		//! \todo handle error in more detail, cleanup sccp channel
1889 		*cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
1890 		goto EXITFUNC;
1891 	}
1892 
1893 	/* set initial connected line information, to be exchange with remove party during first CONNECTED_LINE update */
1894 	ast_set_callerid(channel->owner, channel->line->cid_num, channel->line->cid_name, channel->line->cid_num);
1895 	struct ast_party_connected_line connected;
1896 	ast_party_connected_line_set_init(&connected, ast_channel_connected(channel->owner));
1897 	connected.id.number.valid = 1;
1898 	connected.id.number.str = (char *)channel->line->cid_num;
1899 	connected.id.number.presentation = AST_PRES_ALLOWED_NETWORK_NUMBER;
1900 	connected.id.name.valid = 1;
1901 	connected.id.name.str = (char *)channel->line->cid_name;
1902 	connected.id.name.presentation = AST_PRES_ALLOWED_NETWORK_NUMBER;
1903 	connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN;
1904 	ast_channel_set_connected_line(channel->owner, &connected, NULL);
1905 	/* end */
1906 
1907 	if (requestor) {
1908 		/* set calling party */
1909 		sccp_callinfo_t *ci = sccp_channel_getCallInfo(channel);
1910 		iCallInfo.Setter(ci,
1911 				SCCP_CALLINFO_CALLINGPARTY_NAME, ast_channel_caller((PBX_CHANNEL_TYPE *) requestor)->id.name.str,
1912 				SCCP_CALLINFO_CALLINGPARTY_NUMBER, ast_channel_caller((PBX_CHANNEL_TYPE *) requestor)->id.number.str,
1913 				SCCP_CALLINFO_ORIG_CALLEDPARTY_NAME, ast_channel_redirecting((PBX_CHANNEL_TYPE *) requestor)->orig.name.str,
1914 				SCCP_CALLINFO_ORIG_CALLEDPARTY_NUMBER, ast_channel_redirecting((PBX_CHANNEL_TYPE *) requestor)->orig.number.str,
1915 				SCCP_CALLINFO_KEY_SENTINEL);
1916 	}
1917 
1918 	/** workaround for asterisk console log flooded
1919 	 channel.c:5080 ast_write: Codec mismatch on channel SCCP/xxx-0000002d setting write format to g722 from unknown native formats (nothing)
1920 	*/
1921 	if (!channel->capabilities.audio[0]) {
1922 		skinny_codec_t codecs[SKINNY_MAX_CAPABILITIES] = { SKINNY_CODEC_WIDEBAND_256K, SKINNY_CODEC_NONE};
1923 		sccp_astwrap_setNativeAudioFormats(channel, codecs);
1924 		sccp_astwrap_setReadFormat(channel, SKINNY_CODEC_WIDEBAND_256K);
1925 		sccp_astwrap_setWriteFormat(channel, SKINNY_CODEC_WIDEBAND_256K);
1926 	}
1927 
1928 	/* get remote codecs from channel driver */
1929 	//ast_rtp_instance_get_codecs(c->rtp.adio.rtp);
1930 	//ast_rtp_instance_get_codecs(c->rtp.video.instance);
1931 	/** done */
1932 
1933 EXITFUNC:
1934 	if (channel  && channel->owner) {
1935 		result_ast_channel = channel->owner;
1936 		if (callid) {
1937 			ast_channel_callid_set(result_ast_channel, callid);
1938 		}
1939 	} else if (callid) {
1940 #if !defined(CS_AST_CHANNEL_CALLID_TYPEDEF)
1941 		ast_callid_unref(callid);
1942 #endif
1943 	}
1944 	return result_ast_channel;
1945 }
1946 
sccp_astwrap_call(PBX_CHANNEL_TYPE * ast,const char * dest,int timeout)1947 static int sccp_astwrap_call(PBX_CHANNEL_TYPE * ast, const char *dest, int timeout)
1948 {
1949 	int res = 0;
1950 
1951 	sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "SCCP: Asterisk request to call %s (dest:%s, timeout: %d)\n", pbx_channel_name(ast), dest, timeout);
1952 
1953 	if (!sccp_strlen_zero(pbx_channel_call_forward(ast))) {
1954 		iPbx.queue_control(ast, (enum ast_control_frame_type) -1);						/* Prod Channel if in the middle of a call_forward instead of proceed */
1955 		sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "SCCP: Forwarding Call to '%s'\n", pbx_channel_call_forward(ast));
1956 		return 0;
1957 	}
1958 
1959 	AUTO_RELEASE(sccp_channel_t, c , get_sccp_channel_from_pbx_channel(ast));
1960 	if (!c) {
1961 		pbx_log(LOG_WARNING, "SCCP: Asterisk request to call %s on channel: %s, but we don't have this channel!\n", dest, pbx_channel_name(ast));
1962 		return -1;
1963 	}
1964 
1965 	/* Check whether there is MaxCallBR variables */
1966 	const char *MaxCallBRStr = pbx_builtin_getvar_helper(ast, "MaxCallBR");
1967 	if (MaxCallBRStr && !sccp_strlen_zero(MaxCallBRStr)) {
1968 		sccp_astgenwrap_channel_write(ast, "CHANNEL", "MaxCallBR", MaxCallBRStr);
1969 	}
1970 
1971 	res = sccp_pbx_call(c, (char *) dest, timeout);
1972 	return res;
1973 }
1974 
1975 /*
1976  * Remote side has answered the call switch to up state
1977  * Is being called with pbxchan locked by app_dial
1978  */
sccp_astwrap_answer(PBX_CHANNEL_TYPE * pbxchan)1979 static int sccp_astwrap_answer(PBX_CHANNEL_TYPE * pbxchan)
1980 {
1981 	int res = -1;
1982 	int timedout = 0;
1983 	if(pbx_channel_state(pbxchan) == AST_STATE_UP) {
1984 		pbx_log(LOG_NOTICE, "%s: Channel has already been answered remotely, skipping\n", pbx_channel_name(pbxchan));
1985 		return 0;
1986 	}
1987 
1988 	pbx_channel_ref(pbxchan);
1989 	AUTO_RELEASE(sccp_channel_t, c , get_sccp_channel_from_pbx_channel(pbxchan));
1990 	if(c && c->state < SCCP_GROUPED_CHANNELSTATE_CONNECTION) {
1991 		sccp_log(DEBUGCAT_CORE)(VERBOSE_PREFIX_3 "%s: Remote has answered the call.\n", c->designator);
1992 
1993 		AUTO_RELEASE(sccp_device_t, d, sccp_channel_getDevice(c));
1994 		if(d && d->session) {
1995 			sccp_log(DEBUGCAT_PBX)(VERBOSE_PREFIX_3 "%s: Waiting for pendingRequests\n", c->designator);
1996 			// this needs to be done with the pbx_channel unlocked to prevent lock investion
1997 			// note we still have a pbx_channel_ref, so the channel cannot be removed under our feet
1998 			pbx_channel_unlock(pbxchan);
1999 			timedout = sccp_session_waitForPendingRequests(d->session);
2000 			pbx_channel_lock(pbxchan);
2001 		}
2002 		if (!timedout) {
2003 			// pbx_indicate(pbxchan, AST_CONTROL_PROGRESS);
2004 			res = sccp_pbx_remote_answer(c);
2005 		}
2006 	}
2007 	pbx_channel_unref(pbxchan);
2008 	return res;
2009 }
2010 
2011 /**
2012  *
2013  * \todo update remote capabilities after fixup
2014  */
sccp_astwrap_fixup(PBX_CHANNEL_TYPE * oldchan,PBX_CHANNEL_TYPE * newchan)2015 static int sccp_astwrap_fixup(PBX_CHANNEL_TYPE * oldchan, PBX_CHANNEL_TYPE * newchan)
2016 {
2017 	sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "SCCP: we got a fixup request for %s and %s\n", pbx_channel_name(oldchan), pbx_channel_name(newchan));
2018 	int res = 0;
2019 
2020 	AUTO_RELEASE(sccp_channel_t, c , get_sccp_channel_from_pbx_channel(newchan));
2021 	if (c) {
2022 		if (c->owner != oldchan) {
2023 			ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, c->owner);
2024 			res = -1;
2025 		} else {
2026 			/* during a masquerade, fixup gets called twice */
2027 			if(ast_channel_masqr(newchan)) { /* this is the channel that is masquaraded out */
2028 				// set to simple channel requestHangup, we are out of pbx_run_pbx, upon returning from masquerade */
2029 				// sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: set c->hangupRequest = requestHangup\n", c->designator);
2030 				c->hangupRequest = sccp_astgenwrap_requestHangup;
2031 
2032 				if (pbx_channel_hangupcause(newchan) == AST_CAUSE_ANSWERED_ELSEWHERE) {
2033 					sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: Fixup Adding Redirecting Party from:%s\n", c->designator, pbx_channel_name(oldchan));
2034 					iCallInfo.Setter(sccp_channel_getCallInfo(c),
2035 						SCCP_CALLINFO_HUNT_PILOT_NAME, ast_channel_caller(oldchan)->id.name.str,
2036 						SCCP_CALLINFO_HUNT_PILOT_NUMBER, ast_channel_caller(oldchan)->id.number.str,
2037 						SCCP_CALLINFO_LAST_REDIRECTINGPARTY_NAME, ast_channel_caller(oldchan)->id.name.str,
2038 						SCCP_CALLINFO_LAST_REDIRECTINGPARTY_NUMBER, ast_channel_caller(oldchan)->id.number.str,
2039 						SCCP_CALLINFO_LAST_REDIRECT_REASON, 5,
2040 						SCCP_CALLINFO_KEY_SENTINEL);
2041 				}
2042 			} else {
2043 				// set channel requestHangup to use ast_hangup (as it will not be part of __ast_pbx_run, upon returning from masquerade) */
2044 				// sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: set c->hangupRequest = requestQueueHangup\n", c->designator);
2045 				c->hangupRequest = sccp_astgenwrap_requestQueueHangup;
2046 
2047 				if (!sccp_strlen_zero(c->line->language)) {
2048 					ast_channel_language_set(newchan, c->line->language);
2049 				}
2050 
2051 				//! \todo update remote capabilities after fixup
2052 				pbx_retrieve_remote_capabilities(c);
2053 
2054 				/* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native
2055 				   RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be
2056 				   able to do this if the masquerade happens before the bridge breaks (e.g., AMI
2057 				   redirect of both channels). Note that a channel can not be masqueraded *into*
2058 				   a native bridge. So there is no danger that this breaks a native bridge that
2059 				   should stay up. */
2060 				// sccp_astwrap_update_rtp_peer(newchan, NULL, NULL, 0, 0, 0);
2061 			}
2062 			sccp_astwrap_setOwner(c, newchan);
2063 		}
2064 	} else {
2065 		pbx_log(LOG_WARNING, "sccp_pbx_fixup(old: %s(%p), new: %s(%p)). no SCCP channel to fix\n", pbx_channel_name(oldchan), (void *) oldchan, pbx_channel_name(newchan), (void *) newchan);
2066 		res = -1;
2067 	}
2068 	return res;
2069 }
2070 
2071 #if 0
2072 #ifdef CS_AST_RTP_INSTANCE_BRIDGE
2073 static enum ast_bridge_result sccp_astwrap_rtpBridge(PBX_CHANNEL_TYPE * c0, PBX_CHANNEL_TYPE * c1, int flags, PBX_FRAME_TYPE ** fo, PBX_CHANNEL_TYPE ** rc, int timeoutms)
2074 {
2075 	enum ast_bridge_result res;
2076 	int new_flags = flags;
2077 
2078 	/* \note temporarily marked out until we figure out how to get directrtp back on track - DdG */
2079 	AUTO_RELEASE(sccp_channel_t, sc0 , get_sccp_channel_from_pbx_channel(c0));
2080 	AUTO_RELEASE(sccp_channel_t, sc1 , get_sccp_channel_from_pbx_channel(c1));
2081 
2082 	if ((sc0 && sc1)) {
2083 		// Switch off DTMF between SCCP phones
2084 		new_flags &= !AST_BRIDGE_DTMF_CHANNEL_0;
2085 		new_flags &= !AST_BRIDGE_DTMF_CHANNEL_1;
2086 		if (GLOB(directrtp)) {
2087 			ast_channel_defer_dtmf(c0);
2088 			ast_channel_defer_dtmf(c1);
2089 		} else {
2090 			AUTO_RELEASE(sccp_device_t, d0 , sccp_channel_getDevice(sc0));
2091 			AUTO_RELEASE(sccp_device_t, d1 , sccp_channel_getDevice(sc1));
2092 			if ((d0 && d1) && ((d0->directrtp && d1->directrtp)) {
2093 				ast_channel_defer_dtmf(c0);
2094 				ast_channel_defer_dtmf(c1);
2095 			}
2096 		}
2097 		sc0->peerIsSCCP = TRUE;
2098 		sc1->peerIsSCCP = TRUE;
2099 		// SCCP Key handle direction to asterisk is still to be implemented here
2100 		// sccp_pbx_senddigit
2101 	} else {
2102 		// Switch on DTMF between differing channels
2103 		ast_channel_undefer_dtmf(c0);
2104 		ast_channel_undefer_dtmf(c1);
2105 	}
2106 	//res = ast_rtp_bridge(c0, c1, new_flags, fo, rc, timeoutms);
2107 	res = ast_rtp_instance_bridge(c0, c1, new_flags, fo, rc, timeoutms);
2108 	switch (res) {
2109 		case AST_BRIDGE_COMPLETE:
2110 			sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_1 "SCCP: Bridge chan %s and chan %s: Complete\n", ast_channel_name(c0), ast_channel_name(c1));
2111 			break;
2112 		case AST_BRIDGE_FAILED:
2113 			sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_1 "SCCP: Bridge chan %s and chan %s: Failed\n", ast_channel_name(c0), ast_channel_name(c1));
2114 			break;
2115 		case AST_BRIDGE_FAILED_NOWARN:
2116 			sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_1 "SCCP: Bridge chan %s and chan %s: Failed NoWarn\n", ast_channel_name(c0), ast_channel_name(c1));
2117 			break;
2118 		case AST_BRIDGE_RETRY:
2119 			sccp_log((DEBUGCAT_PBX)) (VERBOSE_PREFIX_1 "SCCP: Bridge chan %s and chan %s: Failed Retry\n", ast_channel_name(c0), ast_channel_name(c1));
2120 			break;
2121 	}
2122 	/*! \todo Implement callback function queue upon completion */
2123 	return res;
2124 }
2125 #endif
2126 #endif
2127 
sccp_astwrap_get_rtp_info(PBX_CHANNEL_TYPE * ast,PBX_RTP_TYPE ** rtp)2128 static enum ast_rtp_glue_result sccp_astwrap_get_rtp_info(PBX_CHANNEL_TYPE * ast, PBX_RTP_TYPE ** rtp)
2129 {
2130 	//AUTO_RELEASE(sccp_channel_t, c , get_sccp_channel_from_pbx_channel(ast));				// not following the refcount rules... channel is already retained
2131 	sccp_channel_t *c = NULL;
2132 	sccp_rtp_info_t rtpInfo = SCCP_RTP_INFO_NORTP;
2133 	struct sccp_rtp *audioRTP = NULL;
2134 	enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_REMOTE;
2135 
2136 	if (!(c = CS_AST_CHANNEL_PVT(ast))) {
2137 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_1 "SCCP: (get_rtp_info) NO PVT\n");
2138 		return AST_RTP_GLUE_RESULT_FORBID;
2139 	}
2140 
2141 	if (pbx_channel_state(ast) != AST_STATE_UP) {
2142 		sccp_log((DEBUGCAT_CHANNEL | DEBUGCAT_RTP)) (VERBOSE_PREFIX_1 "%s: (get_rtp_info) Asterisk requested EarlyRTP peer for channel %s\n", c->currentDeviceId, pbx_channel_name(ast));
2143 		return AST_RTP_GLUE_RESULT_LOCAL;
2144 	} else {
2145 		sccp_log((DEBUGCAT_CHANNEL | DEBUGCAT_RTP)) (VERBOSE_PREFIX_1 "%s: (get_rtp_info) Asterisk requested RTP peer for channel %s\n", c->currentDeviceId, pbx_channel_name(ast));
2146 	}
2147 
2148 	rtpInfo = sccp_rtp_getAudioPeerInfo(c, &audioRTP);
2149 	if (rtpInfo == SCCP_RTP_INFO_NORTP) {
2150 		sccp_log(DEBUGCAT_RTP)(VERBOSE_PREFIX_2 "%s: (get_rtp_info) got SCCP_RTP_INFO_NORTP => returning AST_RTP_GLUE_RESULT_FORBID\n", c->designator);
2151 		return AST_RTP_GLUE_RESULT_FORBID;
2152 	}
2153 
2154 	*rtp = audioRTP->instance;
2155 	if (!*rtp) {
2156 		sccp_log(DEBUGCAT_RTP)(VERBOSE_PREFIX_2 "%s: (get_rtp_info) no rtp instance yet => returning AST_RTP_GLUE_RESULT_FORBID\n", c->designator);
2157 		return AST_RTP_GLUE_RESULT_FORBID;
2158 	}
2159 #ifdef HAVE_PBX_RTP_ENGINE_H
2160 	ao2_ref(*rtp, +1);
2161 #endif
2162 	// struct ast_sockaddr ast_sockaddr_tmp;
2163 	// ast_rtp_instance_get_remote_address(*rtp, &ast_sockaddr_tmp);
2164 	// sccp_log((DEBUGCAT_RTP | DEBUGCAT_HIGH)) (VERBOSE_PREFIX_3 "%s: (get_rtp_info) remote address:'%s:%d'\n", c->currentDeviceId, ast_sockaddr_stringify_host(&ast_sockaddr_tmp), ast_sockaddr_port(&ast_sockaddr_tmp));
2165 
2166 	if (ast_test_flag(GLOB(global_jbconf), AST_JB_FORCED)) {
2167 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_1 "%s: (get_rtp_info) JitterBuffer is Forced. AST_RTP_GET_FAILED\n", c->currentDeviceId);
2168 		return AST_RTP_GLUE_RESULT_LOCAL;
2169 	}
2170 
2171 	if (!(rtpInfo & SCCP_RTP_INFO_ALLOW_DIRECTRTP)) {
2172 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_1 "%s: (get_rtp_info) Direct RTP disabled ->  Using AST_RTP_TRY_PARTIAL for channel %s\n", c->currentDeviceId, pbx_channel_name(ast));
2173 		return AST_RTP_GLUE_RESULT_LOCAL;
2174 	}
2175 
2176 	sccp_log((DEBUGCAT_RTP | DEBUGCAT_HIGH)) (VERBOSE_PREFIX_1 "%s: (get_rtp_info) Channel %s Returning res: %s\n", c->currentDeviceId, pbx_channel_name(ast), ((res == 2) ? "indirect-rtp" : ((res == 1) ? "direct-rtp" : "forbid")));
2177 	return res;
2178 }
2179 
sccp_astwrap_get_vrtp_info(PBX_CHANNEL_TYPE * ast,PBX_RTP_TYPE ** rtp)2180 static enum ast_rtp_glue_result sccp_astwrap_get_vrtp_info(PBX_CHANNEL_TYPE * ast, PBX_RTP_TYPE ** rtp)
2181 {
2182 	//AUTO_RELEASE(sccp_channel_t, c , get_sccp_channel_from_pbx_channel(ast));				// not following the refcount rules... channel is already retained
2183 	sccp_channel_t *c = NULL;
2184 	sccp_rtp_info_t rtpInfo = SCCP_RTP_INFO_NORTP;
2185 	struct sccp_rtp *videoRTP = NULL;
2186 	enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_REMOTE;
2187 
2188 	if (!(c = CS_AST_CHANNEL_PVT(ast))) {
2189 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_1 "SCCP: (get_vrtp_info) NO PVT\n");
2190 		return AST_RTP_GLUE_RESULT_FORBID;
2191 	}
2192 
2193 	if (pbx_channel_state(ast) != AST_STATE_UP) {
2194 		sccp_log((DEBUGCAT_CHANNEL | DEBUGCAT_RTP)) (VERBOSE_PREFIX_1 "%s: (get_vrtp_info) Asterisk requested EarlyRTP peer for channel %s\n", c->currentDeviceId, pbx_channel_name(ast));
2195 	} else {
2196 		sccp_log((DEBUGCAT_CHANNEL | DEBUGCAT_RTP)) (VERBOSE_PREFIX_1 "%s: (get_vrtp_info) Asterisk requested RTP peer for channel %s\n", c->currentDeviceId, pbx_channel_name(ast));
2197 	}
2198 
2199 #ifdef CS_SCCP_VIDEO
2200 	rtpInfo = sccp_rtp_getVideoPeerInfo(c, &videoRTP);
2201 #endif
2202 	if (rtpInfo == SCCP_RTP_INFO_NORTP) {
2203 		return AST_RTP_GLUE_RESULT_FORBID;
2204 	}
2205 
2206 	*rtp = videoRTP->instance;
2207 	if (!*rtp) {
2208 		return AST_RTP_GLUE_RESULT_FORBID;
2209 	}
2210 #ifdef HAVE_PBX_RTP_ENGINE_H
2211 	ao2_ref(*rtp, +1);
2212 #endif
2213 	// struct ast_sockaddr ast_sockaddr_tmp;
2214 	// ast_rtp_instance_get_remote_address(*rtp, &ast_sockaddr_tmp);
2215 	// sccp_log((DEBUGCAT_RTP | DEBUGCAT_HIGH)) (VERBOSE_PREFIX_3 "%s: (get_vrtp_info) remote address:'%s:%d'\n", c->currentDeviceId, ast_sockaddr_stringify_host(&ast_sockaddr_tmp), ast_sockaddr_port(&ast_sockaddr_tmp));
2216 	if (ast_test_flag(GLOB(global_jbconf), AST_JB_FORCED)) {
2217 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_1 "%s: (get_vrtp_info) JitterBuffer is Forced. AST_RTP_GET_FAILED\n", c->currentDeviceId);
2218 		return AST_RTP_GLUE_RESULT_FORBID;
2219 	}
2220 
2221 	if (!(rtpInfo & SCCP_RTP_INFO_ALLOW_DIRECTRTP)) {
2222 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_1 "%s: (get_vrtp_info) Direct RTP disabled ->  Using AST_RTP_TRY_PARTIAL for channel %s\n", c->currentDeviceId, pbx_channel_name(ast));
2223 		return AST_RTP_GLUE_RESULT_LOCAL;
2224 	}
2225 
2226 	sccp_log((DEBUGCAT_RTP | DEBUGCAT_HIGH)) (VERBOSE_PREFIX_1 "%s: (get_vrtp_info) Channel %s Returning res: %s\n", c->currentDeviceId, pbx_channel_name(ast), ((res == 2) ? "indirect-rtp" : ((res == 1) ? "direct-rtp" : "forbid")));
2227 	return res;
2228 }
2229 
sccp_astwrap_update_rtp_peer(PBX_CHANNEL_TYPE * ast,PBX_RTP_TYPE * rtp,PBX_RTP_TYPE * vrtp,PBX_RTP_TYPE * trtp,const struct ast_format_cap * codecs,int nat_active)2230 static int sccp_astwrap_update_rtp_peer(PBX_CHANNEL_TYPE * ast, PBX_RTP_TYPE * rtp, PBX_RTP_TYPE * vrtp, PBX_RTP_TYPE * trtp, const struct ast_format_cap *codecs, int nat_active)
2231 {
2232 	//AUTO_RELEASE(sccp_channel_t, c , get_sccp_channel_from_pbx_channel(ast));				// not following the refcount rules... channel is already retained
2233 	sccp_channel_t *c = NULL;
2234 	int result = 0;
2235 	do {
2236 		pbx_str_t *codec_buf = pbx_str_alloca(64);
2237 
2238 		if (!(c = CS_AST_CHANNEL_PVT(ast))) {
2239 			sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_1 "SCCP: (update_rtp_peer) NO PVT\n");
2240 			result = -1;
2241 			break;
2242 		}
2243 
2244 		if (!codecs || ast_format_cap_count(codecs) <= 0) {
2245 			sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_1 "%s: (update_rtp_peer) NO Codecs\n", c->currentDeviceId);
2246 			result = -1;
2247 			break;
2248 		}
2249 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_2 "%s: (update_rtp_peer) stage: %s, remote codecs capabilty: %s, nat_active: %d\n", c->currentDeviceId,
2250 			S_COR(AST_STATE_UP == pbx_channel_state(ast), "RTP", "EarlyRTP"), ast_format_cap_get_names((struct ast_format_cap *) codecs, &codec_buf), nat_active);
2251 
2252 		if (!c->line) {
2253 			sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_1 "%s: (update_rtp_peer) NO LINE\n", c->currentDeviceId);
2254 			result = -1;
2255 			break;
2256 		}
2257 		if (c->state == SCCP_CHANNELSTATE_HOLD) {
2258 			sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_1 "%s: (update_rtp_peer) On Hold -> No Update\n", c->currentDeviceId);
2259 			result = 0;
2260 			break;
2261 		}
2262 		AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(c));
2263 		if (!d) {
2264 			sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_1 "%s: (update_rtp_peer) NO DEVICE\n", c->currentDeviceId);
2265 			result = -1;
2266 			break;
2267 		}
2268 
2269 		if (!rtp && !vrtp && !trtp) {
2270 			sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_1 "%s: (update_rtp_peer) RTP not ready\n", c->currentDeviceId);
2271 			result = 0;
2272 			break;
2273 		}
2274 
2275 		PBX_RTP_TYPE *instance = { 0, };
2276 		struct sockaddr_storage sas = { 0, };
2277 		//struct sockaddr_in sin = { 0, };
2278 		struct ast_sockaddr sin_tmp;
2279 		boolean_t directmedia = FALSE;
2280 
2281 		if (rtp) {											// generalize input
2282 			instance = rtp;
2283 		} else if (vrtp) {
2284 			instance = vrtp;
2285 #ifdef CS_SCCP_VIDEO
2286 			/* video requested by remote side, let's see if we support video */
2287  			/* should be moved to sccp_rtp.c */
2288 /*
2289 			if (ast_format_cap_has_type(codecs, AST_MEDIA_TYPE_VIDEO) && sccp_device_isVideoSupported(d) && sccp_channel_getVideoMode(c) == SCCP_VIDEO_MODE_AUTO) {
2290 				if (!c->rtp.video.instance && !sccp_rtp_createVideoServer(c)) {
2291 					sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_3 "%s: can not start vrtp\n", DEV_ID_LOG(d));
2292 				} else {
2293 					if (!c->rtp.video.transmission.state) {
2294 						sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_3 "%s: video rtp started\n", DEV_ID_LOG(d));
2295 						sccp_channel_startMultiMediaTransmission(c);
2296 					}
2297 				}
2298 			}
2299 */
2300 #endif
2301 		} else {
2302 			instance = trtp;
2303 		}
2304 
2305 		if (d->directrtp && d->nat < SCCP_NAT_ON && !nat_active && !c->conference) {			// assume directrtp
2306 			ast_rtp_instance_get_remote_address(instance, &sin_tmp);
2307 			memcpy(&sas, &sin_tmp, sizeof(struct sockaddr_storage));
2308 			//ast_sockaddr_to_sin(&sin_tmp, &sin);
2309 			if (d->nat == SCCP_NAT_OFF) {								// forced nat off to circumvent autodetection + direcrtp, requires checking both phone_ip and external session ip address against devices permit/deny
2310 				struct ast_sockaddr sin_local;
2311 				struct sockaddr_storage localsas = { 0, };
2312 				ast_rtp_instance_get_local_address(instance, &sin_local);
2313 				memcpy(&localsas, &sin_local, sizeof(struct sockaddr_storage));
2314 				if (sccp_apply_ha(d->ha, &sas) == AST_SENSE_ALLOW && sccp_apply_ha(d->ha, &localsas) == AST_SENSE_ALLOW) {
2315 					directmedia = TRUE;
2316 				}
2317 			} else if (sccp_apply_ha(d->ha, &sas) == AST_SENSE_ALLOW) {					// check remote sin against local device acl (to match netmask)
2318 				directmedia = TRUE;
2319 				// ast_channel_defer_dtmf(ast);
2320 			}
2321 		}
2322 		if (!directmedia) {										// fallback to indirectrtp
2323 			ast_rtp_instance_get_local_address(instance, &sin_tmp);
2324 			memcpy(&sas, &sin_tmp, sizeof(struct sockaddr_storage));
2325 			sccp_session_getOurIP(d->session, &sas, sccp_netsock_is_IPv4(&sas) ? AF_INET : AF_INET6);
2326 		}
2327 
2328 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_1 "%s: (update_rtp_peer) new remote rtp ip = '%s'\n (d->directrtp: %s && !d->nat: %s && !remote->nat_active: %s && d->acl_allow: %s) => directmedia=%s\n", c->currentDeviceId, sccp_netsock_stringify(&sas), S_COR(d->directrtp, "yes", "no"),
2329 					  sccp_nat2str(d->nat),
2330 					  S_COR(!nat_active, "yes", "no"), S_COR(directmedia, "yes", "no"), S_COR(directmedia, "yes", "no")
2331 		    );
2332 
2333 		if (rtp) {											// send peer info to phone
2334 			sccp_rtp_set_peer(c, &c->rtp.audio, &sas);
2335 			c->rtp.audio.directMedia = directmedia;
2336 		} else if (vrtp) {
2337 			sccp_rtp_set_peer(c, &c->rtp.video, &sas);
2338 			c->rtp.video.directMedia = directmedia;
2339 		} else {
2340 			//sccp_rtp_set_peer(c, &c->rtp.text, &sas);
2341 			//c->rtp.text.directMedia = directmedia;
2342 		}
2343 	} while (0);
2344 
2345 	/* Need a return here to break the bridge */
2346 	sccp_log(DEBUGCAT_RTP) (VERBOSE_PREFIX_3 "%s: (update_rtp_peer) Result: %d\n", c->currentDeviceId, result);
2347 	return result;
2348 }
2349 
sccp_astwrap_getCodec(PBX_CHANNEL_TYPE * ast,struct ast_format_cap * result)2350 static void sccp_astwrap_getCodec(PBX_CHANNEL_TYPE * ast, struct ast_format_cap *result)
2351 {
2352 	uint8_t i;
2353 	AUTO_RELEASE(sccp_channel_t, channel , get_sccp_channel_from_pbx_channel(ast));
2354 
2355 	if (!channel) {
2356 		sccp_log((DEBUGCAT_RTP | DEBUGCAT_CODEC)) (VERBOSE_PREFIX_1 "SCCP: (getCodec) NO PVT\n");
2357 		return;
2358 	}
2359 
2360 	ast_debug(10, "asterisk requests format for channel %s, readFormat: %s(%d)\n", pbx_channel_name(ast), codec2str(channel->rtp.audio.transmission.format), channel->rtp.audio.transmission.format);
2361 	for (i = 0; i < ARRAY_LEN(channel->preferences.audio); i++) {
2362 		struct ast_format *ast_format = sccp_astwrap_skinny2ast_format(channel->preferences.audio[i]);
2363 		if (ast_format != ast_format_none) {
2364 			unsigned int framing = ast_format_get_default_ms(ast_format);
2365 			ast_format_cap_append(result, ast_format, framing);
2366 		}
2367 	}
2368 	for (i = 0; i < ARRAY_LEN(channel->preferences.video); i++) {
2369 		struct ast_format *ast_format = sccp_astwrap_skinny2ast_format(channel->preferences.video[i]);
2370 		if (ast_format != ast_format_none) {
2371 			unsigned int framing = ast_format_get_default_ms(ast_format);
2372 			ast_format_cap_append(result, ast_format, framing);
2373 		}
2374 	}
2375 
2376 	return;
2377 }
2378 
2379 /*
2380  * \brief get callerid_name from pbx
2381  * \param sccp_channle Asterisk Channel
2382  * \param cid name result
2383  * \return parse result
2384  */
sccp_astwrap_callerid_name(PBX_CHANNEL_TYPE * pbx_chan,char ** cid_name)2385 static int sccp_astwrap_callerid_name(PBX_CHANNEL_TYPE *pbx_chan, char **cid_name)
2386 {
2387 	if (pbx_chan && ast_channel_caller(pbx_chan)->id.name.str && strlen(ast_channel_caller(pbx_chan)->id.name.str) > 0) {
2388 		*cid_name = pbx_strdup(ast_channel_caller(pbx_chan)->id.name.str);
2389 		return 1;
2390 	}
2391 
2392 	return 0;
2393 }
2394 
2395 /*
2396  * \brief get callerid_name from pbx
2397  * \param ast_chan Asterisk Channel
2398  * \return char * with the caller number
2399  */
sccp_astwrap_callerid_number(PBX_CHANNEL_TYPE * pbx_chan,char ** cid_number)2400 static int sccp_astwrap_callerid_number(PBX_CHANNEL_TYPE *pbx_chan, char **cid_number)
2401 {
2402 	if (pbx_chan && ast_channel_caller(pbx_chan)->id.number.str && strlen(ast_channel_caller(pbx_chan)->id.number.str) > 0) {
2403 		*cid_number = pbx_strdup(ast_channel_caller(pbx_chan)->id.number.str);
2404 		return 1;
2405 	}
2406 
2407 	return 0;
2408 }
2409 
2410 /*
2411  * \brief get callerid_ton from pbx
2412  * \param ast_chan Asterisk Channel
2413  * \return char * with the caller number
2414  */
sccp_astwrap_callerid_ton(PBX_CHANNEL_TYPE * pbx_chan,int * cid_ton)2415 static int sccp_astwrap_callerid_ton(PBX_CHANNEL_TYPE *pbx_chan, int *cid_ton)
2416 {
2417 	if (pbx_chan && ast_channel_caller(pbx_chan)->id.number.valid) {
2418 		*cid_ton = ast_channel_caller(pbx_chan)->ani.number.plan;
2419 		return *cid_ton;
2420 	}
2421 	return 0;
2422 }
2423 
2424 /*
2425  * \brief get callerid_ani from pbx
2426  * \param ast_chan Asterisk Channel
2427  * \return char * with the caller number
2428  */
sccp_astwrap_callerid_ani(PBX_CHANNEL_TYPE * pbx_chan,char ** cid_ani)2429 static int sccp_astwrap_callerid_ani(PBX_CHANNEL_TYPE *pbx_chan, char **cid_ani)
2430 {
2431 	if (pbx_chan && ast_channel_caller(pbx_chan)->ani.number.valid && ast_channel_caller(pbx_chan)->ani.number.str && strlen(ast_channel_caller(pbx_chan)->ani.number.str) > 0) {
2432 		*cid_ani = pbx_strdup(ast_channel_caller(pbx_chan)->ani.number.str);
2433 		return 1;
2434 	}
2435 
2436 	return 0;
2437 }
2438 
2439 /*
2440  * \brief get callerid_dnid from pbx
2441  * \param ast_chan Asterisk Channel
2442  * \return char * with the caller number
2443  */
sccp_astwrap_callerid_subaddr(PBX_CHANNEL_TYPE * pbx_chan,char ** cid_subaddr)2444 static int sccp_astwrap_callerid_subaddr(PBX_CHANNEL_TYPE *pbx_chan, char **cid_subaddr)
2445 {
2446 	if (pbx_chan && ast_channel_caller(pbx_chan)->id.subaddress.valid && ast_channel_caller(pbx_chan)->id.subaddress.str && strlen(ast_channel_caller(pbx_chan)->id.subaddress.str) > 0) {
2447 		*cid_subaddr = pbx_strdup(ast_channel_caller(pbx_chan)->id.subaddress.str);
2448 		return 1;
2449 	}
2450 
2451 	return 0;
2452 }
2453 
2454 /*
2455  * \brief get callerid_dnid from pbx (Destination ID)
2456  * \param ast_chan Asterisk Channel
2457  * \return char * with the caller number
2458  */
sccp_astwrap_callerid_dnid(PBX_CHANNEL_TYPE * pbx_chan,char ** cid_dnid)2459 static int sccp_astwrap_callerid_dnid(PBX_CHANNEL_TYPE *pbx_chan, char **cid_dnid)
2460 {
2461 	if (pbx_chan && ast_channel_dialed(pbx_chan)->number.str && strlen(ast_channel_dialed(pbx_chan)->number.str) > 0) {
2462 		*cid_dnid = pbx_strdup(ast_channel_dialed(pbx_chan)->number.str);
2463 		return 1;
2464 	}
2465 
2466 	return 0;
2467 }
2468 
2469 /*
2470  * \brief get callerid_rdnis from pbx
2471  * \param ast_chan Asterisk Channel
2472  * \return char * with the caller number
2473  */
sccp_astwrap_callerid_rdnis(PBX_CHANNEL_TYPE * pbx_chan,char ** cid_rdnis)2474 static int sccp_astwrap_callerid_rdnis(PBX_CHANNEL_TYPE *pbx_chan, char **cid_rdnis)
2475 {
2476 	if (pbx_chan && ast_channel_redirecting(pbx_chan)->from.number.valid && ast_channel_redirecting(pbx_chan)->from.number.str && strlen(ast_channel_redirecting(pbx_chan)->from.number.str) > 0) {
2477 		*cid_rdnis = pbx_strdup(ast_channel_redirecting(pbx_chan)->from.number.str);
2478 		return 1;
2479 	}
2480 
2481 	return 0;
2482 }
2483 
2484 /*
2485  * \brief get callerid_presence from pbx
2486  * \param ast_chan Asterisk Channel
2487  * \return char * with the caller number
2488  */
sccp_astwrap_callerid_presentation(PBX_CHANNEL_TYPE * pbx_chan)2489 static sccp_callerid_presentation_t sccp_astwrap_callerid_presentation(PBX_CHANNEL_TYPE *pbx_chan)
2490 {
2491 	if (pbx_chan && (ast_party_id_presentation(&ast_channel_caller(pbx_chan)->id) & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) {
2492 		return CALLERID_PRESENTATION_ALLOWED;
2493 	}
2494 	return CALLERID_PRESENTATION_FORBIDDEN;
2495 }
2496 
sccp_astwrap_createRtpInstance(constDevicePtr d,constChannelPtr c,sccp_rtp_t * rtp)2497 static boolean_t sccp_astwrap_createRtpInstance(constDevicePtr d, constChannelPtr c, sccp_rtp_t *rtp)
2498 {
2499 	uint32_t tos = 0, cos = 0;
2500 
2501 	if (!c || !d) {
2502 		return FALSE;
2503 	}
2504 	struct sockaddr_storage ourip = { 0 };
2505 	sccp_session_getOurIP(d->session, &ourip, 0);
2506 	struct ast_sockaddr sock = { {
2507 	    0,
2508 	} };
2509 	storage2ast_sockaddr(&ourip, &sock);
2510 
2511 	if ((rtp->instance = ast_rtp_instance_new("asterisk", sched, &sock, NULL))) {
2512 		struct ast_sockaddr instance_addr = { {0,} };
2513 		ast_rtp_instance_get_local_address(rtp->instance, &instance_addr);
2514 		sccp_log(DEBUGCAT_RTP) (VERBOSE_PREFIX_3 "%s: rtp server instance created at %s\n", c->designator, ast_sockaddr_stringify(&instance_addr));
2515 	} else {
2516 		return FALSE;
2517 	}
2518 
2519 	/* rest below should be moved out of here (refactoring required) */
2520 	PBX_RTP_TYPE *instance = rtp->instance;
2521 	char *rtp_map_filter = NULL;
2522 	//enum ast_media_type format_type = AST_MEDIA_TYPE_AUDIO;
2523 	int fd_offset = 0;
2524 	switch(rtp->type) {
2525 		case SCCP_RTP_AUDIO:
2526 			tos = d->audio_tos;
2527 			cos = d->audio_cos;
2528 			rtp_map_filter = "audio";
2529 			//format_type = AST_MEDIA_TYPE_AUDIO;
2530 			break;
2531 
2532 #if CS_SCCP_VIDEO
2533 		case SCCP_RTP_VIDEO:
2534 			tos = d->video_tos;
2535 			cos = d->video_cos;
2536 			rtp_map_filter = "video";
2537 			//format_type = AST_MEDIA_TYPE_VIDEO;
2538 			fd_offset = 2;
2539 			break;
2540 #endif
2541 		default:
2542 			pbx_log(LOG_ERROR, "%s: (wrapper_create_rtp) unknown/unhandled rtp type, returning instance for now\n", c->designator);
2543 			return TRUE;
2544 	}
2545 
2546 	if (c->owner) {
2547 		ast_rtp_instance_set_channel_id(instance, ast_channel_uniqueid(c->owner));
2548 		ast_channel_set_fd(c->owner, fd_offset, ast_rtp_instance_fd(instance, 0));		// RTP
2549 		ast_channel_set_fd(c->owner, fd_offset + 1, ast_rtp_instance_fd(instance, 1));		// RTCP
2550 	}
2551 	ast_rtp_instance_set_prop(instance, AST_RTP_PROPERTY_RTCP, 1);
2552 	ast_rtp_instance_set_qos(instance, tos, cos, "SCCP RTP");
2553 
2554 	if (rtp->type == SCCP_RTP_AUDIO) {
2555 		ast_rtp_instance_set_prop(instance, AST_RTP_PROPERTY_DTMF, 1);
2556 		sccp_log(DEBUGCAT_CODEC)(VERBOSE_PREFIX_2 "%s: update rtpmap: format:%s, payload:%d, mime:%s, rate:%d\n",
2557 			c->designator, "telephone-event", c->dtmfmode == SCCP_DTMFMODE_SKINNY ? 121 : 101, "audio", 0);
2558 		if (c->dtmfmode == SCCP_DTMFMODE_SKINNY) {
2559 			/* untested */
2560 			//ast_rtp_codecs_payloads_set_m_type(ast_rtp_instance_get_codecs(instance), instance, 121);
2561 			//if (ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(instance), instance, 121, rtp_map_filter, "cisco-telephone-event", 0)) {
2562 			//	ast_rtp_codecs_payloads_unset(ast_rtp_instance_get_codecs(instance), instance, 121);
2563 			//}
2564 			/* \untested */
2565 			ast_rtp_instance_set_prop(instance, AST_RTP_PROPERTY_DTMF_COMPENSATE, 1);
2566 			ast_rtp_instance_dtmf_mode_set(instance, AST_RTP_DTMF_MODE_INBAND);
2567 		} else {
2568 			ast_rtp_codecs_payloads_set_m_type(ast_rtp_instance_get_codecs(instance), instance, 101);
2569 			if (ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(instance), instance, 101, rtp_map_filter, "telephone-event", (enum ast_rtp_options)0)) {
2570 				ast_rtp_codecs_payloads_unset(ast_rtp_instance_get_codecs(instance), instance, 101);
2571 			}
2572 			ast_rtp_instance_dtmf_mode_set(instance, AST_RTP_DTMF_MODE_RFC2833);
2573 		}
2574 		sccp_log(DEBUGCAT_CODEC)(VERBOSE_PREFIX_2 "%s: update rtpmap: format:%s, payload:%d, mime:%s, rate:%d\n",
2575 			c->designator, "slin16", 25, "audio", 16000);
2576 		ast_rtp_codecs_payload_replace_format(ast_rtp_instance_get_codecs(instance), 25, ast_format_slin16);				// replace slin16 RTPPayloadType=25 (wideband-256)
2577 	}
2578 	ast_rtp_codecs_set_framing(ast_rtp_instance_get_codecs(instance), ast_format_cap_get_framing(ast_channel_nativeformats(c->owner)));
2579 
2580 	ast_rtp_instance_activate(instance);
2581 
2582 	if (c->owner) {
2583 		ast_queue_frame(c->owner, &ast_null_frame);
2584 	}
2585 
2586 	return TRUE;
2587 }
2588 
sccp_wrapper_get_codec_framing(constChannelPtr c)2589 static uint sccp_wrapper_get_codec_framing(constChannelPtr c)
2590 {
2591 	return ast_rtp_codecs_get_framing(ast_rtp_instance_get_codecs(c->rtp.audio.instance));
2592 }
2593 
sccp_wrapper_get_dtmf_payload_code(constChannelPtr c)2594 static uint sccp_wrapper_get_dtmf_payload_code(constChannelPtr c)
2595 {
2596 	int rtp_code = 0;
2597 	if (SCCP_DTMFMODE_SKINNY == c->dtmfmode) {
2598 		/* untested*/
2599 		//rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(c->rtp.audio.instance), 0, NULL, AST_RTP_CISCO_DTMF);	// 121
2600 		/* \untested */
2601 	} else {
2602 		rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(c->rtp.audio.instance), 0, NULL, AST_RTP_DTMF);		// 101
2603 	}
2604 	sccp_log(DEBUGCAT_RTP)(VERBOSE_PREFIX_3 "%s: Using dtmf rtp_code : %d\n", c->designator, rtp_code);
2605 	return rtp_code != -1 ? rtp_code : 0;
2606 }
2607 
sccp_astwrap_destroyRTP(PBX_RTP_TYPE * rtp)2608 static boolean_t sccp_astwrap_destroyRTP(PBX_RTP_TYPE * rtp)
2609 {
2610 	int res;
2611 
2612 	res = ast_rtp_instance_destroy(rtp);
2613 	return (!res) ? TRUE : FALSE;
2614 }
2615 
sccp_astwrap_checkHangup(constChannelPtr channel)2616 static boolean_t sccp_astwrap_checkHangup(constChannelPtr channel)
2617 {
2618 	int res;
2619 
2620 	res = ast_check_hangup(channel->owner);
2621 	return (!res) ? TRUE : FALSE;
2622 }
2623 
sccp_astwrap_rtpGetPeer(PBX_RTP_TYPE * rtp,struct sockaddr_storage * address)2624 static boolean_t sccp_astwrap_rtpGetPeer(PBX_RTP_TYPE * rtp, struct sockaddr_storage *address)
2625 {
2626 	struct ast_sockaddr addr;
2627 
2628 	ast_rtp_instance_get_remote_address(rtp, &addr);
2629 	memcpy(address, &addr.ss, sizeof(struct sockaddr_storage));
2630 	return TRUE;
2631 }
2632 
sccp_astwrap_rtpGetUs(PBX_RTP_TYPE * rtp,struct sockaddr_storage * address)2633 static boolean_t sccp_astwrap_rtpGetUs(PBX_RTP_TYPE * rtp, struct sockaddr_storage *address)
2634 {
2635 	struct ast_sockaddr addr;
2636 
2637 	ast_rtp_instance_get_local_address(rtp, &addr);
2638 	memcpy(address, &addr.ss, sizeof(struct sockaddr_storage));
2639 	return TRUE;
2640 }
2641 
sccp_astwrap_getChannelByName(const char * name,PBX_CHANNEL_TYPE ** pbx_channel)2642 static boolean_t sccp_astwrap_getChannelByName(const char *name, PBX_CHANNEL_TYPE ** pbx_channel)
2643 {
2644 	PBX_CHANNEL_TYPE *ast = ast_channel_get_by_name(name);
2645 
2646 	if (!ast) {
2647 		return FALSE;
2648 	}
2649 	pbx_channel_lock(ast);
2650 	*pbx_channel = pbx_channel_ref(ast);
2651 	pbx_channel_unlock(ast);
2652 	return TRUE;
2653 }
2654 
2655 //static int sccp_astwrap_rtp_set_peer(const struct sccp_rtp *rtp, const struct sockaddr_storage *new_peer, int nat_active)
sccp_astwrap_setPhoneRTPAddress(const struct sccp_rtp * rtp,const struct sockaddr_storage * new_peer,int nat_active)2656 static int sccp_astwrap_setPhoneRTPAddress(const struct sccp_rtp *rtp, const struct sockaddr_storage *new_peer, int nat_active)
2657 {
2658 	struct ast_sockaddr ast_sockaddr_dest;
2659 	int res;
2660 
2661 	memcpy(&ast_sockaddr_dest.ss, new_peer, sizeof(struct sockaddr_storage));
2662 	ast_sockaddr_dest.len = (ast_sockaddr_dest.ss.ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
2663 	res = ast_rtp_instance_set_remote_address(rtp->instance, &ast_sockaddr_dest);
2664 
2665 	sccp_log((DEBUGCAT_RTP | DEBUGCAT_HIGH)) (VERBOSE_PREFIX_3 "SCCP: (setPhoneRTPAddress) Update PBX to send RTP/UDP media to '%s' (new remote) (NAT: %s)\n", ast_sockaddr_stringify(&ast_sockaddr_dest), S_COR(nat_active, "yes", "no"));
2666 	if (nat_active) {
2667 		ast_rtp_instance_set_prop(rtp->instance, AST_RTP_PROPERTY_NAT, 1);
2668 	} else {
2669 		ast_rtp_instance_set_prop(rtp->instance, AST_RTP_PROPERTY_NAT, 0);
2670 	}
2671 	return res;
2672 }
2673 
2674 
sccp_astwrap_setCalleridName(PBX_CHANNEL_TYPE * pbx_channel,const char * name)2675 static void sccp_astwrap_setCalleridName(PBX_CHANNEL_TYPE *pbx_channel, const char *name)
2676 {
2677 	if (pbx_channel && name) {
2678 		ast_party_name_free(&ast_channel_caller(pbx_channel)->id.name);
2679 		ast_channel_caller(pbx_channel)->id.name.str = pbx_strdup(name);
2680 		ast_channel_caller(pbx_channel)->id.name.valid = 1;
2681 	}
2682 }
2683 
sccp_astwrap_setCalleridNumber(PBX_CHANNEL_TYPE * pbx_channel,const char * number)2684 static void sccp_astwrap_setCalleridNumber(PBX_CHANNEL_TYPE *pbx_channel, const char *number)
2685 {
2686 	if (pbx_channel && number) {
2687 		ast_party_number_free(&ast_channel_caller(pbx_channel)->id.number);
2688 		ast_channel_caller(pbx_channel)->id.number.str = pbx_strdup(number);
2689 		ast_channel_caller(pbx_channel)->id.number.valid = 1;
2690 	}
2691 }
2692 
sccp_astwrap_setCalleridAni(PBX_CHANNEL_TYPE * pbx_channel,const char * number)2693 static void sccp_astwrap_setCalleridAni(PBX_CHANNEL_TYPE *pbx_channel, const char *number)
2694 {
2695 	if (pbx_channel && number) {
2696 		ast_party_number_free(&ast_channel_caller(pbx_channel)->ani.number);
2697 		ast_channel_caller(pbx_channel)->ani.number.str = pbx_strdup(number);
2698 		ast_channel_caller(pbx_channel)->ani.number.valid = 1;
2699 	}
2700 }
2701 
sccp_astwrap_setRedirectingParty(PBX_CHANNEL_TYPE * pbx_channel,const char * number,const char * name)2702 static void sccp_astwrap_setRedirectingParty(PBX_CHANNEL_TYPE *pbx_channel, const char *number, const char *name)
2703 {
2704 	if (pbx_channel) {
2705 		if (number) {
2706 			ast_party_number_free(&ast_channel_redirecting(pbx_channel)->from.number);
2707 			ast_channel_redirecting(pbx_channel)->from.number.str = pbx_strdup(number);
2708 			ast_channel_redirecting(pbx_channel)->from.number.valid = 1;
2709 		}
2710 
2711 		if (name) {
2712 			ast_party_name_free(&ast_channel_redirecting(pbx_channel)->from.name);
2713 			ast_channel_redirecting(pbx_channel)->from.name.str = pbx_strdup(name);
2714 			ast_channel_redirecting(pbx_channel)->from.name.valid = 1;
2715 		}
2716 	}
2717 }
2718 
sccp_astwrap_setRedirectedParty(PBX_CHANNEL_TYPE * pbx_channel,const char * number,const char * name)2719 static void sccp_astwrap_setRedirectedParty(PBX_CHANNEL_TYPE *pbx_channel, const char *number, const char *name)
2720 {
2721 	if (pbx_channel) {
2722 		if (number) {
2723 			ast_party_number_free(&ast_channel_redirecting(pbx_channel)->to.number);
2724 			ast_channel_redirecting(pbx_channel)->to.number.str = pbx_strdup(number);
2725 			ast_channel_redirecting(pbx_channel)->to.number.valid = 1;
2726 		}
2727 
2728 		if (name) {
2729 			ast_party_name_free(&ast_channel_redirecting(pbx_channel)->to.name);
2730 			ast_channel_redirecting(pbx_channel)->to.name.str = pbx_strdup(name);
2731 			ast_channel_redirecting(pbx_channel)->to.name.valid = 1;
2732 		}
2733 	}
2734 }
2735 
sccp_astwrap_updateConnectedLine(constChannelPtr channel,const char * number,const char * name,uint8_t reason)2736 static void sccp_astwrap_updateConnectedLine(constChannelPtr channel, const char *number, const char *name, uint8_t reason)
2737 {
2738 	if (!channel || !channel->owner) {
2739 		return;
2740 	}
2741 	__sccp_astwrap_updateConnectedLine(channel->owner, number,name, reason);
2742 }
2743 
sccp_astwrap_sched_add(int when,sccp_sched_cb callback,const void * data)2744 static int sccp_astwrap_sched_add(int when, sccp_sched_cb callback, const void *data)
2745 {
2746 	if (sched) {
2747 		return ast_sched_add(sched, when, callback, data);
2748 	}
2749 	return -1;
2750 }
2751 
sccp_astwrap_sched_del(int id)2752 static int sccp_astwrap_sched_del(int id)
2753 {
2754 	if (sched) {
2755 		return AST_SCHED_DEL(sched, id);
2756 	}
2757 	return -1;
2758 }
2759 
sccp_astwrap_sched_add_ref(int * id,int when,sccp_sched_cb callback,sccp_channel_t * channel)2760 static int sccp_astwrap_sched_add_ref(int *id, int when, sccp_sched_cb callback, sccp_channel_t * channel)
2761 {
2762 	if (sched && channel) {
2763 		sccp_channel_t *c = sccp_channel_retain(channel);
2764 
2765 		if (c) {
2766 			if ((*id  = ast_sched_add(sched, when, callback, c)) < 0) {
2767 				sccp_log(DEBUGCAT_CORE)(VERBOSE_PREFIX_3 "%s: sched add id:%d, when:%d, failed\n", c->designator, *id, when);
2768 				sccp_channel_release(&channel);			/* explicit release during failure */
2769 			}
2770 			return *id;
2771 		}
2772 	}
2773 	return -2;
2774 }
2775 
sccp_astwrap_sched_del_ref(int * id,sccp_channel_t * channel)2776 static int sccp_astwrap_sched_del_ref(int *id, sccp_channel_t *channel)
2777 {
2778 	if (sched) {
2779 		AST_SCHED_DEL_UNREF(sched, *id, sccp_channel_release(&channel));
2780 		return *id;
2781 	}
2782 	return -2;
2783 }
2784 
sccp_astwrap_sched_replace_ref(int * id,int when,ast_sched_cb callback,sccp_channel_t * channel)2785 static int sccp_astwrap_sched_replace_ref(int *id, int when, ast_sched_cb callback, sccp_channel_t *channel)
2786 {
2787 	if (sched) {
2788 		//sccp_log(DEBUGCAT_CORE)(VERBOSE_PREFIX_3 "%s: (sched_replace_ref) replacing id: %d\n", channel->designator, *id);
2789 		AST_SCHED_REPLACE_UNREF(*id, sched, when, callback, channel, sccp_channel_release((sccp_channel_t **)&_data), sccp_channel_release(&channel), sccp_channel_retain(channel));	/* explicit retain/release */
2790 		//sccp_log(DEBUGCAT_CORE)(VERBOSE_PREFIX_3 "%s: (sched_replace_ref) returning id: %d\n", channel->designator, *id);
2791 		return *id;
2792 	}
2793 	return -2;
2794 }
2795 
sccp_astwrap_sched_when(int id)2796 static long sccp_astwrap_sched_when(int id)
2797 {
2798 	if (sched) {
2799 		return ast_sched_when(sched, id);
2800 	}
2801 	return FALSE;
2802 }
2803 
sccp_astwrap_sched_wait(int id)2804 static int sccp_astwrap_sched_wait(int id)
2805 {
2806 	if (sched) {
2807 		return ast_sched_wait(sched);
2808 	}
2809 	return FALSE;
2810 }
2811 
sccp_astwrap_setCallState(constChannelPtr channel,enum ast_channel_state state)2812 static int sccp_astwrap_setCallState(constChannelPtr channel, enum ast_channel_state state)
2813 {
2814         if (channel && channel->owner) {
2815 		pbx_setstate(channel->owner, state);
2816 	}
2817 	return 0;
2818 }
2819 
sccp_astwrap_getRemoteChannel(constChannelPtr channel,PBX_CHANNEL_TYPE ** pbx_channel)2820 static boolean_t sccp_astwrap_getRemoteChannel(constChannelPtr channel, PBX_CHANNEL_TYPE ** pbx_channel)
2821 {
2822 
2823 	PBX_CHANNEL_TYPE *remotePeer = NULL;
2824 
2825 	/*
2826 	struct ast_channel_iterator *iterator = ast_channel_iterator_all_new();
2827 	((struct ao2_iterator *)iterator)->flags |= AO2_ITERATOR_DONTLOCK;
2828 	for (; (remotePeer = ast_channel_iterator_next(iterator)); pbx_channel_unref(remotePeer)) {
2829 		if (pbx_find_channel_by_linkid(remotePeer, (void *)ast_channel_linkedid(channel->owner))) {
2830 			break;
2831 		}
2832 	}
2833 	while(!(remotePeer = ast_channel_iterator_next(iterator) ){
2834 		pbx_channel_unref(remotePeer);
2835 	}
2836 	ast_channel_iterator_destroy(iterator);
2837 	if (remotePeer) {
2838 		*pbx_channel = remotePeer;
2839 		remotePeer = pbx_channel_unref(remotePeer);                     //  should we be releasing th referenec here, it has not been taken explicitly.
2840 		return TRUE;
2841 	}
2842 	*/
2843 	*pbx_channel = remotePeer;
2844 	return FALSE;
2845 }
2846 
2847 /*!
2848  * \brief Send Text to Asterisk Channel
2849  * \param ast Asterisk Channel as ast_channel
2850  * \param text Text to be send as char
2851  * \return Succes as int
2852  *
2853  * \called_from_asterisk
2854  */
sccp_pbx_sendtext(PBX_CHANNEL_TYPE * ast,const char * text)2855 static int sccp_pbx_sendtext(PBX_CHANNEL_TYPE * ast, const char *text)
2856 {
2857 	uint8_t instance;
2858 
2859 	if (!ast) {
2860 		sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "SCCP: No PBX CHANNEL to send text to\n");
2861 		return -1;
2862 	}
2863 
2864 	AUTO_RELEASE(sccp_channel_t, c , get_sccp_channel_from_pbx_channel(ast));
2865 	if (!c) {
2866 		sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "SCCP: No SCCP CHANNEL to send text to (%s)\n", pbx_channel_name(ast));
2867 		return -1;
2868 	}
2869 
2870 	AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(c));
2871 	if (!d) {
2872 		sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "SCCP: No SCCP DEVICE to send text to (%s)\n", pbx_channel_name(ast));
2873 		return -1;
2874 	}
2875 
2876 	sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: Sending text %s on %s\n", d->id, text, pbx_channel_name(ast));
2877 
2878 	instance = sccp_device_find_index_for_line(d, c->line->name);
2879 	sccp_dev_displayprompt(d, instance, c->callid, (char *) text, 10);
2880 	return 0;
2881 }
2882 
2883 /*!
2884  * \brief Receive First Digit from Asterisk Channel
2885  * \param ast Asterisk Channel as ast_channel
2886  * \param digit First Digit as char
2887  * \return Always Return -1 as int
2888  *
2889  * \called_from_asterisk
2890  */
sccp_wrapper_recvdigit_begin(PBX_CHANNEL_TYPE * ast,char digit)2891 static int sccp_wrapper_recvdigit_begin(PBX_CHANNEL_TYPE * ast, char digit)
2892 {
2893 	return -1;
2894 }
2895 
2896 /*!
2897  * \brief Receive Last Digit from Asterisk Channel
2898  * \param ast Asterisk Channel as ast_channel
2899  * \param digit Last Digit as char
2900  * \param duration Duration as int
2901  * \return boolean
2902  *
2903  * \called_from_asterisk
2904  */
sccp_wrapper_recvdigit_end(PBX_CHANNEL_TYPE * ast,char digit,unsigned int duration)2905 static int sccp_wrapper_recvdigit_end(PBX_CHANNEL_TYPE * ast, char digit, unsigned int duration)
2906 {
2907 	AUTO_RELEASE(sccp_channel_t, c , get_sccp_channel_from_pbx_channel(ast));
2908 	if (c) {
2909 		if (c->dtmfmode == SCCP_DTMFMODE_RFC2833) {
2910 			sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: Channel(%s) DTMF Mode is RFC2833. Skipping...\n", c->designator, pbx_channel_name(ast));
2911 			return -1;
2912 		}
2913 
2914 		AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(c));
2915 		if (!d) {
2916 			sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "SCCP: No SCCP DEVICE to send digit to (%s)\n", pbx_channel_name(ast));
2917 			return -1;
2918 		}
2919 
2920 		sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: Asterisk asked to send dtmf '%d' to channel %s. Trying to send it %s\n", d->id, digit, pbx_channel_name(ast), sccp_dtmfmode2str(d->dtmfmode));
2921 		if (c->state != SCCP_CHANNELSTATE_CONNECTED) {
2922 			sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "%s: Can't send the dtmf '%d' %c to a not connected channel %s\n", d->id, digit, digit, pbx_channel_name(ast));
2923 			return -1;
2924 		}
2925 		sccp_dev_keypadbutton(d, digit, sccp_device_find_index_for_line(d, c->line->name), c->callid);
2926 	} else {
2927 		sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_3 "SCCP: No SCCP CHANNEL to send digit to (%s)\n", pbx_channel_name(ast));
2928 		return -1;
2929 	}
2930 
2931 	return -1;
2932 }
2933 
sccp_astwrap_findChannelWithCallback(int (* const found_cb)(PBX_CHANNEL_TYPE * c,void * data),void * data,boolean_t lock)2934 static PBX_CHANNEL_TYPE *sccp_astwrap_findChannelWithCallback(int (*const found_cb) (PBX_CHANNEL_TYPE * c, void *data), void *data, boolean_t lock)
2935 {
2936 	PBX_CHANNEL_TYPE *remotePeer = NULL;
2937 
2938 	/*
2939 	struct ast_channel_iterator *iterator = ast_channel_iterator_all_new();
2940 	if (!lock) {
2941 		((struct ao2_iterator *)iterator)->flags |= AO2_ITERATOR_DONTLOCK;
2942 	}
2943 	for (; (remotePeer = ast_channel_iterator_next(iterator)); remotePeer = pbx_channel_unref(remotePeer)) {
2944 		if (found_cb(remotePeer, data)) {
2945 			// ast_channel_lock(remotePeer);
2946 			pbx_channel_unref(remotePeer);
2947 			break;
2948 		}
2949 	}
2950 	ast_channel_iterator_destroy(iterator);
2951 	*/
2952 
2953 	return remotePeer;
2954 }
2955 
2956 /*! \brief Set an option on a asterisk channel */
2957 #if 0
2958 static int sccp_astwrap_setOption(PBX_CHANNEL_TYPE * ast, int option, void *data, int datalen)
2959 {
2960 	int res = -1;
2961 	AUTO_RELEASE(sccp_channel_t, c , get_sccp_channel_from_pbx_channel(ast));
2962 
2963 	if (c) {
2964 		sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_2 "%s: channel: %s(%s) setOption: %d\n", c->currentDeviceId, sccp_channel_toString(c), pbx_channel_name(ast), option);
2965 		//! if AST_OPTION_FORMAT_READ / AST_OPTION_FORMAT_WRITE are available we might be indication that we can do transcoding (channel.c:set_format). Correct ? */
2966 		switch (option) {
2967 			case AST_OPTION_FORMAT_READ:
2968 				if (c->rtp.audio.instance) {
2969 					res = ast_rtp_instance_set_read_format(c->rtp.audio.instance, (struct ast_format *) data);
2970 				}
2971 				//sccp_astwrap_setReadFormat(c, (struct ast_format *) data);
2972 				break;
2973 			case AST_OPTION_FORMAT_WRITE:
2974 				if (c->rtp.audio.instance) {
2975 					res = ast_rtp_instance_set_write_format(c->rtp.audio.instance, (struct ast_format *) data);
2976 				}
2977 				//sccp_astwrap_setWriteFormat(c, (struct ast_format *) data);
2978 				break;
2979 
2980 			case AST_OPTION_MAKE_COMPATIBLE:
2981 				if (c->rtp.audio.instance) {
2982 					res = ast_rtp_instance_make_compatible(ast, c->rtp.audio.instance, (PBX_CHANNEL_TYPE *) data);
2983 				}
2984 				break;
2985 			case AST_OPTION_DIGIT_DETECT:
2986 			case AST_OPTION_SECURE_SIGNALING:
2987 			case AST_OPTION_SECURE_MEDIA:
2988 				res = -1;
2989 				break;
2990 			default:
2991 				break;
2992 		}
2993 	}
2994 	return res;
2995 }
2996 #endif
2997 
sccp_astwrap_set_pbxchannel_linkedid(PBX_CHANNEL_TYPE * pbx_channel,const char * new_linkedid)2998 static void sccp_astwrap_set_pbxchannel_linkedid(PBX_CHANNEL_TYPE * pbx_channel, const char *new_linkedid)
2999 {
3000 	if (pbx_channel) {
3001 		if (!strcmp(ast_channel_linkedid(pbx_channel), new_linkedid)) {
3002 			return;
3003 		}
3004 		// ast_cel_check_retire_linkedid(pbx_channel);
3005 		// ast_channel_linkedid_set(pbx_channel, new_linkedid);
3006 		// ast_cel_linkedid_ref(new_linkedid);
3007 	}
3008 };
3009 
3010 #define DECLARE_PBX_CHANNEL_STRGET(_field) 									\
3011 static const char *sccp_astwrap_get_channel_##_field(constChannelPtr channel)	 		\
3012 {														\
3013 	static const char *empty_channel_##_field = "--no-channel" #_field "--";				\
3014 	if (channel && channel->owner) {											\
3015 		return ast_channel_##_field(channel->owner);							\
3016 	}													\
3017 	return empty_channel_##_field;										\
3018 };
3019 
3020 #define DECLARE_PBX_CHANNEL_STRSET(_field)									\
3021 static void sccp_astwrap_set_channel_##_field(constChannelPtr channel, const char * (_field))	\
3022 { 														\
3023 	if (channel && channel->owner) {											\
3024 		ast_channel_##_field##_set(channel->owner, _field);						\
3025 	}													\
3026 };
3027 
3028 DECLARE_PBX_CHANNEL_STRGET(name)
DECLARE_PBX_CHANNEL_STRSET(name)3029     DECLARE_PBX_CHANNEL_STRSET(name)
3030     DECLARE_PBX_CHANNEL_STRGET(uniqueid)
3031     DECLARE_PBX_CHANNEL_STRGET(appl)
3032     DECLARE_PBX_CHANNEL_STRGET(exten)
3033     DECLARE_PBX_CHANNEL_STRSET(exten)
3034     DECLARE_PBX_CHANNEL_STRGET(linkedid)
3035     DECLARE_PBX_CHANNEL_STRGET(context)
3036     DECLARE_PBX_CHANNEL_STRSET(context)
3037     DECLARE_PBX_CHANNEL_STRGET(macroexten)
3038     DECLARE_PBX_CHANNEL_STRSET(macroexten)
3039     DECLARE_PBX_CHANNEL_STRGET(macrocontext)
3040     DECLARE_PBX_CHANNEL_STRSET(macrocontext)
3041     DECLARE_PBX_CHANNEL_STRGET(call_forward)
3042     DECLARE_PBX_CHANNEL_STRSET(call_forward)
3043 
3044 static void sccp_astwrap_set_channel_linkedid(constChannelPtr channel, const char *new_linkedid)
3045 {
3046 	if (channel && channel->owner) {
3047 		sccp_astwrap_set_pbxchannel_linkedid(channel->owner, new_linkedid);
3048 	}
3049 };
3050 
sccp_astwrap_get_channel_state(constChannelPtr channel)3051 static enum ast_channel_state sccp_astwrap_get_channel_state(constChannelPtr channel)
3052 {
3053 	if (channel && channel->owner) {
3054 		return ast_channel_state(channel->owner);
3055 	}
3056 	return (enum ast_channel_state) 0;
3057 }
3058 
sccp_astwrap_get_channel_pbx(constChannelPtr channel)3059 static const struct ast_pbx *sccp_astwrap_get_channel_pbx(constChannelPtr channel)
3060 {
3061 	if (channel && channel->owner) {
3062 		return ast_channel_pbx(channel->owner);
3063 	}
3064 	return NULL;
3065 }
3066 
sccp_pbx_sendHTML(PBX_CHANNEL_TYPE * ast,int subclass,const char * data,int datalen)3067 static int sccp_pbx_sendHTML(PBX_CHANNEL_TYPE * ast, int subclass, const char *data, int datalen)
3068 {
3069 	int res = -1;
3070 	if (!datalen || sccp_strlen_zero(data) || !(!strncmp(data, "http://", 7) || !strncmp(data, "file://", 7) || !strncmp(data, "ftp://", 6))) {
3071 		pbx_log(LOG_NOTICE, "SCCP: Received a non valid URL\n");
3072 		return res;
3073 	}
3074 	struct ast_frame fr;
3075 
3076 	AUTO_RELEASE(sccp_channel_t, c , get_sccp_channel_from_pbx_channel(ast));
3077 	if (c) {
3078 		AUTO_RELEASE(sccp_device_t, d , c->getDevice(c));
3079 		if (d) {
3080 			memset(&fr, 0, sizeof(fr));
3081 			fr.frametype = AST_FRAME_HTML;
3082 			fr.data.ptr = (char *) data;
3083 			fr.src = "SCCP Send URL";
3084 			fr.datalen = datalen;
3085 
3086 			sccp_push_result_t pushResult = d->pushURL(d, data, 1, SKINNY_TONE_ZIP);
3087 
3088 			if (SCCP_PUSH_RESULT_SUCCESS == pushResult) {
3089 				fr.subclass.integer = AST_HTML_LDCOMPLETE;
3090 			} else {
3091 				fr.subclass.integer = AST_HTML_NOSUPPORT;
3092 			}
3093 			ast_queue_frame(ast, ast_frisolate(&fr));
3094 			res = 0;
3095 		}
3096 	}
3097 	return res;
3098 }
3099 
3100 /*!
3101  * \brief Queue a control frame
3102  * \param pbx_channel PBX Channel
3103  * \param control as Asterisk Control Frame Type
3104  */
sccp_astwrap_queue_control(const PBX_CHANNEL_TYPE * pbx_channel,enum ast_control_frame_type control)3105 int sccp_astwrap_queue_control(const PBX_CHANNEL_TYPE * pbx_channel, enum ast_control_frame_type control)
3106 {
3107 	struct ast_frame f = { AST_FRAME_CONTROL,.subclass.integer = control };
3108 	return ast_queue_frame((PBX_CHANNEL_TYPE *) pbx_channel, &f);
3109 }
3110 
3111 /*!
3112  * \brief Queue a control frame with payload
3113  * \param pbx_channel PBX Channel
3114  * \param control as Asterisk Control Frame Type
3115  * \param data Payload
3116  * \param datalen Payload Length
3117  */
sccp_astwrap_queue_control_data(const PBX_CHANNEL_TYPE * pbx_channel,enum ast_control_frame_type control,const void * data,size_t datalen)3118 int sccp_astwrap_queue_control_data(const PBX_CHANNEL_TYPE * pbx_channel, enum ast_control_frame_type control, const void *data, size_t datalen)
3119 {
3120 	struct ast_frame f = { AST_FRAME_CONTROL,.subclass.integer = control,.data.ptr = (void *) data,.datalen = datalen };
3121 	return ast_queue_frame((PBX_CHANNEL_TYPE *) pbx_channel, &f);
3122 }
3123 
3124 /*!
3125  * \brief Get Hint Extension State and return the matching Busy Lamp Field State
3126  */
sccp_astwrap_getExtensionState(const char * extension,const char * context)3127 static skinny_busylampfield_state_t sccp_astwrap_getExtensionState(const char *extension, const char *context)
3128 {
3129 	skinny_busylampfield_state_t result = SKINNY_BLF_STATUS_UNKNOWN;
3130 
3131 	if (sccp_strlen_zero(extension) || sccp_strlen_zero(context)) {
3132 		pbx_log(LOG_ERROR, "SCCP: iPbx.getExtensionState: Either extension:'%s' or context:;%s' provided is empty\n", extension, context);
3133 		return result;
3134 	}
3135 
3136 	int state = ast_extension_state(NULL, context, extension);
3137 
3138 	switch (state) {
3139 		case AST_EXTENSION_REMOVED:
3140 		case AST_EXTENSION_DEACTIVATED:
3141 		case AST_EXTENSION_UNAVAILABLE:
3142 			result = SKINNY_BLF_STATUS_UNKNOWN;
3143 			break;
3144 		case AST_EXTENSION_NOT_INUSE:
3145 			result = SKINNY_BLF_STATUS_IDLE;
3146 			break;
3147 		case AST_EXTENSION_INUSE:
3148 		case AST_EXTENSION_ONHOLD:
3149 		case AST_EXTENSION_ONHOLD + AST_EXTENSION_INUSE:
3150 			result = SKINNY_BLF_STATUS_INUSE;
3151 			break;
3152 		case AST_EXTENSION_BUSY:
3153 			result = SKINNY_BLF_STATUS_DND;
3154 			break;
3155 		case AST_EXTENSION_RINGING + AST_EXTENSION_INUSE:
3156 		case AST_EXTENSION_RINGING:
3157 			result = SKINNY_BLF_STATUS_ALERTING;
3158 			break;
3159 	}
3160 	sccp_log(DEBUGCAT_HINT) (VERBOSE_PREFIX_4 "SCCP: (getExtensionState) extension: %s@%s, extension_state: '%s (%d)' -> blf state '%d'\n", extension, context, ast_extension_state2str(state), state, result);
3161 	return result;
3162 }
3163 
sccp_astwrap_endpoint_create(const char * tech,const char * resource)3164 static struct ast_endpoint *sccp_astwrap_endpoint_create(const char *tech, const char *resource)
3165 {
3166 	return ast_endpoint_create(tech, resource);
3167 }
3168 
sccp_astwrap_endpoint_online(struct ast_endpoint * endpoint,const char * address)3169 static void sccp_astwrap_endpoint_online(struct ast_endpoint *endpoint, const char *address)
3170 {
3171 	RAII(struct ast_json *, blob, NULL, ast_json_unref);
3172 	ast_endpoint_set_state(endpoint, AST_ENDPOINT_ONLINE);
3173 	blob = ast_json_pack("{s: s, s: s}", "peer_status", "Registered", "address", address);
3174 	ast_endpoint_blob_publish(endpoint, ast_endpoint_state_type(), blob);
3175 }
3176 
sccp_astwrap_endpoint_offline(struct ast_endpoint * endpoint,const char * cause)3177 static void sccp_astwrap_endpoint_offline(struct ast_endpoint *endpoint, const char *cause)
3178 {
3179 	RAII(struct ast_json *, blob, NULL, ast_json_unref);
3180 	ast_endpoint_set_state(endpoint, AST_ENDPOINT_OFFLINE);
3181 	blob = ast_json_pack("{s: s, s: s}", "peer_status", "Unregistered", "cause", cause);
3182 	ast_endpoint_blob_publish(endpoint, ast_endpoint_state_type(), blob);
3183 }
3184 
sccp_astwrap_endpoint_shutdown(struct ast_endpoint ** endpoint)3185 static void sccp_astwrap_endpoint_shutdown(struct ast_endpoint **endpoint)
3186 {
3187 	ast_endpoint_shutdown(*endpoint);
3188 	*endpoint = NULL;
3189 }
3190 
sccp_astwrap_dumpchan(PBX_CHANNEL_TYPE * const c,char * const buf,size_t size)3191 static int sccp_astwrap_dumpchan(PBX_CHANNEL_TYPE * const c, char * const buf, size_t size)
3192 {
3193 	long elapsed_seconds = 0;
3194 	int hour = 0, min = 0, sec = 0;
3195 	char cgrp[256];
3196 	char pgrp[256];
3197 	pbx_str_t *write_transpath = pbx_str_alloca(256);
3198 	pbx_str_t *read_transpath = pbx_str_alloca(256);
3199 	struct ast_bridge *bridge;
3200 	struct ast_str *vars = ast_str_thread_get(&ast_str_thread_global_buf, 16);
3201 	pbx_str_t *codec_buf = pbx_str_alloca(64);
3202 
3203 	memset(buf, 0, size);
3204 	if (!c) {
3205 		return -1;
3206 	}
3207 
3208 	elapsed_seconds = ast_channel_get_duration(c);
3209 	hour = elapsed_seconds / 3600;
3210 	min = (elapsed_seconds % 3600) / 60;
3211 	sec = elapsed_seconds % 60;
3212 
3213 	ast_channel_lock(c);
3214 	bridge = ast_channel_get_bridge(c);
3215 	ast_channel_unlock(c);
3216 
3217 	pbx_builtin_serialize_variables(c, &vars);
3218 
3219 	snprintf(buf, size, "Name=               %s\n"
3220 				"Type=               %s\n"
3221 				"UniqueID=           %s\n"
3222 				"LinkedID=           %s\n"
3223 				"CallerIDNum=        %s\n"
3224 				"CallerIDName=       %s\n"
3225 				"ConnectedLineIDNum= %s\n"
3226 				"ConnectedLineIDName=%s\n"
3227 				"DNIDDigits=         %s\n"
3228 				"RDNIS=              %s\n"
3229 				"Parkinglot=         %s\n"
3230 				"Language=           %s\n"
3231 				"State=              %s (%d)\n"
3232 				"Rings=              %d\n"
3233 				"NativeFormat=       %s\n"
3234 				"WriteFormat=        %s\n"
3235 				"ReadFormat=         %s\n"
3236 				"RawWriteFormat=     %s\n"
3237 				"RawReadFormat=      %s\n"
3238 				"WriteTranscode=     %s %s\n"
3239 				"ReadTranscode=      %s %s\n"
3240 				"1stFileDescriptor=  %d\n"
3241 				"Framesin=           %d %s\n"
3242 				"Framesout=          %d %s\n"
3243 				"TimetoHangup=       %ld\n"
3244 				"ElapsedTime=        %dh%dm%ds\n"
3245 				"BridgeID=           %s\n"
3246 				"Context=            %s\n"
3247 				"Extension=          %s\n"
3248 				"Priority=           %d\n"
3249 				"CallGroup=          %s\n"
3250 				"PickupGroup=        %s\n"
3251 				"Application=        %s\n"
3252 				"Data=               %s\n"
3253 				"Blocking_in=        %s\n"
3254 				"Variables=          %s\n",
3255 		ast_channel_name(c),
3256 		ast_channel_tech(c)->type,
3257 		ast_channel_uniqueid(c),
3258 		ast_channel_linkedid(c),
3259 		S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, "(N/A)"),
3260 		S_COR(ast_channel_caller(c)->id.name.valid, ast_channel_caller(c)->id.name.str, "(N/A)"),
3261 		S_COR(ast_channel_connected(c)->id.number.valid, ast_channel_connected(c)->id.number.str, "(N/A)"),
3262 		S_COR(ast_channel_connected(c)->id.name.valid, ast_channel_connected(c)->id.name.str, "(N/A)"),
3263 		S_OR(ast_channel_dialed(c)->number.str, "(N/A)"),
3264 		S_COR(ast_channel_redirecting(c)->from.number.valid, ast_channel_redirecting(c)->from.number.str, "(N/A)"),
3265 		ast_channel_parkinglot(c),
3266 		ast_channel_language(c),
3267 		ast_state2str(ast_channel_state(c)),
3268 		ast_channel_state(c),
3269 		ast_channel_rings(c),
3270 		ast_format_cap_get_names(ast_channel_nativeformats(c), &codec_buf),	//ast_getformatname_multiple(nf, sizeof(nf), ast_channel_nativeformats(c)),
3271 		ast_format_get_name(ast_channel_writeformat(c)),
3272 		ast_format_get_name(ast_channel_readformat(c)),
3273 		ast_format_get_name(ast_channel_rawwriteformat(c)),
3274 		ast_format_get_name(ast_channel_rawreadformat(c)),
3275 		ast_channel_writetrans(c) ? "Yes" : "No",
3276 		ast_translate_path_to_str(ast_channel_writetrans(c), &write_transpath),
3277 		ast_channel_readtrans(c) ? "Yes" : "No",
3278 		ast_translate_path_to_str(ast_channel_readtrans(c), &read_transpath),
3279 		ast_channel_fd(c, 0),
3280 		ast_channel_fin(c) & ~DEBUGCHAN_FLAG, (ast_channel_fin(c) & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
3281 		ast_channel_fout(c) & ~DEBUGCHAN_FLAG, (ast_channel_fout(c) & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
3282 		(long) ast_channel_whentohangup(c)->tv_sec,
3283 		hour,
3284 		min,
3285 		sec,
3286 		bridge ? bridge->uniqueid : "(Not bridged)",
3287 		ast_channel_context(c),
3288 		ast_channel_exten(c),
3289 		ast_channel_priority(c),
3290 		ast_print_group(cgrp, sizeof(cgrp), ast_channel_callgroup(c)),
3291 		ast_print_group(pgrp, sizeof(pgrp), ast_channel_pickupgroup(c)),
3292 		ast_channel_appl(c) ? ast_channel_appl(c) : "(N/A)",
3293 		ast_channel_data(c) ? S_OR(ast_channel_data(c), "(Empty)") : "(None)",
3294 		(ast_test_flag(ast_channel_flags(c), AST_FLAG_BLOCKING) ? ast_channel_blockproc(c) : "(Not Blocking)"),
3295 		ast_str_buffer(vars)
3296 	);
3297 
3298 	ao2_cleanup(bridge);
3299 	return 0;
3300 }
3301 
sccp_astwrap_channelIsBridged(sccp_channel_t * channel)3302 static boolean_t sccp_astwrap_channelIsBridged(sccp_channel_t * channel)
3303 {
3304 	boolean_t res = FALSE;
3305 
3306 	if (!channel || !channel->owner) {
3307 		return res;
3308 	}
3309 	ast_channel_lock(channel->owner);
3310 	res = ast_channel_is_bridged(channel->owner);
3311 	ast_channel_unlock(channel->owner);
3312 	return res;
3313 }
3314 
sccp_astwrap_getBridgeChannel(PBX_CHANNEL_TYPE * pbx_channel)3315 static PBX_CHANNEL_TYPE *sccp_astwrap_getBridgeChannel(PBX_CHANNEL_TYPE * pbx_channel)
3316 {
3317 	PBX_CHANNEL_TYPE *bridgePeer = NULL;
3318 	if (pbx_channel) {
3319 		bridgePeer = ast_channel_bridge_peer(pbx_channel);		/* return pbx_channel_ref +1 */
3320 	}
3321 	return bridgePeer;
3322 }
3323 
sccp_astwrap_attended_transfer(sccp_channel_t * destination_channel,sccp_channel_t * source_channel)3324 static boolean_t sccp_astwrap_attended_transfer(sccp_channel_t * destination_channel, sccp_channel_t * source_channel)
3325 {
3326 	enum ast_transfer_result res;
3327 	// possibly move transfer related callinfo updates here
3328 	if (!destination_channel || !source_channel || !destination_channel->owner || !source_channel->owner) {
3329 		return FALSE;
3330 	}
3331 	PBX_CHANNEL_TYPE *pbx_destination_local_channel = destination_channel->owner;
3332 	PBX_CHANNEL_TYPE *pbx_source_local_channel = source_channel->owner;
3333 
3334 	res = ast_bridge_transfer_attended(pbx_destination_local_channel, pbx_source_local_channel);
3335 	if (res != AST_BRIDGE_TRANSFER_SUCCESS) {
3336 		pbx_log(LOG_ERROR, "%s: Failed to transfer %s to %s (%u)\n", source_channel->designator, source_channel->designator, destination_channel->designator, res);
3337 		ast_queue_control(pbx_destination_local_channel, AST_CONTROL_HOLD);
3338 		return FALSE;
3339 	}
3340 	return TRUE;
3341 }
3342 
3343 /*!
3344  * \brief using RTP Glue Engine
3345  */
3346 #if defined(__cplusplus) || defined(c_plusplus)
3347 struct ast_rtp_glue sccp_rtp = {
3348 	/* *INDENT-OFF* */
3349 	type:	SCCP_TECHTYPE_STR,
3350 	mod:	NULL,
3351 	get_rtp_info:sccp_astwrap_get_rtp_info,
3352 	//allow_rtp_remote:sccp_astwrap_allow_rtp_remote, 		/* check c->directmedia and return 1 if ok */
3353 	get_vrtp_info:sccp_astwrap_get_vrtp_info,
3354 	//allow_vrtp_remote:sccp_astwrap_allow_vrtp_remote, 	/* check c->directmedia and return 1 if ok */
3355 	get_trtp_info:NULL,
3356 	update_peer:sccp_astwrap_update_rtp_peer,
3357 	get_codec:sccp_astwrap_getCodec,
3358 	/* *INDENT-ON* */
3359 };
3360 #else
3361 struct ast_rtp_glue sccp_rtp = {
3362 	.type = SCCP_TECHTYPE_STR,
3363 	.get_rtp_info = sccp_astwrap_get_rtp_info,
3364 	//.allow_rtp_remote = sccp_astwrap_allow_rtp_remote, 	/* check c->directmedia and return 1 if ok */
3365 	.get_vrtp_info = sccp_astwrap_get_vrtp_info,
3366 	//.allow_vrtp_remote = sccp_astwrap_allow_vrtp_remote, 	/* check c->directmedia and return 1 if ok */
3367 	.update_peer = sccp_astwrap_update_rtp_peer,
3368 	.get_codec = sccp_astwrap_getCodec,
3369 };
3370 #endif
3371 
3372 #ifdef HAVE_PBX_MESSAGE_H
3373 #include <asterisk/message.h>
sccp_astwrap_message_send(const struct ast_msg * msg,const char * to,const char * from)3374 static int sccp_astwrap_message_send(const struct ast_msg *msg, const char *to, const char *from)
3375 {
3376 	char *lineName;
3377 	const char *messageText = ast_msg_get_body(msg);
3378 	int res = -1;
3379 
3380 	lineName = pbx_strdupa(to);
3381 	if (strchr(lineName, '@')) {
3382 		strsep(&lineName, "@");
3383 	} else {
3384 		strsep(&lineName, ":");
3385 	}
3386 	if (sccp_strlen_zero(lineName)) {
3387 		pbx_log(LOG_WARNING, "MESSAGE(to) is invalid for SCCP - '%s'\n", to);
3388 		return -1;
3389 	}
3390 
3391 	AUTO_RELEASE(sccp_line_t, line , sccp_line_find_byname(lineName, FALSE));
3392 	if (!line) {
3393 		pbx_log(LOG_WARNING, "line '%s' not found\n", lineName);
3394 		return -1;
3395 	}
3396 
3397 	/** \todo move this to line implementation */
3398 	sccp_linedevice_t * ld = NULL;
3399 	sccp_push_result_t pushResult;
3400 
3401 	SCCP_LIST_LOCK(&line->devices);
3402 	SCCP_LIST_TRAVERSE(&line->devices, ld, list) {
3403 		pushResult = ld->device->pushTextMessage(ld->device, messageText, from, 1, SKINNY_TONE_ZIP);
3404 		if (SCCP_PUSH_RESULT_SUCCESS == pushResult) {
3405 			res = 0;
3406 		}
3407 	}
3408 	SCCP_LIST_UNLOCK(&line->devices);
3409 
3410 	return res;
3411 }
3412 
3413 #if defined(__cplusplus) || defined(c_plusplus)
3414 static const struct ast_msg_tech sccp_msg_tech = {
3415 	/* *INDENT-OFF* */
3416 	name:	"sccp",
3417 	msg_send:sccp_astwrap_message_send,
3418 	/* *INDENT-ON* */
3419 };
3420 #else
3421 static const struct ast_msg_tech sccp_msg_tech = {
3422 	/* *INDENT-OFF* */
3423 	.name = "sccp",
3424 	.msg_send = sccp_astwrap_message_send,
3425 	/* *INDENT-ON* */
3426 };
3427 #endif
3428 
3429 #endif
3430 
3431 /*!
3432  * \brief pbx_manager_register
3433  *
3434  * \note this functions needs to be defined here, because it depends on the static declaration of pbx_module_info->self
3435  */
pbx_manager_register(const char * action,int authority,int (* func)(struct mansession * s,const struct message * m),const char * synopsis,const char * description)3436 int pbx_manager_register(const char * action, int authority, int (*func)(struct mansession * s, const struct message * m), const char * synopsis, const char * description)
3437 {
3438 #if defined(__cplusplus) || defined(c_plusplus)
3439 	return 0;
3440 #else
3441 	return ast_manager_register2(action, authority, func, pbx_module_info->self, synopsis, description);
3442 #endif
3443 }
3444 
sccp_wrapper_register_manager(const char * action,int authority,int (* func)(struct mansession * s,const struct message * m),const char * synopsis,const char * description)3445 static int sccp_wrapper_register_manager(const char * action, int authority, int (*func)(struct mansession * s, const struct message * m), const char * synopsis, const char * description)
3446 {
3447 #if defined(__cplusplus) || defined(c_plusplus)
3448 	return 0;
3449 #else
3450 	return ast_manager_register2(action, authority, func, ast_module_info->self, synopsis, description);
3451 #endif
3452 }
3453 
sccp_wrapper_register_application(const char * app_name,int (* execute)(struct ast_channel *,const char *))3454 static int sccp_wrapper_register_application(const char *app_name, int (*execute)(struct ast_channel *, const char *))
3455 {
3456 #if defined(__cplusplus) || defined(c_plusplus)
3457 	return 0;
3458 #else
3459 	return ast_register_application2(app_name, execute, NULL, NULL, ast_module_info->self);
3460 #endif
3461 }
3462 
sccp_wrapper_unregister_application(const char * app_name)3463 static int sccp_wrapper_unregister_application(const char *app_name)
3464 {
3465 	return ast_unregister_application(app_name);
3466 }
3467 
sccp_wrapper_register_function(struct pbx_custom_function * custom_function)3468 static int sccp_wrapper_register_function(struct pbx_custom_function *custom_function)
3469 {
3470 #if defined(__cplusplus) || defined(c_plusplus)
3471 	return 0;
3472 #else
3473 	return __ast_custom_function_register(custom_function, ast_module_info->self);
3474 #endif
3475 }
3476 
sccp_wrapper_unregister_function(struct pbx_custom_function * custom_function)3477 static int sccp_wrapper_unregister_function(struct pbx_custom_function *custom_function)
3478 {
3479 	return ast_custom_function_unregister(custom_function);
3480 }
3481 
sccp_astwrap_setLanguage(PBX_CHANNEL_TYPE * pbxChannel,const char * language)3482 static boolean_t sccp_astwrap_setLanguage(PBX_CHANNEL_TYPE * pbxChannel, const char *language)
3483 {
3484 	ast_channel_language_set(pbxChannel, language);
3485 	return TRUE;
3486 }
3487 
3488 #if defined(__cplusplus) || defined(c_plusplus)
3489 //sccp_pbx_cb sccp_pbx = {
3490 const PbxInterface iPbx = {
3491 	/* *INDENT-OFF* */
3492 
3493 	/* channel */
3494 	alloc_pbxChannel: sccp_astwrap_allocPBXChannel,
3495 	extension_status: sccp_astwrap_extensionStatus,
3496 	setPBXChannelLinkedId: sccp_astwrap_set_pbxchannel_linkedid,
3497 
3498 	getChannelByName: sccp_astwrap_getChannelByName,
3499 	getChannelLinkedId: sccp_astwrap_get_channel_linkedid,
3500 	setChannelLinkedId: sccp_astwrap_set_channel_linkedid,
3501 	getChannelName: sccp_astwrap_get_channel_name,
3502 	setChannelName: sccp_astwrap_set_channel_name,
3503 	getChannelUniqueID: sccp_astwrap_get_channel_uniqueid,
3504 	getChannelExten: sccp_astwrap_get_channel_exten,
3505 	setChannelExten: sccp_astwrap_set_channel_exten,
3506 	getChannelContext: sccp_astwrap_get_channel_context,
3507 	setChannelContext: sccp_astwrap_set_channel_context,
3508 	getChannelMacroExten: sccp_astwrap_get_channel_macroexten,
3509 	setChannelMacroExten: sccp_astwrap_set_channel_macroexten,
3510 	getChannelMacroContext: sccp_astwrap_get_channel_macrocontext,
3511 	setChannelMacroContext: sccp_astwrap_set_channel_macrocontext,
3512 	getChannelCallForward: sccp_astwrap_get_channel_call_forward,
3513 	setChannelCallForward: sccp_astwrap_set_channel_call_forward,
3514 
3515 	getChannelAppl: sccp_astwrap_get_channel_appl,
3516 	getChannelState: sccp_astwrap_get_channel_state,
3517 	getChannelPbx: sccp_astwrap_get_channel_pbx,
3518 
3519 	getRemoteChannel: sccp_astwrap_getRemoteChannel,
3520 	checkhangup: sccp_astwrap_checkHangup,
3521 
3522 	/* digits */
3523 	send_digits: sccp_wrapper_sendDigits,
3524 	send_digit: sccp_wrapper_sendDigit,
3525 
3526 	/* schedulers */
3527 	sched_add: sccp_astwrap_sched_add,
3528 	sched_del: sccp_astwrap_sched_del,
3529 	sched_add_ref: sccp_astwrap_sched_add_ref,
3530 	sched_del_ref: sccp_astwrap_sched_del_ref,
3531 	sched_replace_ref: sccp_astwrap_sched_replace_ref,
3532 	sched_when: sccp_astwrap_sched_when,
3533 	sched_wait: sccp_astwrap_sched_wait,
3534 
3535 	/* callstate / indicate */
3536 	set_callstate: sccp_astwrap_setCallState,
3537 
3538 	/* codecs */
3539 	set_nativeAudioFormats: sccp_astwrap_setNativeAudioFormats,
3540 	set_nativeVideoFormats: sccp_astwrap_setNativeVideoFormats,
3541 
3542 	/* rtp */
3543 	rtp_getPeer: sccp_astwrap_rtpGetPeer,
3544 	rtp_getUs: sccp_astwrap_rtpGetUs,
3545 	rtp_stop: ast_rtp_instance_stop,
3546 	rtp_create_instance: sccp_astwrap_createRtpInstance,
3547 	rtp_get_payloadType: sccp_astwrap_get_payloadType,
3548 	rtp_get_sampleRate: sccp_astwrap_get_sampleRate,
3549 	rtp_destroy: sccp_astwrap_destroyRTP,
3550 	rtp_setWriteFormat: sccp_astwrap_setWriteFormat,
3551 	rtp_setReadFormat: sccp_astwrap_setReadFormat,
3552 	rtp_setPhoneAddress: sccp_astwrap_setPhoneRTPAddress,
3553 
3554 	/* callerid */
3555 	get_callerid_name: sccp_astwrap_callerid_name,
3556 	get_callerid_number: sccp_astwrap_callerid_number,
3557 	get_callerid_ton: sccp_astwrap_callerid_ton,
3558 	get_callerid_ani: sccp_astwrap_callerid_ani,
3559 	get_callerid_subaddr: sccp_astwrap_callerid_subaddr,
3560 	get_callerid_dnid: sccp_astwrap_callerid_dnid,
3561 	get_callerid_rdnis: sccp_astwrap_callerid_rdnis,
3562 	get_callerid_presentation: sccp_astwrap_callerid_presentation,
3563 
3564 	set_callerid_name: sccp_astwrap_setCalleridName,
3565 	set_callerid_number: sccp_astwrap_setCalleridNumber,
3566 	set_callerid_ani: sccp_astwrap_setCalleridAni,
3567 	set_callerid_dnid: NULL,                                        //! \todo implement callback
3568 	set_callerid_redirectingParty: sccp_astwrap_setRedirectingParty,
3569 	set_callerid_redirectedParty: sccp_astwrap_setRedirectedParty,
3570 	set_callerid_presentation: sccp_astwrap_setCalleridPresentation,
3571 	set_dialed_number: sccp_astwrap_setDialedNumber,
3572 	set_connected_line: sccp_astwrap_updateConnectedLine,
3573 	sendRedirectedUpdate: sccp_astwrap_sendRedirectedUpdate,
3574 
3575 	/* database */
3576 	feature_addToDatabase: sccp_astwrap_addToDatabase,
3577 	feature_getFromDatabase: sccp_astwrap_getFromDatabase,
3578 	feature_removeFromDatabase: sccp_astwrap_removeFromDatabase,
3579 	feature_removeTreeFromDatabase: sccp_astwrap_removeTreeFromDatabase,
3580 	feature_monitor: sccp_astgenwrap_featureMonitor,
3581 
3582 	feature_park: sccp_astwrap_park,
3583 	getFeatureExtension: sccp_astwrap_getFeatureExtension,
3584 	getPickupExtension: sccp_astwrap_getPickupExtension,
3585 
3586 	findChannelByCallback: sccp_astwrap_findChannelWithCallback,
3587 
3588 	moh_start: sccp_astwrap_moh_start,
3589 	moh_stop: sccp_astwrap_moh_stop,
3590 	queue_control: sccp_astwrap_queue_control,
3591 	queue_control_data: sccp_astwrap_queue_control_data,
3592 
3593 	allocTempPBXChannel: sccp_astwrap_allocTempPBXChannel,
3594 	masqueradeHelper: sccp_astwrap_masqueradeHelper,
3595 	requestAnnouncementChannel: sccp_astwrap_requestAnnouncementChannel,
3596 
3597 	set_language: sccp_astwrap_setLanguage,
3598 
3599 	getExtensionState: sccp_astwrap_getExtensionState,
3600 	findPickupChannelByExtenLocked: sccp_astwrap_findPickupChannelByExtenLocked,
3601 	findPickupChannelByGroupLocked: sccp_astwrap_findPickupChannelByGroupLocked,
3602 
3603 	endpoint_create: sccp_astwrap_endpoint_create,
3604 	endpoint_online: sccp_astwrap_endpoint_online,
3605 	endpoint_offline: sccp_astwrap_endpoint_offline,
3606 	endpoint_shutdown: sccp_astwrap_endpoint_shutdown,
3607 
3608 	set_owner: sccp_astwrap_setOwner,
3609 	removeTimingFD: sccp_astwrap_removeTimingFD,
3610 	dumpchan: sccp_astwrap_dumpchan,
3611 	channel_is_bridged: sccp_astwrap_channelIsBridged,
3612 	get_bridged_channel: sccp_astwrap_getBridgeChannel,
3613 	get_underlying_channel: sccp_astwrap_getBridgeChannel,
3614 	attended_transfer: sccp_astwrap_attended_transfer,
3615 
3616 	set_callgroup: sccp_astgenwrap_set_callgroup,
3617 	set_pickupgroup: sccp_astgenwrap_set_pickupgroup,
3618 	set_named_callgroups: sccp_astgenwrap_set_named_callgroups,
3619 	set_named_pickupgroups: sccp_astgenwrap_set_named_pickupgroups,
3620 
3621 	register_manager: sccp_wrapper_register_manager,
3622 	register_application: sccp_wrapper_register_application,
3623 	unregister_application: sccp_wrapper_unregister_application,
3624 	register_function: sccp_wrapper_register_function,
3625 	unregister_function: sccp_wrapper_unregister_function,
3626 
3627 	get_codec_framing: sccp_wrapper_get_codec_framing,
3628 	get_dtmf_payload_code: sccp_wrapper_get_dtmf_payload_code,
3629 
3630 	retrieve_remote_capabilities: pbx_retrieve_remote_capabilities,
3631 	/* *INDENT-ON* */
3632 };
3633 
3634 #else
3635 
3636 /*!
3637  * \brief SCCP - PBX Callback Functions
3638  * (Decoupling Tight Dependencies on Asterisk Functions)
3639  */
3640 //struct sccp_pbx_cb sccp_pbx = {
3641 const PbxInterface iPbx = {
3642 	/* *INDENT-OFF* */
3643 
3644 	/* channel */
3645 	.alloc_pbxChannel = sccp_astwrap_allocPBXChannel,
3646 	.extension_status = sccp_astwrap_extensionStatus,
3647 	.setPBXChannelLinkedId = sccp_astwrap_set_pbxchannel_linkedid,
3648 
3649 	.getChannelByName = sccp_astwrap_getChannelByName,
3650 	.getChannelLinkedId = sccp_astwrap_get_channel_linkedid,
3651 	.setChannelLinkedId = sccp_astwrap_set_channel_linkedid,
3652 	.getChannelName = sccp_astwrap_get_channel_name,
3653 	.setChannelName = sccp_astwrap_set_channel_name,
3654 	.getChannelUniqueID = sccp_astwrap_get_channel_uniqueid,
3655 	.getChannelExten = sccp_astwrap_get_channel_exten,
3656 	.setChannelExten = sccp_astwrap_set_channel_exten,
3657 	.getChannelContext = sccp_astwrap_get_channel_context,
3658 	.setChannelContext = sccp_astwrap_set_channel_context,
3659 	.getChannelMacroExten = sccp_astwrap_get_channel_macroexten,
3660 	.setChannelMacroExten = sccp_astwrap_set_channel_macroexten,
3661 	.getChannelMacroContext = sccp_astwrap_get_channel_macrocontext,
3662 	.setChannelMacroContext = sccp_astwrap_set_channel_macrocontext,
3663 	.getChannelCallForward = sccp_astwrap_get_channel_call_forward,
3664 	.setChannelCallForward = sccp_astwrap_set_channel_call_forward,
3665 
3666 	.getChannelAppl = sccp_astwrap_get_channel_appl,
3667 	.getChannelState = sccp_astwrap_get_channel_state,
3668 	.getChannelPbx = sccp_astwrap_get_channel_pbx,
3669 
3670 	.getRemoteChannel = sccp_astwrap_getRemoteChannel,
3671 	.checkhangup = sccp_astwrap_checkHangup,
3672 
3673 	/* digits */
3674 	.send_digits = sccp_wrapper_sendDigits,
3675 	.send_digit = sccp_wrapper_sendDigit,
3676 
3677 	/* schedulers */
3678 	.sched_add = sccp_astwrap_sched_add,
3679 	.sched_del = sccp_astwrap_sched_del,
3680 	.sched_add_ref = sccp_astwrap_sched_add_ref,
3681 	.sched_del_ref = sccp_astwrap_sched_del_ref,
3682 	.sched_replace_ref = sccp_astwrap_sched_replace_ref,
3683 	.sched_when = sccp_astwrap_sched_when,
3684 	.sched_wait = sccp_astwrap_sched_wait,
3685 
3686 	/* callstate / indicate */
3687 	.set_callstate = sccp_astwrap_setCallState,
3688 
3689 	/* codecs */
3690 	.set_nativeAudioFormats = sccp_astwrap_setNativeAudioFormats,
3691 	.set_nativeVideoFormats = sccp_astwrap_setNativeVideoFormats,
3692 
3693 	/* rtp */
3694 	.rtp_getPeer = sccp_astwrap_rtpGetPeer,
3695 	.rtp_getUs = sccp_astwrap_rtpGetUs,
3696 	.rtp_stop = ast_rtp_instance_stop,
3697 	.rtp_create_instance = sccp_astwrap_createRtpInstance,
3698 	.rtp_get_payloadType = sccp_astwrap_get_payloadType,
3699 	.rtp_get_sampleRate = sccp_astwrap_get_sampleRate,
3700 	.rtp_destroy = sccp_astwrap_destroyRTP,
3701 	.rtp_setWriteFormat = sccp_astwrap_setWriteFormat,
3702 	.rtp_setReadFormat = sccp_astwrap_setReadFormat,
3703 	.rtp_setPhoneAddress = sccp_astwrap_setPhoneRTPAddress,
3704 
3705 	/* callerid */
3706 	.get_callerid_name = sccp_astwrap_callerid_name,
3707 	.get_callerid_number = sccp_astwrap_callerid_number,
3708 	.get_callerid_ton = sccp_astwrap_callerid_ton,
3709 	.get_callerid_ani = sccp_astwrap_callerid_ani,
3710 	.get_callerid_subaddr = sccp_astwrap_callerid_subaddr,
3711 	.get_callerid_dnid = sccp_astwrap_callerid_dnid,
3712 	.get_callerid_rdnis = sccp_astwrap_callerid_rdnis,
3713 	.get_callerid_presentation = sccp_astwrap_callerid_presentation,
3714 
3715 	.set_callerid_name = sccp_astwrap_setCalleridName,
3716 	.set_callerid_number = sccp_astwrap_setCalleridNumber,
3717 	.set_callerid_ani = sccp_astwrap_setCalleridAni,
3718 	.set_callerid_dnid = NULL,                                        //! \todo implement callback
3719 	.set_callerid_redirectingParty = sccp_astwrap_setRedirectingParty,
3720 	.set_callerid_redirectedParty = sccp_astwrap_setRedirectedParty,
3721 	.set_callerid_presentation = sccp_astwrap_setCalleridPresentation,
3722 	.set_dialed_number = sccp_astwrap_setDialedNumber,
3723 	.set_connected_line = sccp_astwrap_updateConnectedLine,
3724 	.sendRedirectedUpdate = sccp_astwrap_sendRedirectedUpdate,
3725 
3726 	/* database */
3727 	.feature_addToDatabase = sccp_astwrap_addToDatabase,
3728 	.feature_getFromDatabase = sccp_astwrap_getFromDatabase,
3729 	.feature_removeFromDatabase = sccp_astwrap_removeFromDatabase,
3730 	.feature_removeTreeFromDatabase = sccp_astwrap_removeTreeFromDatabase,
3731 	.feature_monitor = sccp_astgenwrap_featureMonitor,
3732 
3733 	.feature_park = sccp_astwrap_park,
3734 	.getFeatureExtension = sccp_astwrap_getFeatureExtension,
3735 	.getPickupExtension = sccp_astwrap_getPickupExtension,
3736 
3737 	.findChannelByCallback = sccp_astwrap_findChannelWithCallback,
3738 
3739 	.moh_start = sccp_astwrap_moh_start,
3740 	.moh_stop = sccp_astwrap_moh_stop,
3741 	.queue_control = sccp_astwrap_queue_control,
3742 	.queue_control_data = sccp_astwrap_queue_control_data,
3743 
3744 	.allocTempPBXChannel = sccp_astwrap_allocTempPBXChannel,
3745 	.masqueradeHelper = sccp_astwrap_masqueradeHelper,
3746 	.requestAnnouncementChannel = sccp_astwrap_requestAnnouncementChannel,
3747 
3748 	.set_language = sccp_astwrap_setLanguage,
3749 
3750 	.getExtensionState = sccp_astwrap_getExtensionState,
3751 	.findPickupChannelByExtenLocked = sccp_astwrap_findPickupChannelByExtenLocked,
3752 	.findPickupChannelByGroupLocked = sccp_astwrap_findPickupChannelByGroupLocked,
3753 
3754 	.endpoint_create = sccp_astwrap_endpoint_create,
3755 	.endpoint_online = sccp_astwrap_endpoint_online,
3756 	.endpoint_offline = sccp_astwrap_endpoint_offline,
3757 	.endpoint_shutdown = sccp_astwrap_endpoint_shutdown,
3758 
3759 	.set_owner = sccp_astwrap_setOwner,
3760 	.removeTimingFD = sccp_astwrap_removeTimingFD,
3761 	.dumpchan = sccp_astwrap_dumpchan,
3762 	.channel_is_bridged = sccp_astwrap_channelIsBridged,
3763 	.get_bridged_channel = sccp_astwrap_getBridgeChannel,
3764 	.get_underlying_channel = sccp_astwrap_getBridgeChannel,
3765 	.attended_transfer = sccp_astwrap_attended_transfer,
3766 
3767 	.set_callgroup = sccp_astgenwrap_set_callgroup,
3768 	.set_pickupgroup = sccp_astgenwrap_set_pickupgroup,
3769 	.set_named_callgroups = sccp_astgenwrap_set_named_callgroups,
3770 	.set_named_pickupgroups = sccp_astgenwrap_set_named_pickupgroups,
3771 
3772 	.register_manager = sccp_wrapper_register_manager,
3773 	.register_application = sccp_wrapper_register_application,
3774 	.unregister_application = sccp_wrapper_unregister_application,
3775 	.register_function = sccp_wrapper_register_function,
3776 	.unregister_function = sccp_wrapper_unregister_function,
3777 
3778 	.get_codec_framing = sccp_wrapper_get_codec_framing,
3779 	.get_dtmf_payload_code = sccp_wrapper_get_dtmf_payload_code,
3780 
3781 	.retrieve_remote_capabilities = pbx_retrieve_remote_capabilities,
3782 	/* *INDENT-ON* */
3783 };
3784 #endif
3785 
register_channel_tech(struct ast_channel_tech * tech)3786 static int register_channel_tech(struct ast_channel_tech *tech)
3787 {
3788 	tech->capabilities = ast_format_cap_alloc((enum ast_format_cap_flags)0);
3789 	if (!tech->capabilities) {
3790 		ao2_cleanup(tech->capabilities);
3791 		return -1;
3792 	}
3793 	ast_format_cap_append_by_type(tech->capabilities, AST_MEDIA_TYPE_AUDIO);
3794 	ast_format_cap_append_by_type(tech->capabilities, AST_MEDIA_TYPE_VIDEO);
3795 	//ast_format_cap_append_by_type(tech->capabilities, AST_MEDIA_TYPE_TEXT);
3796 	//pbx_format_cap_append_skinny(tech->capabilities, GLOB(global_preferences));
3797 
3798 	if (ast_channel_register(tech)) {
3799 		ast_log(LOG_ERROR, "Unable to register channel technology %s(%s).\n", tech->type, tech->description);
3800 		return -1;
3801 	}
3802 	return 0;
3803 }
3804 
unregister_channel_tech(struct ast_channel_tech * tech)3805 static void unregister_channel_tech(struct ast_channel_tech *tech)
3806 {
3807 	ast_channel_unregister(tech);
3808 	if (tech->capabilities) {
3809 		ao2_ref(tech->capabilities, -1);
3810 	}
3811 	tech->capabilities = NULL;
3812 	tech = NULL;
3813 }
3814 
unload_module(void)3815 static int unload_module(void)
3816 {
3817 	pbx_log(LOG_NOTICE, "SCCP: Module Unload\n");
3818 	sccp_preUnload();
3819 	sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_2 "SCCP: Unregister SCCP RTP protocol\n");
3820 	ast_rtp_glue_unregister(&sccp_rtp);
3821 	sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_2 "SCCP: Unregister SCCP Channel Tech\n");
3822 
3823 	unregister_channel_tech(&sccp_tech);
3824 	sccp_unregister_dialplan_functions();
3825 	sccp_unregister_cli();
3826 #ifdef CS_SCCP_MANAGER
3827 	sccp_unregister_management();
3828 #endif
3829 #ifdef HAVE_PBX_MESSAGE_H
3830 	ast_msg_tech_unregister(&sccp_msg_tech);
3831 #endif
3832 #ifdef CS_SCCP_CONFERENCE
3833 	unregister_channel_tech(sccpconf_announce_get_tech());
3834 #endif
3835 	if (io) {
3836 		io_context_destroy(io);
3837 		io = NULL;
3838 	}
3839 
3840 	while (SCCP_REF_DESTROYED != sccp_refcount_isRunning()) {
3841 		usleep(SCCP_TIME_TO_KEEP_REFCOUNTEDOBJECT);							// give enough time for all schedules to end and refcounted object to be cleanup completely
3842 	}
3843 
3844 	if (sched) {
3845 		pbx_log(LOG_NOTICE, "Cleaning up scheduled items:\n");
3846 		int scheduled_items = 0;
3847 
3848 		ast_sched_dump(sched);
3849 		while ((scheduled_items = ast_sched_runq(sched))) {
3850 			pbx_log(LOG_NOTICE, "Cleaning up %d scheduled items... please wait\n", scheduled_items);
3851 			usleep(ast_sched_wait(sched));
3852 		}
3853 		ast_sched_context_destroy(sched);
3854 		sched = NULL;
3855 	}
3856 
3857 	pbx_log(LOG_NOTICE, "Running Cleanup\n");
3858 	sccp_free(sccp_globals);
3859 	pbx_log(LOG_NOTICE, "Module chan_sccp unloaded\n");
3860 	return 0;
3861 }
3862 
load_module(void)3863 static enum ast_module_load_result load_module(void)
3864 {
3865 	if (ast_module_check("chan_skinny.so")) {
3866 		pbx_log(LOG_ERROR, "Chan_skinny is loaded. Please check modules.conf and remove chan_skinny before loading chan_sccp.\n");
3867 		return AST_MODULE_LOAD_SUCCESS;
3868 	}
3869 
3870 	enum ast_module_load_result res = AST_MODULE_LOAD_DECLINE;
3871 	do {
3872 		if (!(sched = ast_sched_context_create())) {
3873 			pbx_log(LOG_WARNING, "Unable to create schedule context. SCCP channel type disabled\n");
3874 			break;
3875 		}
3876 		if (ast_sched_start_thread(sched)) {
3877 			pbx_log(LOG_ERROR, "Unable to start scheduler\n");
3878 			ast_sched_context_destroy(sched);
3879 			sched = NULL;
3880 			break;
3881 		}
3882 #if defined(CS_DEVSTATE_FEATURE) || defined(CS_USE_ASTERISK_DISTRIBUTED_DEVSTATE)
3883 		// ast_enable_distributed_devstate();
3884 #endif
3885 		if (!sccp_prePBXLoad()) {
3886 			pbx_log(LOG_ERROR, "SCCP: prePBXLoad Failed\n");
3887 			break;
3888 		}
3889 		if (!(io = io_context_create())) {
3890 			pbx_log(LOG_ERROR, "Unable to create I/O context. SCCP channel type disabled\n");
3891 			break;
3892 		}
3893 		if (!load_config()) {
3894 			pbx_log(LOG_ERROR, "SCCP: config file could not be parsed\n");
3895 			res = AST_MODULE_LOAD_DECLINE;
3896 			break;
3897 		}
3898 		if (register_channel_tech(&sccp_tech)) {
3899 			pbx_log(LOG_ERROR, "Unable to register channel class SCCP\n");
3900 			break;
3901 		}
3902 #ifdef HAVE_PBX_MESSAGE_H
3903 		if (ast_msg_tech_register(&sccp_msg_tech)) {
3904 			pbx_log(LOG_ERROR, "Unable to register message interface\n");
3905 			break;
3906 		}
3907 #endif
3908 
3909 #ifdef CS_SCCP_CONFERENCE
3910 		if (register_channel_tech(sccpconf_announce_get_tech())) {
3911 			pbx_log(LOG_ERROR, "Unable to register channel class ANNOUNCE (conference)\n");
3912 			break;
3913 		}
3914 #endif
3915 		if (ast_rtp_glue_register(&sccp_rtp)) {
3916 			pbx_log(LOG_ERROR, "Unable to register RTP Glue\n");
3917 			break;
3918 		}
3919 		if (sccp_register_management()) {
3920 			pbx_log(LOG_ERROR, "Unable to register management functions");
3921 			break;
3922 		}
3923 		if (sccp_register_cli()) {
3924 			pbx_log(LOG_ERROR, "Unable to register CLI functions");
3925 			break;
3926 		}
3927 		if (sccp_register_dialplan_functions()) {
3928 			pbx_log(LOG_ERROR, "Unable to register dialplan functions");
3929 			break;
3930 		}
3931 		if (!sccp_postPBX_load()) {
3932 			pbx_log(LOG_ERROR, "SCCP: postPBXLoad Failed\n");
3933 			break;
3934 		}
3935 		res = AST_MODULE_LOAD_SUCCESS;
3936 	} while (0);
3937 
3938 	if (res != AST_MODULE_LOAD_SUCCESS) {
3939 		pbx_log(LOG_ERROR, "SCCP: Module Load Failed, unloading...\n");
3940 		unload_module();
3941 		return res;
3942 	}
3943 	return res;
3944 }
3945 
module_reload(void)3946 static int module_reload(void)
3947 {
3948 	return sccp_reload();
3949 }
3950 
3951 #if defined(__cplusplus) || defined(c_plusplus)
3952 static struct ast_module_info __mod_info = {
3953 	NULL,
3954 	load_module,
3955 	module_reload,
3956 	unload_module,
3957 	NULL,
3958 	NULL,
3959 	AST_MODULE,
3960 	SCCP_VERSIONSTR,
3961 	ASTERISK_GPL_KEY,
3962 	AST_MODFLAG_LOAD_ORDER,
3963 	AST_BUILDOPT_SUM,
3964 	AST_MODPRI_CHANNEL_DRIVER,
3965 	NULL,
3966 };
3967 
__reg_module(void)3968 static void __attribute__ ((constructor)) __reg_module(void)
3969 {
3970 	ast_module_register(&__mod_info);
3971 }
3972 
__unreg_module(void)3973 static void __attribute__ ((destructor)) __unreg_module(void)
3974 {
3975 	ast_module_unregister(&__mod_info);
3976 }
3977 
3978 static const __attribute__ ((unused))
3979 struct ast_module_info *ast_module_info = &__mod_info;
3980 #else
3981 AST_MODULE_INFO(
3982 	ASTERISK_GPL_KEY,
3983 	AST_MODFLAG_LOAD_ORDER,
3984 	SCCP_VERSIONSTR,
3985 	.load = load_module,
3986 	.unload = unload_module,
3987 	.reload = module_reload,
3988 	.load_pri = AST_MODPRI_DEFAULT,
3989 	.nonoptreq = "chan_local"
3990 );
3991 #endif
3992 
sccp_astwrap_findPickupChannelByExtenLocked(PBX_CHANNEL_TYPE * chan,const char * exten,const char * context)3993 PBX_CHANNEL_TYPE *sccp_astwrap_findPickupChannelByExtenLocked(PBX_CHANNEL_TYPE * chan, const char *exten, const char *context)
3994 {
3995 	struct ast_channel *target = NULL;									/*!< Potential pickup target */
3996 	struct ast_channel_iterator *iter;
3997 
3998 	if (!(iter = ast_channel_iterator_by_exten_new(exten, context))) {
3999 		return NULL;
4000 	}
4001 
4002 	//ast_log(LOG_NOTICE, "(findPickupChannelByExtenLocked) checking pickup of channel: %s, context: %s, exten: %s, iter: %p\n", pbx_channel_name(chan), exten, context, iter);
4003 	while ((target = ast_channel_iterator_next(iter))) {
4004 		ast_channel_lock(target);
4005 		//ast_log(LOG_NOTICE, "(findPickupChannelByExtenLocked) checking channel: %s, target:%s, can_pickup: %d\n", pbx_channel_name(chan), pbx_channel_name(target), ast_can_pickup(target));
4006 		if ((chan != target) && ast_can_pickup(target)) {
4007 			ast_log(LOG_NOTICE, "%s pickup by %s\n", ast_channel_name(target), ast_channel_name(chan));
4008 			break;
4009 		}
4010 		ast_channel_unlock(target);
4011 		target = pbx_channel_unref(target);
4012 	}
4013 
4014 	ast_channel_iterator_destroy(iter);
4015 	return target;
4016 }
4017 
sccp_astwrap_findPickupChannelByGroupLocked(PBX_CHANNEL_TYPE * chan)4018 PBX_CHANNEL_TYPE *sccp_astwrap_findPickupChannelByGroupLocked(PBX_CHANNEL_TYPE * chan)
4019 {
4020 	struct ast_channel *target = NULL;									/*!< Potential pickup target */
4021 
4022 	target = ast_pickup_find_by_group(chan);
4023 	return target;
4024 }
4025 
4026 // 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;
4027