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