Merge "pbx: deadlock when outgoing dialed channel hangs up too quickly"
[asterisk/asterisk.git] / res / res_pjsip_sdp_rtp.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Joshua Colp <jcolp@digium.com>
7  * Kevin Harwell <kharwell@digium.com>
8  *
9  * See http://www.asterisk.org for more information about
10  * the Asterisk project. Please do not directly contact
11  * any of the maintainers of this project for assistance;
12  * the project provides a web site, mailing lists and IRC
13  * channels for your use.
14  *
15  * This program is free software, distributed under the terms of
16  * the GNU General Public License Version 2. See the LICENSE file
17  * at the top of the source tree.
18  */
19
20 /*! \file
21  *
22  * \author Joshua Colp <jcolp@digium.com>
23  *
24  * \brief SIP SDP media stream handling
25  */
26
27 /*** MODULEINFO
28         <depend>pjproject</depend>
29         <depend>res_pjsip</depend>
30         <depend>res_pjsip_session</depend>
31         <support_level>core</support_level>
32  ***/
33
34 #include "asterisk.h"
35
36 #include <pjsip.h>
37 #include <pjsip_ua.h>
38 #include <pjmedia.h>
39 #include <pjlib.h>
40
41 #include "asterisk/utils.h"
42 #include "asterisk/module.h"
43 #include "asterisk/format.h"
44 #include "asterisk/format_cap.h"
45 #include "asterisk/rtp_engine.h"
46 #include "asterisk/netsock2.h"
47 #include "asterisk/channel.h"
48 #include "asterisk/causes.h"
49 #include "asterisk/sched.h"
50 #include "asterisk/acl.h"
51 #include "asterisk/sdp_srtp.h"
52 #include "asterisk/dsp.h"
53 #include "asterisk/linkedlists.h"       /* for AST_LIST_NEXT */
54 #include "asterisk/stream.h"
55 #include "asterisk/format_cache.h"
56
57 #include "asterisk/res_pjsip.h"
58 #include "asterisk/res_pjsip_session.h"
59
60 /*! \brief Scheduler for RTCP purposes */
61 static struct ast_sched_context *sched;
62
63 /*! \brief Address for RTP */
64 static struct ast_sockaddr address_rtp;
65
66 static const char STR_AUDIO[] = "audio";
67 static const char STR_VIDEO[] = "video";
68
69 static int send_keepalive(const void *data)
70 {
71         struct ast_sip_session_media *session_media = (struct ast_sip_session_media *) data;
72         struct ast_rtp_instance *rtp = session_media->rtp;
73         int keepalive;
74         time_t interval;
75         int send_keepalive;
76
77         if (!rtp) {
78                 return 0;
79         }
80
81         keepalive = ast_rtp_instance_get_keepalive(rtp);
82
83         if (!ast_sockaddr_isnull(&session_media->direct_media_addr)) {
84                 ast_debug(3, "Not sending RTP keepalive on RTP instance %p since direct media is in use\n", rtp);
85                 return keepalive * 1000;
86         }
87
88         interval = time(NULL) - ast_rtp_instance_get_last_tx(rtp);
89         send_keepalive = interval >= keepalive;
90
91         ast_debug(3, "It has been %d seconds since RTP was last sent on instance %p. %sending keepalive\n",
92                         (int) interval, rtp, send_keepalive ? "S" : "Not s");
93
94         if (send_keepalive) {
95                 ast_rtp_instance_sendcng(rtp, 0);
96                 return keepalive * 1000;
97         }
98
99         return (keepalive - interval) * 1000;
100 }
101
102 /*! \brief Check whether RTP is being received or not */
103 static int rtp_check_timeout(const void *data)
104 {
105         struct ast_sip_session_media *session_media = (struct ast_sip_session_media *)data;
106         struct ast_rtp_instance *rtp = session_media->rtp;
107         int elapsed;
108         struct ast_channel *chan;
109
110         if (!rtp) {
111                 return 0;
112         }
113
114         elapsed = time(NULL) - ast_rtp_instance_get_last_rx(rtp);
115         if (elapsed < ast_rtp_instance_get_timeout(rtp)) {
116                 return (ast_rtp_instance_get_timeout(rtp) - elapsed) * 1000;
117         }
118
119         chan = ast_channel_get_by_name(ast_rtp_instance_get_channel_id(rtp));
120         if (!chan) {
121                 return 0;
122         }
123
124         ast_log(LOG_NOTICE, "Disconnecting channel '%s' for lack of RTP activity in %d seconds\n",
125                 ast_channel_name(chan), elapsed);
126
127         ast_channel_lock(chan);
128         ast_channel_hangupcause_set(chan, AST_CAUSE_REQUESTED_CHAN_UNAVAIL);
129         ast_channel_unlock(chan);
130
131         ast_softhangup(chan, AST_SOFTHANGUP_DEV);
132         ast_channel_unref(chan);
133
134         return 0;
135 }
136
137 /*!
138  * \brief Enable RTCP on an RTP session.
139  */
140 static void enable_rtcp(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
141         const struct pjmedia_sdp_media *remote_media)
142 {
143         enum ast_rtp_instance_rtcp rtcp_type;
144
145         if (session->endpoint->media.rtcp_mux && session_media->remote_rtcp_mux) {
146                 rtcp_type = AST_RTP_INSTANCE_RTCP_MUX;
147         } else {
148                 rtcp_type = AST_RTP_INSTANCE_RTCP_STANDARD;
149         }
150
151         ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_RTCP, rtcp_type);
152 }
153
154 /*!
155  * \brief Enable an RTP extension on an RTP session.
156  */
157 static void enable_rtp_extension(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
158         enum ast_rtp_extension extension, enum ast_rtp_extension_direction direction,
159         const pjmedia_sdp_session *sdp)
160 {
161         int id = -1;
162
163         /* For a bundle group the local unique identifier space is shared across all streams within
164          * it.
165          */
166         if (session_media->bundle_group != -1) {
167                 int index;
168
169                 for (index = 0; index < sdp->media_count; ++index) {
170                         struct ast_sip_session_media *other_session_media;
171                         int other_id;
172
173                         if (index >= AST_VECTOR_SIZE(&session->pending_media_state->sessions)) {
174                                 break;
175                         }
176
177                         other_session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, index);
178                         if (!other_session_media->rtp || other_session_media->bundle_group != session_media->bundle_group) {
179                                 continue;
180                         }
181
182                         other_id = ast_rtp_instance_extmap_get_id(other_session_media->rtp, extension);
183                         if (other_id == -1) {
184                                 /* Worst case we have to fall back to the highest available free local unique identifier
185                                  * for the bundle group.
186                                  */
187                                 other_id = ast_rtp_instance_extmap_count(other_session_media->rtp) + 1;
188                                 if (id < other_id) {
189                                         id = other_id;
190                                 }
191                                 continue;
192                         }
193
194                         id = other_id;
195                         break;
196                 }
197         }
198
199         ast_rtp_instance_extmap_enable(session_media->rtp, id, extension, direction);
200 }
201
202 /*! \brief Internal function which creates an RTP instance */
203 static int create_rtp(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
204         const pjmedia_sdp_session *sdp)
205 {
206         struct ast_rtp_engine_ice *ice;
207         struct ast_sockaddr temp_media_address;
208         struct ast_sockaddr *media_address =  &address_rtp;
209
210         if (session->endpoint->media.bind_rtp_to_media_address && !ast_strlen_zero(session->endpoint->media.address)) {
211                 if (ast_sockaddr_parse(&temp_media_address, session->endpoint->media.address, 0)) {
212                         ast_debug(1, "Endpoint %s: Binding RTP media to %s\n",
213                                 ast_sorcery_object_get_id(session->endpoint),
214                                 session->endpoint->media.address);
215                         media_address = &temp_media_address;
216                 } else {
217                         ast_debug(1, "Endpoint %s: RTP media address invalid: %s\n",
218                                 ast_sorcery_object_get_id(session->endpoint),
219                                 session->endpoint->media.address);
220                 }
221         } else {
222                 struct ast_sip_transport *transport;
223
224                 transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport",
225                         session->endpoint->transport);
226                 if (transport) {
227                         struct ast_sip_transport_state *trans_state;
228
229                         trans_state = ast_sip_get_transport_state(ast_sorcery_object_get_id(transport));
230                         if (trans_state) {
231                                 char hoststr[PJ_INET6_ADDRSTRLEN];
232
233                                 pj_sockaddr_print(&trans_state->host, hoststr, sizeof(hoststr), 0);
234                                 if (ast_sockaddr_parse(&temp_media_address, hoststr, 0)) {
235                                         ast_debug(1, "Transport %s bound to %s: Using it for RTP media.\n",
236                                                 session->endpoint->transport, hoststr);
237                                         media_address = &temp_media_address;
238                                 } else {
239                                         ast_debug(1, "Transport %s bound to %s: Invalid for RTP media.\n",
240                                                 session->endpoint->transport, hoststr);
241                                 }
242                                 ao2_ref(trans_state, -1);
243                         }
244                         ao2_ref(transport, -1);
245                 }
246         }
247
248         if (!(session_media->rtp = ast_rtp_instance_new(session->endpoint->media.rtp.engine, sched, media_address, NULL))) {
249                 ast_log(LOG_ERROR, "Unable to create RTP instance using RTP engine '%s'\n", session->endpoint->media.rtp.engine);
250                 return -1;
251         }
252
253         ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_NAT, session->endpoint->media.rtp.symmetric);
254         ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_ASYMMETRIC_CODEC, session->endpoint->asymmetric_rtp_codec);
255
256         if (!session->endpoint->media.rtp.ice_support && (ice = ast_rtp_instance_get_ice(session_media->rtp))) {
257                 ice->stop(session_media->rtp);
258         }
259
260         if (session->dtmf == AST_SIP_DTMF_RFC_4733 || session->dtmf == AST_SIP_DTMF_AUTO || session->dtmf == AST_SIP_DTMF_AUTO_INFO) {
261                 ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_RFC2833);
262                 ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_DTMF, 1);
263         } else if (session->dtmf == AST_SIP_DTMF_INBAND) {
264                 ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_INBAND);
265         }
266
267         if (session_media->type == AST_MEDIA_TYPE_AUDIO &&
268                         (session->endpoint->media.tos_audio || session->endpoint->media.cos_audio)) {
269                 ast_rtp_instance_set_qos(session_media->rtp, session->endpoint->media.tos_audio,
270                                 session->endpoint->media.cos_audio, "SIP RTP Audio");
271         } else if (session_media->type == AST_MEDIA_TYPE_VIDEO) {
272                 ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_RETRANS_RECV, session->endpoint->media.webrtc);
273                 ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_RETRANS_SEND, session->endpoint->media.webrtc);
274                 ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_REMB, session->endpoint->media.webrtc);
275                 if (session->endpoint->media.webrtc) {
276                         enable_rtp_extension(session, session_media, AST_RTP_EXTENSION_ABS_SEND_TIME, AST_RTP_EXTENSION_DIRECTION_SENDRECV, sdp);
277                         enable_rtp_extension(session, session_media, AST_RTP_EXTENSION_TRANSPORT_WIDE_CC, AST_RTP_EXTENSION_DIRECTION_SENDRECV, sdp);
278                 }
279                 if (session->endpoint->media.tos_video || session->endpoint->media.cos_video) {
280                         ast_rtp_instance_set_qos(session_media->rtp, session->endpoint->media.tos_video,
281                                         session->endpoint->media.cos_video, "SIP RTP Video");
282                 }
283         }
284
285         ast_rtp_instance_set_last_rx(session_media->rtp, time(NULL));
286
287         return 0;
288 }
289
290 static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp_media *stream, struct ast_rtp_codecs *codecs,
291         struct ast_sip_session_media *session_media)
292 {
293         pjmedia_sdp_attr *attr;
294         pjmedia_sdp_rtpmap *rtpmap;
295         pjmedia_sdp_fmtp fmtp;
296         struct ast_format *format;
297         int i, num = 0, tel_event = 0;
298         char name[256];
299         char media[20];
300         char fmt_param[256];
301         enum ast_rtp_options options = session->endpoint->media.g726_non_standard ?
302                 AST_RTP_OPT_G726_NONSTANDARD : 0;
303
304         ast_rtp_codecs_payloads_initialize(codecs);
305
306         /* Iterate through provided formats */
307         for (i = 0; i < stream->desc.fmt_count; ++i) {
308                 /* The payload is kept as a string for things like t38 but for video it is always numerical */
309                 ast_rtp_codecs_payloads_set_m_type(codecs, NULL, pj_strtoul(&stream->desc.fmt[i]));
310                 /* Look for the optional rtpmap attribute */
311                 if (!(attr = pjmedia_sdp_media_find_attr2(stream, "rtpmap", &stream->desc.fmt[i]))) {
312                         continue;
313                 }
314
315                 /* Interpret the attribute as an rtpmap */
316                 if ((pjmedia_sdp_attr_to_rtpmap(session->inv_session->pool_prov, attr, &rtpmap)) != PJ_SUCCESS) {
317                         continue;
318                 }
319
320                 ast_copy_pj_str(name, &rtpmap->enc_name, sizeof(name));
321                 if (strcmp(name, "telephone-event") == 0) {
322                         tel_event++;
323                 }
324
325                 ast_copy_pj_str(media, (pj_str_t*)&stream->desc.media, sizeof(media));
326                 ast_rtp_codecs_payloads_set_rtpmap_type_rate(codecs, NULL,
327                         pj_strtoul(&stream->desc.fmt[i]), media, name, options, rtpmap->clock_rate);
328                 /* Look for an optional associated fmtp attribute */
329                 if (!(attr = pjmedia_sdp_media_find_attr2(stream, "fmtp", &rtpmap->pt))) {
330                         continue;
331                 }
332
333                 if ((pjmedia_sdp_attr_get_fmtp(attr, &fmtp)) == PJ_SUCCESS) {
334                         ast_copy_pj_str(fmt_param, &fmtp.fmt, sizeof(fmt_param));
335                         if (sscanf(fmt_param, "%30d", &num) != 1) {
336                                 continue;
337                         }
338
339                         if ((format = ast_rtp_codecs_get_payload_format(codecs, num))) {
340                                 struct ast_format *format_parsed;
341
342                                 ast_copy_pj_str(fmt_param, &fmtp.fmt_param, sizeof(fmt_param));
343
344                                 format_parsed = ast_format_parse_sdp_fmtp(format, fmt_param);
345                                 if (format_parsed) {
346                                         ast_rtp_codecs_payload_replace_format(codecs, num, format_parsed);
347                                         ao2_ref(format_parsed, -1);
348                                 }
349
350                                 ao2_ref(format, -1);
351                         }
352                 }
353         }
354         if (!tel_event && (session->dtmf == AST_SIP_DTMF_AUTO)) {
355                 ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_INBAND);
356         }
357
358         if (session->dtmf == AST_SIP_DTMF_AUTO_INFO) {
359                 if  (tel_event) {
360                         ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_RFC2833);
361                 } else {
362                         ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_NONE);
363                 }
364         }
365
366
367         /* Get the packetization, if it exists */
368         if ((attr = pjmedia_sdp_media_find_attr2(stream, "ptime", NULL))) {
369                 unsigned long framing = pj_strtoul(pj_strltrim(&attr->value));
370                 if (framing && session->endpoint->media.rtp.use_ptime) {
371                         ast_rtp_codecs_set_framing(codecs, framing);
372                 }
373         }
374 }
375
376 static int set_caps(struct ast_sip_session *session,
377         struct ast_sip_session_media *session_media,
378         struct ast_sip_session_media *session_media_transport,
379         const struct pjmedia_sdp_media *stream,
380         int is_offer, struct ast_stream *asterisk_stream)
381 {
382         RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup);
383         RAII_VAR(struct ast_format_cap *, peer, NULL, ao2_cleanup);
384         RAII_VAR(struct ast_format_cap *, joint, NULL, ao2_cleanup);
385         enum ast_media_type media_type = session_media->type;
386         struct ast_rtp_codecs codecs = AST_RTP_CODECS_NULL_INIT;
387         int fmts = 0;
388         int direct_media_enabled = !ast_sockaddr_isnull(&session_media->direct_media_addr) &&
389                 ast_format_cap_count(session->direct_media_cap);
390         int dsp_features = 0;
391
392         if (!(caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT)) ||
393             !(peer = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT)) ||
394             !(joint = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
395                 ast_log(LOG_ERROR, "Failed to allocate %s capabilities\n",
396                         ast_codec_media_type2str(session_media->type));
397                 return -1;
398         }
399
400         /* get the endpoint capabilities */
401         if (direct_media_enabled) {
402                 ast_format_cap_get_compatible(session->endpoint->media.codecs, session->direct_media_cap, caps);
403         } else {
404                 ast_format_cap_append_from_cap(caps, session->endpoint->media.codecs, media_type);
405         }
406
407         /* get the capabilities on the peer */
408         get_codecs(session, stream, &codecs,  session_media);
409         ast_rtp_codecs_payload_formats(&codecs, peer, &fmts);
410
411         /* get the joint capabilities between peer and endpoint */
412         ast_format_cap_get_compatible(caps, peer, joint);
413         if (!ast_format_cap_count(joint)) {
414                 struct ast_str *usbuf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
415                 struct ast_str *thembuf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
416
417                 ast_rtp_codecs_payloads_destroy(&codecs);
418                 ast_log(LOG_NOTICE, "No joint capabilities for '%s' media stream between our configuration(%s) and incoming SDP(%s)\n",
419                         ast_codec_media_type2str(session_media->type),
420                         ast_format_cap_get_names(caps, &usbuf),
421                         ast_format_cap_get_names(peer, &thembuf));
422                 return -1;
423         }
424
425         if (is_offer) {
426                 /*
427                  * Setup rx payload type mapping to prefer the mapping
428                  * from the peer that the RFC says we SHOULD use.
429                  */
430                 ast_rtp_codecs_payloads_xover(&codecs, &codecs, NULL);
431         }
432         ast_rtp_codecs_payloads_copy(&codecs, ast_rtp_instance_get_codecs(session_media->rtp),
433                 session_media->rtp);
434
435         ast_stream_set_formats(asterisk_stream, joint);
436
437         /* If this is a bundled stream then apply the payloads to RTP instance acting as transport to prevent conflicts */
438         if (session_media_transport != session_media && session_media->bundled) {
439                 int index;
440
441                 for (index = 0; index < ast_format_cap_count(joint); ++index) {
442                         struct ast_format *format = ast_format_cap_get_format(joint, index);
443                         int rtp_code;
444
445                         /* Ensure this payload is in the bundle group transport codecs, this purposely doesn't check the return value for
446                          * things as the format is guaranteed to have a payload already.
447                          */
448                         rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media->rtp), 1, format, 0);
449                         ast_rtp_codecs_payload_set_rx(ast_rtp_instance_get_codecs(session_media_transport->rtp), rtp_code, format);
450
451                         ao2_ref(format, -1);
452                 }
453         }
454
455         if (session->channel && ast_sip_session_is_pending_stream_default(session, asterisk_stream)) {
456                 ast_channel_lock(session->channel);
457                 ast_format_cap_remove_by_type(caps, AST_MEDIA_TYPE_UNKNOWN);
458                 ast_format_cap_append_from_cap(caps, ast_channel_nativeformats(session->channel),
459                         AST_MEDIA_TYPE_UNKNOWN);
460                 ast_format_cap_remove_by_type(caps, media_type);
461
462                 if (session->endpoint->preferred_codec_only){
463                         struct ast_format *preferred_fmt = ast_format_cap_get_format(joint, 0);
464                         ast_format_cap_append(caps, preferred_fmt, 0);
465                         ao2_ref(preferred_fmt, -1);
466                 } else if (!session->endpoint->asymmetric_rtp_codec) {
467                         struct ast_format *best;
468                         /*
469                          * If we don't allow the sending codec to be changed on our side
470                          * then get the best codec from the joint capabilities of the media
471                          * type and use only that. This ensures the core won't start sending
472                          * out a format that we aren't currently sending.
473                          */
474
475                         best = ast_format_cap_get_best_by_type(joint, media_type);
476                         if (best) {
477                                 ast_format_cap_append(caps, best, ast_format_cap_get_framing(joint));
478                                 ao2_ref(best, -1);
479                         }
480                 } else {
481                         ast_format_cap_append_from_cap(caps, joint, media_type);
482                 }
483
484                 /*
485                  * Apply the new formats to the channel, potentially changing
486                  * raw read/write formats and translation path while doing so.
487                  */
488                 ast_channel_nativeformats_set(session->channel, caps);
489                 if (media_type == AST_MEDIA_TYPE_AUDIO) {
490                         ast_set_read_format(session->channel, ast_channel_readformat(session->channel));
491                         ast_set_write_format(session->channel, ast_channel_writeformat(session->channel));
492                 }
493
494                 if ( ((session->dtmf == AST_SIP_DTMF_AUTO) || (session->dtmf == AST_SIP_DTMF_AUTO_INFO) )
495                     && (ast_rtp_instance_dtmf_mode_get(session_media->rtp) == AST_RTP_DTMF_MODE_RFC2833)
496                     && (session->dsp)) {
497                         dsp_features = ast_dsp_get_features(session->dsp);
498                         dsp_features &= ~DSP_FEATURE_DIGIT_DETECT;
499                         if (dsp_features) {
500                                 ast_dsp_set_features(session->dsp, dsp_features);
501                         } else {
502                                 ast_dsp_free(session->dsp);
503                                 session->dsp = NULL;
504                         }
505                 }
506
507                 if (ast_channel_is_bridged(session->channel)) {
508                         ast_channel_set_unbridged_nolock(session->channel, 1);
509                 }
510
511                 ast_channel_unlock(session->channel);
512         }
513
514         ast_rtp_codecs_payloads_destroy(&codecs);
515         return 0;
516 }
517
518 static pjmedia_sdp_attr* generate_rtpmap_attr(struct ast_sip_session *session, pjmedia_sdp_media *media, pj_pool_t *pool,
519                                               int rtp_code, int asterisk_format, struct ast_format *format, int code)
520 {
521 #ifndef HAVE_PJSIP_ENDPOINT_COMPACT_FORM
522         extern pj_bool_t pjsip_use_compact_form;
523 #else
524         pj_bool_t pjsip_use_compact_form = pjsip_cfg()->endpt.use_compact_form;
525 #endif
526         pjmedia_sdp_rtpmap rtpmap;
527         pjmedia_sdp_attr *attr = NULL;
528         char tmp[64];
529         enum ast_rtp_options options = session->endpoint->media.g726_non_standard ?
530                 AST_RTP_OPT_G726_NONSTANDARD : 0;
531
532         snprintf(tmp, sizeof(tmp), "%d", rtp_code);
533         pj_strdup2(pool, &media->desc.fmt[media->desc.fmt_count++], tmp);
534
535         if (rtp_code <= AST_RTP_PT_LAST_STATIC && pjsip_use_compact_form) {
536                 return NULL;
537         }
538
539         rtpmap.pt = media->desc.fmt[media->desc.fmt_count - 1];
540         rtpmap.clock_rate = ast_rtp_lookup_sample_rate2(asterisk_format, format, code);
541         pj_strdup2(pool, &rtpmap.enc_name, ast_rtp_lookup_mime_subtype2(asterisk_format, format, code, options));
542         if (!pj_stricmp2(&rtpmap.enc_name, "opus")) {
543                 pj_cstr(&rtpmap.param, "2");
544         } else {
545                 pj_cstr(&rtpmap.param, NULL);
546         }
547
548         pjmedia_sdp_rtpmap_to_attr(pool, &rtpmap, &attr);
549
550         return attr;
551 }
552
553 static pjmedia_sdp_attr* generate_fmtp_attr(pj_pool_t *pool, struct ast_format *format, int rtp_code)
554 {
555         struct ast_str *fmtp0 = ast_str_alloca(256);
556         pj_str_t fmtp1;
557         pjmedia_sdp_attr *attr = NULL;
558         char *tmp;
559
560         ast_format_generate_sdp_fmtp(format, rtp_code, &fmtp0);
561         if (ast_str_strlen(fmtp0)) {
562                 tmp = ast_str_buffer(fmtp0) + ast_str_strlen(fmtp0) - 1;
563                 /* remove any carriage return line feeds */
564                 while (*tmp == '\r' || *tmp == '\n') --tmp;
565                 *++tmp = '\0';
566                 /* ast...generate gives us everything, just need value */
567                 tmp = strchr(ast_str_buffer(fmtp0), ':');
568                 if (tmp && tmp[1] != '\0') {
569                         fmtp1 = pj_str(tmp + 1);
570                 } else {
571                         fmtp1 = pj_str(ast_str_buffer(fmtp0));
572                 }
573                 attr = pjmedia_sdp_attr_create(pool, "fmtp", &fmtp1);
574         }
575         return attr;
576 }
577
578 /*! \brief Function which adds ICE attributes to a media stream */
579 static void add_ice_to_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media,
580         unsigned int include_candidates)
581 {
582         struct ast_rtp_engine_ice *ice;
583         struct ao2_container *candidates;
584         const char *username, *password;
585         pj_str_t stmp;
586         pjmedia_sdp_attr *attr;
587         struct ao2_iterator it_candidates;
588         struct ast_rtp_engine_ice_candidate *candidate;
589
590         if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) {
591                 return;
592         }
593
594         if (!session_media->remote_ice) {
595                 return;
596         }
597
598         if ((username = ice->get_ufrag(session_media->rtp))) {
599                 attr = pjmedia_sdp_attr_create(pool, "ice-ufrag", pj_cstr(&stmp, username));
600                 media->attr[media->attr_count++] = attr;
601         }
602
603         if ((password = ice->get_password(session_media->rtp))) {
604                 attr = pjmedia_sdp_attr_create(pool, "ice-pwd", pj_cstr(&stmp, password));
605                 media->attr[media->attr_count++] = attr;
606         }
607
608         if (!include_candidates) {
609                 return;
610         }
611
612         candidates = ice->get_local_candidates(session_media->rtp);
613         if (!candidates) {
614                 return;
615         }
616
617         it_candidates = ao2_iterator_init(candidates, 0);
618         for (; (candidate = ao2_iterator_next(&it_candidates)); ao2_ref(candidate, -1)) {
619                 struct ast_str *attr_candidate = ast_str_create(128);
620
621                 ast_str_set(&attr_candidate, -1, "%s %u %s %d %s ", candidate->foundation, candidate->id, candidate->transport,
622                                         candidate->priority, ast_sockaddr_stringify_addr_remote(&candidate->address));
623                 ast_str_append(&attr_candidate, -1, "%s typ ", ast_sockaddr_stringify_port(&candidate->address));
624
625                 switch (candidate->type) {
626                         case AST_RTP_ICE_CANDIDATE_TYPE_HOST:
627                                 ast_str_append(&attr_candidate, -1, "host");
628                                 break;
629                         case AST_RTP_ICE_CANDIDATE_TYPE_SRFLX:
630                                 ast_str_append(&attr_candidate, -1, "srflx");
631                                 break;
632                         case AST_RTP_ICE_CANDIDATE_TYPE_RELAYED:
633                                 ast_str_append(&attr_candidate, -1, "relay");
634                                 break;
635                 }
636
637                 if (!ast_sockaddr_isnull(&candidate->relay_address)) {
638                         ast_str_append(&attr_candidate, -1, " raddr %s rport", ast_sockaddr_stringify_addr_remote(&candidate->relay_address));
639                         ast_str_append(&attr_candidate, -1, " %s", ast_sockaddr_stringify_port(&candidate->relay_address));
640                 }
641
642                 attr = pjmedia_sdp_attr_create(pool, "candidate", pj_cstr(&stmp, ast_str_buffer(attr_candidate)));
643                 media->attr[media->attr_count++] = attr;
644
645                 ast_free(attr_candidate);
646         }
647
648         ao2_iterator_destroy(&it_candidates);
649         ao2_ref(candidates, -1);
650 }
651
652 /*! \brief Function which checks for ice attributes in an audio stream */
653 static void check_ice_support(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
654                                    const struct pjmedia_sdp_media *remote_stream)
655 {
656         struct ast_rtp_engine_ice *ice;
657         const pjmedia_sdp_attr *attr;
658         unsigned int attr_i;
659
660         if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) {
661                 session_media->remote_ice = 0;
662                 return;
663         }
664
665         /* Find all of the candidates */
666         for (attr_i = 0; attr_i < remote_stream->attr_count; ++attr_i) {
667                 attr = remote_stream->attr[attr_i];
668                 if (!pj_strcmp2(&attr->name, "candidate")) {
669                         session_media->remote_ice = 1;
670                         break;
671                 }
672         }
673
674         if (attr_i == remote_stream->attr_count) {
675                 session_media->remote_ice = 0;
676         }
677 }
678
679 /*! \brief Function which processes ICE attributes in an audio stream */
680 static void process_ice_attributes(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
681                                    const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream)
682 {
683         struct ast_rtp_engine_ice *ice;
684         const pjmedia_sdp_attr *attr;
685         char attr_value[256];
686         unsigned int attr_i;
687
688         /* If ICE support is not enabled or available exit early */
689         if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) {
690                 return;
691         }
692
693         attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-ufrag", NULL);
694         if (!attr) {
695                 attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-ufrag", NULL);
696         }
697         if (attr) {
698                 ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
699                 ice->set_authentication(session_media->rtp, attr_value, NULL);
700         } else {
701                 return;
702         }
703
704         attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-pwd", NULL);
705         if (!attr) {
706                 attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-pwd", NULL);
707         }
708         if (attr) {
709                 ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
710                 ice->set_authentication(session_media->rtp, NULL, attr_value);
711         } else {
712                 return;
713         }
714
715         if (pjmedia_sdp_media_find_attr2(remote_stream, "ice-lite", NULL)) {
716                 ice->ice_lite(session_media->rtp);
717         }
718
719         /* Find all of the candidates */
720         for (attr_i = 0; attr_i < remote_stream->attr_count; ++attr_i) {
721                 char foundation[33], transport[32], address[PJ_INET6_ADDRSTRLEN + 1], cand_type[6], relay_address[PJ_INET6_ADDRSTRLEN + 1] = "";
722                 unsigned int port, relay_port = 0;
723                 struct ast_rtp_engine_ice_candidate candidate = { 0, };
724
725                 attr = remote_stream->attr[attr_i];
726
727                 /* If this is not a candidate line skip it */
728                 if (pj_strcmp2(&attr->name, "candidate")) {
729                         continue;
730                 }
731
732                 ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
733
734                 if (sscanf(attr_value, "%32s %30u %31s %30u %46s %30u typ %5s %*s %23s %*s %30u", foundation, &candidate.id, transport,
735                         (unsigned *)&candidate.priority, address, &port, cand_type, relay_address, &relay_port) < 7) {
736                         /* Candidate did not parse properly */
737                         continue;
738                 }
739
740                 if (session->endpoint->media.rtcp_mux && session_media->remote_rtcp_mux && candidate.id > 1) {
741                         /* Remote side may have offered RTP and RTCP candidates. However, if we're using RTCP MUX,
742                          * then we should ignore RTCP candidates.
743                          */
744                         continue;
745                 }
746
747                 candidate.foundation = foundation;
748                 candidate.transport = transport;
749
750                 ast_sockaddr_parse(&candidate.address, address, PARSE_PORT_FORBID);
751                 ast_sockaddr_set_port(&candidate.address, port);
752
753                 if (!strcasecmp(cand_type, "host")) {
754                         candidate.type = AST_RTP_ICE_CANDIDATE_TYPE_HOST;
755                 } else if (!strcasecmp(cand_type, "srflx")) {
756                         candidate.type = AST_RTP_ICE_CANDIDATE_TYPE_SRFLX;
757                 } else if (!strcasecmp(cand_type, "relay")) {
758                         candidate.type = AST_RTP_ICE_CANDIDATE_TYPE_RELAYED;
759                 } else {
760                         continue;
761                 }
762
763                 if (!ast_strlen_zero(relay_address)) {
764                         ast_sockaddr_parse(&candidate.relay_address, relay_address, PARSE_PORT_FORBID);
765                 }
766
767                 if (relay_port) {
768                         ast_sockaddr_set_port(&candidate.relay_address, relay_port);
769                 }
770
771                 ice->add_remote_candidate(session_media->rtp, &candidate);
772         }
773
774         ice->set_role(session_media->rtp, pjmedia_sdp_neg_was_answer_remote(session->inv_session->neg) == PJ_TRUE ?
775                 AST_RTP_ICE_ROLE_CONTROLLING : AST_RTP_ICE_ROLE_CONTROLLED);
776         ice->start(session_media->rtp);
777 }
778
779 /*! \brief figure out if media stream has crypto lines for sdes */
780 static int media_stream_has_crypto(const struct pjmedia_sdp_media *stream)
781 {
782         int i;
783
784         for (i = 0; i < stream->attr_count; i++) {
785                 pjmedia_sdp_attr *attr;
786
787                 /* check the stream for the required crypto attribute */
788                 attr = stream->attr[i];
789                 if (pj_strcmp2(&attr->name, "crypto")) {
790                         continue;
791                 }
792
793                 return 1;
794         }
795
796         return 0;
797 }
798
799 /*! \brief figure out media transport encryption type from the media transport string */
800 static enum ast_sip_session_media_encryption get_media_encryption_type(pj_str_t transport,
801         const struct pjmedia_sdp_media *stream, unsigned int *optimistic)
802 {
803         RAII_VAR(char *, transport_str, ast_strndup(transport.ptr, transport.slen), ast_free);
804
805         *optimistic = 0;
806
807         if (!transport_str) {
808                 return AST_SIP_MEDIA_TRANSPORT_INVALID;
809         }
810         if (strstr(transport_str, "UDP/TLS")) {
811                 return AST_SIP_MEDIA_ENCRYPT_DTLS;
812         } else if (strstr(transport_str, "SAVP")) {
813                 return AST_SIP_MEDIA_ENCRYPT_SDES;
814         } else if (media_stream_has_crypto(stream)) {
815                 *optimistic = 1;
816                 return AST_SIP_MEDIA_ENCRYPT_SDES;
817         } else {
818                 return AST_SIP_MEDIA_ENCRYPT_NONE;
819         }
820 }
821
822 /*!
823  * \brief Checks whether the encryption offered in SDP is compatible with the endpoint's configuration
824  * \internal
825  *
826  * \param endpoint_encryption Media encryption configured for the endpoint
827  * \param stream pjmedia_sdp_media stream description
828  *
829  * \retval AST_SIP_MEDIA_TRANSPORT_INVALID on encryption mismatch
830  * \retval The encryption requested in the SDP
831  */
832 static enum ast_sip_session_media_encryption check_endpoint_media_transport(
833         struct ast_sip_endpoint *endpoint,
834         const struct pjmedia_sdp_media *stream)
835 {
836         enum ast_sip_session_media_encryption incoming_encryption;
837         char transport_end = stream->desc.transport.ptr[stream->desc.transport.slen - 1];
838         unsigned int optimistic;
839
840         if ((transport_end == 'F' && !endpoint->media.rtp.use_avpf)
841                 || (transport_end != 'F' && endpoint->media.rtp.use_avpf)) {
842                 return AST_SIP_MEDIA_TRANSPORT_INVALID;
843         }
844
845         incoming_encryption = get_media_encryption_type(stream->desc.transport, stream, &optimistic);
846
847         if (incoming_encryption == endpoint->media.rtp.encryption) {
848                 return incoming_encryption;
849         }
850
851         if (endpoint->media.rtp.force_avp ||
852                 endpoint->media.rtp.encryption_optimistic) {
853                 return incoming_encryption;
854         }
855
856         /* If an optimistic offer has been made but encryption is not enabled consider it as having
857          * no offer of crypto at all instead of invalid so the session proceeds.
858          */
859         if (optimistic) {
860                 return AST_SIP_MEDIA_ENCRYPT_NONE;
861         }
862
863         return AST_SIP_MEDIA_TRANSPORT_INVALID;
864 }
865
866 static int setup_srtp(struct ast_sip_session_media *session_media)
867 {
868         if (!session_media->srtp) {
869                 session_media->srtp = ast_sdp_srtp_alloc();
870                 if (!session_media->srtp) {
871                         return -1;
872                 }
873         }
874
875         if (!session_media->srtp->crypto) {
876                 session_media->srtp->crypto = ast_sdp_crypto_alloc();
877                 if (!session_media->srtp->crypto) {
878                         return -1;
879                 }
880         }
881
882         return 0;
883 }
884
885 static int setup_dtls_srtp(struct ast_sip_session *session,
886         struct ast_sip_session_media *session_media)
887 {
888         struct ast_rtp_engine_dtls *dtls;
889
890         if (!session->endpoint->media.rtp.dtls_cfg.enabled || !session_media->rtp) {
891                 return -1;
892         }
893
894         dtls = ast_rtp_instance_get_dtls(session_media->rtp);
895         if (!dtls) {
896                 return -1;
897         }
898
899         session->endpoint->media.rtp.dtls_cfg.suite = ((session->endpoint->media.rtp.srtp_tag_32) ? AST_AES_CM_128_HMAC_SHA1_32 : AST_AES_CM_128_HMAC_SHA1_80);
900         if (dtls->set_configuration(session_media->rtp, &session->endpoint->media.rtp.dtls_cfg)) {
901                 ast_log(LOG_ERROR, "Attempted to set an invalid DTLS-SRTP configuration on RTP instance '%p'\n",
902                         session_media->rtp);
903                 return -1;
904         }
905
906         if (setup_srtp(session_media)) {
907                 return -1;
908         }
909         return 0;
910 }
911
912 static void apply_dtls_attrib(struct ast_sip_session_media *session_media,
913         pjmedia_sdp_attr *attr)
914 {
915         struct ast_rtp_engine_dtls *dtls = ast_rtp_instance_get_dtls(session_media->rtp);
916         pj_str_t *value;
917
918         if (!attr->value.ptr || !dtls) {
919                 return;
920         }
921
922         value = pj_strtrim(&attr->value);
923
924         if (!pj_strcmp2(&attr->name, "setup")) {
925                 if (!pj_stricmp2(value, "active")) {
926                         dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_ACTIVE);
927                 } else if (!pj_stricmp2(value, "passive")) {
928                         dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_PASSIVE);
929                 } else if (!pj_stricmp2(value, "actpass")) {
930                         dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_ACTPASS);
931                 } else if (!pj_stricmp2(value, "holdconn")) {
932                         dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_HOLDCONN);
933                 } else {
934                         ast_log(LOG_WARNING, "Unsupported setup attribute value '%*s'\n", (int)value->slen, value->ptr);
935                 }
936         } else if (!pj_strcmp2(&attr->name, "connection")) {
937                 if (!pj_stricmp2(value, "new")) {
938                         dtls->reset(session_media->rtp);
939                 } else if (!pj_stricmp2(value, "existing")) {
940                         /* Do nothing */
941                 } else {
942                         ast_log(LOG_WARNING, "Unsupported connection attribute value '%*s'\n", (int)value->slen, value->ptr);
943                 }
944         } else if (!pj_strcmp2(&attr->name, "fingerprint")) {
945                 char hash_value[256], hash[32];
946                 char fingerprint_text[value->slen + 1];
947                 ast_copy_pj_str(fingerprint_text, value, sizeof(fingerprint_text));
948                         if (sscanf(fingerprint_text, "%31s %255s", hash, hash_value) == 2) {
949                         if (!strcasecmp(hash, "sha-1")) {
950                                 dtls->set_fingerprint(session_media->rtp, AST_RTP_DTLS_HASH_SHA1, hash_value);
951                         } else if (!strcasecmp(hash, "sha-256")) {
952                                 dtls->set_fingerprint(session_media->rtp, AST_RTP_DTLS_HASH_SHA256, hash_value);
953                         } else {
954                                 ast_log(LOG_WARNING, "Unsupported fingerprint hash type '%s'\n",
955                                 hash);
956                         }
957                 }
958         }
959 }
960
961 static int parse_dtls_attrib(struct ast_sip_session_media *session_media,
962         const struct pjmedia_sdp_session *sdp,
963         const struct pjmedia_sdp_media *stream)
964 {
965         int i;
966
967         for (i = 0; i < sdp->attr_count; i++) {
968                 apply_dtls_attrib(session_media, sdp->attr[i]);
969         }
970
971         for (i = 0; i < stream->attr_count; i++) {
972                 apply_dtls_attrib(session_media, stream->attr[i]);
973         }
974
975         ast_set_flag(session_media->srtp, AST_SRTP_CRYPTO_OFFER_OK);
976
977         return 0;
978 }
979
980 static int setup_sdes_srtp(struct ast_sip_session_media *session_media,
981         const struct pjmedia_sdp_media *stream)
982 {
983         int i;
984
985         for (i = 0; i < stream->attr_count; i++) {
986                 pjmedia_sdp_attr *attr;
987                 RAII_VAR(char *, crypto_str, NULL, ast_free);
988
989                 /* check the stream for the required crypto attribute */
990                 attr = stream->attr[i];
991                 if (pj_strcmp2(&attr->name, "crypto")) {
992                         continue;
993                 }
994
995                 crypto_str = ast_strndup(attr->value.ptr, attr->value.slen);
996                 if (!crypto_str) {
997                         return -1;
998                 }
999
1000                 if (setup_srtp(session_media)) {
1001                         return -1;
1002                 }
1003
1004                 if (!ast_sdp_crypto_process(session_media->rtp, session_media->srtp, crypto_str)) {
1005                         /* found a valid crypto attribute */
1006                         return 0;
1007                 }
1008
1009                 ast_log(LOG_WARNING, "Ignoring crypto offer with unsupported parameters: %s\n", crypto_str);
1010         }
1011
1012         /* no usable crypto attributes found */
1013         return -1;
1014 }
1015
1016 static int setup_media_encryption(struct ast_sip_session *session,
1017         struct ast_sip_session_media *session_media,
1018         const struct pjmedia_sdp_session *sdp,
1019         const struct pjmedia_sdp_media *stream)
1020 {
1021         switch (session_media->encryption) {
1022         case AST_SIP_MEDIA_ENCRYPT_SDES:
1023                 if (setup_sdes_srtp(session_media, stream)) {
1024                         return -1;
1025                 }
1026                 break;
1027         case AST_SIP_MEDIA_ENCRYPT_DTLS:
1028                 if (setup_dtls_srtp(session, session_media)) {
1029                         return -1;
1030                 }
1031                 if (parse_dtls_attrib(session_media, sdp, stream)) {
1032                         return -1;
1033                 }
1034                 break;
1035         case AST_SIP_MEDIA_TRANSPORT_INVALID:
1036         case AST_SIP_MEDIA_ENCRYPT_NONE:
1037                 break;
1038         }
1039
1040         return 0;
1041 }
1042
1043 static void set_ice_components(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
1044 {
1045         struct ast_rtp_engine_ice *ice;
1046
1047         ast_assert(session_media->rtp != NULL);
1048
1049         ice = ast_rtp_instance_get_ice(session_media->rtp);
1050         if (!session->endpoint->media.rtp.ice_support || !ice) {
1051                 return;
1052         }
1053
1054         if (session->endpoint->media.rtcp_mux && session_media->remote_rtcp_mux) {
1055                 /* We both support RTCP mux. Only one ICE component necessary */
1056                 ice->change_components(session_media->rtp, 1);
1057         } else {
1058                 /* They either don't support RTCP mux or we don't know if they do yet. */
1059                 ice->change_components(session_media->rtp, 2);
1060         }
1061 }
1062
1063 /*! \brief Function which adds ssrc attributes to a media stream */
1064 static void add_ssrc_to_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media)
1065 {
1066         pj_str_t stmp;
1067         pjmedia_sdp_attr *attr;
1068         char tmp[128];
1069
1070         if (!session->endpoint->media.bundle || session_media->bundle_group == -1) {
1071                 return;
1072         }
1073
1074         snprintf(tmp, sizeof(tmp), "%u cname:%s", ast_rtp_instance_get_ssrc(session_media->rtp), ast_rtp_instance_get_cname(session_media->rtp));
1075         attr = pjmedia_sdp_attr_create(pool, "ssrc", pj_cstr(&stmp, tmp));
1076         media->attr[media->attr_count++] = attr;
1077 }
1078
1079 /*! \brief Function which processes ssrc attributes in a stream */
1080 static void process_ssrc_attributes(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
1081                                    const struct pjmedia_sdp_media *remote_stream)
1082 {
1083         int index;
1084
1085         if (!session->endpoint->media.bundle) {
1086                 return;
1087         }
1088
1089         for (index = 0; index < remote_stream->attr_count; ++index) {
1090                 pjmedia_sdp_attr *attr = remote_stream->attr[index];
1091                 char attr_value[pj_strlen(&attr->value) + 1];
1092                 char *ssrc_attribute_name, *ssrc_attribute_value = NULL;
1093                 unsigned int ssrc;
1094
1095                 /* We only care about ssrc attributes */
1096                 if (pj_strcmp2(&attr->name, "ssrc")) {
1097                         continue;
1098                 }
1099
1100                 ast_copy_pj_str(attr_value, &attr->value, sizeof(attr_value));
1101
1102                 if ((ssrc_attribute_name = strchr(attr_value, ' '))) {
1103                         /* This has an actual attribute */
1104                         *ssrc_attribute_name++ = '\0';
1105                         ssrc_attribute_value = strchr(ssrc_attribute_name, ':');
1106                         if (ssrc_attribute_value) {
1107                                 /* Values are actually optional according to the spec */
1108                                 *ssrc_attribute_value++ = '\0';
1109                         }
1110                 }
1111
1112                 if (sscanf(attr_value, "%30u", &ssrc) < 1) {
1113                         continue;
1114                 }
1115
1116                 /* If we are currently negotiating as a result of the remote side renegotiating then
1117                  * determine if the source for this stream has changed.
1118                  */
1119                 if (pjmedia_sdp_neg_get_state(session->inv_session->neg) == PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER &&
1120                         session->active_media_state) {
1121                         struct ast_rtp_instance_stats stats = { 0, };
1122
1123                         if (!ast_rtp_instance_get_stats(session_media->rtp, &stats, AST_RTP_INSTANCE_STAT_REMOTE_SSRC) &&
1124                                 stats.remote_ssrc != ssrc) {
1125                                 session_media->changed = 1;
1126                         }
1127                 }
1128
1129                 ast_rtp_instance_set_remote_ssrc(session_media->rtp, ssrc);
1130                 break;
1131         }
1132 }
1133
1134 static void add_msid_to_stream(struct ast_sip_session *session,
1135         struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media,
1136         struct ast_stream *stream)
1137 {
1138         pj_str_t stmp;
1139         pjmedia_sdp_attr *attr;
1140         char msid[(AST_UUID_STR_LEN * 2) + 2];
1141         const char *stream_label = ast_stream_get_metadata(stream, "SDP:LABEL");
1142
1143         if (!session->endpoint->media.webrtc) {
1144                 return;
1145         }
1146
1147         if (ast_strlen_zero(session_media->mslabel)) {
1148                 /* If this stream is grouped with another then use its media stream label if possible */
1149                 if (ast_stream_get_group(stream) != -1) {
1150                         struct ast_sip_session_media *group_session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, ast_stream_get_group(stream));
1151
1152                         ast_copy_string(session_media->mslabel, group_session_media->mslabel, sizeof(session_media->mslabel));
1153                 }
1154
1155                 if (ast_strlen_zero(session_media->mslabel)) {
1156                         ast_uuid_generate_str(session_media->mslabel, sizeof(session_media->mslabel));
1157                 }
1158         }
1159
1160         if (ast_strlen_zero(session_media->label)) {
1161                 ast_uuid_generate_str(session_media->label, sizeof(session_media->label));
1162                 /* add for stream identification to replace stream_name */
1163                 ast_stream_set_metadata(stream, "MSID:LABEL", session_media->label);
1164         }
1165
1166         snprintf(msid, sizeof(msid), "%s %s", session_media->mslabel, session_media->label);
1167         ast_debug(3, "Stream msid: %p %s %s\n", stream,
1168                 ast_codec_media_type2str(ast_stream_get_type(stream)), msid);
1169         attr = pjmedia_sdp_attr_create(pool, "msid", pj_cstr(&stmp, msid));
1170         pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1171
1172         /* 'label' must come after 'msid' */
1173         if (!ast_strlen_zero(stream_label)) {
1174                 ast_debug(3, "Stream Label: %p %s %s\n", stream,
1175                         ast_codec_media_type2str(ast_stream_get_type(stream)), stream_label);
1176                 attr = pjmedia_sdp_attr_create(pool, "label", pj_cstr(&stmp, stream_label));
1177                 pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1178         }
1179 }
1180
1181 static void add_rtcp_fb_to_stream(struct ast_sip_session *session,
1182         struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media)
1183 {
1184         pj_str_t stmp;
1185         pjmedia_sdp_attr *attr;
1186
1187         if (!session->endpoint->media.webrtc) {
1188                 return;
1189         }
1190
1191         /* transport-cc is supposed to be for the entire transport, and any media sources so
1192          * while the header does not appear in audio streams and isn't negotiated there, we still
1193          * place this attribute in as Chrome does.
1194          */
1195         attr = pjmedia_sdp_attr_create(pool, "rtcp-fb", pj_cstr(&stmp, "* transport-cc"));
1196         pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1197
1198         if (session_media->type != AST_MEDIA_TYPE_VIDEO) {
1199                 return;
1200         }
1201
1202         /*
1203          * For now just automatically add it the stream even though it hasn't
1204          * necessarily been negotiated.
1205          */
1206         attr = pjmedia_sdp_attr_create(pool, "rtcp-fb", pj_cstr(&stmp, "* ccm fir"));
1207         pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1208
1209         attr = pjmedia_sdp_attr_create(pool, "rtcp-fb", pj_cstr(&stmp, "* goog-remb"));
1210         pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1211
1212         attr = pjmedia_sdp_attr_create(pool, "rtcp-fb", pj_cstr(&stmp, "* nack"));
1213         pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1214 }
1215
1216 static void add_extmap_to_stream(struct ast_sip_session *session,
1217         struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media)
1218 {
1219         int idx;
1220         char extmap_value[256];
1221
1222         if (!session->endpoint->media.webrtc || session_media->type != AST_MEDIA_TYPE_VIDEO) {
1223                 return;
1224         }
1225
1226         /* RTP extension local unique identifiers start at '1' */
1227         for (idx = 1; idx <= ast_rtp_instance_extmap_count(session_media->rtp); ++idx) {
1228                 enum ast_rtp_extension extension = ast_rtp_instance_extmap_get_extension(session_media->rtp, idx);
1229                 const char *direction_str = "";
1230                 pj_str_t stmp;
1231                 pjmedia_sdp_attr *attr;
1232
1233                 /* If this is an unsupported RTP extension we can't place it into the SDP */
1234                 if (extension == AST_RTP_EXTENSION_UNSUPPORTED) {
1235                         continue;
1236                 }
1237
1238                 switch (ast_rtp_instance_extmap_get_direction(session_media->rtp, idx)) {
1239                 case AST_RTP_EXTENSION_DIRECTION_SENDRECV:
1240                         /* Lack of a direction indicates sendrecv, so we leave it out */
1241                         direction_str = "";
1242                         break;
1243                 case AST_RTP_EXTENSION_DIRECTION_SENDONLY:
1244                         direction_str = "/sendonly";
1245                         break;
1246                 case AST_RTP_EXTENSION_DIRECTION_RECVONLY:
1247                         direction_str = "/recvonly";
1248                         break;
1249                 case AST_RTP_EXTENSION_DIRECTION_NONE:
1250                         /* It is impossible for a "none" direction extension to be negotiated but just in case
1251                          * we treat it as inactive.
1252                          */
1253                 case AST_RTP_EXTENSION_DIRECTION_INACTIVE:
1254                         direction_str = "/inactive";
1255                         break;
1256                 }
1257
1258                 snprintf(extmap_value, sizeof(extmap_value), "%d%s %s", idx, direction_str,
1259                         ast_rtp_instance_extmap_get_uri(session_media->rtp, idx));
1260                 attr = pjmedia_sdp_attr_create(pool, "extmap", pj_cstr(&stmp, extmap_value));
1261                 pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1262         }
1263 }
1264
1265 /*! \brief Function which processes extmap attributes in a stream */
1266 static void process_extmap_attributes(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
1267                                    const struct pjmedia_sdp_media *remote_stream)
1268 {
1269         int index;
1270
1271         if (!session->endpoint->media.webrtc || session_media->type != AST_MEDIA_TYPE_VIDEO) {
1272                 return;
1273         }
1274
1275         ast_rtp_instance_extmap_clear(session_media->rtp);
1276
1277         for (index = 0; index < remote_stream->attr_count; ++index) {
1278                 pjmedia_sdp_attr *attr = remote_stream->attr[index];
1279                 char attr_value[pj_strlen(&attr->value) + 1];
1280                 char *uri;
1281                 int id;
1282                 char direction_str[10] = "";
1283                 char *attributes;
1284                 enum ast_rtp_extension_direction direction = AST_RTP_EXTENSION_DIRECTION_SENDRECV;
1285
1286                 /* We only care about extmap attributes */
1287                 if (pj_strcmp2(&attr->name, "extmap")) {
1288                         continue;
1289                 }
1290
1291                 ast_copy_pj_str(attr_value, &attr->value, sizeof(attr_value));
1292
1293                 /* Split the combined unique identifier and direction away from the URI and attributes for easier parsing */
1294                 uri = strchr(attr_value, ' ');
1295                 if (ast_strlen_zero(uri)) {
1296                         continue;
1297                 }
1298                 *uri++ = '\0';
1299
1300                 if ((sscanf(attr_value, "%30d%9s", &id, direction_str) < 1) || (id < 1)) {
1301                         /* We require at a minimum the unique identifier */
1302                         continue;
1303                 }
1304
1305                 /* Convert from the string to the internal representation */
1306                 if (!strcasecmp(direction_str, "/sendonly")) {
1307                         direction = AST_RTP_EXTENSION_DIRECTION_SENDONLY;
1308                 } else if (!strcasecmp(direction_str, "/recvonly")) {
1309                         direction = AST_RTP_EXTENSION_DIRECTION_RECVONLY;
1310                 } else if (!strcasecmp(direction_str, "/inactive")) {
1311                         direction = AST_RTP_EXTENSION_DIRECTION_INACTIVE;
1312                 }
1313
1314                 attributes = strchr(uri, ' ');
1315                 if (!ast_strlen_zero(attributes)) {
1316                         *attributes++ = '\0';
1317                 }
1318
1319                 ast_rtp_instance_extmap_negotiate(session_media->rtp, id, direction, uri, attributes);
1320         }
1321 }
1322
1323 /*! \brief Function which negotiates an incoming media stream */
1324 static int negotiate_incoming_sdp_stream(struct ast_sip_session *session,
1325         struct ast_sip_session_media *session_media, const pjmedia_sdp_session *sdp,
1326         int index, struct ast_stream *asterisk_stream)
1327 {
1328         char host[NI_MAXHOST];
1329         RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free);
1330         pjmedia_sdp_media *stream = sdp->media[index];
1331         struct ast_sip_session_media *session_media_transport;
1332         enum ast_media_type media_type = session_media->type;
1333         enum ast_sip_session_media_encryption encryption = AST_SIP_MEDIA_ENCRYPT_NONE;
1334         int res;
1335
1336         /* If no type formats have been configured reject this stream */
1337         if (!ast_format_cap_has_type(session->endpoint->media.codecs, media_type)) {
1338                 ast_debug(3, "Endpoint has no codecs for media type '%s', declining stream\n",
1339                         ast_codec_media_type2str(session_media->type));
1340                 return 0;
1341         }
1342
1343         /* Ensure incoming transport is compatible with the endpoint's configuration */
1344         if (!session->endpoint->media.rtp.use_received_transport) {
1345                 encryption = check_endpoint_media_transport(session->endpoint, stream);
1346
1347                 if (encryption == AST_SIP_MEDIA_TRANSPORT_INVALID) {
1348                         return -1;
1349                 }
1350         }
1351
1352         ast_copy_pj_str(host, stream->conn ? &stream->conn->addr : &sdp->conn->addr, sizeof(host));
1353
1354         /* Ensure that the address provided is valid */
1355         if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC) <= 0) {
1356                 /* The provided host was actually invalid so we error out this negotiation */
1357                 return -1;
1358         }
1359
1360         /* Using the connection information create an appropriate RTP instance */
1361         if (!session_media->rtp && create_rtp(session, session_media, sdp)) {
1362                 return -1;
1363         }
1364
1365         process_ssrc_attributes(session, session_media, stream);
1366         process_extmap_attributes(session, session_media, stream);
1367         session_media_transport = ast_sip_session_media_get_transport(session, session_media);
1368
1369         if (session_media_transport == session_media || !session_media->bundled) {
1370                 /* If this media session is carrying actual traffic then set up those aspects */
1371                 session_media->remote_rtcp_mux = (pjmedia_sdp_media_find_attr2(stream, "rtcp-mux", NULL) != NULL);
1372                 set_ice_components(session, session_media);
1373
1374                 enable_rtcp(session, session_media, stream);
1375
1376                 res = setup_media_encryption(session, session_media, sdp, stream);
1377                 if (res) {
1378                         if (!session->endpoint->media.rtp.encryption_optimistic ||
1379                                 !pj_strncmp2(&stream->desc.transport, "RTP/SAVP", 8)) {
1380                                 /* If optimistic encryption is disabled and crypto should have been enabled
1381                                  * but was not this session must fail. This must also fail if crypto was
1382                                  * required in the offer but could not be set up.
1383                                  */
1384                                 return -1;
1385                         }
1386                         /* There is no encryption, sad. */
1387                         session_media->encryption = AST_SIP_MEDIA_ENCRYPT_NONE;
1388                 }
1389
1390                 /* If we've been explicitly configured to use the received transport OR if
1391                  * encryption is on and crypto is present use the received transport.
1392                  * This is done in case of optimistic because it may come in as RTP/AVP or RTP/SAVP depending
1393                  * on the configuration of the remote endpoint (optimistic themselves or mandatory).
1394                  */
1395                 if ((session->endpoint->media.rtp.use_received_transport) ||
1396                         ((encryption == AST_SIP_MEDIA_ENCRYPT_SDES) && !res)) {
1397                         pj_strdup(session->inv_session->pool, &session_media->transport, &stream->desc.transport);
1398                 }
1399         } else {
1400                 /* This is bundled with another session, so mark it as such */
1401                 ast_rtp_instance_bundle(session_media->rtp, session_media_transport->rtp);
1402
1403                 enable_rtcp(session, session_media, stream);
1404         }
1405
1406         /* If ICE support is enabled find all the needed attributes */
1407         check_ice_support(session, session_media, stream);
1408
1409         if (set_caps(session, session_media, session_media_transport, stream, 1, asterisk_stream)) {
1410                 return 0;
1411         }
1412
1413         return 1;
1414 }
1415
1416 static int add_crypto_to_stream(struct ast_sip_session *session,
1417         struct ast_sip_session_media *session_media,
1418         pj_pool_t *pool, pjmedia_sdp_media *media)
1419 {
1420         pj_str_t stmp;
1421         pjmedia_sdp_attr *attr;
1422         enum ast_rtp_dtls_hash hash;
1423         const char *crypto_attribute;
1424         struct ast_rtp_engine_dtls *dtls;
1425         struct ast_sdp_srtp *tmp;
1426         static const pj_str_t STR_NEW = { "new", 3 };
1427         static const pj_str_t STR_EXISTING = { "existing", 8 };
1428         static const pj_str_t STR_ACTIVE = { "active", 6 };
1429         static const pj_str_t STR_PASSIVE = { "passive", 7 };
1430         static const pj_str_t STR_ACTPASS = { "actpass", 7 };
1431         static const pj_str_t STR_HOLDCONN = { "holdconn", 8 };
1432         enum ast_rtp_dtls_setup setup;
1433
1434         switch (session_media->encryption) {
1435         case AST_SIP_MEDIA_ENCRYPT_NONE:
1436         case AST_SIP_MEDIA_TRANSPORT_INVALID:
1437                 break;
1438         case AST_SIP_MEDIA_ENCRYPT_SDES:
1439                 if (!session_media->srtp) {
1440                         session_media->srtp = ast_sdp_srtp_alloc();
1441                         if (!session_media->srtp) {
1442                                 return -1;
1443                         }
1444                 }
1445
1446                 tmp = session_media->srtp;
1447
1448                 do {
1449                         crypto_attribute = ast_sdp_srtp_get_attrib(tmp,
1450                                 0 /* DTLS running? No */,
1451                                 session->endpoint->media.rtp.srtp_tag_32 /* 32 byte tag length? */);
1452                         if (!crypto_attribute) {
1453                                 /* No crypto attribute to add, bad news */
1454                                 return -1;
1455                         }
1456
1457                         attr = pjmedia_sdp_attr_create(pool, "crypto",
1458                                 pj_cstr(&stmp, crypto_attribute));
1459                         media->attr[media->attr_count++] = attr;
1460                 } while ((tmp = AST_LIST_NEXT(tmp, sdp_srtp_list)));
1461
1462                 break;
1463         case AST_SIP_MEDIA_ENCRYPT_DTLS:
1464                 if (setup_dtls_srtp(session, session_media)) {
1465                         return -1;
1466                 }
1467
1468                 dtls = ast_rtp_instance_get_dtls(session_media->rtp);
1469                 if (!dtls) {
1470                         return -1;
1471                 }
1472
1473                 switch (dtls->get_connection(session_media->rtp)) {
1474                 case AST_RTP_DTLS_CONNECTION_NEW:
1475                         attr = pjmedia_sdp_attr_create(pool, "connection", &STR_NEW);
1476                         media->attr[media->attr_count++] = attr;
1477                         break;
1478                 case AST_RTP_DTLS_CONNECTION_EXISTING:
1479                         attr = pjmedia_sdp_attr_create(pool, "connection", &STR_EXISTING);
1480                         media->attr[media->attr_count++] = attr;
1481                         break;
1482                 default:
1483                         break;
1484                 }
1485
1486                 /* If this is an answer we need to use our current state, if it's an offer we need to use
1487                  * the configured value.
1488                  */
1489                 if (session->inv_session->neg
1490                         && pjmedia_sdp_neg_get_state(session->inv_session->neg) != PJMEDIA_SDP_NEG_STATE_DONE) {
1491                         setup = dtls->get_setup(session_media->rtp);
1492                 } else {
1493                         setup = session->endpoint->media.rtp.dtls_cfg.default_setup;
1494                 }
1495
1496                 switch (setup) {
1497                 case AST_RTP_DTLS_SETUP_ACTIVE:
1498                         attr = pjmedia_sdp_attr_create(pool, "setup", &STR_ACTIVE);
1499                         media->attr[media->attr_count++] = attr;
1500                         break;
1501                 case AST_RTP_DTLS_SETUP_PASSIVE:
1502                         attr = pjmedia_sdp_attr_create(pool, "setup", &STR_PASSIVE);
1503                         media->attr[media->attr_count++] = attr;
1504                         break;
1505                 case AST_RTP_DTLS_SETUP_ACTPASS:
1506                         attr = pjmedia_sdp_attr_create(pool, "setup", &STR_ACTPASS);
1507                         media->attr[media->attr_count++] = attr;
1508                         break;
1509                 case AST_RTP_DTLS_SETUP_HOLDCONN:
1510                         attr = pjmedia_sdp_attr_create(pool, "setup", &STR_HOLDCONN);
1511                         break;
1512                 default:
1513                         break;
1514                 }
1515
1516                 hash = dtls->get_fingerprint_hash(session_media->rtp);
1517                 crypto_attribute = dtls->get_fingerprint(session_media->rtp);
1518                 if (crypto_attribute && (hash == AST_RTP_DTLS_HASH_SHA1 || hash == AST_RTP_DTLS_HASH_SHA256)) {
1519                         RAII_VAR(struct ast_str *, fingerprint, ast_str_create(64), ast_free);
1520                         if (!fingerprint) {
1521                                 return -1;
1522                         }
1523
1524                         if (hash == AST_RTP_DTLS_HASH_SHA1) {
1525                                 ast_str_set(&fingerprint, 0, "SHA-1 %s", crypto_attribute);
1526                         } else {
1527                                 ast_str_set(&fingerprint, 0, "SHA-256 %s", crypto_attribute);
1528                         }
1529
1530                         attr = pjmedia_sdp_attr_create(pool, "fingerprint", pj_cstr(&stmp, ast_str_buffer(fingerprint)));
1531                         media->attr[media->attr_count++] = attr;
1532                 }
1533                 break;
1534         }
1535
1536         return 0;
1537 }
1538
1539 /*! \brief Function which creates an outgoing stream */
1540 static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
1541                                       struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_session *remote, struct ast_stream *stream)
1542 {
1543         pj_pool_t *pool = session->inv_session->pool_prov;
1544         static const pj_str_t STR_RTP_AVP = { "RTP/AVP", 7 };
1545         static const pj_str_t STR_IN = { "IN", 2 };
1546         static const pj_str_t STR_IP4 = { "IP4", 3};
1547         static const pj_str_t STR_IP6 = { "IP6", 3};
1548         static const pj_str_t STR_SENDRECV = { "sendrecv", 8 };
1549         static const pj_str_t STR_SENDONLY = { "sendonly", 8 };
1550         pjmedia_sdp_media *media;
1551         const char *hostip = NULL;
1552         struct ast_sockaddr addr;
1553         char tmp[512];
1554         pj_str_t stmp;
1555         pjmedia_sdp_attr *attr;
1556         int index = 0;
1557         int noncodec = (session->dtmf == AST_SIP_DTMF_RFC_4733 || session->dtmf == AST_SIP_DTMF_AUTO || session->dtmf == AST_SIP_DTMF_AUTO_INFO) ? AST_RTP_DTMF : 0;
1558         int min_packet_size = 0, max_packet_size = 0;
1559         int rtp_code;
1560         RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup);
1561         enum ast_media_type media_type = session_media->type;
1562         struct ast_sip_session_media *session_media_transport;
1563         pj_sockaddr ip;
1564
1565         int direct_media_enabled = !ast_sockaddr_isnull(&session_media->direct_media_addr) &&
1566                 ast_format_cap_count(session->direct_media_cap);
1567
1568         media = pj_pool_zalloc(pool, sizeof(struct pjmedia_sdp_media));
1569         if (!media) {
1570                 return -1;
1571         }
1572         pj_strdup2(pool, &media->desc.media, ast_codec_media_type2str(session_media->type));
1573
1574         /* If this is a removed (or declined) stream OR if no formats exist then construct a minimal stream in SDP */
1575         if (ast_stream_get_state(stream) == AST_STREAM_STATE_REMOVED || !ast_stream_get_formats(stream) ||
1576                 !ast_format_cap_count(ast_stream_get_formats(stream))) {
1577                 media->desc.port = 0;
1578                 media->desc.port_count = 1;
1579
1580                 if (remote && remote->media[ast_stream_get_position(stream)]) {
1581                         pjmedia_sdp_media *remote_media = remote->media[ast_stream_get_position(stream)];
1582                         int index;
1583
1584                         media->desc.transport = remote_media->desc.transport;
1585
1586                         /* Preserve existing behavior by copying the formats provided from the offer */
1587                         for (index = 0; index < remote_media->desc.fmt_count; ++index) {
1588                                 media->desc.fmt[index] = remote_media->desc.fmt[index];
1589                         }
1590                         media->desc.fmt_count = remote_media->desc.fmt_count;
1591                 } else {
1592                         /* This is actually an offer so put a dummy payload in that is ignored and sane transport */
1593                         media->desc.transport = STR_RTP_AVP;
1594                         pj_strdup2(pool, &media->desc.fmt[media->desc.fmt_count++], "32");
1595                 }
1596
1597                 sdp->media[sdp->media_count++] = media;
1598                 ast_stream_set_state(stream, AST_STREAM_STATE_REMOVED);
1599
1600                 return 1;
1601         }
1602
1603         if (!session_media->rtp && create_rtp(session, session_media, sdp)) {
1604                 return -1;
1605         }
1606
1607         /* If this stream has not been bundled already it is new and we need to ensure there is no SSRC conflict */
1608         if (session_media->bundle_group != -1 && !session_media->bundled) {
1609                 for (index = 0; index < sdp->media_count; ++index) {
1610                         struct ast_sip_session_media *other_session_media;
1611
1612                         other_session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, index);
1613                         if (!other_session_media->rtp || other_session_media->bundle_group != session_media->bundle_group) {
1614                                 continue;
1615                         }
1616
1617                         if (ast_rtp_instance_get_ssrc(session_media->rtp) == ast_rtp_instance_get_ssrc(other_session_media->rtp)) {
1618                                 ast_rtp_instance_change_source(session_media->rtp);
1619                                 /* Start the conflict check over again */
1620                                 index = -1;
1621                                 continue;
1622                         }
1623                 }
1624         }
1625
1626         session_media_transport = ast_sip_session_media_get_transport(session, session_media);
1627
1628         if (session_media_transport == session_media || !session_media->bundled) {
1629                 set_ice_components(session, session_media);
1630                 enable_rtcp(session, session_media, NULL);
1631
1632                 /* Crypto has to be added before setting the media transport so that SRTP is properly
1633                  * set up according to the configuration. This ends up changing the media transport.
1634                  */
1635                 if (add_crypto_to_stream(session, session_media, pool, media)) {
1636                         return -1;
1637                 }
1638
1639                 if (pj_strlen(&session_media->transport)) {
1640                         /* If a transport has already been specified use it */
1641                         media->desc.transport = session_media->transport;
1642                 } else {
1643                         media->desc.transport = pj_str(ast_sdp_get_rtp_profile(
1644                                 /* Optimistic encryption places crypto in the normal RTP/AVP profile */
1645                                 !session->endpoint->media.rtp.encryption_optimistic &&
1646                                         (session_media->encryption == AST_SIP_MEDIA_ENCRYPT_SDES),
1647                                 session_media->rtp, session->endpoint->media.rtp.use_avpf,
1648                                 session->endpoint->media.rtp.force_avp));
1649                 }
1650
1651                 media->conn = pj_pool_zalloc(pool, sizeof(struct pjmedia_sdp_conn));
1652                 if (!media->conn) {
1653                         return -1;
1654                 }
1655
1656                 /* Add connection level details */
1657                 if (direct_media_enabled) {
1658                         hostip = ast_sockaddr_stringify_fmt(&session_media->direct_media_addr, AST_SOCKADDR_STR_ADDR);
1659                 } else if (ast_strlen_zero(session->endpoint->media.address)) {
1660                         hostip = ast_sip_get_host_ip_string(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET());
1661                 } else {
1662                         hostip = session->endpoint->media.address;
1663                 }
1664
1665                 if (ast_strlen_zero(hostip)) {
1666                         ast_log(LOG_ERROR, "No local host IP available for stream %s\n",
1667                                 ast_codec_media_type2str(session_media->type));
1668                         return -1;
1669                 }
1670
1671                 media->conn->net_type = STR_IN;
1672                 /* Assume that the connection will use IPv4 until proven otherwise */
1673                 media->conn->addr_type = STR_IP4;
1674                 pj_strdup2(pool, &media->conn->addr, hostip);
1675
1676                 if ((pj_sockaddr_parse(pj_AF_UNSPEC(), 0, &media->conn->addr, &ip) == PJ_SUCCESS) &&
1677                         (ip.addr.sa_family == pj_AF_INET6())) {
1678                         media->conn->addr_type = STR_IP6;
1679                 }
1680
1681                 /* Add ICE attributes and candidates */
1682                 add_ice_to_stream(session, session_media, pool, media, 1);
1683
1684                 ast_rtp_instance_get_local_address(session_media->rtp, &addr);
1685                 media->desc.port = direct_media_enabled ? ast_sockaddr_port(&session_media->direct_media_addr) : (pj_uint16_t) ast_sockaddr_port(&addr);
1686                 media->desc.port_count = 1;
1687         } else {
1688                 pjmedia_sdp_media *bundle_group_stream = sdp->media[session_media_transport->stream_num];
1689
1690                 /* As this is in a bundle group it shares the same details as the group instance */
1691                 media->desc.transport = bundle_group_stream->desc.transport;
1692                 media->conn = bundle_group_stream->conn;
1693                 media->desc.port = bundle_group_stream->desc.port;
1694
1695                 if (add_crypto_to_stream(session, session_media_transport, pool, media)) {
1696                         return -1;
1697                 }
1698
1699                 add_ice_to_stream(session, session_media_transport, pool, media, 0);
1700
1701                 enable_rtcp(session, session_media, NULL);
1702         }
1703
1704         if (!(caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
1705                 ast_log(LOG_ERROR, "Failed to allocate %s capabilities\n",
1706                         ast_codec_media_type2str(session_media->type));
1707                 return -1;
1708         }
1709
1710         if (direct_media_enabled) {
1711                 ast_format_cap_get_compatible(session->endpoint->media.codecs, session->direct_media_cap, caps);
1712         } else {
1713                 ast_format_cap_append_from_cap(caps, ast_stream_get_formats(stream), media_type);
1714         }
1715
1716         for (index = 0; index < ast_format_cap_count(caps); ++index) {
1717                 struct ast_format *format = ast_format_cap_get_format(caps, index);
1718
1719                 if (ast_format_get_type(format) != media_type) {
1720                         ao2_ref(format, -1);
1721                         continue;
1722                 }
1723
1724                 /* If this stream is not a transport we need to use the transport codecs structure for payload management to prevent
1725                  * conflicts.
1726                  */
1727                 if (session_media_transport != session_media) {
1728                         if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media_transport->rtp), 1, format, 0)) == -1) {
1729                                 ast_log(LOG_WARNING,"Unable to get rtp codec payload code for %s\n", ast_format_get_name(format));
1730                                 ao2_ref(format, -1);
1731                                 continue;
1732                         }
1733                         /* Our instance has to match the payload number though */
1734                         ast_rtp_codecs_payload_set_rx(ast_rtp_instance_get_codecs(session_media->rtp), rtp_code, format);
1735                 } else {
1736                         if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media->rtp), 1, format, 0)) == -1) {
1737                                 ast_log(LOG_WARNING,"Unable to get rtp codec payload code for %s\n", ast_format_get_name(format));
1738                                 ao2_ref(format, -1);
1739                                 continue;
1740                         }
1741                 }
1742
1743                 if ((attr = generate_rtpmap_attr(session, media, pool, rtp_code, 1, format, 0))) {
1744                         media->attr[media->attr_count++] = attr;
1745                 }
1746
1747                 if ((attr = generate_fmtp_attr(pool, format, rtp_code))) {
1748                         media->attr[media->attr_count++] = attr;
1749                 }
1750
1751                 if (ast_format_get_maximum_ms(format) &&
1752                         ((ast_format_get_maximum_ms(format) < max_packet_size) || !max_packet_size)) {
1753                         max_packet_size = ast_format_get_maximum_ms(format);
1754                 }
1755                 ao2_ref(format, -1);
1756
1757                 if (media->desc.fmt_count == PJMEDIA_MAX_SDP_FMT) {
1758                         break;
1759                 }
1760         }
1761
1762         /* Add non-codec formats */
1763         if (ast_sip_session_is_pending_stream_default(session, stream) && media_type != AST_MEDIA_TYPE_VIDEO
1764                 && media->desc.fmt_count < PJMEDIA_MAX_SDP_FMT) {
1765                 for (index = 1LL; index <= AST_RTP_MAX; index <<= 1) {
1766                         if (!(noncodec & index)) {
1767                                 continue;
1768                         }
1769                         rtp_code = ast_rtp_codecs_payload_code(
1770                                 ast_rtp_instance_get_codecs(session_media->rtp), 0, NULL, index);
1771                         if (rtp_code == -1) {
1772                                 continue;
1773                         }
1774
1775                         if ((attr = generate_rtpmap_attr(session, media, pool, rtp_code, 0, NULL, index))) {
1776                                 media->attr[media->attr_count++] = attr;
1777                         }
1778
1779                         if (index == AST_RTP_DTMF) {
1780                                 snprintf(tmp, sizeof(tmp), "%d 0-16", rtp_code);
1781                                 attr = pjmedia_sdp_attr_create(pool, "fmtp", pj_cstr(&stmp, tmp));
1782                                 media->attr[media->attr_count++] = attr;
1783                         }
1784
1785                         if (media->desc.fmt_count == PJMEDIA_MAX_SDP_FMT) {
1786                                 break;
1787                         }
1788                 }
1789         }
1790
1791
1792         /* If no formats were actually added to the media stream don't add it to the SDP */
1793         if (!media->desc.fmt_count) {
1794                 return 1;
1795         }
1796
1797         /* If ptime is set add it as an attribute */
1798         min_packet_size = ast_rtp_codecs_get_framing(ast_rtp_instance_get_codecs(session_media->rtp));
1799         if (!min_packet_size) {
1800                 min_packet_size = ast_format_cap_get_framing(caps);
1801         }
1802         if (min_packet_size) {
1803                 snprintf(tmp, sizeof(tmp), "%d", min_packet_size);
1804                 attr = pjmedia_sdp_attr_create(pool, "ptime", pj_cstr(&stmp, tmp));
1805                 media->attr[media->attr_count++] = attr;
1806         }
1807
1808         if (max_packet_size) {
1809                 snprintf(tmp, sizeof(tmp), "%d", max_packet_size);
1810                 attr = pjmedia_sdp_attr_create(pool, "maxptime", pj_cstr(&stmp, tmp));
1811                 media->attr[media->attr_count++] = attr;
1812         }
1813
1814         /* Add the sendrecv attribute - we purposely don't keep track because pjmedia-sdp will automatically change our offer for us */
1815         attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr);
1816         attr->name = !session_media->locally_held ? STR_SENDRECV : STR_SENDONLY;
1817         media->attr[media->attr_count++] = attr;
1818
1819         /* If we've got rtcp-mux enabled, add it unless we received an offer without it */
1820         if (session->endpoint->media.rtcp_mux && session_media->remote_rtcp_mux) {
1821                 attr = pjmedia_sdp_attr_create(pool, "rtcp-mux", NULL);
1822                 pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1823         }
1824
1825         add_ssrc_to_stream(session, session_media, pool, media);
1826         add_msid_to_stream(session, session_media, pool, media, stream);
1827         add_rtcp_fb_to_stream(session, session_media, pool, media);
1828         add_extmap_to_stream(session, session_media, pool, media);
1829
1830         /* Add the media stream to the SDP */
1831         sdp->media[sdp->media_count++] = media;
1832
1833         return 1;
1834 }
1835
1836 static struct ast_frame *media_session_rtp_read_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
1837 {
1838         struct ast_frame *f;
1839
1840         if (!session_media->rtp) {
1841                 return &ast_null_frame;
1842         }
1843
1844         f = ast_rtp_instance_read(session_media->rtp, 0);
1845         if (!f) {
1846                 return NULL;
1847         }
1848
1849         ast_rtp_instance_set_last_rx(session_media->rtp, time(NULL));
1850
1851         return f;
1852 }
1853
1854 static struct ast_frame *media_session_rtcp_read_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
1855 {
1856         struct ast_frame *f;
1857
1858         if (!session_media->rtp) {
1859                 return &ast_null_frame;
1860         }
1861
1862         f = ast_rtp_instance_read(session_media->rtp, 1);
1863         if (!f) {
1864                 return NULL;
1865         }
1866
1867         ast_rtp_instance_set_last_rx(session_media->rtp, time(NULL));
1868
1869         return f;
1870 }
1871
1872 static int media_session_rtp_write_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct ast_frame *frame)
1873 {
1874         if (!session_media->rtp) {
1875                 return 0;
1876         }
1877
1878         return ast_rtp_instance_write(session_media->rtp, frame);
1879 }
1880
1881 static int apply_negotiated_sdp_stream(struct ast_sip_session *session,
1882         struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *local,
1883         const struct pjmedia_sdp_session *remote, int index, struct ast_stream *asterisk_stream)
1884 {
1885         RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free);
1886         struct pjmedia_sdp_media *remote_stream = remote->media[index];
1887         enum ast_media_type media_type = session_media->type;
1888         char host[NI_MAXHOST];
1889         int res;
1890         struct ast_sip_session_media *session_media_transport;
1891
1892         if (!session->channel) {
1893                 return 1;
1894         }
1895
1896         /* Ensure incoming transport is compatible with the endpoint's configuration */
1897         if (!session->endpoint->media.rtp.use_received_transport &&
1898                 check_endpoint_media_transport(session->endpoint, remote_stream) == AST_SIP_MEDIA_TRANSPORT_INVALID) {
1899                 return -1;
1900         }
1901
1902         /* Create an RTP instance if need be */
1903         if (!session_media->rtp && create_rtp(session, session_media, local)) {
1904                 return -1;
1905         }
1906
1907         process_ssrc_attributes(session, session_media, remote_stream);
1908         process_extmap_attributes(session, session_media, remote_stream);
1909
1910         session_media_transport = ast_sip_session_media_get_transport(session, session_media);
1911
1912         if (session_media_transport == session_media || !session_media->bundled) {
1913                 session_media->remote_rtcp_mux = (pjmedia_sdp_media_find_attr2(remote_stream, "rtcp-mux", NULL) != NULL);
1914                 set_ice_components(session, session_media);
1915
1916                 enable_rtcp(session, session_media, remote_stream);
1917
1918                 res = setup_media_encryption(session, session_media, remote, remote_stream);
1919                 if (!session->endpoint->media.rtp.encryption_optimistic && res) {
1920                         /* If optimistic encryption is disabled and crypto should have been enabled but was not
1921                          * this session must fail.
1922                          */
1923                         return -1;
1924                 }
1925
1926                 if (!remote_stream->conn && !remote->conn) {
1927                         return 1;
1928                 }
1929
1930                 ast_copy_pj_str(host, remote_stream->conn ? &remote_stream->conn->addr : &remote->conn->addr, sizeof(host));
1931
1932                 /* Ensure that the address provided is valid */
1933                 if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC) <= 0) {
1934                         /* The provided host was actually invalid so we error out this negotiation */
1935                         return -1;
1936                 }
1937
1938                 /* Apply connection information to the RTP instance */
1939                 ast_sockaddr_set_port(addrs, remote_stream->desc.port);
1940                 ast_rtp_instance_set_remote_address(session_media->rtp, addrs);
1941
1942                 ast_sip_session_media_set_write_callback(session, session_media, media_session_rtp_write_callback);
1943                 ast_sip_session_media_add_read_callback(session, session_media, ast_rtp_instance_fd(session_media->rtp, 0),
1944                         media_session_rtp_read_callback);
1945                 if (!session->endpoint->media.rtcp_mux || !session_media->remote_rtcp_mux) {
1946                         ast_sip_session_media_add_read_callback(session, session_media, ast_rtp_instance_fd(session_media->rtp, 1),
1947                                 media_session_rtcp_read_callback);
1948                 }
1949
1950                 /* If ICE support is enabled find all the needed attributes */
1951                 process_ice_attributes(session, session_media, remote, remote_stream);
1952         } else {
1953                 /* This is bundled with another session, so mark it as such */
1954                 ast_rtp_instance_bundle(session_media->rtp, session_media_transport->rtp);
1955                 ast_sip_session_media_set_write_callback(session, session_media, media_session_rtp_write_callback);
1956                 enable_rtcp(session, session_media, remote_stream);
1957         }
1958
1959         if (set_caps(session, session_media, session_media_transport, remote_stream, 0, asterisk_stream)) {
1960                 return -1;
1961         }
1962
1963         /* Set the channel uniqueid on the RTP instance now that it is becoming active */
1964         ast_channel_lock(session->channel);
1965         ast_rtp_instance_set_channel_id(session_media->rtp, ast_channel_uniqueid(session->channel));
1966         ast_channel_unlock(session->channel);
1967
1968         /* Ensure the RTP instance is active */
1969         ast_rtp_instance_set_stream_num(session_media->rtp, ast_stream_get_position(asterisk_stream));
1970         ast_rtp_instance_activate(session_media->rtp);
1971
1972         /* audio stream handles music on hold */
1973         if (media_type != AST_MEDIA_TYPE_AUDIO) {
1974                 if ((pjmedia_sdp_neg_was_answer_remote(session->inv_session->neg) == PJ_FALSE)
1975                         && (session->inv_session->state == PJSIP_INV_STATE_CONFIRMED)) {
1976                         ast_queue_control(session->channel, AST_CONTROL_UPDATE_RTP_PEER);
1977                 }
1978                 return 1;
1979         }
1980
1981         if (ast_sockaddr_isnull(addrs) ||
1982                 ast_sockaddr_is_any(addrs) ||
1983                 pjmedia_sdp_media_find_attr2(remote_stream, "sendonly", NULL) ||
1984                 pjmedia_sdp_media_find_attr2(remote_stream, "inactive", NULL)) {
1985                 if (!session_media->remotely_held) {
1986                         /* The remote side has put us on hold */
1987                         ast_queue_hold(session->channel, session->endpoint->mohsuggest);
1988                         ast_rtp_instance_stop(session_media->rtp);
1989                         ast_queue_frame(session->channel, &ast_null_frame);
1990                         session_media->remotely_held = 1;
1991                 }
1992         } else if (session_media->remotely_held) {
1993                 /* The remote side has taken us off hold */
1994                 ast_queue_unhold(session->channel);
1995                 ast_queue_frame(session->channel, &ast_null_frame);
1996                 session_media->remotely_held = 0;
1997         } else if ((pjmedia_sdp_neg_was_answer_remote(session->inv_session->neg) == PJ_FALSE)
1998                 && (session->inv_session->state == PJSIP_INV_STATE_CONFIRMED)) {
1999                 ast_queue_control(session->channel, AST_CONTROL_UPDATE_RTP_PEER);
2000         }
2001
2002         /* This purposely resets the encryption to the configured in case it gets added later */
2003         session_media->encryption = session->endpoint->media.rtp.encryption;
2004
2005         if (session->endpoint->media.rtp.keepalive > 0 &&
2006                         session_media->type == AST_MEDIA_TYPE_AUDIO) {
2007                 ast_rtp_instance_set_keepalive(session_media->rtp, session->endpoint->media.rtp.keepalive);
2008                 /* Schedule the initial keepalive early in case this is being used to punch holes through
2009                  * a NAT. This way there won't be an awkward delay before media starts flowing in some
2010                  * scenarios.
2011                  */
2012                 AST_SCHED_DEL(sched, session_media->keepalive_sched_id);
2013                 session_media->keepalive_sched_id = ast_sched_add_variable(sched, 500, send_keepalive,
2014                         session_media, 1);
2015         }
2016
2017         /* As the channel lock is not held during this process the scheduled item won't block if
2018          * it is hanging up the channel at the same point we are applying this negotiated SDP.
2019          */
2020         AST_SCHED_DEL(sched, session_media->timeout_sched_id);
2021
2022         /* Due to the fact that we only ever have one scheduled timeout item for when we are both
2023          * off hold and on hold we don't need to store the two timeouts differently on the RTP
2024          * instance itself.
2025          */
2026         ast_rtp_instance_set_timeout(session_media->rtp, 0);
2027         if (session->endpoint->media.rtp.timeout && !session_media->remotely_held) {
2028                 ast_rtp_instance_set_timeout(session_media->rtp, session->endpoint->media.rtp.timeout);
2029         } else if (session->endpoint->media.rtp.timeout_hold && session_media->remotely_held) {
2030                 ast_rtp_instance_set_timeout(session_media->rtp, session->endpoint->media.rtp.timeout_hold);
2031         }
2032
2033         if (ast_rtp_instance_get_timeout(session_media->rtp)) {
2034                 session_media->timeout_sched_id = ast_sched_add_variable(sched,
2035                         ast_rtp_instance_get_timeout(session_media->rtp) * 1000, rtp_check_timeout,
2036                         session_media, 1);
2037         }
2038
2039         return 1;
2040 }
2041
2042 /*! \brief Function which updates the media stream with external media address, if applicable */
2043 static void change_outgoing_sdp_stream_media_address(pjsip_tx_data *tdata, struct pjmedia_sdp_media *stream, struct ast_sip_transport *transport)
2044 {
2045         RAII_VAR(struct ast_sip_transport_state *, transport_state, ast_sip_get_transport_state(ast_sorcery_object_get_id(transport)), ao2_cleanup);
2046         char host[NI_MAXHOST];
2047         struct ast_sockaddr our_sdp_addr = { { 0, } };
2048
2049         /* If the stream has been rejected there will be no connection line */
2050         if (!stream->conn || !transport_state) {
2051                 return;
2052         }
2053
2054         ast_copy_pj_str(host, &stream->conn->addr, sizeof(host));
2055         ast_sockaddr_parse(&our_sdp_addr, host, PARSE_PORT_FORBID);
2056
2057         /* Reversed check here. We don't check the remote endpoint being
2058          * in our local net, but whether our outgoing session IP is
2059          * local. If it is not, we won't do rewriting. No localnet
2060          * configured? Always rewrite. */
2061         if (ast_sip_transport_is_nonlocal(transport_state, &our_sdp_addr) && transport_state->localnet) {
2062                 return;
2063         }
2064         ast_debug(5, "Setting media address to %s\n", ast_sockaddr_stringify_host(&transport_state->external_media_address));
2065         pj_strdup2(tdata->pool, &stream->conn->addr, ast_sockaddr_stringify_host(&transport_state->external_media_address));
2066 }
2067
2068 /*! \brief Function which stops the RTP instance */
2069 static void stream_stop(struct ast_sip_session_media *session_media)
2070 {
2071         if (!session_media->rtp) {
2072                 return;
2073         }
2074
2075         AST_SCHED_DEL(sched, session_media->keepalive_sched_id);
2076         AST_SCHED_DEL(sched, session_media->timeout_sched_id);
2077         ast_rtp_instance_stop(session_media->rtp);
2078 }
2079
2080 /*! \brief Function which destroys the RTP instance when session ends */
2081 static void stream_destroy(struct ast_sip_session_media *session_media)
2082 {
2083         if (session_media->rtp) {
2084                 stream_stop(session_media);
2085                 ast_rtp_instance_destroy(session_media->rtp);
2086         }
2087         session_media->rtp = NULL;
2088 }
2089
2090 /*! \brief SDP handler for 'audio' media stream */
2091 static struct ast_sip_session_sdp_handler audio_sdp_handler = {
2092         .id = STR_AUDIO,
2093         .negotiate_incoming_sdp_stream = negotiate_incoming_sdp_stream,
2094         .create_outgoing_sdp_stream = create_outgoing_sdp_stream,
2095         .apply_negotiated_sdp_stream = apply_negotiated_sdp_stream,
2096         .change_outgoing_sdp_stream_media_address = change_outgoing_sdp_stream_media_address,
2097         .stream_stop = stream_stop,
2098         .stream_destroy = stream_destroy,
2099 };
2100
2101 /*! \brief SDP handler for 'video' media stream */
2102 static struct ast_sip_session_sdp_handler video_sdp_handler = {
2103         .id = STR_VIDEO,
2104         .negotiate_incoming_sdp_stream = negotiate_incoming_sdp_stream,
2105         .create_outgoing_sdp_stream = create_outgoing_sdp_stream,
2106         .apply_negotiated_sdp_stream = apply_negotiated_sdp_stream,
2107         .change_outgoing_sdp_stream_media_address = change_outgoing_sdp_stream_media_address,
2108         .stream_stop = stream_stop,
2109         .stream_destroy = stream_destroy,
2110 };
2111
2112 static int video_info_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
2113 {
2114         struct pjsip_transaction *tsx;
2115         pjsip_tx_data *tdata;
2116
2117         if (!session->channel
2118                 || !ast_sip_is_content_type(&rdata->msg_info.msg->body->content_type,
2119                         "application",
2120                         "media_control+xml")) {
2121                 return 0;
2122         }
2123
2124         tsx = pjsip_rdata_get_tsx(rdata);
2125
2126         ast_queue_control(session->channel, AST_CONTROL_VIDUPDATE);
2127
2128         if (pjsip_dlg_create_response(session->inv_session->dlg, rdata, 200, NULL, &tdata) == PJ_SUCCESS) {
2129                 pjsip_dlg_send_response(session->inv_session->dlg, tsx, tdata);
2130         }
2131
2132         return 0;
2133 }
2134
2135 static struct ast_sip_session_supplement video_info_supplement = {
2136         .method = "INFO",
2137         .incoming_request = video_info_incoming_request,
2138 };
2139
2140 /*! \brief Unloads the sdp RTP/AVP module from Asterisk */
2141 static int unload_module(void)
2142 {
2143         ast_sip_session_unregister_supplement(&video_info_supplement);
2144         ast_sip_session_unregister_sdp_handler(&video_sdp_handler, STR_VIDEO);
2145         ast_sip_session_unregister_sdp_handler(&audio_sdp_handler, STR_AUDIO);
2146
2147         if (sched) {
2148                 ast_sched_context_destroy(sched);
2149         }
2150
2151         return 0;
2152 }
2153
2154 /*!
2155  * \brief Load the module
2156  *
2157  * Module loading including tests for configuration or dependencies.
2158  * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
2159  * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
2160  * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the
2161  * configuration file or other non-critical problem return
2162  * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
2163  */
2164 static int load_module(void)
2165 {
2166         if (ast_check_ipv6()) {
2167                 ast_sockaddr_parse(&address_rtp, "::", 0);
2168         } else {
2169                 ast_sockaddr_parse(&address_rtp, "0.0.0.0", 0);
2170         }
2171
2172         if (!(sched = ast_sched_context_create())) {
2173                 ast_log(LOG_ERROR, "Unable to create scheduler context.\n");
2174                 goto end;
2175         }
2176
2177         if (ast_sched_start_thread(sched)) {
2178                 ast_log(LOG_ERROR, "Unable to create scheduler context thread.\n");
2179                 goto end;
2180         }
2181
2182         if (ast_sip_session_register_sdp_handler(&audio_sdp_handler, STR_AUDIO)) {
2183                 ast_log(LOG_ERROR, "Unable to register SDP handler for %s stream type\n", STR_AUDIO);
2184                 goto end;
2185         }
2186
2187         if (ast_sip_session_register_sdp_handler(&video_sdp_handler, STR_VIDEO)) {
2188                 ast_log(LOG_ERROR, "Unable to register SDP handler for %s stream type\n", STR_VIDEO);
2189                 goto end;
2190         }
2191
2192         ast_sip_session_register_supplement(&video_info_supplement);
2193
2194         return AST_MODULE_LOAD_SUCCESS;
2195 end:
2196         unload_module();
2197
2198         return AST_MODULE_LOAD_DECLINE;
2199 }
2200
2201 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP SDP RTP/AVP stream handler",
2202         .support_level = AST_MODULE_SUPPORT_CORE,
2203         .load = load_module,
2204         .unload = unload_module,
2205         .load_pri = AST_MODPRI_CHANNEL_DRIVER,
2206         .requires = "res_pjsip,res_pjsip_session",
2207 );