Asterisk - The Open Source Telephony Project  GIT-master-a1fa8df
res_pjsip_sdp_rtp.c
Go to the documentation of this file.
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"
56 #include "asterisk/format_cache.h"
57 
58 #include "asterisk/res_pjsip.h"
61 
62 /*! \brief Scheduler for RTCP purposes */
63 static struct ast_sched_context *sched;
64 
65 /*! \brief Address for RTP */
66 static struct ast_sockaddr address_rtp;
67 
68 static const char STR_AUDIO[] = "audio";
69 static const char STR_VIDEO[] = "video";
70 
71 static int send_keepalive(const void *data)
72 {
73  struct ast_sip_session_media *session_media = (struct ast_sip_session_media *) data;
74  struct ast_rtp_instance *rtp = session_media->rtp;
75  int keepalive;
76  time_t interval;
77  int send_keepalive;
78 
79  if (!rtp) {
80  return 0;
81  }
82 
83  keepalive = ast_rtp_instance_get_keepalive(rtp);
84 
85  if (!ast_sockaddr_isnull(&session_media->direct_media_addr)) {
86  ast_debug_rtp(3, "(%p) RTP not sending keepalive since direct media is in use\n", rtp);
87  return keepalive * 1000;
88  }
89 
90  interval = time(NULL) - ast_rtp_instance_get_last_tx(rtp);
91  send_keepalive = interval >= keepalive;
92 
93  ast_debug_rtp(3, "(%p) RTP it has been %d seconds since RTP was last sent. %sending keepalive\n",
94  rtp, (int) interval, send_keepalive ? "S" : "Not s");
95 
96  if (send_keepalive) {
98  return keepalive * 1000;
99  }
100 
101  return (keepalive - interval) * 1000;
102 }
103 
104 /*! \brief Check whether RTP is being received or not */
105 static int rtp_check_timeout(const void *data)
106 {
107  struct ast_sip_session_media *session_media = (struct ast_sip_session_media *)data;
108  struct ast_rtp_instance *rtp = session_media->rtp;
109  int elapsed;
110  int timeout;
111  struct ast_channel *chan;
112 
113  if (!rtp) {
114  return 0;
115  }
116 
118  if (!chan) {
119  return 0;
120  }
121 
122  /* Get channel lock to make sure that we access a consistent set of values
123  * (last_rx and direct_media_addr) - the lock is held when values are modified
124  * (see send_direct_media_request()/check_for_rtp_changes() in chan_pjsip.c). We
125  * are trying to avoid a situation where direct_media_addr has been reset but the
126  * last-rx time was not set yet.
127  */
128  ast_channel_lock(chan);
129 
130  elapsed = time(NULL) - ast_rtp_instance_get_last_rx(rtp);
131  timeout = ast_rtp_instance_get_timeout(rtp);
132  if (elapsed < timeout) {
133  ast_channel_unlock(chan);
134  ast_channel_unref(chan);
135  return (timeout - elapsed) * 1000;
136  }
137 
138  /* Last RTP packet was received too long ago
139  * - disconnect channel unless direct media is in use.
140  */
141  if (!ast_sockaddr_isnull(&session_media->direct_media_addr)) {
142  ast_debug_rtp(3, "(%p) RTP not disconnecting channel '%s' for lack of %s RTP activity in %d seconds "
143  "since direct media is in use\n", rtp, ast_channel_name(chan),
144  ast_codec_media_type2str(session_media->type), elapsed);
145  ast_channel_unlock(chan);
146  ast_channel_unref(chan);
147  return timeout * 1000; /* recheck later, direct media may have ended then */
148  }
149 
150  ast_log(LOG_NOTICE, "Disconnecting channel '%s' for lack of %s RTP activity in %d seconds\n",
151  ast_channel_name(chan), ast_codec_media_type2str(session_media->type), elapsed);
152 
155 
156  ast_channel_unlock(chan);
157  ast_channel_unref(chan);
158 
159  return 0;
160 }
161 
162 /*!
163  * \brief Enable RTCP on an RTP session.
164  */
165 static void enable_rtcp(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
166  const struct pjmedia_sdp_media *remote_media)
167 {
168  enum ast_rtp_instance_rtcp rtcp_type;
169 
170  if (session->endpoint->media.rtcp_mux && session_media->remote_rtcp_mux) {
171  rtcp_type = AST_RTP_INSTANCE_RTCP_MUX;
172  } else {
173  rtcp_type = AST_RTP_INSTANCE_RTCP_STANDARD;
174  }
175 
176  ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_RTCP, rtcp_type);
177 }
178 
179 /*!
180  * \brief Enable an RTP extension on an RTP session.
181  */
182 static void enable_rtp_extension(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
184  const pjmedia_sdp_session *sdp)
185 {
186  int id = -1;
187 
188  /* For a bundle group the local unique identifier space is shared across all streams within
189  * it.
190  */
191  if (session_media->bundle_group != -1) {
192  int index;
193 
194  for (index = 0; index < sdp->media_count; ++index) {
195  struct ast_sip_session_media *other_session_media;
196  int other_id;
197 
198  if (index >= AST_VECTOR_SIZE(&session->pending_media_state->sessions)) {
199  break;
200  }
201 
202  other_session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, index);
203  if (!other_session_media->rtp || other_session_media->bundle_group != session_media->bundle_group) {
204  continue;
205  }
206 
207  other_id = ast_rtp_instance_extmap_get_id(other_session_media->rtp, extension);
208  if (other_id == -1) {
209  /* Worst case we have to fall back to the highest available free local unique identifier
210  * for the bundle group.
211  */
212  other_id = ast_rtp_instance_extmap_count(other_session_media->rtp) + 1;
213  if (id < other_id) {
214  id = other_id;
215  }
216  continue;
217  }
218 
219  id = other_id;
220  break;
221  }
222  }
223 
224  ast_rtp_instance_extmap_enable(session_media->rtp, id, extension, direction);
225 }
226 
227 /*! \brief Internal function which creates an RTP instance */
228 static int create_rtp(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
229  const pjmedia_sdp_session *sdp)
230 {
231  struct ast_rtp_engine_ice *ice;
232  struct ast_sockaddr temp_media_address;
234 
236  if (ast_sockaddr_parse(&temp_media_address, session->endpoint->media.address, 0)) {
237  ast_debug_rtp(1, "Endpoint %s: Binding RTP media to %s\n",
239  session->endpoint->media.address);
240  media_address = &temp_media_address;
241  } else {
242  ast_debug_rtp(1, "Endpoint %s: RTP media address invalid: %s\n",
244  session->endpoint->media.address);
245  }
246  } else {
247  struct ast_sip_transport *transport;
248 
249  transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport",
250  session->endpoint->transport);
251  if (transport) {
252  struct ast_sip_transport_state *trans_state;
253 
254  trans_state = ast_sip_get_transport_state(ast_sorcery_object_get_id(transport));
255  if (trans_state) {
256  char hoststr[PJ_INET6_ADDRSTRLEN];
257 
258  pj_sockaddr_print(&trans_state->host, hoststr, sizeof(hoststr), 0);
259  if (ast_sockaddr_parse(&temp_media_address, hoststr, 0)) {
260  ast_debug_rtp(1, "Transport %s bound to %s: Using it for RTP media.\n",
261  session->endpoint->transport, hoststr);
262  media_address = &temp_media_address;
263  } else {
264  ast_debug_rtp(1, "Transport %s bound to %s: Invalid for RTP media.\n",
265  session->endpoint->transport, hoststr);
266  }
267  ao2_ref(trans_state, -1);
268  }
269  ao2_ref(transport, -1);
270  }
271  }
272 
273  if (!(session_media->rtp = ast_rtp_instance_new(session->endpoint->media.rtp.engine, sched, media_address, NULL))) {
274  ast_log(LOG_ERROR, "Unable to create RTP instance using RTP engine '%s'\n", session->endpoint->media.rtp.engine);
275  return -1;
276  }
277 
280 
281  if (!session->endpoint->media.rtp.ice_support && (ice = ast_rtp_instance_get_ice(session_media->rtp))) {
282  ice->stop(session_media->rtp);
283  }
284 
285  if (session->dtmf == AST_SIP_DTMF_RFC_4733 || session->dtmf == AST_SIP_DTMF_AUTO || session->dtmf == AST_SIP_DTMF_AUTO_INFO) {
288  } else if (session->dtmf == AST_SIP_DTMF_INBAND) {
290  }
291 
292  if (session_media->type == AST_MEDIA_TYPE_AUDIO &&
293  (session->endpoint->media.tos_audio || session->endpoint->media.cos_audio)) {
294  ast_rtp_instance_set_qos(session_media->rtp, session->endpoint->media.tos_audio,
295  session->endpoint->media.cos_audio, "SIP RTP Audio");
296  } else if (session_media->type == AST_MEDIA_TYPE_VIDEO) {
300  if (session->endpoint->media.webrtc) {
303  }
304  if (session->endpoint->media.tos_video || session->endpoint->media.cos_video) {
305  ast_rtp_instance_set_qos(session_media->rtp, session->endpoint->media.tos_video,
306  session->endpoint->media.cos_video, "SIP RTP Video");
307  }
308  }
309 
310  ast_rtp_instance_set_last_rx(session_media->rtp, time(NULL));
311 
312  return 0;
313 }
314 
315 static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp_media *stream, struct ast_rtp_codecs *codecs,
316  struct ast_sip_session_media *session_media)
317 {
318  pjmedia_sdp_attr *attr;
319  pjmedia_sdp_rtpmap *rtpmap;
320  pjmedia_sdp_fmtp fmtp;
321  struct ast_format *format;
322  int i, num = 0, tel_event = 0;
323  char name[256];
324  char media[20];
325  char fmt_param[256];
328  SCOPE_ENTER(1, "%s\n", ast_sip_session_get_name(session));
329 
331 
332  /* Iterate through provided formats */
333  for (i = 0; i < stream->desc.fmt_count; ++i) {
334  /* The payload is kept as a string for things like t38 but for video it is always numerical */
335  ast_rtp_codecs_payloads_set_m_type(codecs, NULL, pj_strtoul(&stream->desc.fmt[i]));
336  /* Look for the optional rtpmap attribute */
337  if (!(attr = pjmedia_sdp_media_find_attr2(stream, "rtpmap", &stream->desc.fmt[i]))) {
338  continue;
339  }
340 
341  /* Interpret the attribute as an rtpmap */
342  if ((pjmedia_sdp_attr_to_rtpmap(session->inv_session->pool_prov, attr, &rtpmap)) != PJ_SUCCESS) {
343  continue;
344  }
345 
346  ast_copy_pj_str(name, &rtpmap->enc_name, sizeof(name));
347  if (strcmp(name, "telephone-event") == 0) {
348  tel_event++;
349  }
350 
351  ast_copy_pj_str(media, (pj_str_t*)&stream->desc.media, sizeof(media));
353  pj_strtoul(&stream->desc.fmt[i]), media, name, options, rtpmap->clock_rate);
354  /* Look for an optional associated fmtp attribute */
355  if (!(attr = pjmedia_sdp_media_find_attr2(stream, "fmtp", &rtpmap->pt))) {
356  continue;
357  }
358 
359  if ((pjmedia_sdp_attr_get_fmtp(attr, &fmtp)) == PJ_SUCCESS) {
360  ast_copy_pj_str(fmt_param, &fmtp.fmt, sizeof(fmt_param));
361  if (sscanf(fmt_param, "%30d", &num) != 1) {
362  continue;
363  }
364 
365  if ((format = ast_rtp_codecs_get_payload_format(codecs, num))) {
366  struct ast_format *format_parsed;
367 
368  ast_copy_pj_str(fmt_param, &fmtp.fmt_param, sizeof(fmt_param));
369 
370  format_parsed = ast_format_parse_sdp_fmtp(format, fmt_param);
371  if (format_parsed) {
372  ast_rtp_codecs_payload_replace_format(codecs, num, format_parsed);
373  ao2_ref(format_parsed, -1);
374  }
375 
376  ao2_ref(format, -1);
377  }
378  }
379  }
380  if (!tel_event && (session->dtmf == AST_SIP_DTMF_AUTO)) {
383  }
384 
385  if (session->dtmf == AST_SIP_DTMF_AUTO_INFO) {
386  if (tel_event) {
389  } else {
392  }
393  }
394 
395 
396  /* Get the packetization, if it exists */
397  if ((attr = pjmedia_sdp_media_find_attr2(stream, "ptime", NULL))) {
398  unsigned long framing = pj_strtoul(pj_strltrim(&attr->value));
399  if (framing && session->endpoint->media.rtp.use_ptime) {
400  ast_rtp_codecs_set_framing(codecs, framing);
401  }
402  }
403 
404  SCOPE_EXIT_RTN();
405 }
406 
407 static int apply_cap_to_bundled(struct ast_sip_session_media *session_media,
408  struct ast_sip_session_media *session_media_transport,
409  struct ast_stream *asterisk_stream, struct ast_format_cap *joint)
410 {
411  if (!joint) {
412  return -1;
413  }
414 
415  ast_stream_set_formats(asterisk_stream, joint);
416 
417  /* If this is a bundled stream then apply the payloads to RTP instance acting as transport to prevent conflicts */
418  if (session_media_transport != session_media && session_media->bundled) {
419  int index;
420 
421  for (index = 0; index < ast_format_cap_count(joint); ++index) {
422  struct ast_format *format = ast_format_cap_get_format(joint, index);
423  int rtp_code;
424 
425  /* Ensure this payload is in the bundle group transport codecs, this purposely doesn't check the return value for
426  * things as the format is guaranteed to have a payload already.
427  */
428  rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media->rtp), 1, format, 0);
429  ast_rtp_codecs_payload_set_rx(ast_rtp_instance_get_codecs(session_media_transport->rtp), rtp_code, format);
430 
431  ao2_ref(format, -1);
432  }
433  }
434 
435  return 0;
436 }
437 
439  struct ast_sip_session *session, struct ast_sip_session_media *session_media,
440  const struct pjmedia_sdp_media *stream)
441 {
442  struct ast_format_cap *incoming_call_offer_cap;
443  struct ast_format_cap *remote;
445  int fmts = 0;
446  SCOPE_ENTER(1, "%s\n", ast_sip_session_get_name(session));
447 
448 
450  if (!remote) {
451  ast_log(LOG_ERROR, "Failed to allocate %s incoming remote capabilities\n",
452  ast_codec_media_type2str(session_media->type));
453  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't allocate caps\n");
454  }
455 
456  /* Get the peer's capabilities*/
457  get_codecs(session, stream, &codecs, session_media);
458  ast_rtp_codecs_payload_formats(&codecs, remote, &fmts);
459 
460  incoming_call_offer_cap = ast_sip_session_create_joint_call_cap(
461  session, session_media->type, remote);
462 
463  ao2_ref(remote, -1);
464 
465  if (!incoming_call_offer_cap || ast_format_cap_empty(incoming_call_offer_cap)) {
466  ao2_cleanup(incoming_call_offer_cap);
468  SCOPE_EXIT_RTN_VALUE(NULL, "No incoming call offer caps\n");
469  }
470 
471  /*
472  * Setup rx payload type mapping to prefer the mapping
473  * from the peer that the RFC says we SHOULD use.
474  */
475  ast_rtp_codecs_payloads_xover(&codecs, &codecs, NULL);
476 
478  ast_rtp_instance_get_codecs(session_media->rtp), session_media->rtp);
479 
481 
482  SCOPE_EXIT_RTN_VALUE(incoming_call_offer_cap);
483 }
484 
485 static int set_caps(struct ast_sip_session *session,
486  struct ast_sip_session_media *session_media,
487  struct ast_sip_session_media *session_media_transport,
488  const struct pjmedia_sdp_media *stream,
489  int is_offer, struct ast_stream *asterisk_stream)
490 {
491  RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup);
492  RAII_VAR(struct ast_format_cap *, peer, NULL, ao2_cleanup);
493  RAII_VAR(struct ast_format_cap *, joint, NULL, ao2_cleanup);
494  enum ast_media_type media_type = session_media->type;
496  int fmts = 0;
497  int direct_media_enabled = !ast_sockaddr_isnull(&session_media->direct_media_addr) &&
499  int dsp_features = 0;
500  SCOPE_ENTER(1, "%s %s\n", ast_sip_session_get_name(session), is_offer ? "OFFER" : "ANSWER");
501 
505  ast_log(LOG_ERROR, "Failed to allocate %s capabilities\n",
506  ast_codec_media_type2str(session_media->type));
507  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create %s capabilities\n",
508  ast_codec_media_type2str(session_media->type));
509  }
510 
511  /* get the endpoint capabilities */
512  if (direct_media_enabled) {
514  } else {
515  ast_format_cap_append_from_cap(caps, session->endpoint->media.codecs, media_type);
516  }
517 
518  /* get the capabilities on the peer */
519  get_codecs(session, stream, &codecs, session_media);
520  ast_rtp_codecs_payload_formats(&codecs, peer, &fmts);
521 
522  /* get the joint capabilities between peer and endpoint */
523  ast_format_cap_get_compatible(caps, peer, joint);
524  if (!ast_format_cap_count(joint)) {
527 
529  ast_log(LOG_NOTICE, "No joint capabilities for '%s' media stream between our configuration(%s) and incoming SDP(%s)\n",
530  ast_codec_media_type2str(session_media->type),
531  ast_format_cap_get_names(caps, &usbuf),
532  ast_format_cap_get_names(peer, &thembuf));
533  SCOPE_EXIT_RTN_VALUE(-1, "No joint capabilities for '%s' media stream between our configuration(%s) and incoming SDP(%s)\n",
534  ast_codec_media_type2str(session_media->type),
535  ast_format_cap_get_names(caps, &usbuf),
536  ast_format_cap_get_names(peer, &thembuf));
537  }
538 
539  if (is_offer) {
540  /*
541  * Setup rx payload type mapping to prefer the mapping
542  * from the peer that the RFC says we SHOULD use.
543  */
544  ast_rtp_codecs_payloads_xover(&codecs, &codecs, NULL);
545  }
547  session_media->rtp);
548 
549  apply_cap_to_bundled(session_media, session_media_transport, asterisk_stream, joint);
550 
551  if (session->channel && ast_sip_session_is_pending_stream_default(session, asterisk_stream)) {
552  ast_channel_lock(session->channel);
556  ast_format_cap_remove_by_type(caps, media_type);
557 
558  if (session->endpoint->preferred_codec_only){
559  struct ast_format *preferred_fmt = ast_format_cap_get_format(joint, 0);
560  ast_format_cap_append(caps, preferred_fmt, 0);
561  ao2_ref(preferred_fmt, -1);
562  } else if (!session->endpoint->asymmetric_rtp_codec) {
563  struct ast_format *best;
564  /*
565  * If we don't allow the sending codec to be changed on our side
566  * then get the best codec from the joint capabilities of the media
567  * type and use only that. This ensures the core won't start sending
568  * out a format that we aren't currently sending.
569  */
570 
571  best = ast_format_cap_get_best_by_type(joint, media_type);
572  if (best) {
574  ao2_ref(best, -1);
575  }
576  } else {
577  ast_format_cap_append_from_cap(caps, joint, media_type);
578  }
579 
580  /*
581  * Apply the new formats to the channel, potentially changing
582  * raw read/write formats and translation path while doing so.
583  */
584  ast_channel_nativeformats_set(session->channel, caps);
585  if (media_type == AST_MEDIA_TYPE_AUDIO) {
588  }
589 
590  if ( ((session->dtmf == AST_SIP_DTMF_AUTO) || (session->dtmf == AST_SIP_DTMF_AUTO_INFO) )
592  && (session->dsp)) {
593  dsp_features = ast_dsp_get_features(session->dsp);
594  dsp_features &= ~DSP_FEATURE_DIGIT_DETECT;
595  if (dsp_features) {
596  ast_dsp_set_features(session->dsp, dsp_features);
597  } else {
598  ast_dsp_free(session->dsp);
599  session->dsp = NULL;
600  }
601  }
602 
603  if (ast_channel_is_bridged(session->channel)) {
605  }
606 
607  ast_channel_unlock(session->channel);
608  }
609 
612 }
613 
614 static pjmedia_sdp_attr* generate_rtpmap_attr(struct ast_sip_session *session, pjmedia_sdp_media *media, pj_pool_t *pool,
615  int rtp_code, int asterisk_format, struct ast_format *format, int code)
616 {
617 #ifndef HAVE_PJSIP_ENDPOINT_COMPACT_FORM
618  extern pj_bool_t pjsip_use_compact_form;
619 #else
620  pj_bool_t pjsip_use_compact_form = pjsip_cfg()->endpt.use_compact_form;
621 #endif
622  pjmedia_sdp_rtpmap rtpmap;
623  pjmedia_sdp_attr *attr = NULL;
624  char tmp[64];
627 
628  snprintf(tmp, sizeof(tmp), "%d", rtp_code);
629  pj_strdup2(pool, &media->desc.fmt[media->desc.fmt_count++], tmp);
630 
631  if (rtp_code <= AST_RTP_PT_LAST_STATIC && pjsip_use_compact_form) {
632  return NULL;
633  }
634 
635  rtpmap.pt = media->desc.fmt[media->desc.fmt_count - 1];
636  rtpmap.clock_rate = ast_rtp_lookup_sample_rate2(asterisk_format, format, code);
637  pj_strdup2(pool, &rtpmap.enc_name, ast_rtp_lookup_mime_subtype2(asterisk_format, format, code, options));
638  if (!pj_stricmp2(&rtpmap.enc_name, "opus")) {
639  pj_cstr(&rtpmap.param, "2");
640  } else {
641  pj_cstr(&rtpmap.param, NULL);
642  }
643 
644  pjmedia_sdp_rtpmap_to_attr(pool, &rtpmap, &attr);
645 
646  return attr;
647 }
648 
649 static pjmedia_sdp_attr* generate_fmtp_attr(pj_pool_t *pool, struct ast_format *format, int rtp_code)
650 {
651  struct ast_str *fmtp0 = ast_str_alloca(256);
652  pj_str_t fmtp1;
653  pjmedia_sdp_attr *attr = NULL;
654  char *tmp;
655 
656  ast_format_generate_sdp_fmtp(format, rtp_code, &fmtp0);
657  if (ast_str_strlen(fmtp0)) {
658  tmp = ast_str_buffer(fmtp0) + ast_str_strlen(fmtp0) - 1;
659  /* remove any carriage return line feeds */
660  while (*tmp == '\r' || *tmp == '\n') --tmp;
661  *++tmp = '\0';
662  /* ast...generate gives us everything, just need value */
663  tmp = strchr(ast_str_buffer(fmtp0), ':');
664  if (tmp && tmp[1] != '\0') {
665  fmtp1 = pj_str(tmp + 1);
666  } else {
667  fmtp1 = pj_str(ast_str_buffer(fmtp0));
668  }
669  attr = pjmedia_sdp_attr_create(pool, "fmtp", &fmtp1);
670  }
671  return attr;
672 }
673 
674 /*! \brief Function which adds ICE attributes to a media stream */
675 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,
676  unsigned int include_candidates)
677 {
678  struct ast_rtp_engine_ice *ice;
679  struct ao2_container *candidates;
680  const char *username, *password;
681  pj_str_t stmp;
682  pjmedia_sdp_attr *attr;
683  struct ao2_iterator it_candidates;
684  struct ast_rtp_engine_ice_candidate *candidate;
685 
686  if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) {
687  return;
688  }
689 
690  if (!session_media->remote_ice) {
691  ice->stop(session_media->rtp);
692  return;
693  }
694 
695  if ((username = ice->get_ufrag(session_media->rtp))) {
696  attr = pjmedia_sdp_attr_create(pool, "ice-ufrag", pj_cstr(&stmp, username));
697  media->attr[media->attr_count++] = attr;
698  }
699 
700  if ((password = ice->get_password(session_media->rtp))) {
701  attr = pjmedia_sdp_attr_create(pool, "ice-pwd", pj_cstr(&stmp, password));
702  media->attr[media->attr_count++] = attr;
703  }
704 
705  if (!include_candidates) {
706  return;
707  }
708 
709  candidates = ice->get_local_candidates(session_media->rtp);
710  if (!candidates) {
711  return;
712  }
713 
714  it_candidates = ao2_iterator_init(candidates, 0);
715  for (; (candidate = ao2_iterator_next(&it_candidates)); ao2_ref(candidate, -1)) {
716  struct ast_str *attr_candidate = ast_str_create(128);
717 
718  ast_str_set(&attr_candidate, -1, "%s %u %s %d %s ", candidate->foundation, candidate->id, candidate->transport,
719  candidate->priority, ast_sockaddr_stringify_addr_remote(&candidate->address));
720  ast_str_append(&attr_candidate, -1, "%s typ ", ast_sockaddr_stringify_port(&candidate->address));
721 
722  switch (candidate->type) {
724  ast_str_append(&attr_candidate, -1, "host");
725  break;
727  ast_str_append(&attr_candidate, -1, "srflx");
728  break;
730  ast_str_append(&attr_candidate, -1, "relay");
731  break;
732  }
733 
734  if (!ast_sockaddr_isnull(&candidate->relay_address)) {
735  ast_str_append(&attr_candidate, -1, " raddr %s rport", ast_sockaddr_stringify_addr_remote(&candidate->relay_address));
736  ast_str_append(&attr_candidate, -1, " %s", ast_sockaddr_stringify_port(&candidate->relay_address));
737  }
738 
739  attr = pjmedia_sdp_attr_create(pool, "candidate", pj_cstr(&stmp, ast_str_buffer(attr_candidate)));
740  media->attr[media->attr_count++] = attr;
741 
742  ast_free(attr_candidate);
743  }
744 
745  ao2_iterator_destroy(&it_candidates);
746  ao2_ref(candidates, -1);
747 }
748 
749 /*! \brief Function which checks for ice attributes in an audio stream */
750 static void check_ice_support(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
751  const struct pjmedia_sdp_media *remote_stream)
752 {
753  struct ast_rtp_engine_ice *ice;
754  const pjmedia_sdp_attr *attr;
755  unsigned int attr_i;
756 
757  if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) {
758  session_media->remote_ice = 0;
759  return;
760  }
761 
762  /* Find all of the candidates */
763  for (attr_i = 0; attr_i < remote_stream->attr_count; ++attr_i) {
764  attr = remote_stream->attr[attr_i];
765  if (!pj_strcmp2(&attr->name, "candidate")) {
766  session_media->remote_ice = 1;
767  break;
768  }
769  }
770 
771  if (attr_i == remote_stream->attr_count) {
772  session_media->remote_ice = 0;
773  }
774 }
775 
776 static void process_ice_auth_attrb(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
777  const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream)
778 {
779  struct ast_rtp_engine_ice *ice;
780  const pjmedia_sdp_attr *ufrag_attr, *passwd_attr;
781  char ufrag_attr_value[256];
782  char passwd_attr_value[256];
783 
784  /* If ICE support is not enabled or available exit early */
785  if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) {
786  return;
787  }
788 
789  ufrag_attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-ufrag", NULL);
790  if (!ufrag_attr) {
791  ufrag_attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-ufrag", NULL);
792  }
793  if (ufrag_attr) {
794  ast_copy_pj_str(ufrag_attr_value, (pj_str_t*)&ufrag_attr->value, sizeof(ufrag_attr_value));
795  } else {
796  return;
797  }
798  passwd_attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-pwd", NULL);
799  if (!passwd_attr) {
800  passwd_attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-pwd", NULL);
801  }
802  if (passwd_attr) {
803  ast_copy_pj_str(passwd_attr_value, (pj_str_t*)&passwd_attr->value, sizeof(passwd_attr_value));
804  } else {
805  return;
806  }
807 
808  if (ufrag_attr && passwd_attr) {
809  ice->set_authentication(session_media->rtp, ufrag_attr_value, passwd_attr_value);
810  }
811 }
812 
813 /*! \brief Function which processes ICE attributes in an audio stream */
814 static void process_ice_attributes(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
815  const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream)
816 {
817  struct ast_rtp_engine_ice *ice;
818  const pjmedia_sdp_attr *attr;
819  char attr_value[256];
820  unsigned int attr_i;
821 
822  /* If ICE support is not enabled or available exit early */
823  if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) {
824  return;
825  }
826 
827  ast_debug_ice(2, "(%p) ICE process attributes\n", session_media->rtp);
828 
829  attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-ufrag", NULL);
830  if (!attr) {
831  attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-ufrag", NULL);
832  }
833  if (attr) {
834  ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
835  ice->set_authentication(session_media->rtp, attr_value, NULL);
836  } else {
837  ast_debug_ice(2, "(%p) ICE no, or invalid ice-ufrag\n", session_media->rtp);
838  return;
839  }
840 
841  attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-pwd", NULL);
842  if (!attr) {
843  attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-pwd", NULL);
844  }
845  if (attr) {
846  ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
847  ice->set_authentication(session_media->rtp, NULL, attr_value);
848  } else {
849  ast_debug_ice(2, "(%p) ICE no, or invalid ice-pwd\n", session_media->rtp);
850  return;
851  }
852 
853  if (pjmedia_sdp_media_find_attr2(remote_stream, "ice-lite", NULL)) {
854  ice->ice_lite(session_media->rtp);
855  }
856 
857  /* Find all of the candidates */
858  for (attr_i = 0; attr_i < remote_stream->attr_count; ++attr_i) {
859  char foundation[33], transport[32], address[PJ_INET6_ADDRSTRLEN + 1], cand_type[6], relay_address[PJ_INET6_ADDRSTRLEN + 1] = "";
860  unsigned int port, relay_port = 0;
861  struct ast_rtp_engine_ice_candidate candidate = { 0, };
862 
863  attr = remote_stream->attr[attr_i];
864 
865  /* If this is not a candidate line skip it */
866  if (pj_strcmp2(&attr->name, "candidate")) {
867  continue;
868  }
869 
870  ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
871 
872  if (sscanf(attr_value, "%32s %30u %31s %30u %46s %30u typ %5s %*s %23s %*s %30u", foundation, &candidate.id, transport,
873  (unsigned *)&candidate.priority, address, &port, cand_type, relay_address, &relay_port) < 7) {
874  /* Candidate did not parse properly */
875  continue;
876  }
877 
878  if (session->endpoint->media.rtcp_mux && session_media->remote_rtcp_mux && candidate.id > 1) {
879  /* Remote side may have offered RTP and RTCP candidates. However, if we're using RTCP MUX,
880  * then we should ignore RTCP candidates.
881  */
882  continue;
883  }
884 
885  candidate.foundation = foundation;
886  candidate.transport = transport;
887 
888  ast_sockaddr_parse(&candidate.address, address, PARSE_PORT_FORBID);
889  ast_sockaddr_set_port(&candidate.address, port);
890 
891  if (!strcasecmp(cand_type, "host")) {
893  } else if (!strcasecmp(cand_type, "srflx")) {
895  } else if (!strcasecmp(cand_type, "relay")) {
897  } else {
898  continue;
899  }
900 
901  if (!ast_strlen_zero(relay_address)) {
902  ast_sockaddr_parse(&candidate.relay_address, relay_address, PARSE_PORT_FORBID);
903  }
904 
905  if (relay_port) {
906  ast_sockaddr_set_port(&candidate.relay_address, relay_port);
907  }
908 
909  ice->add_remote_candidate(session_media->rtp, &candidate);
910  }
911 
912  ice->set_role(session_media->rtp, pjmedia_sdp_neg_was_answer_remote(session->inv_session->neg) == PJ_TRUE ?
914  ice->start(session_media->rtp);
915 }
916 
917 /*! \brief figure out if media stream has crypto lines for sdes */
918 static int media_stream_has_crypto(const struct pjmedia_sdp_media *stream)
919 {
920  int i;
921 
922  for (i = 0; i < stream->attr_count; i++) {
923  pjmedia_sdp_attr *attr;
924 
925  /* check the stream for the required crypto attribute */
926  attr = stream->attr[i];
927  if (pj_strcmp2(&attr->name, "crypto")) {
928  continue;
929  }
930 
931  return 1;
932  }
933 
934  return 0;
935 }
936 
937 /*! \brief figure out media transport encryption type from the media transport string */
939  const struct pjmedia_sdp_media *stream, unsigned int *optimistic)
940 {
941  RAII_VAR(char *, transport_str, ast_strndup(transport.ptr, transport.slen), ast_free);
942 
943  *optimistic = 0;
944 
945  if (!transport_str) {
947  }
948  if (strstr(transport_str, "UDP/TLS")) {
950  } else if (strstr(transport_str, "SAVP")) {
952  } else if (media_stream_has_crypto(stream)) {
953  *optimistic = 1;
955  } else {
957  }
958 }
959 
960 /*!
961  * \brief Checks whether the encryption offered in SDP is compatible with the endpoint's configuration
962  * \internal
963  *
964  * \param endpoint_encryption Media encryption configured for the endpoint
965  * \param stream pjmedia_sdp_media stream description
966  *
967  * \retval AST_SIP_MEDIA_TRANSPORT_INVALID on encryption mismatch
968  * \retval The encryption requested in the SDP
969  */
971  struct ast_sip_endpoint *endpoint,
972  const struct pjmedia_sdp_media *stream)
973 {
974  enum ast_sip_session_media_encryption incoming_encryption;
975  char transport_end = stream->desc.transport.ptr[stream->desc.transport.slen - 1];
976  unsigned int optimistic;
977 
978  if ((transport_end == 'F' && !endpoint->media.rtp.use_avpf)
979  || (transport_end != 'F' && endpoint->media.rtp.use_avpf)) {
981  }
982 
983  incoming_encryption = get_media_encryption_type(stream->desc.transport, stream, &optimistic);
984 
985  if (incoming_encryption == endpoint->media.rtp.encryption) {
986  return incoming_encryption;
987  }
988 
989  if (endpoint->media.rtp.force_avp ||
990  endpoint->media.rtp.encryption_optimistic) {
991  return incoming_encryption;
992  }
993 
994  /* If an optimistic offer has been made but encryption is not enabled consider it as having
995  * no offer of crypto at all instead of invalid so the session proceeds.
996  */
997  if (optimistic) {
999  }
1000 
1002 }
1003 
1004 static int setup_srtp(struct ast_sip_session_media *session_media)
1005 {
1006  if (!session_media->srtp) {
1007  session_media->srtp = ast_sdp_srtp_alloc();
1008  if (!session_media->srtp) {
1009  return -1;
1010  }
1011  }
1012 
1013  if (!session_media->srtp->crypto) {
1014  session_media->srtp->crypto = ast_sdp_crypto_alloc();
1015  if (!session_media->srtp->crypto) {
1016  return -1;
1017  }
1018  }
1019 
1020  return 0;
1021 }
1022 
1024  struct ast_sip_session_media *session_media)
1025 {
1026  struct ast_rtp_engine_dtls *dtls;
1027 
1028  if (!session->endpoint->media.rtp.dtls_cfg.enabled || !session_media->rtp) {
1029  return -1;
1030  }
1031 
1032  dtls = ast_rtp_instance_get_dtls(session_media->rtp);
1033  if (!dtls) {
1034  return -1;
1035  }
1036 
1038  if (dtls->set_configuration(session_media->rtp, &session->endpoint->media.rtp.dtls_cfg)) {
1039  ast_log(LOG_ERROR, "Attempted to set an invalid DTLS-SRTP configuration on RTP instance '%p'\n",
1040  session_media->rtp);
1041  return -1;
1042  }
1043 
1044  if (setup_srtp(session_media)) {
1045  return -1;
1046  }
1047  return 0;
1048 }
1049 
1050 static void apply_dtls_attrib(struct ast_sip_session_media *session_media,
1051  pjmedia_sdp_attr *attr)
1052 {
1053  struct ast_rtp_engine_dtls *dtls = ast_rtp_instance_get_dtls(session_media->rtp);
1054  pj_str_t *value;
1055 
1056  if (!attr->value.ptr || !dtls) {
1057  return;
1058  }
1059 
1060  value = pj_strtrim(&attr->value);
1061 
1062  if (!pj_strcmp2(&attr->name, "setup")) {
1063  if (!pj_stricmp2(value, "active")) {
1064  dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_ACTIVE);
1065  } else if (!pj_stricmp2(value, "passive")) {
1066  dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_PASSIVE);
1067  } else if (!pj_stricmp2(value, "actpass")) {
1068  dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_ACTPASS);
1069  } else if (!pj_stricmp2(value, "holdconn")) {
1070  dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_HOLDCONN);
1071  } else {
1072  ast_log(LOG_WARNING, "Unsupported setup attribute value '%*s'\n", (int)value->slen, value->ptr);
1073  }
1074  } else if (!pj_strcmp2(&attr->name, "connection")) {
1075  if (!pj_stricmp2(value, "new")) {
1076  dtls->reset(session_media->rtp);
1077  } else if (!pj_stricmp2(value, "existing")) {
1078  /* Do nothing */
1079  } else {
1080  ast_log(LOG_WARNING, "Unsupported connection attribute value '%*s'\n", (int)value->slen, value->ptr);
1081  }
1082  } else if (!pj_strcmp2(&attr->name, "fingerprint")) {
1083  char hash_value[256], hash[32];
1084  char fingerprint_text[value->slen + 1];
1085  ast_copy_pj_str(fingerprint_text, value, sizeof(fingerprint_text));
1086  if (sscanf(fingerprint_text, "%31s %255s", hash, hash_value) == 2) {
1087  if (!strcasecmp(hash, "sha-1")) {
1088  dtls->set_fingerprint(session_media->rtp, AST_RTP_DTLS_HASH_SHA1, hash_value);
1089  } else if (!strcasecmp(hash, "sha-256")) {
1090  dtls->set_fingerprint(session_media->rtp, AST_RTP_DTLS_HASH_SHA256, hash_value);
1091  } else {
1092  ast_log(LOG_WARNING, "Unsupported fingerprint hash type '%s'\n",
1093  hash);
1094  }
1095  }
1096  }
1097 }
1098 
1099 static int parse_dtls_attrib(struct ast_sip_session_media *session_media,
1100  const struct pjmedia_sdp_session *sdp,
1101  const struct pjmedia_sdp_media *stream)
1102 {
1103  int i;
1104 
1105  for (i = 0; i < sdp->attr_count; i++) {
1106  apply_dtls_attrib(session_media, sdp->attr[i]);
1107  }
1108 
1109  for (i = 0; i < stream->attr_count; i++) {
1110  apply_dtls_attrib(session_media, stream->attr[i]);
1111  }
1112 
1113  ast_set_flag(session_media->srtp, AST_SRTP_CRYPTO_OFFER_OK);
1114 
1115  return 0;
1116 }
1117 
1118 static int setup_sdes_srtp(struct ast_sip_session_media *session_media,
1119  const struct pjmedia_sdp_media *stream)
1120 {
1121  int i;
1122 
1123  for (i = 0; i < stream->attr_count; i++) {
1124  pjmedia_sdp_attr *attr;
1125  RAII_VAR(char *, crypto_str, NULL, ast_free);
1126 
1127  /* check the stream for the required crypto attribute */
1128  attr = stream->attr[i];
1129  if (pj_strcmp2(&attr->name, "crypto")) {
1130  continue;
1131  }
1132 
1133  crypto_str = ast_strndup(attr->value.ptr, attr->value.slen);
1134  if (!crypto_str) {
1135  return -1;
1136  }
1137 
1138  if (setup_srtp(session_media)) {
1139  return -1;
1140  }
1141 
1142  if (!ast_sdp_crypto_process(session_media->rtp, session_media->srtp, crypto_str)) {
1143  /* found a valid crypto attribute */
1144  return 0;
1145  }
1146 
1147  ast_log(LOG_WARNING, "Ignoring crypto offer with unsupported parameters: %s\n", crypto_str);
1148  }
1149 
1150  /* no usable crypto attributes found */
1151  return -1;
1152 }
1153 
1155  struct ast_sip_session_media *session_media,
1156  const struct pjmedia_sdp_session *sdp,
1157  const struct pjmedia_sdp_media *stream)
1158 {
1159  switch (session_media->encryption) {
1161  if (setup_sdes_srtp(session_media, stream)) {
1162  return -1;
1163  }
1164  break;
1166  if (setup_dtls_srtp(session, session_media)) {
1167  return -1;
1168  }
1169  if (parse_dtls_attrib(session_media, sdp, stream)) {
1170  return -1;
1171  }
1172  break;
1175  break;
1176  }
1177 
1178  return 0;
1179 }
1180 
1181 static void set_ice_components(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
1182 {
1183  struct ast_rtp_engine_ice *ice;
1184 
1185  ast_assert(session_media->rtp != NULL);
1186 
1187  ice = ast_rtp_instance_get_ice(session_media->rtp);
1188  if (!session->endpoint->media.rtp.ice_support || !ice) {
1189  return;
1190  }
1191 
1192  if (session->endpoint->media.rtcp_mux && session_media->remote_rtcp_mux) {
1193  /* We both support RTCP mux. Only one ICE component necessary */
1194  ice->change_components(session_media->rtp, 1);
1195  } else {
1196  /* They either don't support RTCP mux or we don't know if they do yet. */
1197  ice->change_components(session_media->rtp, 2);
1198  }
1199 }
1200 
1201 /*! \brief Function which adds ssrc attributes to a media stream */
1202 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)
1203 {
1204  pj_str_t stmp;
1205  pjmedia_sdp_attr *attr;
1206  char tmp[128];
1207 
1208  if (!session->endpoint->media.bundle || session_media->bundle_group == -1) {
1209  return;
1210  }
1211 
1212  snprintf(tmp, sizeof(tmp), "%u cname:%s", ast_rtp_instance_get_ssrc(session_media->rtp), ast_rtp_instance_get_cname(session_media->rtp));
1213  attr = pjmedia_sdp_attr_create(pool, "ssrc", pj_cstr(&stmp, tmp));
1214  media->attr[media->attr_count++] = attr;
1215 }
1216 
1217 /*! \brief Function which processes ssrc attributes in a stream */
1218 static void process_ssrc_attributes(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
1219  const struct pjmedia_sdp_media *remote_stream)
1220 {
1221  int index;
1222 
1223  if (!session->endpoint->media.bundle) {
1224  return;
1225  }
1226 
1227  for (index = 0; index < remote_stream->attr_count; ++index) {
1228  pjmedia_sdp_attr *attr = remote_stream->attr[index];
1229  char attr_value[pj_strlen(&attr->value) + 1];
1230  char *ssrc_attribute_name, *ssrc_attribute_value = NULL;
1231  unsigned int ssrc;
1232 
1233  /* We only care about ssrc attributes */
1234  if (pj_strcmp2(&attr->name, "ssrc")) {
1235  continue;
1236  }
1237 
1238  ast_copy_pj_str(attr_value, &attr->value, sizeof(attr_value));
1239 
1240  if ((ssrc_attribute_name = strchr(attr_value, ' '))) {
1241  /* This has an actual attribute */
1242  *ssrc_attribute_name++ = '\0';
1243  ssrc_attribute_value = strchr(ssrc_attribute_name, ':');
1244  if (ssrc_attribute_value) {
1245  /* Values are actually optional according to the spec */
1246  *ssrc_attribute_value++ = '\0';
1247  }
1248  }
1249 
1250  if (sscanf(attr_value, "%30u", &ssrc) < 1) {
1251  continue;
1252  }
1253 
1254  /* If we are currently negotiating as a result of the remote side renegotiating then
1255  * determine if the source for this stream has changed.
1256  */
1257  if (pjmedia_sdp_neg_get_state(session->inv_session->neg) == PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER &&
1258  session->active_media_state) {
1259  struct ast_rtp_instance_stats stats = { 0, };
1260 
1261  if (!ast_rtp_instance_get_stats(session_media->rtp, &stats, AST_RTP_INSTANCE_STAT_REMOTE_SSRC) &&
1262  stats.remote_ssrc != ssrc) {
1263  session_media->changed = 1;
1264  }
1265  }
1266 
1267  ast_rtp_instance_set_remote_ssrc(session_media->rtp, ssrc);
1268  break;
1269  }
1270 }
1271 
1273  struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media,
1274  struct ast_stream *stream)
1275 {
1276  pj_str_t stmp;
1277  pjmedia_sdp_attr *attr;
1278  char msid[(AST_UUID_STR_LEN * 2) + 2];
1279  const char *stream_label = ast_stream_get_metadata(stream, "SDP:LABEL");
1280 
1281  if (!session->endpoint->media.webrtc) {
1282  return;
1283  }
1284 
1285  if (ast_strlen_zero(session_media->mslabel)) {
1286  /* If this stream is grouped with another then use its media stream label if possible */
1287  if (ast_stream_get_group(stream) != -1) {
1288  struct ast_sip_session_media *group_session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, ast_stream_get_group(stream));
1289 
1290  ast_copy_string(session_media->mslabel, group_session_media->mslabel, sizeof(session_media->mslabel));
1291  }
1292 
1293  if (ast_strlen_zero(session_media->mslabel)) {
1294  ast_uuid_generate_str(session_media->mslabel, sizeof(session_media->mslabel));
1295  }
1296  }
1297 
1298  if (ast_strlen_zero(session_media->label)) {
1299  ast_uuid_generate_str(session_media->label, sizeof(session_media->label));
1300  /* add for stream identification to replace stream_name */
1301  ast_stream_set_metadata(stream, "MSID:LABEL", session_media->label);
1302  }
1303 
1304  snprintf(msid, sizeof(msid), "%s %s", session_media->mslabel, session_media->label);
1305  ast_debug(3, "Stream msid: %p %s %s\n", stream,
1307  attr = pjmedia_sdp_attr_create(pool, "msid", pj_cstr(&stmp, msid));
1308  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1309 
1310  /* 'label' must come after 'msid' */
1311  if (!ast_strlen_zero(stream_label)) {
1312  ast_debug(3, "Stream Label: %p %s %s\n", stream,
1313  ast_codec_media_type2str(ast_stream_get_type(stream)), stream_label);
1314  attr = pjmedia_sdp_attr_create(pool, "label", pj_cstr(&stmp, stream_label));
1315  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1316  }
1317 }
1318 
1320  struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media)
1321 {
1322  pj_str_t stmp;
1323  pjmedia_sdp_attr *attr;
1324 
1325  if (!session->endpoint->media.webrtc) {
1326  return;
1327  }
1328 
1329  /* transport-cc is supposed to be for the entire transport, and any media sources so
1330  * while the header does not appear in audio streams and isn't negotiated there, we still
1331  * place this attribute in as Chrome does.
1332  */
1333  attr = pjmedia_sdp_attr_create(pool, "rtcp-fb", pj_cstr(&stmp, "* transport-cc"));
1334  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1335 
1336  if (session_media->type != AST_MEDIA_TYPE_VIDEO) {
1337  return;
1338  }
1339 
1340  /*
1341  * For now just automatically add it the stream even though it hasn't
1342  * necessarily been negotiated.
1343  */
1344  attr = pjmedia_sdp_attr_create(pool, "rtcp-fb", pj_cstr(&stmp, "* ccm fir"));
1345  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1346 
1347  attr = pjmedia_sdp_attr_create(pool, "rtcp-fb", pj_cstr(&stmp, "* goog-remb"));
1348  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1349 
1350  attr = pjmedia_sdp_attr_create(pool, "rtcp-fb", pj_cstr(&stmp, "* nack"));
1351  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1352 }
1353 
1355  struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media)
1356 {
1357  int idx;
1358  char extmap_value[256];
1359 
1360  if (!session->endpoint->media.webrtc || session_media->type != AST_MEDIA_TYPE_VIDEO) {
1361  return;
1362  }
1363 
1364  /* RTP extension local unique identifiers start at '1' */
1365  for (idx = 1; idx <= ast_rtp_instance_extmap_count(session_media->rtp); ++idx) {
1367  const char *direction_str = "";
1368  pj_str_t stmp;
1369  pjmedia_sdp_attr *attr;
1370 
1371  /* If this is an unsupported RTP extension we can't place it into the SDP */
1372  if (extension == AST_RTP_EXTENSION_UNSUPPORTED) {
1373  continue;
1374  }
1375 
1376  switch (ast_rtp_instance_extmap_get_direction(session_media->rtp, idx)) {
1378  /* Lack of a direction indicates sendrecv, so we leave it out */
1379  direction_str = "";
1380  break;
1382  direction_str = "/sendonly";
1383  break;
1385  direction_str = "/recvonly";
1386  break;
1388  /* It is impossible for a "none" direction extension to be negotiated but just in case
1389  * we treat it as inactive.
1390  */
1392  direction_str = "/inactive";
1393  break;
1394  }
1395 
1396  snprintf(extmap_value, sizeof(extmap_value), "%d%s %s", idx, direction_str,
1397  ast_rtp_instance_extmap_get_uri(session_media->rtp, idx));
1398  attr = pjmedia_sdp_attr_create(pool, "extmap", pj_cstr(&stmp, extmap_value));
1399  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1400  }
1401 }
1402 
1403 /*! \brief Function which processes extmap attributes in a stream */
1404 static void process_extmap_attributes(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
1405  const struct pjmedia_sdp_media *remote_stream)
1406 {
1407  int index;
1408 
1409  if (!session->endpoint->media.webrtc || session_media->type != AST_MEDIA_TYPE_VIDEO) {
1410  return;
1411  }
1412 
1413  ast_rtp_instance_extmap_clear(session_media->rtp);
1414 
1415  for (index = 0; index < remote_stream->attr_count; ++index) {
1416  pjmedia_sdp_attr *attr = remote_stream->attr[index];
1417  char attr_value[pj_strlen(&attr->value) + 1];
1418  char *uri;
1419  int id;
1420  char direction_str[10] = "";
1421  char *attributes;
1423 
1424  /* We only care about extmap attributes */
1425  if (pj_strcmp2(&attr->name, "extmap")) {
1426  continue;
1427  }
1428 
1429  ast_copy_pj_str(attr_value, &attr->value, sizeof(attr_value));
1430 
1431  /* Split the combined unique identifier and direction away from the URI and attributes for easier parsing */
1432  uri = strchr(attr_value, ' ');
1433  if (ast_strlen_zero(uri)) {
1434  continue;
1435  }
1436  *uri++ = '\0';
1437 
1438  if ((sscanf(attr_value, "%30d%9s", &id, direction_str) < 1) || (id < 1)) {
1439  /* We require at a minimum the unique identifier */
1440  continue;
1441  }
1442 
1443  /* Convert from the string to the internal representation */
1444  if (!strcasecmp(direction_str, "/sendonly")) {
1446  } else if (!strcasecmp(direction_str, "/recvonly")) {
1448  } else if (!strcasecmp(direction_str, "/inactive")) {
1450  }
1451 
1452  attributes = strchr(uri, ' ');
1453  if (!ast_strlen_zero(attributes)) {
1454  *attributes++ = '\0';
1455  }
1456 
1457  ast_rtp_instance_extmap_negotiate(session_media->rtp, id, direction, uri, attributes);
1458  }
1459 }
1460 
1461 static void set_session_media_remotely_held(struct ast_sip_session_media *session_media,
1462  const struct ast_sip_session *session,
1463  const pjmedia_sdp_media *media,
1464  const struct ast_stream *stream,
1465  const struct ast_sockaddr *addrs)
1466 {
1467  if (ast_sip_session_is_pending_stream_default(session, stream) &&
1468  (session_media->type == AST_MEDIA_TYPE_AUDIO)) {
1469  if (((addrs != NULL) && ast_sockaddr_isnull(addrs)) ||
1470  ((addrs != NULL) && ast_sockaddr_is_any(addrs)) ||
1471  pjmedia_sdp_media_find_attr2(media, "sendonly", NULL) ||
1472  pjmedia_sdp_media_find_attr2(media, "inactive", NULL)) {
1473  if (!session_media->remotely_held) {
1474  session_media->remotely_held = 1;
1475  session_media->remotely_held_changed = 1;
1476  }
1477  } else if (session_media->remotely_held) {
1478  session_media->remotely_held = 0;
1479  session_media->remotely_held_changed = 1;
1480  }
1481  }
1482 }
1483 
1484 /*! \brief Function which negotiates an incoming media stream */
1486  struct ast_sip_session_media *session_media, const pjmedia_sdp_session *sdp,
1487  int index, struct ast_stream *asterisk_stream)
1488 {
1489  char host[NI_MAXHOST];
1490  RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free);
1491  pjmedia_sdp_media *stream = sdp->media[index];
1492  struct ast_sip_session_media *session_media_transport;
1493  enum ast_media_type media_type = session_media->type;
1495  struct ast_format_cap *joint;
1496  int res;
1497  SCOPE_ENTER(1, "%s\n", ast_sip_session_get_name(session));
1498 
1499  /* If no type formats have been configured reject this stream */
1500  if (!ast_format_cap_has_type(session->endpoint->media.codecs, media_type)) {
1501  ast_debug(3, "Endpoint has no codecs for media type '%s', declining stream\n",
1502  ast_codec_media_type2str(session_media->type));
1503  SCOPE_EXIT_RTN_VALUE(0, "Endpoint has no codecs\n");
1504  }
1505 
1506  /* Ensure incoming transport is compatible with the endpoint's configuration */
1507  if (!session->endpoint->media.rtp.use_received_transport) {
1508  encryption = check_endpoint_media_transport(session->endpoint, stream);
1509 
1510  if (encryption == AST_SIP_MEDIA_TRANSPORT_INVALID) {
1511  SCOPE_EXIT_RTN_VALUE(-1, "Incompatible transport\n");
1512  }
1513  }
1514 
1515  ast_copy_pj_str(host, stream->conn ? &stream->conn->addr : &sdp->conn->addr, sizeof(host));
1516 
1517  /* Ensure that the address provided is valid */
1518  if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC) <= 0) {
1519  /* The provided host was actually invalid so we error out this negotiation */
1520  SCOPE_EXIT_RTN_VALUE(-1, "Invalid host\n");
1521  }
1522 
1523  /* Using the connection information create an appropriate RTP instance */
1524  if (!session_media->rtp && create_rtp(session, session_media, sdp)) {
1525  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create rtp\n");
1526  }
1527 
1528  process_ssrc_attributes(session, session_media, stream);
1529  process_extmap_attributes(session, session_media, stream);
1530  session_media_transport = ast_sip_session_media_get_transport(session, session_media);
1531 
1532  if (session_media_transport == session_media || !session_media->bundled) {
1533  /* If this media session is carrying actual traffic then set up those aspects */
1534  session_media->remote_rtcp_mux = (pjmedia_sdp_media_find_attr2(stream, "rtcp-mux", NULL) != NULL);
1535  set_ice_components(session, session_media);
1536 
1537  enable_rtcp(session, session_media, stream);
1538 
1539  res = setup_media_encryption(session, session_media, sdp, stream);
1540  if (res) {
1541  if (!session->endpoint->media.rtp.encryption_optimistic ||
1542  !pj_strncmp2(&stream->desc.transport, "RTP/SAVP", 8)) {
1543  /* If optimistic encryption is disabled and crypto should have been enabled
1544  * but was not this session must fail. This must also fail if crypto was
1545  * required in the offer but could not be set up.
1546  */
1547  SCOPE_EXIT_RTN_VALUE(-1, "Incompatible crypto\n");
1548  }
1549  /* There is no encryption, sad. */
1550  session_media->encryption = AST_SIP_MEDIA_ENCRYPT_NONE;
1551  }
1552 
1553  /* If we've been explicitly configured to use the received transport OR if
1554  * encryption is on and crypto is present use the received transport.
1555  * This is done in case of optimistic because it may come in as RTP/AVP or RTP/SAVP depending
1556  * on the configuration of the remote endpoint (optimistic themselves or mandatory).
1557  */
1558  if ((session->endpoint->media.rtp.use_received_transport) ||
1559  ((encryption == AST_SIP_MEDIA_ENCRYPT_SDES) && !res)) {
1560  pj_strdup(session->inv_session->pool, &session_media->transport, &stream->desc.transport);
1561  }
1562  } else {
1563  /* This is bundled with another session, so mark it as such */
1564  ast_rtp_instance_bundle(session_media->rtp, session_media_transport->rtp);
1565 
1566  enable_rtcp(session, session_media, stream);
1567  }
1568 
1569  /* If ICE support is enabled find all the needed attributes */
1570  check_ice_support(session, session_media, stream);
1571 
1572  /* If ICE support is enabled then check remote ICE started? */
1573  if (session_media->remote_ice) {
1574  process_ice_auth_attrb(session, session_media, sdp, stream);
1575  }
1576 
1577  /* Check if incoming SDP is changing the remotely held state */
1578  set_session_media_remotely_held(session_media, session, stream, asterisk_stream, addrs);
1579 
1580  joint = set_incoming_call_offer_cap(session, session_media, stream);
1581  res = apply_cap_to_bundled(session_media, session_media_transport, asterisk_stream, joint);
1582  ao2_cleanup(joint);
1583  if (res != 0) {
1584  SCOPE_EXIT_RTN_VALUE(0, "Something failed\n");
1585  }
1586 
1588 }
1589 
1591  struct ast_sip_session_media *session_media,
1592  pj_pool_t *pool, pjmedia_sdp_media *media)
1593 {
1594  pj_str_t stmp;
1595  pjmedia_sdp_attr *attr;
1596  enum ast_rtp_dtls_hash hash;
1597  const char *crypto_attribute;
1598  struct ast_rtp_engine_dtls *dtls;
1599  struct ast_sdp_srtp *tmp;
1600  static const pj_str_t STR_NEW = { "new", 3 };
1601  static const pj_str_t STR_EXISTING = { "existing", 8 };
1602  static const pj_str_t STR_ACTIVE = { "active", 6 };
1603  static const pj_str_t STR_PASSIVE = { "passive", 7 };
1604  static const pj_str_t STR_ACTPASS = { "actpass", 7 };
1605  static const pj_str_t STR_HOLDCONN = { "holdconn", 8 };
1606  enum ast_rtp_dtls_setup setup;
1607 
1608  switch (session_media->encryption) {
1611  break;
1613  if (!session_media->srtp) {
1614  session_media->srtp = ast_sdp_srtp_alloc();
1615  if (!session_media->srtp) {
1616  return -1;
1617  }
1618  }
1619 
1620  tmp = session_media->srtp;
1621 
1622  do {
1623  crypto_attribute = ast_sdp_srtp_get_attrib(tmp,
1624  0 /* DTLS running? No */,
1625  session->endpoint->media.rtp.srtp_tag_32 /* 32 byte tag length? */);
1626  if (!crypto_attribute) {
1627  /* No crypto attribute to add, bad news */
1628  return -1;
1629  }
1630 
1631  attr = pjmedia_sdp_attr_create(pool, "crypto",
1632  pj_cstr(&stmp, crypto_attribute));
1633  media->attr[media->attr_count++] = attr;
1634  } while ((tmp = AST_LIST_NEXT(tmp, sdp_srtp_list)));
1635 
1636  break;
1638  if (setup_dtls_srtp(session, session_media)) {
1639  return -1;
1640  }
1641 
1642  dtls = ast_rtp_instance_get_dtls(session_media->rtp);
1643  if (!dtls) {
1644  return -1;
1645  }
1646 
1647  switch (dtls->get_connection(session_media->rtp)) {
1649  attr = pjmedia_sdp_attr_create(pool, "connection", &STR_NEW);
1650  media->attr[media->attr_count++] = attr;
1651  break;
1653  attr = pjmedia_sdp_attr_create(pool, "connection", &STR_EXISTING);
1654  media->attr[media->attr_count++] = attr;
1655  break;
1656  default:
1657  break;
1658  }
1659 
1660  /* If this is an answer we need to use our current state, if it's an offer we need to use
1661  * the configured value.
1662  */
1663  if (session->inv_session->neg
1664  && pjmedia_sdp_neg_get_state(session->inv_session->neg) != PJMEDIA_SDP_NEG_STATE_DONE) {
1665  setup = dtls->get_setup(session_media->rtp);
1666  } else {
1667  setup = session->endpoint->media.rtp.dtls_cfg.default_setup;
1668  }
1669 
1670  switch (setup) {
1672  attr = pjmedia_sdp_attr_create(pool, "setup", &STR_ACTIVE);
1673  media->attr[media->attr_count++] = attr;
1674  break;
1676  attr = pjmedia_sdp_attr_create(pool, "setup", &STR_PASSIVE);
1677  media->attr[media->attr_count++] = attr;
1678  break;
1680  attr = pjmedia_sdp_attr_create(pool, "setup", &STR_ACTPASS);
1681  media->attr[media->attr_count++] = attr;
1682  break;
1684  attr = pjmedia_sdp_attr_create(pool, "setup", &STR_HOLDCONN);
1685  break;
1686  default:
1687  break;
1688  }
1689 
1690  hash = dtls->get_fingerprint_hash(session_media->rtp);
1691  crypto_attribute = dtls->get_fingerprint(session_media->rtp);
1692  if (crypto_attribute && (hash == AST_RTP_DTLS_HASH_SHA1 || hash == AST_RTP_DTLS_HASH_SHA256)) {
1693  RAII_VAR(struct ast_str *, fingerprint, ast_str_create(64), ast_free);
1694  if (!fingerprint) {
1695  return -1;
1696  }
1697 
1698  if (hash == AST_RTP_DTLS_HASH_SHA1) {
1699  ast_str_set(&fingerprint, 0, "SHA-1 %s", crypto_attribute);
1700  } else {
1701  ast_str_set(&fingerprint, 0, "SHA-256 %s", crypto_attribute);
1702  }
1703 
1704  attr = pjmedia_sdp_attr_create(pool, "fingerprint", pj_cstr(&stmp, ast_str_buffer(fingerprint)));
1705  media->attr[media->attr_count++] = attr;
1706  }
1707  break;
1708  }
1709 
1710  return 0;
1711 }
1712 
1713 /*! \brief Function which creates an outgoing stream */
1715  struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_session *remote, struct ast_stream *stream)
1716 {
1717  pj_pool_t *pool = session->inv_session->pool_prov;
1718  static const pj_str_t STR_RTP_AVP = { "RTP/AVP", 7 };
1719  static const pj_str_t STR_IN = { "IN", 2 };
1720  static const pj_str_t STR_IP4 = { "IP4", 3};
1721  static const pj_str_t STR_IP6 = { "IP6", 3};
1722  static const pj_str_t STR_SENDRECV = { "sendrecv", 8 };
1723  static const pj_str_t STR_SENDONLY = { "sendonly", 8 };
1724  static const pj_str_t STR_INACTIVE = { "inactive", 8 };
1725  static const pj_str_t STR_RECVONLY = { "recvonly", 8 };
1726  pjmedia_sdp_media *media;
1727  const char *hostip = NULL;
1728  struct ast_sockaddr addr;
1729  char tmp[512];
1730  pj_str_t stmp;
1731  pjmedia_sdp_attr *attr;
1732  int index = 0;
1733  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;
1734  int min_packet_size = 0, max_packet_size = 0;
1735  int rtp_code;
1736  RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup);
1737  enum ast_media_type media_type = session_media->type;
1738  struct ast_sip_session_media *session_media_transport;
1739  pj_sockaddr ip;
1740  int direct_media_enabled = !ast_sockaddr_isnull(&session_media->direct_media_addr) &&
1742  SCOPE_ENTER(1, "%s Type: %s %s\n", ast_sip_session_get_name(session),
1743  ast_codec_media_type2str(media_type), ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)));
1744 
1745  media = pj_pool_zalloc(pool, sizeof(struct pjmedia_sdp_media));
1746  if (!media) {
1747  SCOPE_EXIT_RTN_VALUE(-1, "Pool alloc failure\n");
1748  }
1749  pj_strdup2(pool, &media->desc.media, ast_codec_media_type2str(session_media->type));
1750 
1751  /* If this is a removed (or declined) stream OR if no formats exist then construct a minimal stream in SDP */
1754  media->desc.port = 0;
1755  media->desc.port_count = 1;
1756 
1757  if (remote && remote->media[ast_stream_get_position(stream)]) {
1758  pjmedia_sdp_media *remote_media = remote->media[ast_stream_get_position(stream)];
1759  int index;
1760 
1761  media->desc.transport = remote_media->desc.transport;
1762 
1763  /* Preserve existing behavior by copying the formats provided from the offer */
1764  for (index = 0; index < remote_media->desc.fmt_count; ++index) {
1765  media->desc.fmt[index] = remote_media->desc.fmt[index];
1766  }
1767  media->desc.fmt_count = remote_media->desc.fmt_count;
1768  } else {
1769  /* This is actually an offer so put a dummy payload in that is ignored and sane transport */
1770  media->desc.transport = STR_RTP_AVP;
1771  pj_strdup2(pool, &media->desc.fmt[media->desc.fmt_count++], "32");
1772  }
1773 
1774  sdp->media[sdp->media_count++] = media;
1776 
1777  SCOPE_EXIT_RTN_VALUE(1, "Stream removed or no formats\n");
1778  }
1779 
1780  if (!session_media->rtp && create_rtp(session, session_media, sdp)) {
1781  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create rtp\n");
1782  }
1783 
1784  /* If this stream has not been bundled already it is new and we need to ensure there is no SSRC conflict */
1785  if (session_media->bundle_group != -1 && !session_media->bundled) {
1786  for (index = 0; index < sdp->media_count; ++index) {
1787  struct ast_sip_session_media *other_session_media;
1788 
1789  other_session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, index);
1790  if (!other_session_media->rtp || other_session_media->bundle_group != session_media->bundle_group) {
1791  continue;
1792  }
1793 
1794  if (ast_rtp_instance_get_ssrc(session_media->rtp) == ast_rtp_instance_get_ssrc(other_session_media->rtp)) {
1795  ast_rtp_instance_change_source(session_media->rtp);
1796  /* Start the conflict check over again */
1797  index = -1;
1798  continue;
1799  }
1800  }
1801  }
1802 
1803  session_media_transport = ast_sip_session_media_get_transport(session, session_media);
1804 
1805  if (session_media_transport == session_media || !session_media->bundled) {
1806  set_ice_components(session, session_media);
1807  enable_rtcp(session, session_media, NULL);
1808 
1809  /* Crypto has to be added before setting the media transport so that SRTP is properly
1810  * set up according to the configuration. This ends up changing the media transport.
1811  */
1812  if (add_crypto_to_stream(session, session_media, pool, media)) {
1813  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't add crypto\n");
1814  }
1815 
1816  if (pj_strlen(&session_media->transport)) {
1817  /* If a transport has already been specified use it */
1818  media->desc.transport = session_media->transport;
1819  } else {
1820  media->desc.transport = pj_str(ast_sdp_get_rtp_profile(
1821  /* Optimistic encryption places crypto in the normal RTP/AVP profile */
1822  !session->endpoint->media.rtp.encryption_optimistic &&
1823  (session_media->encryption == AST_SIP_MEDIA_ENCRYPT_SDES),
1824  session_media->rtp, session->endpoint->media.rtp.use_avpf,
1825  session->endpoint->media.rtp.force_avp));
1826  }
1827 
1828  media->conn = pj_pool_zalloc(pool, sizeof(struct pjmedia_sdp_conn));
1829  if (!media->conn) {
1830  SCOPE_EXIT_RTN_VALUE(-1, "Pool alloc failure\n");
1831  }
1832 
1833  /* Add connection level details */
1834  if (direct_media_enabled) {
1836  } else if (ast_strlen_zero(session->endpoint->media.address)) {
1837  hostip = ast_sip_get_host_ip_string(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET());
1838  } else {
1839  hostip = session->endpoint->media.address;
1840  }
1841 
1842  if (ast_strlen_zero(hostip)) {
1843  ast_log(LOG_ERROR, "No local host IP available for stream %s\n",
1844  ast_codec_media_type2str(session_media->type));
1845  SCOPE_EXIT_RTN_VALUE(-1, "No local host ip\n");
1846  }
1847 
1848  media->conn->net_type = STR_IN;
1849  /* Assume that the connection will use IPv4 until proven otherwise */
1850  media->conn->addr_type = STR_IP4;
1851  pj_strdup2(pool, &media->conn->addr, hostip);
1852 
1853  if ((pj_sockaddr_parse(pj_AF_UNSPEC(), 0, &media->conn->addr, &ip) == PJ_SUCCESS) &&
1854  (ip.addr.sa_family == pj_AF_INET6())) {
1855  media->conn->addr_type = STR_IP6;
1856  }
1857 
1858  /* Add ICE attributes and candidates */
1859  add_ice_to_stream(session, session_media, pool, media, 1);
1860 
1861  ast_rtp_instance_get_local_address(session_media->rtp, &addr);
1862  media->desc.port = direct_media_enabled ? ast_sockaddr_port(&session_media->direct_media_addr) : (pj_uint16_t) ast_sockaddr_port(&addr);
1863  media->desc.port_count = 1;
1864  } else {
1865  pjmedia_sdp_media *bundle_group_stream = sdp->media[session_media_transport->stream_num];
1866 
1867  /* As this is in a bundle group it shares the same details as the group instance */
1868  media->desc.transport = bundle_group_stream->desc.transport;
1869  media->conn = bundle_group_stream->conn;
1870  media->desc.port = bundle_group_stream->desc.port;
1871 
1872  if (add_crypto_to_stream(session, session_media_transport, pool, media)) {
1873  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't add crypto\n");
1874  }
1875 
1876  add_ice_to_stream(session, session_media_transport, pool, media, 0);
1877 
1878  enable_rtcp(session, session_media, NULL);
1879  }
1880 
1882  ast_log(LOG_ERROR, "Failed to allocate %s capabilities\n",
1883  ast_codec_media_type2str(session_media->type));
1884  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create caps\n");
1885  }
1886 
1887  if (direct_media_enabled) {
1889  } else {
1890  ast_format_cap_append_from_cap(caps, ast_stream_get_formats(stream), media_type);
1891  }
1892 
1893  for (index = 0; index < ast_format_cap_count(caps); ++index) {
1894  struct ast_format *format = ast_format_cap_get_format(caps, index);
1895 
1896  if (ast_format_get_type(format) != media_type) {
1897  ao2_ref(format, -1);
1898  continue;
1899  }
1900 
1901  /* If this stream is not a transport we need to use the transport codecs structure for payload management to prevent
1902  * conflicts.
1903  */
1904  if (session_media_transport != session_media) {
1905  if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media_transport->rtp), 1, format, 0)) == -1) {
1906  ast_log(LOG_WARNING,"Unable to get rtp codec payload code for %s\n", ast_format_get_name(format));
1907  ao2_ref(format, -1);
1908  continue;
1909  }
1910  /* Our instance has to match the payload number though */
1911  ast_rtp_codecs_payload_set_rx(ast_rtp_instance_get_codecs(session_media->rtp), rtp_code, format);
1912  } else {
1913  if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media->rtp), 1, format, 0)) == -1) {
1914  ast_log(LOG_WARNING,"Unable to get rtp codec payload code for %s\n", ast_format_get_name(format));
1915  ao2_ref(format, -1);
1916  continue;
1917  }
1918  }
1919 
1920  if ((attr = generate_rtpmap_attr(session, media, pool, rtp_code, 1, format, 0))) {
1921  media->attr[media->attr_count++] = attr;
1922  }
1923 
1924  if ((attr = generate_fmtp_attr(pool, format, rtp_code))) {
1925  media->attr[media->attr_count++] = attr;
1926  }
1927 
1928  if (ast_format_get_maximum_ms(format) &&
1929  ((ast_format_get_maximum_ms(format) < max_packet_size) || !max_packet_size)) {
1930  max_packet_size = ast_format_get_maximum_ms(format);
1931  }
1932  ao2_ref(format, -1);
1933 
1934  if (media->desc.fmt_count == PJMEDIA_MAX_SDP_FMT) {
1935  break;
1936  }
1937  }
1938 
1939  /* Add non-codec formats */
1940  if (ast_sip_session_is_pending_stream_default(session, stream) && media_type != AST_MEDIA_TYPE_VIDEO
1941  && media->desc.fmt_count < PJMEDIA_MAX_SDP_FMT) {
1942  for (index = 1LL; index <= AST_RTP_MAX; index <<= 1) {
1943  if (!(noncodec & index)) {
1944  continue;
1945  }
1946  rtp_code = ast_rtp_codecs_payload_code(
1947  ast_rtp_instance_get_codecs(session_media->rtp), 0, NULL, index);
1948  if (rtp_code == -1) {
1949  continue;
1950  }
1951 
1952  if ((attr = generate_rtpmap_attr(session, media, pool, rtp_code, 0, NULL, index))) {
1953  media->attr[media->attr_count++] = attr;
1954  }
1955 
1956  if (index == AST_RTP_DTMF) {
1957  snprintf(tmp, sizeof(tmp), "%d 0-16", rtp_code);
1958  attr = pjmedia_sdp_attr_create(pool, "fmtp", pj_cstr(&stmp, tmp));
1959  media->attr[media->attr_count++] = attr;
1960  }
1961 
1962  if (media->desc.fmt_count == PJMEDIA_MAX_SDP_FMT) {
1963  break;
1964  }
1965  }
1966  }
1967 
1968 
1969  /* If no formats were actually added to the media stream don't add it to the SDP */
1970  if (!media->desc.fmt_count) {
1971  SCOPE_EXIT_RTN_VALUE(1, "No formats added to stream\n");
1972  }
1973 
1974  /* If ptime is set add it as an attribute */
1975  min_packet_size = ast_rtp_codecs_get_framing(ast_rtp_instance_get_codecs(session_media->rtp));
1976  if (!min_packet_size) {
1977  min_packet_size = ast_format_cap_get_framing(caps);
1978  }
1979  if (min_packet_size) {
1980  snprintf(tmp, sizeof(tmp), "%d", min_packet_size);
1981  attr = pjmedia_sdp_attr_create(pool, "ptime", pj_cstr(&stmp, tmp));
1982  media->attr[media->attr_count++] = attr;
1983  }
1984 
1985  if (max_packet_size) {
1986  snprintf(tmp, sizeof(tmp), "%d", max_packet_size);
1987  attr = pjmedia_sdp_attr_create(pool, "maxptime", pj_cstr(&stmp, tmp));
1988  media->attr[media->attr_count++] = attr;
1989  }
1990 
1991  attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr);
1992  if (session_media->locally_held) {
1993  if (session_media->remotely_held) {
1994  attr->name = STR_INACTIVE; /* To place on hold a recvonly stream, send inactive */
1995  } else {
1996  attr->name = STR_SENDONLY; /* Send sendonly to initate a local hold */
1997  }
1998  } else {
1999  if (session_media->remotely_held) {
2000  attr->name = STR_RECVONLY; /* Remote has sent sendonly, reply recvonly */
2001  } else if (ast_stream_get_state(stream) == AST_STREAM_STATE_SENDONLY) {
2002  attr->name = STR_SENDONLY; /* Stream has requested sendonly */
2003  } else if (ast_stream_get_state(stream) == AST_STREAM_STATE_RECVONLY) {
2004  attr->name = STR_RECVONLY; /* Stream has requested recvonly */
2005  } else if (ast_stream_get_state(stream) == AST_STREAM_STATE_INACTIVE) {
2006  attr->name = STR_INACTIVE; /* Stream has requested inactive */
2007  } else {
2008  attr->name = STR_SENDRECV; /* No hold in either direction */
2009  }
2010  }
2011  media->attr[media->attr_count++] = attr;
2012 
2013  /* If we've got rtcp-mux enabled, add it unless we received an offer without it */
2014  if (session->endpoint->media.rtcp_mux && session_media->remote_rtcp_mux) {
2015  attr = pjmedia_sdp_attr_create(pool, "rtcp-mux", NULL);
2016  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
2017  }
2018 
2019  add_ssrc_to_stream(session, session_media, pool, media);
2020  add_msid_to_stream(session, session_media, pool, media, stream);
2021  add_rtcp_fb_to_stream(session, session_media, pool, media);
2022  add_extmap_to_stream(session, session_media, pool, media);
2023 
2024  /* Add the media stream to the SDP */
2025  sdp->media[sdp->media_count++] = media;
2026 
2027  SCOPE_EXIT_RTN_VALUE(1, "RC: 1\n");
2028 }
2029 
2031 {
2032  struct ast_frame *f;
2033 
2034  if (!session_media->rtp) {
2035  return &ast_null_frame;
2036  }
2037 
2038  f = ast_rtp_instance_read(session_media->rtp, 0);
2039  if (!f) {
2040  return NULL;
2041  }
2042 
2043  ast_rtp_instance_set_last_rx(session_media->rtp, time(NULL));
2044 
2045  return f;
2046 }
2047 
2049 {
2050  struct ast_frame *f;
2051 
2052  if (!session_media->rtp) {
2053  return &ast_null_frame;
2054  }
2055 
2056  f = ast_rtp_instance_read(session_media->rtp, 1);
2057  if (!f) {
2058  return NULL;
2059  }
2060 
2061  ast_rtp_instance_set_last_rx(session_media->rtp, time(NULL));
2062 
2063  return f;
2064 }
2065 
2066 static int media_session_rtp_write_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct ast_frame *frame)
2067 {
2068  if (!session_media->rtp) {
2069  return 0;
2070  }
2071 
2072  return ast_rtp_instance_write(session_media->rtp, frame);
2073 }
2074 
2076  struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *local,
2077  const struct pjmedia_sdp_session *remote, int index, struct ast_stream *asterisk_stream)
2078 {
2079  RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free);
2080  struct pjmedia_sdp_media *remote_stream = remote->media[index];
2081  enum ast_media_type media_type = session_media->type;
2082  char host[NI_MAXHOST];
2083  int res;
2084  struct ast_sip_session_media *session_media_transport;
2085  SCOPE_ENTER(1, "%s Stream: %s\n", ast_sip_session_get_name(session),
2086  ast_str_tmp(128, ast_stream_to_str(asterisk_stream, &STR_TMP)));
2087 
2088  if (!session->channel) {
2089  SCOPE_EXIT_RTN_VALUE(1, "No channel\n");
2090  }
2091 
2092  /* Ensure incoming transport is compatible with the endpoint's configuration */
2093  if (!session->endpoint->media.rtp.use_received_transport &&
2095  SCOPE_EXIT_RTN_VALUE(-1, "Incompatible transport\n");
2096  }
2097 
2098  /* Create an RTP instance if need be */
2099  if (!session_media->rtp && create_rtp(session, session_media, local)) {
2100  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create rtp\n");
2101  }
2102 
2103  process_ssrc_attributes(session, session_media, remote_stream);
2104  process_extmap_attributes(session, session_media, remote_stream);
2105 
2106  session_media_transport = ast_sip_session_media_get_transport(session, session_media);
2107 
2108  if (session_media_transport == session_media || !session_media->bundled) {
2109  session_media->remote_rtcp_mux = (pjmedia_sdp_media_find_attr2(remote_stream, "rtcp-mux", NULL) != NULL);
2110  set_ice_components(session, session_media);
2111 
2112  enable_rtcp(session, session_media, remote_stream);
2113 
2114  res = setup_media_encryption(session, session_media, remote, remote_stream);
2115  if (!session->endpoint->media.rtp.encryption_optimistic && res) {
2116  /* If optimistic encryption is disabled and crypto should have been enabled but was not
2117  * this session must fail.
2118  */
2119  SCOPE_EXIT_RTN_VALUE(-1, "Incompatible crypto\n");
2120  }
2121 
2122  if (!remote_stream->conn && !remote->conn) {
2123  SCOPE_EXIT_RTN_VALUE(1, "No connection info\n");
2124  }
2125 
2126  ast_copy_pj_str(host, remote_stream->conn ? &remote_stream->conn->addr : &remote->conn->addr, sizeof(host));
2127 
2128  /* Ensure that the address provided is valid */
2129  if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC) <= 0) {
2130  /* The provided host was actually invalid so we error out this negotiation */
2131  SCOPE_EXIT_RTN_VALUE(-1, "Host invalid\n");
2132  }
2133 
2134  /* Apply connection information to the RTP instance */
2135  ast_sockaddr_set_port(addrs, remote_stream->desc.port);
2136  ast_rtp_instance_set_remote_address(session_media->rtp, addrs);
2137 
2139  ast_sip_session_media_add_read_callback(session, session_media, ast_rtp_instance_fd(session_media->rtp, 0),
2141  if (!session->endpoint->media.rtcp_mux || !session_media->remote_rtcp_mux) {
2142  ast_sip_session_media_add_read_callback(session, session_media, ast_rtp_instance_fd(session_media->rtp, 1),
2144  }
2145 
2146  /* If ICE support is enabled find all the needed attributes */
2147  process_ice_attributes(session, session_media, remote, remote_stream);
2148  } else {
2149  /* This is bundled with another session, so mark it as such */
2150  ast_rtp_instance_bundle(session_media->rtp, session_media_transport->rtp);
2152  enable_rtcp(session, session_media, remote_stream);
2153  }
2154 
2155  if (set_caps(session, session_media, session_media_transport, remote_stream, 0, asterisk_stream)) {
2156  SCOPE_EXIT_RTN_VALUE(-1, "set_caps failed\n");
2157  }
2158 
2159  /* Set the channel uniqueid on the RTP instance now that it is becoming active */
2160  ast_channel_lock(session->channel);
2162  ast_channel_unlock(session->channel);
2163 
2164  /* Ensure the RTP instance is active */
2165  ast_rtp_instance_set_stream_num(session_media->rtp, ast_stream_get_position(asterisk_stream));
2166  ast_rtp_instance_activate(session_media->rtp);
2167 
2168  /* audio stream handles music on hold */
2169  if (media_type != AST_MEDIA_TYPE_AUDIO) {
2170  if ((pjmedia_sdp_neg_was_answer_remote(session->inv_session->neg) == PJ_FALSE)
2171  && (session->inv_session->state == PJSIP_INV_STATE_CONFIRMED)) {
2173  }
2174  SCOPE_EXIT_RTN_VALUE(1, "moh\n");
2175  }
2176 
2177  set_session_media_remotely_held(session_media, session, remote_stream, asterisk_stream, addrs);
2178 
2179  if (session_media->remotely_held_changed) {
2180  if (session_media->remotely_held) {
2181  /* The remote side has put us on hold */
2182  ast_queue_hold(session->channel, session->endpoint->mohsuggest);
2183  ast_rtp_instance_stop(session_media->rtp);
2185  session_media->remotely_held_changed = 0;
2186  } else {
2187  /* The remote side has taken us off hold */
2188  ast_queue_unhold(session->channel);
2190  session_media->remotely_held_changed = 0;
2191  }
2192  } else if ((pjmedia_sdp_neg_was_answer_remote(session->inv_session->neg) == PJ_FALSE)
2193  && (session->inv_session->state == PJSIP_INV_STATE_CONFIRMED)) {
2195  }
2196 
2197  /* This purposely resets the encryption to the configured in case it gets added later */
2198  session_media->encryption = session->endpoint->media.rtp.encryption;
2199 
2200  if (session->endpoint->media.rtp.keepalive > 0 &&
2201  session_media->type == AST_MEDIA_TYPE_AUDIO) {
2202  ast_rtp_instance_set_keepalive(session_media->rtp, session->endpoint->media.rtp.keepalive);
2203  /* Schedule the initial keepalive early in case this is being used to punch holes through
2204  * a NAT. This way there won't be an awkward delay before media starts flowing in some
2205  * scenarios.
2206  */
2207  AST_SCHED_DEL(sched, session_media->keepalive_sched_id);
2208  session_media->keepalive_sched_id = ast_sched_add_variable(sched, 500, send_keepalive,
2209  session_media, 1);
2210  }
2211 
2212  /* As the channel lock is not held during this process the scheduled item won't block if
2213  * it is hanging up the channel at the same point we are applying this negotiated SDP.
2214  */
2215  AST_SCHED_DEL(sched, session_media->timeout_sched_id);
2216 
2217  /* Due to the fact that we only ever have one scheduled timeout item for when we are both
2218  * off hold and on hold we don't need to store the two timeouts differently on the RTP
2219  * instance itself.
2220  */
2221  ast_rtp_instance_set_timeout(session_media->rtp, 0);
2222  if (session->endpoint->media.rtp.timeout && !session_media->remotely_held) {
2223  ast_rtp_instance_set_timeout(session_media->rtp, session->endpoint->media.rtp.timeout);
2224  } else if (session->endpoint->media.rtp.timeout_hold && session_media->remotely_held) {
2225  ast_rtp_instance_set_timeout(session_media->rtp, session->endpoint->media.rtp.timeout_hold);
2226  }
2227 
2228  if (ast_rtp_instance_get_timeout(session_media->rtp)) {
2229  session_media->timeout_sched_id = ast_sched_add_variable(sched,
2230  ast_rtp_instance_get_timeout(session_media->rtp) * 1000, rtp_check_timeout,
2231  session_media, 1);
2232  }
2233 
2234  SCOPE_EXIT_RTN_VALUE(1, "Handled\n");
2235 }
2236 
2237 /*! \brief Function which updates the media stream with external media address, if applicable */
2238 static void change_outgoing_sdp_stream_media_address(pjsip_tx_data *tdata, struct pjmedia_sdp_media *stream, struct ast_sip_transport *transport)
2239 {
2241  char host[NI_MAXHOST];
2242  struct ast_sockaddr our_sdp_addr = { { 0, } };
2243 
2244  /* If the stream has been rejected there will be no connection line */
2245  if (!stream->conn || !transport_state) {
2246  return;
2247  }
2248 
2249  ast_copy_pj_str(host, &stream->conn->addr, sizeof(host));
2250  ast_sockaddr_parse(&our_sdp_addr, host, PARSE_PORT_FORBID);
2251 
2252  /* Reversed check here. We don't check the remote endpoint being
2253  * in our local net, but whether our outgoing session IP is
2254  * local. If it is not, we won't do rewriting. No localnet
2255  * configured? Always rewrite. */
2256  if (ast_sip_transport_is_nonlocal(transport_state, &our_sdp_addr) && transport_state->localnet) {
2257  return;
2258  }
2259  ast_debug(5, "Setting media address to %s\n", ast_sockaddr_stringify_addr_remote(&transport_state->external_media_address));
2260  pj_strdup2(tdata->pool, &stream->conn->addr, ast_sockaddr_stringify_addr_remote(&transport_state->external_media_address));
2261 }
2262 
2263 /*! \brief Function which stops the RTP instance */
2264 static void stream_stop(struct ast_sip_session_media *session_media)
2265 {
2266  if (!session_media->rtp) {
2267  return;
2268  }
2269 
2270  AST_SCHED_DEL(sched, session_media->keepalive_sched_id);
2271  AST_SCHED_DEL(sched, session_media->timeout_sched_id);
2272  ast_rtp_instance_stop(session_media->rtp);
2273 }
2274 
2275 /*! \brief Function which destroys the RTP instance when session ends */
2276 static void stream_destroy(struct ast_sip_session_media *session_media)
2277 {
2278  if (session_media->rtp) {
2279  stream_stop(session_media);
2280  ast_rtp_instance_destroy(session_media->rtp);
2281  }
2282  session_media->rtp = NULL;
2283 }
2284 
2285 /*! \brief SDP handler for 'audio' media stream */
2287  .id = STR_AUDIO,
2288  .negotiate_incoming_sdp_stream = negotiate_incoming_sdp_stream,
2289  .create_outgoing_sdp_stream = create_outgoing_sdp_stream,
2290  .apply_negotiated_sdp_stream = apply_negotiated_sdp_stream,
2291  .change_outgoing_sdp_stream_media_address = change_outgoing_sdp_stream_media_address,
2292  .stream_stop = stream_stop,
2293  .stream_destroy = stream_destroy,
2294 };
2295 
2296 /*! \brief SDP handler for 'video' media stream */
2298  .id = STR_VIDEO,
2299  .negotiate_incoming_sdp_stream = negotiate_incoming_sdp_stream,
2300  .create_outgoing_sdp_stream = create_outgoing_sdp_stream,
2301  .apply_negotiated_sdp_stream = apply_negotiated_sdp_stream,
2302  .change_outgoing_sdp_stream_media_address = change_outgoing_sdp_stream_media_address,
2303  .stream_stop = stream_stop,
2304  .stream_destroy = stream_destroy,
2305 };
2306 
2307 static int video_info_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
2308 {
2309  struct pjsip_transaction *tsx;
2310  pjsip_tx_data *tdata;
2311 
2312  if (!session->channel
2313  || !ast_sip_is_content_type(&rdata->msg_info.msg->body->content_type,
2314  "application",
2315  "media_control+xml")) {
2316  return 0;
2317  }
2318 
2319  tsx = pjsip_rdata_get_tsx(rdata);
2320 
2322 
2323  if (pjsip_dlg_create_response(session->inv_session->dlg, rdata, 200, NULL, &tdata) == PJ_SUCCESS) {
2324  pjsip_dlg_send_response(session->inv_session->dlg, tsx, tdata);
2325  }
2326 
2327  return 0;
2328 }
2329 
2331  .method = "INFO",
2332  .incoming_request = video_info_incoming_request,
2333 };
2334 
2335 /*! \brief Unloads the sdp RTP/AVP module from Asterisk */
2336 static int unload_module(void)
2337 {
2338  ast_sip_session_unregister_supplement(&video_info_supplement);
2341 
2342  if (sched) {
2344  }
2345 
2346  return 0;
2347 }
2348 
2349 /*!
2350  * \brief Load the module
2351  *
2352  * Module loading including tests for configuration or dependencies.
2353  * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
2354  * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
2355  * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the
2356  * configuration file or other non-critical problem return
2357  * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
2358  */
2359 static int load_module(void)
2360 {
2361  if (ast_check_ipv6()) {
2362  ast_sockaddr_parse(&address_rtp, "::", 0);
2363  } else {
2364  ast_sockaddr_parse(&address_rtp, "0.0.0.0", 0);
2365  }
2366 
2367  if (!(sched = ast_sched_context_create())) {
2368  ast_log(LOG_ERROR, "Unable to create scheduler context.\n");
2369  goto end;
2370  }
2371 
2372  if (ast_sched_start_thread(sched)) {
2373  ast_log(LOG_ERROR, "Unable to create scheduler context thread.\n");
2374  goto end;
2375  }
2376 
2377  if (ast_sip_session_register_sdp_handler(&audio_sdp_handler, STR_AUDIO)) {
2378  ast_log(LOG_ERROR, "Unable to register SDP handler for %s stream type\n", STR_AUDIO);
2379  goto end;
2380  }
2381 
2382  if (ast_sip_session_register_sdp_handler(&video_sdp_handler, STR_VIDEO)) {
2383  ast_log(LOG_ERROR, "Unable to register SDP handler for %s stream type\n", STR_VIDEO);
2384  goto end;
2385  }
2386 
2387  ast_sip_session_register_supplement(&video_info_supplement);
2388 
2389  return AST_MODULE_LOAD_SUCCESS;
2390 end:
2391  unload_module();
2392 
2393  return AST_MODULE_LOAD_DECLINE;
2394 }
2395 
2396 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP SDP RTP/AVP stream handler",
2397  .support_level = AST_MODULE_SUPPORT_CORE,
2398  .load = load_module,
2399  .unload = unload_module,
2400  .load_pri = AST_MODPRI_CHANNEL_DRIVER,
2401  .requires = "res_pjsip,res_pjsip_session",
2402 );
unsigned int encryption_optimistic
Definition: res_pjsip.h:713
void ast_rtp_codecs_payload_formats(struct ast_rtp_codecs *codecs, struct ast_format_cap *astformats, int *nonastformats)
Retrieve all formats that were found.
Definition: rtp_engine.c:1580
int ast_sched_start_thread(struct ast_sched_context *con)
Start a thread for processing scheduler entries.
Definition: sched.c:195
static int apply_cap_to_bundled(struct ast_sip_session_media *session_media, struct ast_sip_session_media *session_media_transport, struct ast_stream *asterisk_stream, struct ast_format_cap *joint)
int ast_rtp_instance_activate(struct ast_rtp_instance *instance)
Indicate to the RTP engine that packets are now expected to be sent/received on the RTP instance...
Definition: rtp_engine.c:2647
structure for secure RTP audio
Definition: sdp_srtp.h:37
#define ast_channel_lock(chan)
Definition: channel.h:2913
Main Channel structure associated with a channel.
struct ast_sip_endpoint * endpoint
const char * ast_stream_to_str(const struct ast_stream *stream, struct ast_str **buf)
Get a string representing the stream for debugging/display purposes.
Definition: stream.c:337
ast_rtp_options
Definition: rtp_engine.h:142
static int video_info_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
int(* set_configuration)(struct ast_rtp_instance *instance, const struct ast_rtp_dtls_cfg *dtls_cfg)
Definition: rtp_engine.h:572
static void enable_rtcp(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *remote_media)
Enable RTCP on an RTP session.
enum ast_media_type ast_format_get_type(const struct ast_format *format)
Get the media type of a format.
Definition: format.c:354
static const char name[]
Definition: format_mp3.c:68
Asterisk main include file. File version handling, generic pbx functions.
unsigned int ast_format_cap_get_framing(const struct ast_format_cap *cap)
Get the global framing.
Definition: format_cap.c:438
#define ast_sip_transport_is_nonlocal(transport_state, addr)
Definition: res_pjsip.h:162
static char * ast_sockaddr_stringify_addr_remote(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:317
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1227
unsigned int locally_held
Stream is on hold by local side.
int ast_rtp_instance_extmap_get_id(struct ast_rtp_instance *instance, enum ast_rtp_extension extension)
Retrieve the id for an RTP extension.
Definition: rtp_engine.c:886
int ast_rtp_codecs_payload_replace_format(struct ast_rtp_codecs *codecs, int payload, struct ast_format *format)
Update the format associated with a tx payload type in a codecs structure.
Definition: rtp_engine.c:1503
void ast_rtp_instance_set_channel_id(struct ast_rtp_instance *instance, const char *uniqueid)
Set the channel that owns this RTP instance.
Definition: rtp_engine.c:553
struct ast_sip_session_media_state * pending_media_state
struct ast_sockaddr direct_media_addr
Direct media address.
struct ast_format_cap * ast_sip_session_create_joint_call_cap(const struct ast_sip_session *session, enum ast_media_type media_type, const struct ast_format_cap *remote)
Create joint capabilities.
ast_sip_session_media_encryption
Definition: res_pjsip.h:504
int ast_rtp_instance_dtmf_mode_set(struct ast_rtp_instance *instance, enum ast_rtp_dtmf_mode dtmf_mode)
Set the DTMF mode that should be used.
Definition: rtp_engine.c:2123
static int create_rtp(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const pjmedia_sdp_session *sdp)
Internal function which creates an RTP instance.
#define AST_UUID_STR_LEN
Definition: uuid.h:27
void ast_rtp_instance_change_source(struct ast_rtp_instance *instance)
Indicate a new source of audio has dropped in and the ssrc should change.
Definition: rtp_engine.c:2160
const char *(* get_password)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:497
int ast_rtp_instance_get_stats(struct ast_rtp_instance *instance, struct ast_rtp_instance_stats *stats, enum ast_rtp_instance_stat stat)
Retrieve statistics about an RTP instance.
Definition: rtp_engine.c:2446
const char *(* get_fingerprint)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:590
media_type
Media types generate different "dummy answers" for not accepting the offer of a media stream...
Definition: sip.h:489
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp_media *stream, struct ast_rtp_codecs *codecs, struct ast_sip_session_media *session_media)
int ast_stream_get_group(const struct ast_stream *stream)
Get the stream group that a stream is part of.
Definition: stream.c:1077
static uint32_t keepalive
Definition: res_pktccops.c:162
struct ast_sip_session_media * ast_sip_session_media_get_transport(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
Retrieve the underlying media session that is acting as transport for a media session.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2949
struct ast_rtp_dtls_cfg dtls_cfg
DTLS-SRTP configuration information.
Definition: res_pjsip.h:707
int ast_rtp_instance_bundle(struct ast_rtp_instance *child, struct ast_rtp_instance *parent)
Request that an RTP instance be bundled with another.
Definition: rtp_engine.c:3804
const ast_string_field transport
Definition: res_pjsip.h:817
static int parse_dtls_attrib(struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream)
size_t ast_rtp_instance_extmap_count(struct ast_rtp_instance *instance)
Get the number of known unique identifiers.
Definition: rtp_engine.c:899
char * address
Definition: f2c.h:59
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1770
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
static struct ast_format_cap * set_incoming_call_offer_cap(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *stream)
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Definition: channel.c:1212
int ast_rtp_instance_get_timeout(struct ast_rtp_instance *instance)
Get the RTP timeout value.
Definition: rtp_engine.c:2685
Convenient Signal Processing routines.
static struct ast_frame * media_session_rtcp_read_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
static void apply_dtls_attrib(struct ast_sip_session_media *session_media, pjmedia_sdp_attr *attr)
enum ast_media_type ast_stream_get_type(const struct ast_stream *stream)
Get the media type of a stream.
Definition: stream.c:316
#define ast_set_flag(p, flag)
Definition: utils.h:70
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:727
#define LOG_WARNING
Definition: logger.h:274
static int setup_sdes_srtp(struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *stream)
#define AST_RTP_PT_LAST_STATIC
Definition: rtp_engine.h:89
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
static void check_ice_support(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *remote_stream)
Function which checks for ice attributes in an audio stream.
static int tmp()
Definition: bt_open.c:389
A handler for SDPs in SIP sessions.
const char * ast_codec_media_type2str(enum ast_media_type type)
Conversion function to take a media type and turn it into a string.
Definition: codec.c:347
static struct ast_sched_context * sched
Scheduler for RTCP purposes.
static int load_module(void)
Load the module.
pj_str_t transport
The media transport in use for this stream.
int ast_rtp_instance_set_qos(struct ast_rtp_instance *instance, int tos, int cos, const char *desc)
Set QoS parameters on an RTP session.
Definition: rtp_engine.c:2169
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
Definition: rtp_engine.c:568
unsigned int asymmetric_rtp_codec
Definition: res_pjsip.h:891
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
void ast_rtp_codecs_payloads_xover(struct ast_rtp_codecs *src, struct ast_rtp_codecs *dest, struct ast_rtp_instance *instance)
Crossover copy the tx payload mapping of src to the rx payload mapping of dest.
Definition: rtp_engine.c:1257
struct ast_format_cap * codecs
Definition: res_pjsip.h:770
Set when the stream has been removed/declined.
Definition: stream.h:78
int ast_sdp_crypto_process(struct ast_rtp_instance *rtp, struct ast_sdp_srtp *srtp, const char *attr)
Parse the a=crypto line from SDP and set appropriate values on the ast_sdp_crypto struct...
Definition: sdp_srtp.c:79
int ast_sched_add_variable(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data, int variable) attribute_warn_unused_result
Adds a scheduled event with rescheduling support.
Definition: sched.c:524
struct ast_rtp_engine_ice * ast_rtp_instance_get_ice(struct ast_rtp_instance *instance)
Obtain a pointer to the ICE support present on an RTP instance.
Definition: rtp_engine.c:2891
const ast_string_field address
Definition: res_pjsip.h:758
void(* change_components)(struct ast_rtp_instance *instance, int num_components)
Definition: rtp_engine.h:509
void(* add_remote_candidate)(struct ast_rtp_instance *instance, const struct ast_rtp_engine_ice_candidate *candidate)
Definition: rtp_engine.h:489
Definition of a media format.
Definition: format.c:43
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
static int add_crypto_to_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media)
void ast_rtp_instance_extmap_clear(struct ast_rtp_instance *instance)
Clear negotiated RTP extension information.
Definition: rtp_engine.c:862
static const char STR_VIDEO[]
char * ast_sdp_get_rtp_profile(unsigned int sdes_active, struct ast_rtp_instance *instance, unsigned int using_avpf, unsigned int force_avp)
Get the RTP profile in use by a media session.
Definition: sdp_srtp.c:103
static int setup_dtls_srtp(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
ast_rtp_extension
Known RTP extensions.
Definition: rtp_engine.h:542
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition: format_cap.c:395
struct ast_format * ast_format_cap_get_best_by_type(const struct ast_format_cap *cap, enum ast_media_type type)
Get the most preferred format for a particular media type.
Definition: format_cap.c:417
void ast_rtp_instance_set_timeout(struct ast_rtp_instance *instance, int timeout)
Set the RTP timeout value.
Definition: rtp_engine.c:2670
#define ast_assert(a)
Definition: utils.h:710
Set when the stream is not sending OR receiving media.
Definition: stream.h:94
#define ast_str_alloca(init_len)
Definition: strings.h:800
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
char mslabel[AST_UUID_STR_LEN]
Media stream label.
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:5240
void ast_rtp_codecs_set_framing(struct ast_rtp_codecs *codecs, unsigned int framing)
Set the framing used for a set of codecs.
Definition: rtp_engine.c:1558
#define AST_RTP_CODECS_NULL_INIT
Definition: rtp_engine.h:716
static void stream_destroy(struct ast_sip_session_media *session_media)
Function which destroys the RTP instance when session ends.
void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement)
Unregister a an supplement to SIP session processing.
Definition: pjsip_session.c:63
static int setup_media_encryption(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream)
void(* stop)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:493
#define NULL
Definition: resample.c:96
char * end
Definition: eagi_proxy.c:73
int value
Definition: syslog.c:37
struct pjsip_inv_session * inv_session
void ast_stream_set_formats(struct ast_stream *stream, struct ast_format_cap *caps)
Set the current negotiated formats of a stream.
Definition: stream.c:365
Structure for an ICE candidate.
Definition: rtp_engine.h:474
Socket address structure.
Definition: netsock2.h:97
void ast_rtp_instance_set_stream_num(struct ast_rtp_instance *instance, int stream_num)
Set the stream number for an RTP instance.
Definition: rtp_engine.c:3830
A structure describing a SIP session.
enum ast_rtp_dtls_hash(* get_fingerprint_hash)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:588
static struct ast_sockaddr address_rtp
Address for RTP.
static void enable_rtp_extension(struct ast_sip_session *session, struct ast_sip_session_media *session_media, enum ast_rtp_extension extension, enum ast_rtp_extension_direction direction, const pjmedia_sdp_session *sdp)
Enable an RTP extension on an RTP session.
unsigned int ast_rtp_codecs_get_framing(struct ast_rtp_codecs *codecs)
Get the framing used for a set of codecs.
Definition: rtp_engine.c:1569
enum ast_rtp_dtls_setup(* get_setup)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:582
unsigned int use_received_transport
Definition: res_pjsip.h:705
struct ast_format_cap * direct_media_cap
enum ast_sip_session_media_encryption encryption
What type of encryption is in use on this stream.
Media Stream API.
static int unload_module(void)
Unloads the sdp RTP/AVP module from Asterisk.
static void process_ice_auth_attrb(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream)
const char * ast_rtp_instance_get_channel_id(struct ast_rtp_instance *instance)
Get the unique ID of the channel that owns this RTP instance.
Definition: rtp_engine.c:548
unsigned int bundled
Whether this stream is currently bundled or not.
Utility functions.
Media Format API.
struct ast_sip_session_media_state * active_media_state
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition: sorcery.c:1853
const char * ast_sip_get_host_ip_string(int af)
Retrieve the local host address in string form.
Definition: res_pjsip.c:5473
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
int ast_rtp_instance_extmap_enable(struct ast_rtp_instance *instance, int id, enum ast_rtp_extension extension, enum ast_rtp_extension_direction direction)
Enable support for an RTP extension on an instance.
Definition: rtp_engine.c:732
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
struct ast_dsp * dsp
enum ast_rtp_ice_candidate_type type
Definition: rtp_engine.h:481
static struct ast_sip_session_sdp_handler video_sdp_handler
SDP handler for &#39;video&#39; media stream.
enum ast_rtp_dtls_connection(* get_connection)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:580
#define AST_RTP_MAX
Definition: rtp_engine.h:272
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
ast_rtp_instance_rtcp
Definition: rtp_engine.h:255
static char * ast_sockaddr_stringify_port(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return a port only.
Definition: netsock2.h:362
static struct ast_sockaddr media_address
Definition: chan_sip.c:1136
static int apply_negotiated_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_session *remote, int index, struct ast_stream *asterisk_stream)
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
static pjmedia_sdp_attr * generate_fmtp_attr(pj_pool_t *pool, struct ast_format *format, int rtp_code)
#define ast_log
Definition: astobj2.c:42
int ast_sockaddr_is_any(const struct ast_sockaddr *addr)
Determine if the address type is unspecified, or "any" address.
Definition: netsock2.c:534
struct ast_format * ast_rtp_codecs_get_payload_format(struct ast_rtp_codecs *codecs, int payload)
Retrieve the actual ast_format stored on the codecs structure for a specific tx payload type...
Definition: rtp_engine.c:1537
int ast_dsp_get_features(struct ast_dsp *dsp)
Get features.
Definition: dsp.c:1764
void ast_rtp_instance_stop(struct ast_rtp_instance *instance)
Stop an RTP instance.
Definition: rtp_engine.c:2183
Structure for SIP transport information.
Definition: res_pjsip.h:87
static int rtp_check_timeout(const void *data)
Check whether RTP is being received or not.
General Asterisk PBX channel definitions.
int ast_sip_session_register_sdp_handler(struct ast_sip_session_sdp_handler *handler, const char *stream_type)
Register an SDP handler.
const char * ast_rtp_lookup_mime_subtype2(const int asterisk_format, const struct ast_format *format, int code, enum ast_rtp_options options)
Retrieve mime subtype information on a payload.
Definition: rtp_engine.c:1992
#define AST_SCHED_DEL(sched, id)
Remove a scheduler entry.
Definition: sched.h:46
int ast_sip_session_is_pending_stream_default(const struct ast_sip_session *session, const struct ast_stream *stream)
Determines if a provided pending stream will be the default stream or not.
SRTP and SDP Security descriptions.
int ast_check_ipv6(void)
Test that an OS supports IPv6 Networking.
Definition: main/utils.c:2540
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5766
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, int asterisk_format, struct ast_format *format, int code)
Retrieve a rx mapped payload type based on whether it is an Asterisk format and the code...
Definition: rtp_engine.c:1873
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
#define ast_debug_rtp(sublevel,...)
Log debug level RTP information.
Definition: rtp_engine.h:2860
static struct ast_mansession session
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
void ast_rtp_instance_set_remote_ssrc(struct ast_rtp_instance *rtp, unsigned int ssrc)
Set the remote SSRC for an RTP instance.
Definition: rtp_engine.c:3821
Access Control of various sorts.
static struct ao2_container * codecs
Registered codecs.
Definition: codec.c:48
static int media_session_rtp_write_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct ast_frame *frame)
void(* set_fingerprint)(struct ast_rtp_instance *instance, enum ast_rtp_dtls_hash hash, const char *fingerprint)
Definition: rtp_engine.h:586
Scheduler Routines (derived from cheops)
const ast_string_field engine
Definition: res_pjsip.h:691
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:764
structure to hold extensions
#define ao2_ref(o, delta)
Definition: astobj2.h:464
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2472
static struct ast_sip_session_supplement video_info_supplement
#define AST_SRTP_CRYPTO_OFFER_OK
Definition: sdp_srtp.h:44
static void process_extmap_attributes(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *remote_stream)
Function which processes extmap attributes in a stream.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
struct ast_channel * channel
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
struct ast_sdp_crypto * crypto
Definition: sdp_srtp.h:39
A set of macros to manage forward-linked lists.
int ast_rtp_instance_extmap_negotiate(struct ast_rtp_instance *instance, int id, enum ast_rtp_extension_direction direction, const char *uri, const char *attributes)
Negotiate received RTP extension information.
Definition: rtp_engine.c:818
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition: channel.c:5807
struct ast_sdp_srtp * srtp
Holds SRTP information.
void ast_channel_set_unbridged_nolock(struct ast_channel *chan, int value)
Variant of ast_channel_set_unbridged. Use this if the channel is already locked prior to calling...
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)
Function which adds ssrc attributes to a media stream.
const struct ast_format_cap * ast_stream_get_formats(const struct ast_stream *stream)
Get the current negotiated formats of a stream.
Definition: stream.c:330
An entity with which Asterisk communicates.
Definition: res_pjsip.h:812
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
Queue a hold frame.
Definition: channel.c:1187
void ast_sip_session_unregister_sdp_handler(struct ast_sip_session_sdp_handler *handler, const char *stream_type)
Unregister an SDP handler.
struct ast_sdp_srtp::@305 sdp_srtp_list
static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const pjmedia_sdp_session *sdp, int index, struct ast_stream *asterisk_stream)
Function which negotiates an incoming media stream.
struct ast_sockaddr relay_address
Definition: rtp_engine.h:480
Network socket handling.
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1135
Structure that represents the optional DTLS SRTP support within an RTP engine.
Definition: rtp_engine.h:570
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition: format_cap.c:525
static pjmedia_sdp_attr * generate_rtpmap_attr(struct ast_sip_session *session, pjmedia_sdp_media *media, pj_pool_t *pool, int rtp_code, int asterisk_format, struct ast_format *format, int code)
Format Capabilities API.
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:236
int ast_sip_is_content_type(pjsip_media_type *content_type, char *type, char *subtype)
Checks if the given content type matches type/subtype.
Definition: res_pjsip.c:5259
const char * ast_channel_uniqueid(const struct ast_channel *chan)
ast_rtp_dtls_setup
DTLS setup types.
Definition: rtp_engine.h:513
enum ast_sip_session_media_encryption encryption
Definition: res_pjsip.h:711
int stream_num
The stream number to place into any resulting frames.
const char *(* get_ufrag)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:495
unsigned int enabled
Definition: rtp_engine.h:555
enum ast_rtp_dtls_setup default_setup
Definition: rtp_engine.h:557
time_t ast_rtp_instance_get_last_tx(const struct ast_rtp_instance *rtp)
Get the last RTP transmission time.
Definition: rtp_engine.c:3758
void(* set_authentication)(struct ast_rtp_instance *instance, const char *ufrag, const char *password)
Definition: rtp_engine.h:487
#define LOG_ERROR
Definition: logger.h:285
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
struct ao2_container *(* get_local_candidates)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:499
static void stream_stop(struct ast_sip_session_media *session_media)
Function which stops the RTP instance.
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
struct ast_rtp_engine_dtls * ast_rtp_instance_get_dtls(struct ast_rtp_instance *instance)
Obtain a pointer to the DTLS support present on an RTP instance.
Definition: rtp_engine.c:3011
ast_rtp_extension_direction
Directions for RTP extensions.
Definition: rtp_engine.h:769
enum ast_rtp_extension_direction ast_rtp_instance_extmap_get_direction(struct ast_rtp_instance *instance, int id)
Retrieve the negotiated direction for an RTP extension id.
Definition: rtp_engine.c:930
void(* set_role)(struct ast_rtp_instance *instance, enum ast_rtp_ice_role role)
Definition: rtp_engine.h:503
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
int ast_rtp_instance_sendcng(struct ast_rtp_instance *instance, int level)
Send a comfort noise packet to the RTP instance.
Definition: rtp_engine.c:2772
static struct ast_sip_session_sdp_handler audio_sdp_handler
SDP handler for &#39;audio&#39; media stream.
Transport to bind to.
Definition: res_pjsip.h:171
#define ast_rtp_instance_set_remote_address(instance, address)
Set the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1080
enum ast_sip_dtmf_mode dtmf
enum ast_rtp_ice_component_type id
Definition: rtp_engine.h:476
unsigned int ast_rtp_instance_get_ssrc(struct ast_rtp_instance *rtp)
Retrieve the local SSRC value that we will be using.
Definition: rtp_engine.c:3778
static void change_outgoing_sdp_stream_media_address(pjsip_tx_data *tdata, struct pjmedia_sdp_media *stream, struct ast_sip_transport *transport)
Function which updates the media stream with external media address, if applicable.
#define ast_strndup(str, len)
A wrapper for strndup()
Definition: astmm.h:258
static enum ast_sip_session_media_encryption get_media_encryption_type(pj_str_t transport, const struct pjmedia_sdp_media *stream, unsigned int *optimistic)
figure out media transport encryption type from the media transport string
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
char * ast_sockaddr_stringify_fmt(const struct ast_sockaddr *addr, int format)
Convert a socket address to a string.
Definition: netsock2.c:65
#define LOG_NOTICE
Definition: logger.h:263
static void process_ssrc_attributes(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *remote_stream)
Function which processes ssrc attributes in a stream.
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
void(* reset)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:578
ast_rtp_dtls_hash
DTLS fingerprint hashes.
Definition: rtp_engine.h:527
unsigned int remotely_held
Stream is on hold by remote side.
#define SCOPE_EXIT_RTN(...)
Definition: logger.h:905
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10669
unsigned int preferred_codec_only
Definition: res_pjsip.h:889
#define ast_channel_unlock(chan)
Definition: channel.h:2914
#define ast_debug_ice(sublevel,...)
Log debug level ICE information.
Definition: rtp_engine.h:2898
int timeout_sched_id
Scheduler ID for RTP timeout.
Set when the stream is sending media only.
Definition: stream.h:86
struct ast_sip_transport_state * ast_sip_get_transport_state(const char *transport_id)
Retrieve transport state.
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1755
unsigned int ast_rtp_lookup_sample_rate2(int asterisk_format, const struct ast_format *format, int code)
Get the sample rate associated with known RTP payload types.
Definition: rtp_engine.c:2022
static struct ast_frame * media_session_rtp_read_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
#define ast_free(a)
Definition: astmm.h:182
void(* start)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:491
static int setup_srtp(struct ast_sip_session_media *session_media)
int ast_sip_session_media_add_read_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media, int fd, ast_sip_session_media_read_cb callback)
Set a read callback for a media session with a specific file descriptor.
time_t ast_rtp_instance_get_last_rx(const struct ast_rtp_instance *rtp)
Definition: rtp_engine.c:3768
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, unsigned int include_candidates)
Function which adds ICE attributes to a media stream.
void ast_stream_set_state(struct ast_stream *stream, enum ast_stream_state state)
Set the state of a stream.
Definition: stream.c:380
void(* set_setup)(struct ast_rtp_instance *instance, enum ast_rtp_dtls_setup setup)
Definition: rtp_engine.h:584
struct ast_sdp_srtp * ast_sdp_srtp_alloc(void)
allocate a ast_sdp_srtp structure
Definition: sdp_srtp.c:41
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
Definition: uuid.c:143
#define SCOPE_ENTER(level,...)
Definition: logger.h:890
struct ast_sdp_crypto * ast_sdp_crypto_alloc(void)
Initialize an return an ast_sdp_crypto struct.
Definition: sdp_srtp.c:71
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
Get the file descriptor for an RTP session (or RTCP)
Definition: rtp_engine.c:2192
const char * ast_rtp_instance_extmap_get_uri(struct ast_rtp_instance *instance, int id)
Retrieve the URI for an RTP extension id.
Definition: rtp_engine.c:946
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
int bundle_group
The bundle group the stream belongs to.
int keepalive_sched_id
Scheduler ID for RTP keepalive.
A structure containing SIP session media information.
void ast_rtp_codecs_payloads_destroy(struct ast_rtp_codecs *codecs)
Destroy the contents of an RTP codecs structure (but not the structure itself)
Definition: rtp_engine.c:974
void ast_rtp_instance_get_local_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the local address that we are expecting RTP on.
Definition: rtp_engine.c:643
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
Definition: rtp_engine.c:458
static int send_keepalive(const void *data)
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
void ast_rtp_instance_set_keepalive(struct ast_rtp_instance *instance, int timeout)
Set the RTP keepalive interval.
Definition: rtp_engine.c:2680
static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_session *remote, struct ast_stream *stream)
Function which creates an outgoing stream.
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
A supplement to SIP message processing.
struct ast_frame ast_null_frame
Definition: main/frame.c:79
void ast_rtp_codecs_payloads_copy(struct ast_rtp_codecs *src, struct ast_rtp_codecs *dest, struct ast_rtp_instance *instance)
Copy payload information from one RTP instance to another.
Definition: rtp_engine.c:1224
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Definition: logger.h:909
static enum ast_sip_session_media_encryption check_endpoint_media_transport(struct ast_sip_endpoint *endpoint, const struct pjmedia_sdp_media *stream)
Checks whether the encryption offered in SDP is compatible with the endpoint&#39;s configuration.
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
#define AST_CAUSE_REQUESTED_CHAN_UNAVAIL
Definition: causes.h:124
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
enum ast_media_type type
Media type of this session media.
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
int ast_rtp_codecs_payloads_initialize(struct ast_rtp_codecs *codecs)
Initialize an RTP codecs structure.
Definition: rtp_engine.c:958
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
unsigned int changed
The underlying session has been changed in some fashion.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
unsigned int remotely_held_changed
Stream is held by remote side changed during this negotiation.
struct ast_rtp_instance * rtp
RTP instance itself.
const char * ast_channel_name(const struct ast_channel *chan)
#define AST_SOCKADDR_STR_ADDR
Definition: netsock2.h:202
static void set_ice_components(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
const ast_string_field mohsuggest
Definition: res_pjsip.h:823
unsigned int ast_format_get_maximum_ms(const struct ast_format *format)
Get the maximum amount of media carried in this format.
Definition: format.c:369
int ast_stream_set_metadata(struct ast_stream *stream, const char *m_key, const char *value)
Set a stream metadata value.
Definition: stream.c:460
const char * ast_stream_get_metadata(const struct ast_stream *stream, const char *m_key)
Get a stream metadata value.
Definition: stream.c:423
static void set_session_media_remotely_held(struct ast_sip_session_media *session_media, const struct ast_sip_session *session, const pjmedia_sdp_media *media, const struct ast_stream *stream, const struct ast_sockaddr *addrs)
int ast_rtp_codecs_payloads_set_rtpmap_type_rate(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int pt, char *mimetype, char *mimesubtype, enum ast_rtp_options options, unsigned int sample_rate)
Set tx payload type to a known MIME media type for a codec with a specific sample rate...
Definition: rtp_engine.c:1343
enum ast_rtp_dtmf_mode ast_rtp_instance_dtmf_mode_get(struct ast_rtp_instance *instance)
Get the DTMF mode of an RTP instance.
Definition: rtp_engine.c:2137
static void add_msid_to_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media, struct ast_stream *stream)
Data structure associated with a single frame of data.
int ast_sip_session_media_set_write_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media, ast_sip_session_media_write_cb callback)
Set a write callback for a media session.
int ast_rtp_instance_get_keepalive(struct ast_rtp_instance *instance)
Get the RTP keepalive interval.
Definition: rtp_engine.c:2695
Internal Asterisk hangup causes.
enum ast_srtp_suite suite
Definition: rtp_engine.h:558
Structure that represents the optional ICE support within an RTP engine.
Definition: rtp_engine.h:485
int ast_rtp_codecs_payload_set_rx(struct ast_rtp_codecs *codecs, int code, struct ast_format *format)
Set a payload code for use with a specific Asterisk format.
Definition: rtp_engine.c:1923
void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
Set the value of an RTP instance property.
Definition: rtp_engine.c:705
enum queue_result id
Definition: app_queue.c:1513
ast_media_type
Types of media.
Definition: codec.h:30
char label[AST_UUID_STR_LEN]
Track label.
unsigned int remote_rtcp_mux
Does remote support rtcp_mux.
int ast_format_cap_empty(const struct ast_format_cap *cap)
Determine if a format cap has no formats in it.
Definition: format_cap.c:746
struct ast_sockaddr address
Definition: rtp_engine.h:479
Generic container type.
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
struct ast_format * ast_format_parse_sdp_fmtp(const struct ast_format *format, const char *attributes)
This function is used to have a media format aware module parse and interpret SDP attribute informati...
Definition: format.c:286
static struct test_options options
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition: format_cap.c:400
const char * ast_sdp_srtp_get_attrib(struct ast_sdp_srtp *srtp, int dtls_enabled, int default_taglen_32)
Get the crypto attribute line for the srtp structure.
Definition: sdp_srtp.c:95
struct ast_rtp_instance * ast_rtp_instance_new(const char *engine_name, struct ast_sched_context *sched, const struct ast_sockaddr *sa, void *data)
Create a new RTP instance.
Definition: rtp_engine.c:465
int ast_stream_get_position(const struct ast_stream *stream)
Get the position of the stream in the topology.
Definition: stream.c:500
#define AST_RTP_DTMF
Definition: rtp_engine.h:266
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
direction
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1450
Pluggable RTP Architecture.
Asterisk module definitions.
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
static const char STR_AUDIO[]
void ast_format_generate_sdp_fmtp(const struct ast_format *format, unsigned int payload, struct ast_str **str)
This function is used to produce an fmtp SDP line for an Asterisk format. The attributes present on t...
Definition: format.c:305
const char * ast_rtp_instance_get_cname(struct ast_rtp_instance *rtp)
Retrieve the CNAME used in RTCP SDES items.
Definition: rtp_engine.c:3791
int ast_format_cap_get_compatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2, struct ast_format_cap *result)
Find the compatible formats between two capabilities structures.
Definition: format_cap.c:630
static snd_pcm_format_t format
Definition: chan_alsa.c:106
enum ast_rtp_extension ast_rtp_instance_extmap_get_extension(struct ast_rtp_instance *instance, int id)
Retrieve the extension for an RTP extension id.
Definition: rtp_engine.c:910
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ast_rtp_codecs_payloads_set_m_type(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload)
Record tx payload type information that was seen in an m= SDP line.
Definition: rtp_engine.c:1301
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
Definition: sched.c:269
Set when the stream is receiving media only.
Definition: stream.h:90
enum ast_stream_state ast_stream_get_state(const struct ast_stream *stream)
Get the current state of a stream.
Definition: stream.c:373
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
int ast_format_cap_has_type(const struct ast_format_cap *cap, enum ast_media_type type)
Find out if the capabilities structure has any formats of a specific type.
Definition: format_cap.c:615
void ast_rtp_instance_set_last_rx(struct ast_rtp_instance *rtp, time_t time)
Set the last RTP reception time.
Definition: rtp_engine.c:3773
static int set_caps(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct ast_sip_session_media *session_media_transport, const struct pjmedia_sdp_media *stream, int is_offer, struct ast_stream *asterisk_stream)
static void add_rtcp_fb_to_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media)
struct ast_frame * ast_rtp_instance_read(struct ast_rtp_instance *instance, int rtcp)
Receive a frame over RTP.
Definition: rtp_engine.c:578
Media Format Cache API.
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
unsigned int remote_ssrc
Definition: rtp_engine.h:424
int ast_sockaddr_resolve(struct ast_sockaddr **addrs, const char *str, int flags, int family)
Parses a string with an IPv4 or IPv6 address and place results into an array.
Definition: netsock2.c:280
#define ast_sip_session_register_supplement(supplement)
unsigned int remote_ice
Does remote support ice.
void(* ice_lite)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:501
static int media_stream_has_crypto(const struct pjmedia_sdp_media *stream)
figure out if media stream has crypto lines for sdes
static void add_extmap_to_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media)
static void process_ice_attributes(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream)
Function which processes ICE attributes in an audio stream.