1 /*!
2  * \file        sccp_rtp.c
3  * \brief       SCCP RTP Class
4  * \author      Sergio Chersovani <mlists [at] c-net.it>
5  * \note                Reworked, but based on chan_sccp code.
6  *              The original chan_sccp driver that was made by Zozo which itself was derived from the chan_skinny driver.
7  *              Modified by Jan Czmok and Julien Goodwin
8  * \note                This program is free software and may be modified and distributed under the terms of the GNU Public License.
9  *              See the LICENSE file at the top of the source tree.
10  *
11  */
12 
13 /*!
14  * =============================
15  * Example Networks
16  * =============================
17  * tokyo 200.0.0.254 / 172.20.0.0
18  * 7905:172.20.0.5
19  *
20  * havana 150.0.0.254 / 192.168.0.0
21  * 7970:192.168.0.5
22  *
23  * amsterdam 100.0.0.254 / 10.10.0.0 (IP-Forward) (NoNat)
24  * (PBX):100.0.0.1 & 10.10.0.1)
25  * 7941: 10.10.0.5
26  * 7942: 10.10.0.6
27  *
28  * berlin 80.0.0.254 / 10.20.0.0 (Port Forward) (Nat) sccp.conf needs externip
29  * (PBX): 10.20.0.1
30  * 7941: 10.20.0.5
31  *
32  * ====================================
33  * Example Calls
34  * ====================================
35  * amsterdam -> amsterdam via amsterdam : inDirectRTP
36  * 172.20.0.5 ->                                           10.0.0.1:PBX:10.0.0.1                                           -> 10.0.0.6
37  * leg1:                                                    us           them
38  * leg2:                                                   them           us
39  *
40  * amsterdam -> amsterdam via amsterdam : DirectRTP
41  * 172.20.0.5 ->                                           10.0.0.1:PBX:10.0.0.1                                           -> 10.0.0.6
42  * leg1:us                                                                                                                      them
43  * leg2:them                                                                                                                     us
44  *
45  * tokyo -> amsterdam via amsterdam (Single NAT : IP-Forward) inDirectRTP
46  * 172.20.0.5 -> 200.0.0.254 -> Internet ->               100.0.0.1:PBX:10.0.0.1                                           -> 10.0.0.5
47  * leg1:              us                                                  them
48  * leg2:                                                     them                                                                us
49  *
50  * tokyo -> amsterdam via amsterdam (Single NAT : IP-Forward) DirectRTP
51  * 172.20.0.5 -> 200.0.0.254 -> Internet ->               100.0.0.1:PBX:10.0.0.1                                           -> 10.0.0.5
52  * leg1:              us                                                                                                        them
53  * leg2:             them                                                                                                        us
54  *
55  * tokyo -> havana via amsterdam (Single NAT : IP-Forward) inDirectRTP
56  * 172.20.0.5 -> 200.0.0.254 -> Internet ->               100.0.0.1:PBX:100.0.0.1               -> Internet -> 150.0.0.254 -> 192.168.0.5
57  * leg1:              us                                                  them
58  * leg2:                                                    them                                                   us
59  *
60  * tokyo -> havana via amsterdam (Single NAT : IP-Forward) DirectRTP
61  * 172.20.0.5 -> 200.0.0.254 -> Internet ->               100.0.0.1:PBX:100.0.0.1               -> Internet -> 150.0.0.254 -> 192.168.0.5
62  * leg1:              us                                                                                          them
63  * leg2:             them                                                                                          us
64  *
65  * tokyo -> havana via berlin (Double Nat : Port-Forward on PBX Location) inDirectRTP
66  * 172.20.0.5 -> 200.0.0.254 -> Internet -> 80.0.0.254 -> 10.20.0.1:PBX:10.20.0.1 -> 80.0.0.254 -> Internet -> 150.0.0.254 -> 192.168.0.5
67  * leg1:              us                                                               them
68  * leg2:                                       them                                                                us
69  *
70  * tokyo -> havana via berlin (Double Nat : Port-Forward on PBX Location) DirectRTP
71  * 172.20.0.5 -> 200.0.0.254 -> Internet -> 80.0.0.254 -> 10.20.0.1:PBX:10.20.0.1 -> 80.0.0.254 -> Internet -> 150.0.0.254 -> 192.168.0.5
72  * leg1:              us                                                                                          them
73  * leg2:             them                                                                                          us
74  *
75  * ====================================
76  * How to name the addresses
77  * ====================================
78  * 172.20.0.5 / 192.168.0.5 = phone  			= physicalIP	=> (and phone_remote for the phone on the other side of the channel) This information does not get send to the pbx
79  * 200.0.0.254 / 150.0.0.254 = d->session->sin		= reachableVia	=> (can be equal to physicalIP), remote ip-address + port of the connection (gotten from physicalIP)
80 									=> written to phone(us) during openreceivechannel
81 									=> written to phone_remote(them) during startmediatransmission
82  * 100.0.0.254 / 100.0.0.254 = externalip		= rtp->remote	=> only required when double nat
83  * 100.0.0.1 / 100.0.0.1 = d->session->ourip		= rtp->remote	=> local ip-address + port of the phone's connection
84  * 10.0.0.1 =  d->session->ourip			= rtp->remote	=> local ip-address + port of the phone's connection
85  */
86 
87 #include "config.h"
88 #include "common.h"
89 #include "sccp_channel.h"
90 #include "sccp_device.h"
91 #include "sccp_line.h"
92 #include "sccp_linedevice.h"
93 #include "sccp_rtp.h"
94 #include "sccp_session.h"
95 #include "sccp_utils.h"
96 
97 SCCP_FILE_VERSION(__FILE__, "");
98 
99 /*!
100  * \brief create a new rtp server
101  * \todo refactor iPbx.rtp_???_server to include sccp_rtp_type_t
102  */
sccp_rtp_createServer(constDevicePtr d,channelPtr c,sccp_rtp_type_t type)103 boolean_t sccp_rtp_createServer(constDevicePtr d, channelPtr c, sccp_rtp_type_t type)
104 {
105 	sccp_rtp_t *rtp = NULL;
106 
107 	if (!c || !d) {
108 		return FALSE;
109 	}
110 
111 	switch(type) {
112 		case SCCP_RTP_AUDIO:
113 			rtp = &(c->rtp.audio);
114 			break;
115 #if CS_SCCP_VIDEO
116 		case SCCP_RTP_VIDEO:
117 			rtp = &(c->rtp.video);
118 			break;
119 #endif
120 		default:
121 			pbx_log(LOG_ERROR, "%s: (sccp_rtp_createRTPServer) unknown/unhandled rtp type, cancelling\n", c->designator);
122 			return FALSE;
123 	}
124 
125 	if (rtp->instance) {
126 		if (rtp->instance_active) {
127 			sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_3 "%s: we already have a %s server, we use this one\n", c->designator, sccp_rtp_type2str(type));
128 			return TRUE;
129 		} else {
130 			sccp_rtp_destroy(c);
131 		}
132 	}
133 	rtp->type = type;
134 
135 	if (iPbx.rtp_create_instance) {
136 		rtp->instance_active = iPbx.rtp_create_instance(d, c, rtp);
137 	} else {
138 		pbx_log(LOG_ERROR, "we should start our own rtp server, but we don't have one\n");
139 		return FALSE;
140 	}
141 	struct sockaddr_storage *phone_remote = &rtp->phone_remote;
142 
143 	if (!sccp_rtp_getUs(rtp, phone_remote)) {
144 		pbx_log(LOG_WARNING, "%s: Did not get our rtp part\n", c->currentDeviceId);
145 		return FALSE;
146 	}
147 
148 	uint16_t port = sccp_rtp_getServerPort(rtp);
149 	sccp_session_getOurIP(d->session, phone_remote, 0);
150 	sccp_netsock_setPort(phone_remote, port);
151 
152 	if (ast_test_flag(GLOB(global_jbconf), AST_JB_ENABLED)) {
153 		if (ast_test_flag(GLOB(global_jbconf), AST_JB_FORCED) || !d->directrtp) {
154 			pbx_jb_configure(c->owner, GLOB(global_jbconf));
155 		}
156 	}
157 
158 	char buf[NI_MAXHOST + NI_MAXSERV];
159 	sccp_copy_string(buf, sccp_netsock_stringify(phone_remote), sizeof(buf));
160 	boolean_t isMappedIPv4 = sccp_netsock_ipv4_mapped(phone_remote, phone_remote);
161 	sccp_log(DEBUGCAT_RTP)(VERBOSE_PREFIX_3 "%s: (sccp_rtp_createRtpServer) setting new phone %s destination to: %s, family:%s, mapped: %s\n", c->designator, sccp_rtp_type2str(type), buf,
162 			       sccp_netsock_is_IPv4(phone_remote) ? "IPv4" : "IPv6", isMappedIPv4 ? "True" : "False");
163 
164 	return rtp->instance_active;
165 }
166 
167 /*!
168  * \brief request the port to be used for RTP, early on, so that we can use it during bridging, even before open_receive_ack has been received (directrtp)
169  */
sccp_rtp_requestRTPPorts(constDevicePtr device,channelPtr channel)170 int sccp_rtp_requestRTPPorts(constDevicePtr device, channelPtr channel)
171 {
172 	pbx_assert(device != NULL && channel != NULL);
173 
174 	sccp_log(DEBUGCAT_RTP) (VERBOSE_PREFIX_3 "%s: (requestRTPPort) request rtp port from phone\n", device->id);
175 	device->protocol->sendPortRequest(device, channel, SKINNY_MEDIA_TRANSPORT_TYPE_RTP, SKINNY_MEDIA_TYPE_AUDIO);
176 
177 #ifdef CS_SCCP_VIDEO
178  	if (sccp_channel_getVideoMode(channel) != SCCP_VIDEO_MODE_OFF && sccp_device_isVideoSupported(device)) {
179 		sccp_log(DEBUGCAT_RTP) (VERBOSE_PREFIX_3 "%s: (requestRTPPort) request vrtp port from phone\n", device->id);
180 		if (channel->rtp.video.instance || sccp_rtp_createServer(device, channel, SCCP_RTP_VIDEO)) {
181 			device->protocol->sendPortRequest(device, channel, SKINNY_MEDIA_TRANSPORT_TYPE_RTP, SKINNY_MEDIA_TYPE_MAIN_VIDEO);
182 		}
183 	}
184 #endif
185 	return 1;
186 }
187 
188 /*!
189  * \brief Stop an RTP Source.
190  * \param channel SCCP Channel
191  */
sccp_rtp_stop(constChannelPtr channel)192 void sccp_rtp_stop(constChannelPtr channel)
193 {
194 	if (!channel) {
195 		return;
196 	}
197 	if (iPbx.rtp_stop) {
198 		sccp_rtp_t *const audio = (sccp_rtp_t *) &(channel->rtp.audio);							// discard const
199 		if (audio->instance && audio->instance_active) {
200 			sccp_log(DEBUGCAT_RTP) (VERBOSE_PREFIX_4 "%s: Stopping PBX audio rtp transmission on channel %s\n", channel->currentDeviceId, channel->designator);
201 			iPbx.rtp_stop(audio->instance);
202 			audio->instance_active = FALSE;
203 		}
204 		sccp_rtp_t *const video = (sccp_rtp_t *) &(channel->rtp.video);							// discard const
205 		if (video->instance && video->instance_active) {
206 			sccp_log(DEBUGCAT_RTP) (VERBOSE_PREFIX_4 "%s: Stopping PBX video rtp transmission on channel %s\n", channel->currentDeviceId, channel->designator);
207 			iPbx.rtp_stop(video->instance);
208 			video->instance_active = FALSE;
209 		}
210 	} else {
211 		pbx_log(LOG_ERROR, "no pbx function to stop rtp\n");
212 	}
213 }
214 
215 /*!
216  * \brief Destroy RTP Source.
217  * \param c SCCP Channel
218  */
sccp_rtp_destroy(constChannelPtr c)219 void sccp_rtp_destroy(constChannelPtr c)
220 {
221 	sccp_rtp_t *audio = (sccp_rtp_t *) &(c->rtp.audio);
222 	sccp_rtp_t *video = (sccp_rtp_t *) &(c->rtp.video);
223 
224 	if (audio->instance) {
225 		sccp_log(DEBUGCAT_RTP) (VERBOSE_PREFIX_3 "%s: destroying PBX rtp server on channel %s\n", c->currentDeviceId, c->designator);
226 		if (audio->instance_active) {
227 			iPbx.rtp_stop(audio->instance);
228 		}
229 		iPbx.rtp_destroy(audio->instance);
230 		audio->instance = NULL;
231 	}
232 
233 	if (video->instance) {
234 		sccp_log(DEBUGCAT_RTP) (VERBOSE_PREFIX_3 "%s: destroying PBX vrtp server on channel %s\n", c->currentDeviceId, c->designator);
235 		if (video->instance_active) {
236 			iPbx.rtp_stop(video->instance);
237 		}
238 		iPbx.rtp_destroy(video->instance);
239 		video->instance = NULL;
240 	}
241 }
242 
sccp_rtp_getState(constRtpPtr rtp,sccp_rtp_dir_t dir)243 sccp_rtp_status_t sccp_rtp_getState(constRtpPtr rtp, sccp_rtp_dir_t dir)
244 {
245 	SCOPED_MUTEX(rtplock, (ast_mutex_t *)&rtp->lock);
246 	const sccp_rtp_direction_t * const direction = (dir == SCCP_RTP_RECEPTION) ? &rtp->reception : &rtp->transmission;
247 	return direction->_state;
248 }
249 
sccp_rtp_areBothInvalid(constRtpPtr rtp)250 sccp_rtp_status_t sccp_rtp_areBothInvalid(constRtpPtr rtp)
251 {
252 	SCOPED_MUTEX(rtplock, (ast_mutex_t *)&rtp->lock);
253 	return !rtp->reception._state && !rtp->transmission._state;
254 }
255 
sccp_rtp_appendState(rtpPtr rtp,sccp_rtp_dir_t dir,sccp_rtp_status_t state)256 void sccp_rtp_appendState(rtpPtr rtp, sccp_rtp_dir_t dir, sccp_rtp_status_t state)
257 {
258 	SCOPED_MUTEX(rtplock, (ast_mutex_t *)&rtp->lock);
259 	sccp_rtp_direction_t * direction = (dir == SCCP_RTP_RECEPTION) ? &rtp->reception : &rtp->transmission;
260 	direction->_state |= state;
261 }
262 
sccp_rtp_subtractState(rtpPtr rtp,sccp_rtp_dir_t dir,sccp_rtp_status_t state)263 void sccp_rtp_subtractState(rtpPtr rtp, sccp_rtp_dir_t dir, sccp_rtp_status_t state)
264 {
265 	SCOPED_MUTEX(rtplock, (ast_mutex_t *)&rtp->lock);
266 	sccp_rtp_direction_t * direction = (dir == SCCP_RTP_RECEPTION) ? &rtp->reception : &rtp->transmission;
267 	direction->_state &= ~state;
268 }
269 
sccp_rtp_setState(rtpPtr rtp,sccp_rtp_dir_t dir,sccp_rtp_status_t newstate)270 void sccp_rtp_setState(rtpPtr rtp, sccp_rtp_dir_t dir, sccp_rtp_status_t newstate)
271 {
272 	SCOPED_MUTEX(rtplock, (ast_mutex_t *)&rtp->lock);
273 	sccp_rtp_direction_t * direction = (dir == SCCP_RTP_RECEPTION) ? &rtp->reception : &rtp->transmission;
274 	direction->_state = newstate;
275 }
276 
sccp_rtp_setCallback(rtpPtr rtp,sccp_rtp_dir_t dir,scpp_rtp_direction_cb_t cb)277 void sccp_rtp_setCallback(rtpPtr rtp, sccp_rtp_dir_t dir, scpp_rtp_direction_cb_t cb)
278 {
279 	SCOPED_MUTEX(rtplock, (ast_mutex_t *)&rtp->lock);
280 	sccp_rtp_direction_t * direction = (dir == SCCP_RTP_RECEPTION) ? &rtp->reception : &rtp->transmission;
281 	direction->cb = cb;
282 }
283 
284 /* Note: this does unset callback in the process */
285 /* Note: We should maybe move the callback to sccp_rtp_t instead of sccp_rtp_direction_t because it get's a little confusing in sccp_indicate CONNECTED */
rtp_fetchActiveCallback(rtpPtr rtp,sccp_rtp_dir_t dir)286 static scpp_rtp_direction_cb_t rtp_fetchActiveCallback(rtpPtr rtp, sccp_rtp_dir_t dir)
287 {
288 	SCOPED_MUTEX(rtplock, (ast_mutex_t *)&rtp->lock);
289 	scpp_rtp_direction_cb_t callback = NULL;
290 	sccp_rtp_direction_t * direction = (dir == SCCP_RTP_RECEPTION) ? &rtp->reception : &rtp->transmission;
291 	if(direction->cb && (direction->_state & SCCP_RTP_STATUS_ACTIVE) == SCCP_RTP_STATUS_ACTIVE) {
292 		callback = direction->cb;
293 		direction->cb = NULL;
294 	}
295 	return callback;
296 }
297 
sccp_rtp_runCallback(rtpPtr rtp,sccp_rtp_dir_t dir,constChannelPtr channel)298 boolean_t sccp_rtp_runCallback(rtpPtr rtp, sccp_rtp_dir_t dir, constChannelPtr channel)
299 {
300 	scpp_rtp_direction_cb_t callback = NULL;
301 	if((callback = rtp_fetchActiveCallback(rtp, dir))) {
302 		callback(channel);                                        // note callback has to be called without rtp lock held
303 		return TRUE;
304 	}
305 	return FALSE;
306 }
307 
308 /*!
309  * \brief update the phones destination address (it's peer)
310  * \param c SCCP Channel
311  * \param rtp SCCP RTP
312  * \param new_peer socket info to remote device
313  */
sccp_rtp_set_peer(constChannelPtr c,rtpPtr rtp,struct sockaddr_storage * new_peer)314 void sccp_rtp_set_peer(constChannelPtr c, rtpPtr rtp, struct sockaddr_storage * new_peer)
315 {
316 	/* validate socket */
317 	if (sccp_netsock_getPort(new_peer) == 0) {
318 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_2 "%s: ( sccp_rtp_set_peer ) remote information are invalid, don't change anything\n", c->currentDeviceId);
319 		return;
320 	}
321 
322 	/* check if we have new information, which requires us to update */
323 	if (sccp_netsock_equals(new_peer, &rtp->phone_remote)) {
324 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_2 "%s: (sccp_rtp_set_peer) remote information is equal to the current info, ignore change\n", c->currentDeviceId);
325 		return;
326 	}
327 
328 	memcpy(&rtp->phone_remote, new_peer, sizeof rtp->phone_remote);
329 	pbx_log(LOG_NOTICE, "%s: ( sccp_rtp_set_peer ) Set new remote address to %s\n", c->currentDeviceId, sccp_netsock_stringify(&rtp->phone_remote));
330 
331 	if(sccp_rtp_getState(rtp, SCCP_RTP_TRANSMISSION)) {
332 		/* Shutdown any early-media or previous media on re-invite */
333 		/*! \todo we should wait for the acknowledgement to get back. We don't have a function/procedure in place to do this at this moment in time (sccp_dev_send_wait) */
334 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_2 "%s: (sccp_rtp_set_peer) Restart media transmission on channel %d\n", c->currentDeviceId, c->callid);
335 
336 		/*! \todo we should check if this is a video or audio rtp */
337 		sccp_channel_updateMediaTransmission(c);
338 	}
339 }
340 
341 /*!
342  * \brief update phones source rtp address
343  * \param c SCCP Channel
344  * \param rtp SCCP RTP
345  * \param new_peer socket info to remote device
346  */
sccp_rtp_set_phone(constChannelPtr c,rtpPtr rtp,struct sockaddr_storage * new_peer)347 void sccp_rtp_set_phone(constChannelPtr c, rtpPtr rtp, struct sockaddr_storage * new_peer)
348 {
349 	/* validate socket */
350 	if (sccp_netsock_getPort(new_peer) == 0) {
351 		sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_2 "%s: (sccp_rtp_set_phone) remote information are invalid, don't change anything\n", c->currentDeviceId);
352 		return;
353 	}
354 
355 	AUTO_RELEASE(sccp_device_t, device , sccp_channel_getDevice(c));
356 
357 	if (device) {
358 
359 		/* check if we have new infos */
360 		char peerIpStr[NI_MAXHOST + NI_MAXSERV];
361 		char remoteIpStr[NI_MAXHOST + NI_MAXSERV];
362 		char phoneIpStr[NI_MAXHOST + NI_MAXSERV];
363 		if (device->nat >= SCCP_NAT_ON) {
364 			/* Rewrite ip-addres to the outside source address using the phones connection (device->sin) */
365 			sccp_copy_string(peerIpStr, sccp_netsock_stringify(new_peer), sizeof(peerIpStr));
366 			uint16_t port = sccp_netsock_getPort(new_peer);
367 			sccp_session_getSas(device->session, new_peer);
368 			sccp_netsock_ipv4_mapped(new_peer, new_peer);
369 			sccp_netsock_setPort(new_peer, port);
370 		}
371 
372 		/*! \todo if we enable this, we get an audio issue when resume on the same device, so we need to force asterisk to update -MC */
373 		/*
374 		if (sccp_netsock_equals(new_peer, &c->rtp.audio.phone)) {
375 			sccp_log((DEBUGCAT_RTP)) (VERBOSE_PREFIX_2 "%s: (sccp_rtp_set_phone) remote information are equal to the current one, ignore change\n", c->currentDeviceId);
376 			return;
377 		}
378 		*/
379 
380 		memcpy(&rtp->phone, new_peer, sizeof(rtp->phone));
381 
382 		//update pbx
383 		if (iPbx.rtp_setPhoneAddress) {
384 			iPbx.rtp_setPhoneAddress(rtp, new_peer, device->nat >= SCCP_NAT_ON ? 1 : 0);
385 		}
386 
387 		sccp_copy_string(remoteIpStr, sccp_netsock_stringify(&rtp->phone_remote), sizeof(remoteIpStr));
388 		sccp_copy_string(phoneIpStr, sccp_netsock_stringify(&rtp->phone), sizeof(phoneIpStr));
389 		if (device->nat >= SCCP_NAT_ON) {
390 			sccp_log(DEBUGCAT_RTP) (VERBOSE_PREFIX_3 "%s: Tell PBX   to send RTP/UDP media from %s to %s (NAT:%s)\n", DEV_ID_LOG(device), remoteIpStr, phoneIpStr, peerIpStr);
391 		} else {
392 			sccp_log(DEBUGCAT_RTP) (VERBOSE_PREFIX_3 "%s: Tell PBX   to send RTP/UDP media from %s to %s (NoNat)\n", DEV_ID_LOG(device), remoteIpStr, phoneIpStr);
393 		}
394 	}
395 }
396 
397 /*! \todo move the refreshing of the hostname->ip-address to another location (for example scheduler) to re-enable dns hostname lookup */
sccp_rtp_updateNatRemotePhone(constChannelPtr c,rtpPtr rtp)398 int sccp_rtp_updateNatRemotePhone(constChannelPtr c, rtpPtr rtp)
399 {
400 	int res = 0;
401 	AUTO_RELEASE(sccp_device_t, d , sccp_channel_getDevice(c));
402 	if (d) {
403 		struct sockaddr_storage sus = { 0 };
404 		struct sockaddr_storage *phone_remote = &rtp->phone_remote;
405 		sccp_session_getOurIP(d->session, &sus, 0);
406 
407 		uint16_t usFamily = (sccp_netsock_is_IPv6(&sus) && !sccp_netsock_is_mapped_IPv4(&sus)) ? AF_INET6 : AF_INET;
408 		uint16_t remoteFamily = (sccp_netsock_is_IPv6(phone_remote) && !sccp_netsock_is_mapped_IPv4(phone_remote)) ? AF_INET6 : AF_INET;
409 
410 		sccp_log(DEBUGCAT_RTP) (VERBOSE_PREFIX_3 "%s: checkNat us: %s, usFamily: %s\n", d->id, sccp_netsock_stringify(&sus), (usFamily == AF_INET6) ? "IPv6" : "IPv4");
411 		sccp_log(DEBUGCAT_RTP) (VERBOSE_PREFIX_3 "%s: checkNat remote: %s, remoteFamily: %s\n", d->id, sccp_netsock_stringify(phone_remote), (remoteFamily == AF_INET6) ? "IPv6" : "IPv4");
412 		if (d->nat >= SCCP_NAT_ON) {
413 			uint16_t port = sccp_rtp_getServerPort(rtp);					// get rtp server port
414 			if (!sccp_netsock_getExternalAddr(phone_remote, remoteFamily)) {		// get externip/externhost ip-address (PBX behind NAT Firewall)
415 				sccp_log(DEBUGCAT_RTP) (VERBOSE_PREFIX_2 "%s: no externip/externhost set, falling back to using incoming interface address:%s\n", d->id, sccp_netsock_stringify(&sus));
416 				memcpy(phone_remote, &sus, sizeof(struct sockaddr_storage));
417 			}
418 			if (usFamily != remoteFamily) {
419 				sccp_netsock_ipv4_mapped(phone_remote, phone_remote);			// we need this to convert mapped IPv4 to real IPv4 address
420 			}
421 			sccp_netsock_setPort(phone_remote, port);
422 			sccp_log(DEBUGCAT_RTP) (VERBOSE_PREFIX_3 "%s: (updateNatRemotePhone) new remote: %s, new remoteFamily: %s\n", d->id, sccp_netsock_stringify(phone_remote), (remoteFamily == AF_INET6) ? "IPv6" : "IPv4");
423 			res = 1;
424 		}
425 	}
426 	return res;
427 }
428 
sccp_rtp_print(constChannelPtr c,sccp_rtp_type_t type,struct ast_str * buf,int buflen)429 void sccp_rtp_print(constChannelPtr c, sccp_rtp_type_t type, struct ast_str * buf, int buflen)
430 {
431 	pbx_assert(c && buf);
432 	const sccp_rtp_t * rtp;
433 	switch(type) {
434 		case SCCP_RTP_AUDIO:
435 			rtp = &(c->rtp.audio);
436 			break;
437 #if CS_SCCP_VIDEO
438 		case SCCP_RTP_VIDEO:
439 			rtp = &(c->rtp.video);
440 			break;
441 #endif
442 		default:
443 			pbx_log(LOG_ERROR, "%s: (sccp_rtp_print) unknown/unhandled rtp type, cancelling\n", c->designator);
444 			return;
445 	}
446 	AUTO_RELEASE(sccp_device_t, d, sccp_channel_getDevice(c));
447 	if(!d || !rtp) {
448 		return;
449 	}
450 
451 	boolean_t isNatted = d->nat >= SCCP_NAT_ON ? TRUE : FALSE;
452 	boolean_t isIPv4 = sccp_netsock_is_IPv4(&rtp->phone_remote) || sccp_netsock_ipv4_mapped(&rtp->phone_remote, (struct sockaddr_storage *)&rtp->phone_remote) ? TRUE : FALSE;
453 	boolean_t isDirectRTP = d->directrtp;
454 	const struct sockaddr_storage * const ip = isIPv4 ? &d->ipv4 : &d->ipv6;
455 
456 	pbx_str_reset(buf);
457 	if(isNatted) {
458 		pbx_str_append(&buf, 0, "PH1:%s -> FW:%s ----> FW:%s --> %s:%s\n", sccp_netsock_stringify(ip), sccp_netsock_stringify(&rtp->phone), "", isDirectRTP ? sccp_netsock_stringify(&rtp->phone_remote) : "",
459 			       isDirectRTP ? "AST" : "PH");
460 	} else {
461 		pbx_str_append(&buf, 0, "PH1:%s ----> %s:%s\n", sccp_netsock_stringify(&rtp->phone), isDirectRTP ? sccp_netsock_stringify(&rtp->phone_remote) : "", isDirectRTP ? "AST" : "PH");
462 	}
463 }
464 
465 /*!
466  * \brief Get Audio Peer RTP Information
467  */
sccp_rtp_getAudioPeerInfo(constChannelPtr c,sccp_rtp_t ** rtp)468 sccp_rtp_info_t sccp_rtp_getAudioPeerInfo(constChannelPtr c, sccp_rtp_t **rtp)
469 {
470 	unsigned int result = SCCP_RTP_INFO_NORTP;
471 
472 	AUTO_RELEASE(sccp_device_t, device , sccp_channel_getDevice(c));
473 
474 	if (!device) {
475 		return SCCP_RTP_INFO_NORTP;
476 	}
477 
478 	*rtp = &(((sccp_channel_t *) c)->rtp.audio);
479 
480 	result = SCCP_RTP_INFO_AVAILABLE;
481 	// \todo add apply_ha(d->ha, &sin) check here instead
482 	if (device->directrtp && device->nat <= SCCP_NAT_AUTO_OFF && !c->conference) {
483 		result |= SCCP_RTP_INFO_ALLOW_DIRECTRTP;
484 	}
485 	return (sccp_rtp_info_t) result;
486 }
487 
488 #ifdef CS_SCCP_VIDEO
489 /*!
490  * \brief Get Video Peer RTP Information
491  */
sccp_rtp_getVideoPeerInfo(constChannelPtr c,sccp_rtp_t ** rtp)492 sccp_rtp_info_t sccp_rtp_getVideoPeerInfo(constChannelPtr c, sccp_rtp_t ** rtp)
493 {
494 	unsigned int result = SCCP_RTP_INFO_NORTP;
495 
496 	AUTO_RELEASE(sccp_device_t, device , sccp_channel_getDevice(c));
497 
498 	if (!device) {
499 		return SCCP_RTP_INFO_NORTP;
500 	}
501 
502 	*rtp = &(((sccp_channel_t *) c)->rtp.video);
503 
504 	result = SCCP_RTP_INFO_AVAILABLE;
505 	if (device->directrtp && device->nat <= SCCP_NAT_AUTO_OFF && !c->conference) {
506 		result |= SCCP_RTP_INFO_ALLOW_DIRECTRTP;
507 	}
508 	return (sccp_rtp_info_t)result;
509 }
510 
511 /*!
512  * \brief Get Video Peer
513  */
sccp_rtp_getVideoPeer(constChannelPtr c,struct sockaddr_storage ** new_peer)514 boolean_t sccp_rtp_getVideoPeer(constChannelPtr c, struct sockaddr_storage **new_peer)
515 {
516 	sccp_rtp_t *video = (sccp_rtp_t *) &(c->rtp.video);
517 	*new_peer = &video->phone_remote;
518 	return TRUE;
519 }
520 #endif
521 
522 /*!
523  * \brief Get Audio Peer
524  */
sccp_rtp_getAudioPeer(constChannelPtr c,struct sockaddr_storage ** new_peer)525 boolean_t sccp_rtp_getAudioPeer(constChannelPtr c, struct sockaddr_storage **new_peer)
526 {
527 	sccp_rtp_t *audio = (sccp_rtp_t *) &(c->rtp.audio);
528 	*new_peer = &audio->phone_remote;
529 	return TRUE;
530 }
531 
532 /*!
533  * \brief Get Payload Type
534  */
sccp_rtp_get_payloadType(constRtpPtr rtp,skinny_codec_t codec)535 uint8_t sccp_rtp_get_payloadType(constRtpPtr rtp, skinny_codec_t codec)
536 {
537 	if (iPbx.rtp_get_payloadType) {
538 		return iPbx.rtp_get_payloadType(rtp, codec);
539 	}
540 	return 97;
541 }
542 
543 /*!
544  * \brief Retrieve Phone Socket Information
545  */
sccp_rtp_getUs(constRtpPtr rtp,struct sockaddr_storage * us)546 boolean_t sccp_rtp_getUs(constRtpPtr rtp, struct sockaddr_storage * us)
547 {
548 	if (rtp->instance) {
549 		iPbx.rtp_getUs(rtp->instance, us);
550 		return TRUE;
551 	}
552 	// us = &rtp->phone_remote;
553 	return FALSE;
554 }
555 
sccp_rtp_getServerPort(constRtpPtr rtp)556 uint16_t sccp_rtp_getServerPort(constRtpPtr rtp)
557 {
558 	uint16_t port = 0;
559 	struct sockaddr_storage sas;
560 
561 	sccp_rtp_getUs(rtp, &sas);
562 
563 	port = sccp_netsock_getPort(&sas);
564 	return port;
565 }
566 
567 /*!
568  * \brief Retrieve Phone Socket Information
569  */
sccp_rtp_getPeer(constRtpPtr rtp,struct sockaddr_storage * them)570 boolean_t sccp_rtp_getPeer(constRtpPtr rtp, struct sockaddr_storage * them)
571 {
572 	if (rtp->instance) {
573 		iPbx.rtp_getPeer(rtp->instance, them);
574 		return TRUE;
575 	}
576 	return FALSE;
577 }
578 
579 /*!
580  * \brief Get Sample Rate
581  */
sccp_rtp_get_sampleRate(skinny_codec_t codec)582 int sccp_rtp_get_sampleRate(skinny_codec_t codec)
583 {
584 	if (iPbx.rtp_get_sampleRate) {
585 		return iPbx.rtp_get_sampleRate(codec);
586 	}
587 	return 3840;
588 }
589 
590 // 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;
591