Asterisk - The Open Source Telephony Project  GIT-master-a24979a
res_pjsip_sdp_rtp.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Joshua Colp <jcolp@digium.com>
7  * Kevin Harwell <kharwell@digium.com>
8  *
9  * See http://www.asterisk.org for more information about
10  * the Asterisk project. Please do not directly contact
11  * any of the maintainers of this project for assistance;
12  * the project provides a web site, mailing lists and IRC
13  * channels for your use.
14  *
15  * This program is free software, distributed under the terms of
16  * the GNU General Public License Version 2. See the LICENSE file
17  * at the top of the source tree.
18  */
19 
20 /*! \file
21  *
22  * \author Joshua Colp <jcolp@digium.com>
23  *
24  * \brief SIP SDP media stream handling
25  */
26 
27 /*** MODULEINFO
28  <depend>pjproject</depend>
29  <depend>res_pjsip</depend>
30  <depend>res_pjsip_session</depend>
31  <support_level>core</support_level>
32  ***/
33 
34 #include "asterisk.h"
35 
36 #include <pjsip.h>
37 #include <pjsip_ua.h>
38 #include <pjmedia.h>
39 #include <pjlib.h>
40 
41 #include "asterisk/utils.h"
42 #include "asterisk/module.h"
43 #include "asterisk/format.h"
44 #include "asterisk/format_cap.h"
45 #include "asterisk/rtp_engine.h"
46 #include "asterisk/netsock2.h"
47 #include "asterisk/channel.h"
48 #include "asterisk/causes.h"
49 #include "asterisk/sched.h"
50 #include "asterisk/acl.h"
51 #include "asterisk/sdp_srtp.h"
52 #include "asterisk/dsp.h"
53 #include "asterisk/linkedlists.h" /* for AST_LIST_NEXT */
54 #include "asterisk/stream.h"
56 #include "asterisk/format_cache.h"
57 
58 #include "asterisk/res_pjsip.h"
61 
62 /*! \brief Scheduler for RTCP purposes */
63 static struct ast_sched_context *sched;
64 
65 /*! \brief Address for RTP */
66 static struct ast_sockaddr address_rtp;
67 
68 static const char STR_AUDIO[] = "audio";
69 static const char STR_VIDEO[] = "video";
70 
71 static int send_keepalive(const void *data)
72 {
73  struct ast_sip_session_media *session_media = (struct ast_sip_session_media *) data;
74  struct ast_rtp_instance *rtp = session_media->rtp;
75  int keepalive;
76  time_t interval;
77  int send_keepalive;
78 
79  if (!rtp) {
80  return 0;
81  }
82 
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);
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 
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;
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 
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 
275  ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_NAT, session->endpoint->media.rtp.symmetric);
276  ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_ASYMMETRIC_CODEC, session->endpoint->asymmetric_rtp_codec);
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 
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) {
294  ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_RETRANS_RECV, session->endpoint->media.webrtc);
295  ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_RETRANS_SEND, session->endpoint->media.webrtc);
296  ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_REMB, session->endpoint->media.webrtc);
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 ?
326 
328 
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 
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) {
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 
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;
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  */
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;
502  int direct_media_enabled = !ast_sockaddr_isnull(&session_media->direct_media_addr) &&
503  ast_format_cap_count(session->direct_media_cap);
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) {
518  ast_format_cap_get_compatible(session->endpoint->media.codecs, session->direct_media_cap, caps);
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)) {
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  }
542 
543  if (is_offer) {
544  /*
545  * Setup rx payload type mapping to prefer the mapping
546  * from the peer that the RFC says we SHOULD use.
547  */
549  }
551  session_media->rtp);
552 
553  apply_cap_to_bundled(session_media, session_media_transport, asterisk_stream, joint);
554 
555  if (session->channel && ast_sip_session_is_pending_stream_default(session, asterisk_stream)) {
556  ast_channel_lock(session->channel);
561 
562  if (session->endpoint->preferred_codec_only){
563  struct ast_format *preferred_fmt = ast_format_cap_get_format(joint, 0);
564  ast_format_cap_append(caps, preferred_fmt, 0);
565  ao2_ref(preferred_fmt, -1);
566  } else if (!session->endpoint->asymmetric_rtp_codec) {
567  struct ast_format *best;
568  /*
569  * If we don't allow the sending codec to be changed on our side
570  * then get the best codec from the joint capabilities of the media
571  * type and use only that. This ensures the core won't start sending
572  * out a format that we aren't currently sending.
573  */
574 
576  if (best) {
578  ao2_ref(best, -1);
579  }
580  } else {
582  }
583 
584  /*
585  * Apply the new formats to the channel, potentially changing
586  * raw read/write formats and translation path while doing so.
587  */
588  ast_channel_nativeformats_set(session->channel, caps);
592  }
593 
594  if ( ((session->dtmf == AST_SIP_DTMF_AUTO) || (session->dtmf == AST_SIP_DTMF_AUTO_INFO) )
596  && (session->dsp)) {
597  dsp_features = ast_dsp_get_features(session->dsp);
598  dsp_features &= ~DSP_FEATURE_DIGIT_DETECT;
599  if (dsp_features) {
600  ast_dsp_set_features(session->dsp, dsp_features);
601  } else {
602  ast_dsp_free(session->dsp);
603  session->dsp = NULL;
604  }
605  }
606 
607  if (ast_channel_is_bridged(session->channel)) {
609  }
610 
611  ast_channel_unlock(session->channel);
612  }
613 
616 }
617 
618 static pjmedia_sdp_attr* generate_rtpmap_attr(struct ast_sip_session *session, pjmedia_sdp_media *media, pj_pool_t *pool,
619  int rtp_code, int asterisk_format, struct ast_format *format, int code)
620 {
621 #ifndef HAVE_PJSIP_ENDPOINT_COMPACT_FORM
622  extern pj_bool_t pjsip_use_compact_form;
623 #else
624  pj_bool_t pjsip_use_compact_form = pjsip_cfg()->endpt.use_compact_form;
625 #endif
626  pjmedia_sdp_rtpmap rtpmap;
627  pjmedia_sdp_attr *attr = NULL;
628  char tmp[64];
629  enum ast_rtp_options options = session->endpoint->media.g726_non_standard ?
631 
632  snprintf(tmp, sizeof(tmp), "%d", rtp_code);
633  pj_strdup2(pool, &media->desc.fmt[media->desc.fmt_count++], tmp);
634 
635  if (rtp_code <= AST_RTP_PT_LAST_STATIC && pjsip_use_compact_form) {
636  return NULL;
637  }
638 
639  rtpmap.pt = media->desc.fmt[media->desc.fmt_count - 1];
640  rtpmap.clock_rate = ast_rtp_lookup_sample_rate2(asterisk_format, format, code);
641  pj_strdup2(pool, &rtpmap.enc_name, ast_rtp_lookup_mime_subtype2(asterisk_format, format, code, options));
642  if (!pj_stricmp2(&rtpmap.enc_name, "opus")) {
643  pj_cstr(&rtpmap.param, "2");
644  } else {
645  pj_cstr(&rtpmap.param, NULL);
646  }
647 
648  pjmedia_sdp_rtpmap_to_attr(pool, &rtpmap, &attr);
649 
650  return attr;
651 }
652 
653 static pjmedia_sdp_attr* generate_fmtp_attr(pj_pool_t *pool, struct ast_format *format, int rtp_code)
654 {
655  struct ast_str *fmtp0 = ast_str_alloca(256);
656  pj_str_t fmtp1;
657  pjmedia_sdp_attr *attr = NULL;
658  char *tmp;
659 
660  ast_format_generate_sdp_fmtp(format, rtp_code, &fmtp0);
661  if (ast_str_strlen(fmtp0)) {
662  tmp = ast_str_buffer(fmtp0) + ast_str_strlen(fmtp0) - 1;
663  /* remove any carriage return line feeds */
664  while (*tmp == '\r' || *tmp == '\n') --tmp;
665  *++tmp = '\0';
666  /* ast...generate gives us everything, just need value */
667  tmp = strchr(ast_str_buffer(fmtp0), ':');
668  if (tmp && tmp[1] != '\0') {
669  fmtp1 = pj_str(tmp + 1);
670  } else {
671  fmtp1 = pj_str(ast_str_buffer(fmtp0));
672  }
673  attr = pjmedia_sdp_attr_create(pool, "fmtp", &fmtp1);
674  }
675  return attr;
676 }
677 
678 /*! \brief Function which adds ICE attributes to a media stream */
679 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,
680  unsigned int include_candidates)
681 {
682  struct ast_rtp_engine_ice *ice;
683  struct ao2_container *candidates;
684  const char *username, *password;
685  pj_str_t stmp;
686  pjmedia_sdp_attr *attr;
687  struct ao2_iterator it_candidates;
688  struct ast_rtp_engine_ice_candidate *candidate;
689 
690  if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) {
691  return;
692  }
693 
694  if (!session_media->remote_ice) {
695  ice->stop(session_media->rtp);
696  return;
697  }
698 
699  if ((username = ice->get_ufrag(session_media->rtp))) {
700  attr = pjmedia_sdp_attr_create(pool, "ice-ufrag", pj_cstr(&stmp, username));
701  media->attr[media->attr_count++] = attr;
702  }
703 
704  if ((password = ice->get_password(session_media->rtp))) {
705  attr = pjmedia_sdp_attr_create(pool, "ice-pwd", pj_cstr(&stmp, password));
706  media->attr[media->attr_count++] = attr;
707  }
708 
709  if (!include_candidates) {
710  return;
711  }
712 
713  candidates = ice->get_local_candidates(session_media->rtp);
714  if (!candidates) {
715  return;
716  }
717 
718  it_candidates = ao2_iterator_init(candidates, 0);
719  for (; (candidate = ao2_iterator_next(&it_candidates)); ao2_ref(candidate, -1)) {
720  struct ast_str *attr_candidate = ast_str_create(128);
721 
722  ast_str_set(&attr_candidate, -1, "%s %u %s %d %s ", candidate->foundation, candidate->id, candidate->transport,
723  candidate->priority, ast_sockaddr_stringify_addr_remote(&candidate->address));
724  ast_str_append(&attr_candidate, -1, "%s typ ", ast_sockaddr_stringify_port(&candidate->address));
725 
726  switch (candidate->type) {
728  ast_str_append(&attr_candidate, -1, "host");
729  break;
731  ast_str_append(&attr_candidate, -1, "srflx");
732  break;
734  ast_str_append(&attr_candidate, -1, "relay");
735  break;
736  }
737 
738  if (!ast_sockaddr_isnull(&candidate->relay_address)) {
739  ast_str_append(&attr_candidate, -1, " raddr %s rport", ast_sockaddr_stringify_addr_remote(&candidate->relay_address));
740  ast_str_append(&attr_candidate, -1, " %s", ast_sockaddr_stringify_port(&candidate->relay_address));
741  }
742 
743  attr = pjmedia_sdp_attr_create(pool, "candidate", pj_cstr(&stmp, ast_str_buffer(attr_candidate)));
744  media->attr[media->attr_count++] = attr;
745 
746  ast_free(attr_candidate);
747  }
748 
749  ao2_iterator_destroy(&it_candidates);
750  ao2_ref(candidates, -1);
751 }
752 
753 /*! \brief Function which checks for ice attributes in an audio stream */
754 static void check_ice_support(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
755  const struct pjmedia_sdp_media *remote_stream)
756 {
757  struct ast_rtp_engine_ice *ice;
758  const pjmedia_sdp_attr *attr;
759  unsigned int attr_i;
760 
761  if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) {
762  session_media->remote_ice = 0;
763  return;
764  }
765 
766  /* Find all of the candidates */
767  for (attr_i = 0; attr_i < remote_stream->attr_count; ++attr_i) {
768  attr = remote_stream->attr[attr_i];
769  if (!pj_strcmp2(&attr->name, "candidate")) {
770  session_media->remote_ice = 1;
771  break;
772  }
773  }
774 
775  if (attr_i == remote_stream->attr_count) {
776  session_media->remote_ice = 0;
777  }
778 }
779 
780 static void process_ice_auth_attrb(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
781  const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream)
782 {
783  struct ast_rtp_engine_ice *ice;
784  const pjmedia_sdp_attr *ufrag_attr, *passwd_attr;
785  char ufrag_attr_value[256];
786  char passwd_attr_value[256];
787 
788  /* If ICE support is not enabled or available exit early */
789  if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) {
790  return;
791  }
792 
793  ufrag_attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-ufrag", NULL);
794  if (!ufrag_attr) {
795  ufrag_attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-ufrag", NULL);
796  }
797  if (ufrag_attr) {
798  ast_copy_pj_str(ufrag_attr_value, (pj_str_t*)&ufrag_attr->value, sizeof(ufrag_attr_value));
799  } else {
800  return;
801  }
802  passwd_attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-pwd", NULL);
803  if (!passwd_attr) {
804  passwd_attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-pwd", NULL);
805  }
806  if (passwd_attr) {
807  ast_copy_pj_str(passwd_attr_value, (pj_str_t*)&passwd_attr->value, sizeof(passwd_attr_value));
808  } else {
809  return;
810  }
811 
812  if (ufrag_attr && passwd_attr) {
813  ice->set_authentication(session_media->rtp, ufrag_attr_value, passwd_attr_value);
814  }
815 }
816 
817 /*! \brief Function which processes ICE attributes in an audio stream */
818 static void process_ice_attributes(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 *attr;
823  char attr_value[256];
824  unsigned int attr_i;
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  ast_debug_ice(2, "(%p) ICE process attributes\n", session_media->rtp);
832 
833  attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-ufrag", NULL);
834  if (!attr) {
835  attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-ufrag", NULL);
836  }
837  if (attr) {
838  ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
839  ice->set_authentication(session_media->rtp, attr_value, NULL);
840  } else {
841  ast_debug_ice(2, "(%p) ICE no, or invalid ice-ufrag\n", session_media->rtp);
842  return;
843  }
844 
845  attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-pwd", NULL);
846  if (!attr) {
847  attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-pwd", NULL);
848  }
849  if (attr) {
850  ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
851  ice->set_authentication(session_media->rtp, NULL, attr_value);
852  } else {
853  ast_debug_ice(2, "(%p) ICE no, or invalid ice-pwd\n", session_media->rtp);
854  return;
855  }
856 
857  if (pjmedia_sdp_media_find_attr2(remote_stream, "ice-lite", NULL)) {
858  ice->ice_lite(session_media->rtp);
859  }
860 
861  /* Find all of the candidates */
862  for (attr_i = 0; attr_i < remote_stream->attr_count; ++attr_i) {
863  char foundation[33], transport[32], address[PJ_INET6_ADDRSTRLEN + 1], cand_type[6], relay_address[PJ_INET6_ADDRSTRLEN + 1] = "";
864  unsigned int port, relay_port = 0;
865  struct ast_rtp_engine_ice_candidate candidate = { 0, };
866 
867  attr = remote_stream->attr[attr_i];
868 
869  /* If this is not a candidate line skip it */
870  if (pj_strcmp2(&attr->name, "candidate")) {
871  continue;
872  }
873 
874  ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
875 
876  if (sscanf(attr_value, "%32s %30u %31s %30u %46s %30u typ %5s %*s %23s %*s %30u", foundation, &candidate.id, transport,
877  (unsigned *)&candidate.priority, address, &port, cand_type, relay_address, &relay_port) < 7) {
878  /* Candidate did not parse properly */
879  continue;
880  }
881 
882  if (session->endpoint->media.rtcp_mux && session_media->remote_rtcp_mux && candidate.id > 1) {
883  /* Remote side may have offered RTP and RTCP candidates. However, if we're using RTCP MUX,
884  * then we should ignore RTCP candidates.
885  */
886  continue;
887  }
888 
889  candidate.foundation = foundation;
890  candidate.transport = transport;
891 
893  ast_sockaddr_set_port(&candidate.address, port);
894 
895  if (!strcasecmp(cand_type, "host")) {
897  } else if (!strcasecmp(cand_type, "srflx")) {
899  } else if (!strcasecmp(cand_type, "relay")) {
901  } else {
902  continue;
903  }
904 
907  }
908 
909  if (relay_port) {
910  ast_sockaddr_set_port(&candidate.relay_address, relay_port);
911  }
912 
913  ice->add_remote_candidate(session_media->rtp, &candidate);
914  }
915 
916  ice->set_role(session_media->rtp, pjmedia_sdp_neg_was_answer_remote(session->inv_session->neg) == PJ_TRUE ?
918  ice->start(session_media->rtp);
919 }
920 
921 /*! \brief figure out if media stream has crypto lines for sdes */
922 static int media_stream_has_crypto(const struct pjmedia_sdp_media *stream)
923 {
924  int i;
925 
926  for (i = 0; i < stream->attr_count; i++) {
927  pjmedia_sdp_attr *attr;
928 
929  /* check the stream for the required crypto attribute */
930  attr = stream->attr[i];
931  if (pj_strcmp2(&attr->name, "crypto")) {
932  continue;
933  }
934 
935  return 1;
936  }
937 
938  return 0;
939 }
940 
941 /*! \brief figure out media transport encryption type from the media transport string */
943  const struct pjmedia_sdp_media *stream, unsigned int *optimistic)
944 {
945  RAII_VAR(char *, transport_str, ast_strndup(transport.ptr, transport.slen), ast_free);
946 
947  *optimistic = 0;
948 
949  if (!transport_str) {
951  }
952  if (strstr(transport_str, "UDP/TLS")) {
954  } else if (strstr(transport_str, "SAVP")) {
956  } else if (media_stream_has_crypto(stream)) {
957  *optimistic = 1;
959  } else {
961  }
962 }
963 
964 /*!
965  * \brief Checks whether the encryption offered in SDP is compatible with the endpoint's configuration
966  * \internal
967  *
968  * \param endpoint Media encryption configured for the endpoint
969  * \param stream pjmedia_sdp_media stream description
970  *
971  * \retval AST_SIP_MEDIA_TRANSPORT_INVALID on encryption mismatch
972  * \retval The encryption requested in the SDP
973  */
975  struct ast_sip_endpoint *endpoint,
976  const struct pjmedia_sdp_media *stream)
977 {
978  enum ast_sip_session_media_encryption incoming_encryption;
979  char transport_end = stream->desc.transport.ptr[stream->desc.transport.slen - 1];
980  unsigned int optimistic;
981 
982  if ((transport_end == 'F' && !endpoint->media.rtp.use_avpf)
983  || (transport_end != 'F' && endpoint->media.rtp.use_avpf)) {
985  }
986 
987  incoming_encryption = get_media_encryption_type(stream->desc.transport, stream, &optimistic);
988 
989  if (incoming_encryption == endpoint->media.rtp.encryption) {
990  return incoming_encryption;
991  }
992 
993  if (endpoint->media.rtp.force_avp ||
994  endpoint->media.rtp.encryption_optimistic) {
995  return incoming_encryption;
996  }
997 
998  /* If an optimistic offer has been made but encryption is not enabled consider it as having
999  * no offer of crypto at all instead of invalid so the session proceeds.
1000  */
1001  if (optimistic) {
1003  }
1004 
1006 }
1007 
1008 static int setup_srtp(struct ast_sip_session_media *session_media)
1009 {
1010  if (!session_media->srtp) {
1011  session_media->srtp = ast_sdp_srtp_alloc();
1012  if (!session_media->srtp) {
1013  return -1;
1014  }
1015  }
1016 
1017  if (!session_media->srtp->crypto) {
1018  session_media->srtp->crypto = ast_sdp_crypto_alloc();
1019  if (!session_media->srtp->crypto) {
1020  return -1;
1021  }
1022  }
1023 
1024  return 0;
1025 }
1026 
1028  struct ast_sip_session_media *session_media)
1029 {
1030  struct ast_rtp_engine_dtls *dtls;
1031 
1032  if (!session->endpoint->media.rtp.dtls_cfg.enabled || !session_media->rtp) {
1033  return -1;
1034  }
1035 
1036  dtls = ast_rtp_instance_get_dtls(session_media->rtp);
1037  if (!dtls) {
1038  return -1;
1039  }
1040 
1041  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);
1042  if (dtls->set_configuration(session_media->rtp, &session->endpoint->media.rtp.dtls_cfg)) {
1043  ast_log(LOG_ERROR, "Attempted to set an invalid DTLS-SRTP configuration on RTP instance '%p'\n",
1044  session_media->rtp);
1045  return -1;
1046  }
1047 
1048  if (setup_srtp(session_media)) {
1049  return -1;
1050  }
1051  return 0;
1052 }
1053 
1054 static void apply_dtls_attrib(struct ast_sip_session_media *session_media,
1055  pjmedia_sdp_attr *attr)
1056 {
1057  struct ast_rtp_engine_dtls *dtls = ast_rtp_instance_get_dtls(session_media->rtp);
1058  pj_str_t *value;
1059 
1060  if (!attr->value.ptr || !dtls) {
1061  return;
1062  }
1063 
1064  value = pj_strtrim(&attr->value);
1065 
1066  if (!pj_strcmp2(&attr->name, "setup")) {
1067  if (!pj_stricmp2(value, "active")) {
1068  dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_ACTIVE);
1069  } else if (!pj_stricmp2(value, "passive")) {
1070  dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_PASSIVE);
1071  } else if (!pj_stricmp2(value, "actpass")) {
1072  dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_ACTPASS);
1073  } else if (!pj_stricmp2(value, "holdconn")) {
1074  dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_HOLDCONN);
1075  } else {
1076  ast_log(LOG_WARNING, "Unsupported setup attribute value '%*s'\n", (int)value->slen, value->ptr);
1077  }
1078  } else if (!pj_strcmp2(&attr->name, "connection")) {
1079  if (!pj_stricmp2(value, "new")) {
1080  dtls->reset(session_media->rtp);
1081  } else if (!pj_stricmp2(value, "existing")) {
1082  /* Do nothing */
1083  } else {
1084  ast_log(LOG_WARNING, "Unsupported connection attribute value '%*s'\n", (int)value->slen, value->ptr);
1085  }
1086  } else if (!pj_strcmp2(&attr->name, "fingerprint")) {
1087  char hash_value[256], hash[32];
1088  char fingerprint_text[value->slen + 1];
1089  ast_copy_pj_str(fingerprint_text, value, sizeof(fingerprint_text));
1090  if (sscanf(fingerprint_text, "%31s %255s", hash, hash_value) == 2) {
1091  if (!strcasecmp(hash, "sha-1")) {
1092  dtls->set_fingerprint(session_media->rtp, AST_RTP_DTLS_HASH_SHA1, hash_value);
1093  } else if (!strcasecmp(hash, "sha-256")) {
1094  dtls->set_fingerprint(session_media->rtp, AST_RTP_DTLS_HASH_SHA256, hash_value);
1095  } else {
1096  ast_log(LOG_WARNING, "Unsupported fingerprint hash type '%s'\n",
1097  hash);
1098  }
1099  }
1100  }
1101 }
1102 
1103 static int parse_dtls_attrib(struct ast_sip_session_media *session_media,
1104  const struct pjmedia_sdp_session *sdp,
1105  const struct pjmedia_sdp_media *stream)
1106 {
1107  int i;
1108 
1109  for (i = 0; i < sdp->attr_count; i++) {
1110  apply_dtls_attrib(session_media, sdp->attr[i]);
1111  }
1112 
1113  for (i = 0; i < stream->attr_count; i++) {
1114  apply_dtls_attrib(session_media, stream->attr[i]);
1115  }
1116 
1117  ast_set_flag(session_media->srtp, AST_SRTP_CRYPTO_OFFER_OK);
1118 
1119  return 0;
1120 }
1121 
1122 static int setup_sdes_srtp(struct ast_sip_session_media *session_media,
1123  const struct pjmedia_sdp_media *stream)
1124 {
1125  int i;
1126 
1127  for (i = 0; i < stream->attr_count; i++) {
1128  pjmedia_sdp_attr *attr;
1129  RAII_VAR(char *, crypto_str, NULL, ast_free);
1130 
1131  /* check the stream for the required crypto attribute */
1132  attr = stream->attr[i];
1133  if (pj_strcmp2(&attr->name, "crypto")) {
1134  continue;
1135  }
1136 
1137  crypto_str = ast_strndup(attr->value.ptr, attr->value.slen);
1138  if (!crypto_str) {
1139  return -1;
1140  }
1141 
1142  if (setup_srtp(session_media)) {
1143  return -1;
1144  }
1145 
1146  if (!ast_sdp_crypto_process(session_media->rtp, session_media->srtp, crypto_str)) {
1147  /* found a valid crypto attribute */
1148  return 0;
1149  }
1150 
1151  ast_debug(1, "Ignoring crypto offer with unsupported parameters: %s\n", crypto_str);
1152  }
1153 
1154  /* no usable crypto attributes found */
1155  return -1;
1156 }
1157 
1159  struct ast_sip_session_media *session_media,
1160  const struct pjmedia_sdp_session *sdp,
1161  const struct pjmedia_sdp_media *stream)
1162 {
1163  switch (session_media->encryption) {
1165  if (setup_sdes_srtp(session_media, stream)) {
1166  return -1;
1167  }
1168  break;
1170  if (setup_dtls_srtp(session, session_media)) {
1171  return -1;
1172  }
1173  if (parse_dtls_attrib(session_media, sdp, stream)) {
1174  return -1;
1175  }
1176  break;
1179  break;
1180  }
1181 
1182  return 0;
1183 }
1184 
1185 static void set_ice_components(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
1186 {
1187  struct ast_rtp_engine_ice *ice;
1188 
1189  ast_assert(session_media->rtp != NULL);
1190 
1191  ice = ast_rtp_instance_get_ice(session_media->rtp);
1192  if (!session->endpoint->media.rtp.ice_support || !ice) {
1193  return;
1194  }
1195 
1196  if (session->endpoint->media.rtcp_mux && session_media->remote_rtcp_mux) {
1197  /* We both support RTCP mux. Only one ICE component necessary */
1198  ice->change_components(session_media->rtp, 1);
1199  } else {
1200  /* They either don't support RTCP mux or we don't know if they do yet. */
1201  ice->change_components(session_media->rtp, 2);
1202  }
1203 }
1204 
1205 /*! \brief Function which adds ssrc attributes to a media stream */
1206 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)
1207 {
1208  pj_str_t stmp;
1209  pjmedia_sdp_attr *attr;
1210  char tmp[128];
1211 
1212  if (!session->endpoint->media.bundle || session_media->bundle_group == -1) {
1213  return;
1214  }
1215 
1216  snprintf(tmp, sizeof(tmp), "%u cname:%s", ast_rtp_instance_get_ssrc(session_media->rtp), ast_rtp_instance_get_cname(session_media->rtp));
1217  attr = pjmedia_sdp_attr_create(pool, "ssrc", pj_cstr(&stmp, tmp));
1218  media->attr[media->attr_count++] = attr;
1219 }
1220 
1221 /*! \brief Function which processes ssrc attributes in a stream */
1222 static void process_ssrc_attributes(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
1223  const struct pjmedia_sdp_media *remote_stream)
1224 {
1225  int index;
1226 
1227  if (!session->endpoint->media.bundle) {
1228  return;
1229  }
1230 
1231  for (index = 0; index < remote_stream->attr_count; ++index) {
1232  pjmedia_sdp_attr *attr = remote_stream->attr[index];
1233  char attr_value[pj_strlen(&attr->value) + 1];
1234  char *ssrc_attribute_name, *ssrc_attribute_value = NULL;
1235  unsigned int ssrc;
1236 
1237  /* We only care about ssrc attributes */
1238  if (pj_strcmp2(&attr->name, "ssrc")) {
1239  continue;
1240  }
1241 
1242  ast_copy_pj_str(attr_value, &attr->value, sizeof(attr_value));
1243 
1244  if ((ssrc_attribute_name = strchr(attr_value, ' '))) {
1245  /* This has an actual attribute */
1246  *ssrc_attribute_name++ = '\0';
1247  ssrc_attribute_value = strchr(ssrc_attribute_name, ':');
1248  if (ssrc_attribute_value) {
1249  /* Values are actually optional according to the spec */
1250  *ssrc_attribute_value++ = '\0';
1251  }
1252  }
1253 
1254  if (sscanf(attr_value, "%30u", &ssrc) < 1) {
1255  continue;
1256  }
1257 
1258  /* If we are currently negotiating as a result of the remote side renegotiating then
1259  * determine if the source for this stream has changed.
1260  */
1261  if (pjmedia_sdp_neg_get_state(session->inv_session->neg) == PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER &&
1262  session->active_media_state) {
1263  struct ast_rtp_instance_stats stats = { 0, };
1264 
1265  if (!ast_rtp_instance_get_stats(session_media->rtp, &stats, AST_RTP_INSTANCE_STAT_REMOTE_SSRC) &&
1266  stats.remote_ssrc != ssrc) {
1267  session_media->changed = 1;
1268  }
1269  }
1270 
1271  ast_rtp_instance_set_remote_ssrc(session_media->rtp, ssrc);
1272  break;
1273  }
1274 }
1275 
1277  struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media,
1278  struct ast_stream *stream)
1279 {
1280  pj_str_t stmp;
1281  pjmedia_sdp_attr *attr;
1282  char msid[(AST_UUID_STR_LEN * 2) + 2];
1283  const char *stream_label = ast_stream_get_metadata(stream, "SDP:LABEL");
1284 
1285  if (!session->endpoint->media.webrtc) {
1286  return;
1287  }
1288 
1289  if (ast_strlen_zero(session_media->mslabel)) {
1290  /* If this stream is grouped with another then use its media stream label if possible */
1291  if (ast_stream_get_group(stream) != -1) {
1292  struct ast_sip_session_media *group_session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, ast_stream_get_group(stream));
1293 
1294  ast_copy_string(session_media->mslabel, group_session_media->mslabel, sizeof(session_media->mslabel));
1295  }
1296 
1297  if (ast_strlen_zero(session_media->mslabel)) {
1298  ast_uuid_generate_str(session_media->mslabel, sizeof(session_media->mslabel));
1299  }
1300  }
1301 
1302  if (ast_strlen_zero(session_media->label)) {
1303  ast_uuid_generate_str(session_media->label, sizeof(session_media->label));
1304  /* add for stream identification to replace stream_name */
1305  ast_stream_set_metadata(stream, "MSID:LABEL", session_media->label);
1306  }
1307 
1308  snprintf(msid, sizeof(msid), "%s %s", session_media->mslabel, session_media->label);
1309  ast_debug(3, "Stream msid: %p %s %s\n", stream,
1311  attr = pjmedia_sdp_attr_create(pool, "msid", pj_cstr(&stmp, msid));
1312  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1313 
1314  /* 'label' must come after 'msid' */
1315  if (!ast_strlen_zero(stream_label)) {
1316  ast_debug(3, "Stream Label: %p %s %s\n", stream,
1317  ast_codec_media_type2str(ast_stream_get_type(stream)), stream_label);
1318  attr = pjmedia_sdp_attr_create(pool, "label", pj_cstr(&stmp, stream_label));
1319  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1320  }
1321 }
1322 
1324  struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media)
1325 {
1326  pj_str_t stmp;
1327  pjmedia_sdp_attr *attr;
1328 
1329  if (!session->endpoint->media.webrtc) {
1330  return;
1331  }
1332 
1333  /* transport-cc is supposed to be for the entire transport, and any media sources so
1334  * while the header does not appear in audio streams and isn't negotiated there, we still
1335  * place this attribute in as Chrome does.
1336  */
1337  attr = pjmedia_sdp_attr_create(pool, "rtcp-fb", pj_cstr(&stmp, "* transport-cc"));
1338  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1339 
1340  if (session_media->type != AST_MEDIA_TYPE_VIDEO) {
1341  return;
1342  }
1343 
1344  /*
1345  * For now just automatically add it the stream even though it hasn't
1346  * necessarily been negotiated.
1347  */
1348  attr = pjmedia_sdp_attr_create(pool, "rtcp-fb", pj_cstr(&stmp, "* ccm fir"));
1349  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1350 
1351  attr = pjmedia_sdp_attr_create(pool, "rtcp-fb", pj_cstr(&stmp, "* goog-remb"));
1352  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1353 
1354  attr = pjmedia_sdp_attr_create(pool, "rtcp-fb", pj_cstr(&stmp, "* nack"));
1355  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1356 }
1357 
1359  struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media)
1360 {
1361  int idx;
1362  char extmap_value[256];
1363 
1364  if (!session->endpoint->media.webrtc || session_media->type != AST_MEDIA_TYPE_VIDEO) {
1365  return;
1366  }
1367 
1368  /* RTP extension local unique identifiers start at '1' */
1369  for (idx = 1; idx <= ast_rtp_instance_extmap_count(session_media->rtp); ++idx) {
1371  const char *direction_str = "";
1372  pj_str_t stmp;
1373  pjmedia_sdp_attr *attr;
1374 
1375  /* If this is an unsupported RTP extension we can't place it into the SDP */
1377  continue;
1378  }
1379 
1380  switch (ast_rtp_instance_extmap_get_direction(session_media->rtp, idx)) {
1382  /* Lack of a direction indicates sendrecv, so we leave it out */
1383  direction_str = "";
1384  break;
1386  direction_str = "/sendonly";
1387  break;
1389  direction_str = "/recvonly";
1390  break;
1392  /* It is impossible for a "none" direction extension to be negotiated but just in case
1393  * we treat it as inactive.
1394  */
1396  direction_str = "/inactive";
1397  break;
1398  }
1399 
1400  snprintf(extmap_value, sizeof(extmap_value), "%d%s %s", idx, direction_str,
1401  ast_rtp_instance_extmap_get_uri(session_media->rtp, idx));
1402  attr = pjmedia_sdp_attr_create(pool, "extmap", pj_cstr(&stmp, extmap_value));
1403  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1404  }
1405 }
1406 
1407 /*! \brief Function which processes extmap attributes in a stream */
1408 static void process_extmap_attributes(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
1409  const struct pjmedia_sdp_media *remote_stream)
1410 {
1411  int index;
1412 
1413  if (!session->endpoint->media.webrtc || session_media->type != AST_MEDIA_TYPE_VIDEO) {
1414  return;
1415  }
1416 
1417  ast_rtp_instance_extmap_clear(session_media->rtp);
1418 
1419  for (index = 0; index < remote_stream->attr_count; ++index) {
1420  pjmedia_sdp_attr *attr = remote_stream->attr[index];
1421  char attr_value[pj_strlen(&attr->value) + 1];
1422  char *uri;
1423  int id;
1424  char direction_str[10] = "";
1425  char *attributes;
1427 
1428  /* We only care about extmap attributes */
1429  if (pj_strcmp2(&attr->name, "extmap")) {
1430  continue;
1431  }
1432 
1433  ast_copy_pj_str(attr_value, &attr->value, sizeof(attr_value));
1434 
1435  /* Split the combined unique identifier and direction away from the URI and attributes for easier parsing */
1436  uri = strchr(attr_value, ' ');
1437  if (ast_strlen_zero(uri)) {
1438  continue;
1439  }
1440  *uri++ = '\0';
1441 
1442  if ((sscanf(attr_value, "%30d%9s", &id, direction_str) < 1) || (id < 1)) {
1443  /* We require at a minimum the unique identifier */
1444  continue;
1445  }
1446 
1447  /* Convert from the string to the internal representation */
1448  if (!strcasecmp(direction_str, "/sendonly")) {
1450  } else if (!strcasecmp(direction_str, "/recvonly")) {
1452  } else if (!strcasecmp(direction_str, "/inactive")) {
1454  }
1455 
1456  attributes = strchr(uri, ' ');
1457  if (!ast_strlen_zero(attributes)) {
1458  *attributes++ = '\0';
1459  }
1460 
1461  ast_rtp_instance_extmap_negotiate(session_media->rtp, id, direction, uri, attributes);
1462  }
1463 }
1464 
1465 static void set_session_media_remotely_held(struct ast_sip_session_media *session_media,
1466  const struct ast_sip_session *session,
1467  const pjmedia_sdp_media *media,
1468  const struct ast_stream *stream,
1469  const struct ast_sockaddr *addrs)
1470 {
1472  (session_media->type == AST_MEDIA_TYPE_AUDIO)) {
1473  if (((addrs != NULL) && ast_sockaddr_isnull(addrs)) ||
1474  ((addrs != NULL) && ast_sockaddr_is_any(addrs)) ||
1475  pjmedia_sdp_media_find_attr2(media, "sendonly", NULL) ||
1476  pjmedia_sdp_media_find_attr2(media, "inactive", NULL)) {
1477  if (!session_media->remotely_held) {
1478  session_media->remotely_held = 1;
1479  session_media->remotely_held_changed = 1;
1480  }
1481  } else if (session_media->remotely_held) {
1482  session_media->remotely_held = 0;
1483  session_media->remotely_held_changed = 1;
1484  }
1485  }
1486 }
1487 
1488 /*! \brief Function which negotiates an incoming media stream */
1490  struct ast_sip_session_media *session_media, const pjmedia_sdp_session *sdp,
1491  int index, struct ast_stream *asterisk_stream)
1492 {
1493  char host[NI_MAXHOST];
1494  RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free);
1495  pjmedia_sdp_media *stream = sdp->media[index];
1496  struct ast_sip_session_media *session_media_transport;
1497  enum ast_media_type media_type = session_media->type;
1499  struct ast_format_cap *joint;
1500  int res;
1502 
1503  /* If no type formats have been configured reject this stream */
1504  if (!ast_format_cap_has_type(session->endpoint->media.codecs, media_type)) {
1505  ast_debug(3, "Endpoint has no codecs for media type '%s', declining stream\n",
1506  ast_codec_media_type2str(session_media->type));
1507  SCOPE_EXIT_RTN_VALUE(0, "Endpoint has no codecs\n");
1508  }
1509 
1510  /* Ensure incoming transport is compatible with the endpoint's configuration */
1511  if (!session->endpoint->media.rtp.use_received_transport) {
1512  encryption = check_endpoint_media_transport(session->endpoint, stream);
1513 
1514  if (encryption == AST_SIP_MEDIA_TRANSPORT_INVALID) {
1515  SCOPE_EXIT_RTN_VALUE(-1, "Incompatible transport\n");
1516  }
1517  }
1518 
1519  ast_copy_pj_str(host, stream->conn ? &stream->conn->addr : &sdp->conn->addr, sizeof(host));
1520 
1521  /* Ensure that the address provided is valid */
1522  if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC) <= 0) {
1523  /* The provided host was actually invalid so we error out this negotiation */
1524  SCOPE_EXIT_RTN_VALUE(-1, "Invalid host\n");
1525  }
1526 
1527  /* Using the connection information create an appropriate RTP instance */
1528  if (!session_media->rtp && create_rtp(session, session_media, sdp)) {
1529  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create rtp\n");
1530  }
1531 
1532  process_ssrc_attributes(session, session_media, stream);
1533  process_extmap_attributes(session, session_media, stream);
1534  session_media_transport = ast_sip_session_media_get_transport(session, session_media);
1535 
1536  if (session_media_transport == session_media || !session_media->bundled) {
1537  /* If this media session is carrying actual traffic then set up those aspects */
1538  session_media->remote_rtcp_mux = (pjmedia_sdp_media_find_attr2(stream, "rtcp-mux", NULL) != NULL);
1539  set_ice_components(session, session_media);
1540 
1541  enable_rtcp(session, session_media, stream);
1542 
1543  res = setup_media_encryption(session, session_media, sdp, stream);
1544  if (res) {
1545  if (!session->endpoint->media.rtp.encryption_optimistic ||
1546  !pj_strncmp2(&stream->desc.transport, "RTP/SAVP", 8)) {
1547  /* If optimistic encryption is disabled and crypto should have been enabled
1548  * but was not this session must fail. This must also fail if crypto was
1549  * required in the offer but could not be set up.
1550  */
1551  SCOPE_EXIT_RTN_VALUE(-1, "Incompatible crypto\n");
1552  }
1553  /* There is no encryption, sad. */
1554  session_media->encryption = AST_SIP_MEDIA_ENCRYPT_NONE;
1555  }
1556 
1557  /* If we've been explicitly configured to use the received transport OR if
1558  * encryption is on and crypto is present use the received transport.
1559  * This is done in case of optimistic because it may come in as RTP/AVP or RTP/SAVP depending
1560  * on the configuration of the remote endpoint (optimistic themselves or mandatory).
1561  */
1562  if ((session->endpoint->media.rtp.use_received_transport) ||
1563  ((encryption == AST_SIP_MEDIA_ENCRYPT_SDES) && !res)) {
1564  pj_strdup(session->inv_session->pool, &session_media->transport, &stream->desc.transport);
1565  }
1566  } else {
1567  /* This is bundled with another session, so mark it as such */
1568  ast_rtp_instance_bundle(session_media->rtp, session_media_transport->rtp);
1569 
1570  enable_rtcp(session, session_media, stream);
1571  }
1572 
1573  /* If ICE support is enabled find all the needed attributes */
1574  check_ice_support(session, session_media, stream);
1575 
1576  /* If ICE support is enabled then check remote ICE started? */
1577  if (session_media->remote_ice) {
1578  process_ice_auth_attrb(session, session_media, sdp, stream);
1579  }
1580 
1581  /* Check if incoming SDP is changing the remotely held state */
1582  set_session_media_remotely_held(session_media, session, stream, asterisk_stream, addrs);
1583 
1584  joint = set_incoming_call_offer_cap(session, session_media, stream);
1585  res = apply_cap_to_bundled(session_media, session_media_transport, asterisk_stream, joint);
1586  ao2_cleanup(joint);
1587  if (res != 0) {
1588  SCOPE_EXIT_RTN_VALUE(0, "Something failed\n");
1589  }
1590 
1592 }
1593 
1595  struct ast_sip_session_media *session_media,
1596  pj_pool_t *pool, pjmedia_sdp_media *media)
1597 {
1598  pj_str_t stmp;
1599  pjmedia_sdp_attr *attr;
1600  enum ast_rtp_dtls_hash hash;
1601  const char *crypto_attribute;
1602  struct ast_rtp_engine_dtls *dtls;
1603  struct ast_sdp_srtp *tmp;
1604  static const pj_str_t STR_NEW = { "new", 3 };
1605  static const pj_str_t STR_EXISTING = { "existing", 8 };
1606  static const pj_str_t STR_ACTIVE = { "active", 6 };
1607  static const pj_str_t STR_PASSIVE = { "passive", 7 };
1608  static const pj_str_t STR_ACTPASS = { "actpass", 7 };
1609  static const pj_str_t STR_HOLDCONN = { "holdconn", 8 };
1610  enum ast_rtp_dtls_setup setup;
1611 
1612  switch (session_media->encryption) {
1615  break;
1617  if (!session_media->srtp) {
1618  session_media->srtp = ast_sdp_srtp_alloc();
1619  if (!session_media->srtp) {
1620  return -1;
1621  }
1622  }
1623 
1624  tmp = session_media->srtp;
1625 
1626  do {
1627  crypto_attribute = ast_sdp_srtp_get_attrib(tmp,
1628  0 /* DTLS running? No */,
1629  session->endpoint->media.rtp.srtp_tag_32 /* 32 byte tag length? */);
1630  if (!crypto_attribute) {
1631  /* No crypto attribute to add, bad news */
1632  return -1;
1633  }
1634 
1635  attr = pjmedia_sdp_attr_create(pool, "crypto",
1636  pj_cstr(&stmp, crypto_attribute));
1637  media->attr[media->attr_count++] = attr;
1638  } while ((tmp = AST_LIST_NEXT(tmp, sdp_srtp_list)));
1639 
1640  break;
1642  if (setup_dtls_srtp(session, session_media)) {
1643  return -1;
1644  }
1645 
1646  dtls = ast_rtp_instance_get_dtls(session_media->rtp);
1647  if (!dtls) {
1648  return -1;
1649  }
1650 
1651  switch (dtls->get_connection(session_media->rtp)) {
1653  attr = pjmedia_sdp_attr_create(pool, "connection", &STR_NEW);
1654  media->attr[media->attr_count++] = attr;
1655  break;
1657  attr = pjmedia_sdp_attr_create(pool, "connection", &STR_EXISTING);
1658  media->attr[media->attr_count++] = attr;
1659  break;
1660  default:
1661  break;
1662  }
1663 
1664  /* If this is an answer we need to use our current state, if it's an offer we need to use
1665  * the configured value.
1666  */
1667  if (session->inv_session->neg
1668  && pjmedia_sdp_neg_get_state(session->inv_session->neg) != PJMEDIA_SDP_NEG_STATE_DONE) {
1669  setup = dtls->get_setup(session_media->rtp);
1670  } else {
1671  setup = session->endpoint->media.rtp.dtls_cfg.default_setup;
1672  }
1673 
1674  switch (setup) {
1676  attr = pjmedia_sdp_attr_create(pool, "setup", &STR_ACTIVE);
1677  media->attr[media->attr_count++] = attr;
1678  break;
1680  attr = pjmedia_sdp_attr_create(pool, "setup", &STR_PASSIVE);
1681  media->attr[media->attr_count++] = attr;
1682  break;
1684  attr = pjmedia_sdp_attr_create(pool, "setup", &STR_ACTPASS);
1685  media->attr[media->attr_count++] = attr;
1686  break;
1688  attr = pjmedia_sdp_attr_create(pool, "setup", &STR_HOLDCONN);
1689  break;
1690  default:
1691  break;
1692  }
1693 
1694  hash = dtls->get_fingerprint_hash(session_media->rtp);
1695  crypto_attribute = dtls->get_fingerprint(session_media->rtp);
1696  if (crypto_attribute && (hash == AST_RTP_DTLS_HASH_SHA1 || hash == AST_RTP_DTLS_HASH_SHA256)) {
1697  RAII_VAR(struct ast_str *, fingerprint, ast_str_create(64), ast_free);
1698  if (!fingerprint) {
1699  return -1;
1700  }
1701 
1702  if (hash == AST_RTP_DTLS_HASH_SHA1) {
1703  ast_str_set(&fingerprint, 0, "SHA-1 %s", crypto_attribute);
1704  } else {
1705  ast_str_set(&fingerprint, 0, "SHA-256 %s", crypto_attribute);
1706  }
1707 
1708  attr = pjmedia_sdp_attr_create(pool, "fingerprint", pj_cstr(&stmp, ast_str_buffer(fingerprint)));
1709  media->attr[media->attr_count++] = attr;
1710  }
1711  break;
1712  }
1713 
1714  return 0;
1715 }
1716 
1717 /*! \brief Function which creates an outgoing stream */
1719  struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_session *remote, struct ast_stream *stream)
1720 {
1721  pj_pool_t *pool = session->inv_session->pool_prov;
1722  static const pj_str_t STR_RTP_AVP = { "RTP/AVP", 7 };
1723  static const pj_str_t STR_IN = { "IN", 2 };
1724  static const pj_str_t STR_IP4 = { "IP4", 3};
1725  static const pj_str_t STR_IP6 = { "IP6", 3};
1726  static const pj_str_t STR_SENDRECV = { "sendrecv", 8 };
1727  static const pj_str_t STR_SENDONLY = { "sendonly", 8 };
1728  static const pj_str_t STR_INACTIVE = { "inactive", 8 };
1729  static const pj_str_t STR_RECVONLY = { "recvonly", 8 };
1730  pjmedia_sdp_media *media;
1731  const char *hostip = NULL;
1732  struct ast_sockaddr addr;
1733  char tmp[512];
1734  pj_str_t stmp;
1735  pjmedia_sdp_attr *attr;
1736  int index = 0;
1737  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;
1738  int min_packet_size = 0, max_packet_size = 0;
1739  int rtp_code;
1740  RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup);
1741  enum ast_media_type media_type = session_media->type;
1742  struct ast_sip_session_media *session_media_transport;
1743  pj_sockaddr ip;
1744  int direct_media_enabled = !ast_sockaddr_isnull(&session_media->direct_media_addr) &&
1745  ast_format_cap_count(session->direct_media_cap);
1746  SCOPE_ENTER(1, "%s Type: %s %s\n", ast_sip_session_get_name(session),
1748 
1749  media = pj_pool_zalloc(pool, sizeof(struct pjmedia_sdp_media));
1750  if (!media) {
1751  SCOPE_EXIT_RTN_VALUE(-1, "Pool alloc failure\n");
1752  }
1753  pj_strdup2(pool, &media->desc.media, ast_codec_media_type2str(session_media->type));
1754 
1755  /* If this is a removed (or declined) stream OR if no formats exist then construct a minimal stream in SDP */
1758  media->desc.port = 0;
1759  media->desc.port_count = 1;
1760 
1761  if (remote && remote->media[ast_stream_get_position(stream)]) {
1762  pjmedia_sdp_media *remote_media = remote->media[ast_stream_get_position(stream)];
1763  int index;
1764 
1765  media->desc.transport = remote_media->desc.transport;
1766 
1767  /* Preserve existing behavior by copying the formats provided from the offer */
1768  for (index = 0; index < remote_media->desc.fmt_count; ++index) {
1769  media->desc.fmt[index] = remote_media->desc.fmt[index];
1770  }
1771  media->desc.fmt_count = remote_media->desc.fmt_count;
1772  } else {
1773  /* This is actually an offer so put a dummy payload in that is ignored and sane transport */
1774  media->desc.transport = STR_RTP_AVP;
1775  pj_strdup2(pool, &media->desc.fmt[media->desc.fmt_count++], "32");
1776  }
1777 
1778  sdp->media[sdp->media_count++] = media;
1780 
1781  SCOPE_EXIT_RTN_VALUE(1, "Stream removed or no formats\n");
1782  }
1783 
1784  if (!session_media->rtp && create_rtp(session, session_media, sdp)) {
1785  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create rtp\n");
1786  }
1787 
1788  /* If this stream has not been bundled already it is new and we need to ensure there is no SSRC conflict */
1789  if (session_media->bundle_group != -1 && !session_media->bundled) {
1790  for (index = 0; index < sdp->media_count; ++index) {
1791  struct ast_sip_session_media *other_session_media;
1792 
1793  other_session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, index);
1794  if (!other_session_media->rtp || other_session_media->bundle_group != session_media->bundle_group) {
1795  continue;
1796  }
1797 
1798  if (ast_rtp_instance_get_ssrc(session_media->rtp) == ast_rtp_instance_get_ssrc(other_session_media->rtp)) {
1799  ast_rtp_instance_change_source(session_media->rtp);
1800  /* Start the conflict check over again */
1801  index = -1;
1802  continue;
1803  }
1804  }
1805  }
1806 
1807  session_media_transport = ast_sip_session_media_get_transport(session, session_media);
1808 
1809  if (session_media_transport == session_media || !session_media->bundled) {
1810  set_ice_components(session, session_media);
1811  enable_rtcp(session, session_media, NULL);
1812 
1813  /* Crypto has to be added before setting the media transport so that SRTP is properly
1814  * set up according to the configuration. This ends up changing the media transport.
1815  */
1816  if (add_crypto_to_stream(session, session_media, pool, media)) {
1817  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't add crypto\n");
1818  }
1819 
1820  if (pj_strlen(&session_media->transport)) {
1821  /* If a transport has already been specified use it */
1822  media->desc.transport = session_media->transport;
1823  } else {
1824  media->desc.transport = pj_str(ast_sdp_get_rtp_profile(
1825  /* Optimistic encryption places crypto in the normal RTP/AVP profile */
1826  !session->endpoint->media.rtp.encryption_optimistic &&
1827  (session_media->encryption == AST_SIP_MEDIA_ENCRYPT_SDES),
1828  session_media->rtp, session->endpoint->media.rtp.use_avpf,
1829  session->endpoint->media.rtp.force_avp));
1830  }
1831 
1832  media->conn = pj_pool_zalloc(pool, sizeof(struct pjmedia_sdp_conn));
1833  if (!media->conn) {
1834  SCOPE_EXIT_RTN_VALUE(-1, "Pool alloc failure\n");
1835  }
1836 
1837  /* Add connection level details */
1838  if (direct_media_enabled) {
1840  } else if (ast_strlen_zero(session->endpoint->media.address)) {
1841  hostip = ast_sip_get_host_ip_string(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET());
1842  } else {
1843  hostip = session->endpoint->media.address;
1844  }
1845 
1846  if (ast_strlen_zero(hostip)) {
1847  ast_log(LOG_ERROR, "No local host IP available for stream %s\n",
1848  ast_codec_media_type2str(session_media->type));
1849  SCOPE_EXIT_RTN_VALUE(-1, "No local host ip\n");
1850  }
1851 
1852  media->conn->net_type = STR_IN;
1853  /* Assume that the connection will use IPv4 until proven otherwise */
1854  media->conn->addr_type = STR_IP4;
1855  pj_strdup2(pool, &media->conn->addr, hostip);
1856 
1857  if ((pj_sockaddr_parse(pj_AF_UNSPEC(), 0, &media->conn->addr, &ip) == PJ_SUCCESS) &&
1858  (ip.addr.sa_family == pj_AF_INET6())) {
1859  media->conn->addr_type = STR_IP6;
1860  }
1861 
1862  /* Add ICE attributes and candidates */
1863  add_ice_to_stream(session, session_media, pool, media, 1);
1864 
1865  ast_rtp_instance_get_local_address(session_media->rtp, &addr);
1866  media->desc.port = direct_media_enabled ? ast_sockaddr_port(&session_media->direct_media_addr) : (pj_uint16_t) ast_sockaddr_port(&addr);
1867  media->desc.port_count = 1;
1868  } else {
1869  pjmedia_sdp_media *bundle_group_stream = sdp->media[session_media_transport->stream_num];
1870 
1871  /* As this is in a bundle group it shares the same details as the group instance */
1872  media->desc.transport = bundle_group_stream->desc.transport;
1873  media->conn = bundle_group_stream->conn;
1874  media->desc.port = bundle_group_stream->desc.port;
1875 
1876  if (add_crypto_to_stream(session, session_media_transport, pool, media)) {
1877  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't add crypto\n");
1878  }
1879 
1880  add_ice_to_stream(session, session_media_transport, pool, media, 0);
1881 
1882  enable_rtcp(session, session_media, NULL);
1883  }
1884 
1886  ast_log(LOG_ERROR, "Failed to allocate %s capabilities\n",
1887  ast_codec_media_type2str(session_media->type));
1888  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create caps\n");
1889  }
1890 
1891  if (direct_media_enabled) {
1892  ast_format_cap_get_compatible(session->endpoint->media.codecs, session->direct_media_cap, caps);
1893  } else {
1895  }
1896 
1897  for (index = 0; index < ast_format_cap_count(caps); ++index) {
1898  struct ast_format *format = ast_format_cap_get_format(caps, index);
1899 
1901  ao2_ref(format, -1);
1902  continue;
1903  }
1904 
1905  /* If this stream is not a transport we need to use the transport codecs structure for payload management to prevent
1906  * conflicts.
1907  */
1908  if (session_media_transport != session_media) {
1909  if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media_transport->rtp), 1, format, 0)) == -1) {
1910  ast_log(LOG_WARNING,"Unable to get rtp codec payload code for %s\n", ast_format_get_name(format));
1911  ao2_ref(format, -1);
1912  continue;
1913  }
1914  /* Our instance has to match the payload number though */
1916  } else {
1917  if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media->rtp), 1, format, 0)) == -1) {
1918  ast_log(LOG_WARNING,"Unable to get rtp codec payload code for %s\n", ast_format_get_name(format));
1919  ao2_ref(format, -1);
1920  continue;
1921  }
1922  }
1923 
1924  if ((attr = generate_rtpmap_attr(session, media, pool, rtp_code, 1, format, 0))) {
1925  media->attr[media->attr_count++] = attr;
1926  }
1927 
1928  if ((attr = generate_fmtp_attr(pool, format, rtp_code))) {
1929  media->attr[media->attr_count++] = attr;
1930  }
1931 
1933  ((ast_format_get_maximum_ms(format) < max_packet_size) || !max_packet_size)) {
1934  max_packet_size = ast_format_get_maximum_ms(format);
1935  }
1936  ao2_ref(format, -1);
1937 
1938  if (media->desc.fmt_count == PJMEDIA_MAX_SDP_FMT) {
1939  break;
1940  }
1941  }
1942 
1943  /* Add non-codec formats */
1945  && media->desc.fmt_count < PJMEDIA_MAX_SDP_FMT) {
1946  for (index = 1LL; index <= AST_RTP_MAX; index <<= 1) {
1947  if (!(noncodec & index)) {
1948  continue;
1949  }
1950  rtp_code = ast_rtp_codecs_payload_code(
1951  ast_rtp_instance_get_codecs(session_media->rtp), 0, NULL, index);
1952  if (rtp_code == -1) {
1953  continue;
1954  }
1955 
1956  if ((attr = generate_rtpmap_attr(session, media, pool, rtp_code, 0, NULL, index))) {
1957  media->attr[media->attr_count++] = attr;
1958  }
1959 
1960  if (index == AST_RTP_DTMF) {
1961  snprintf(tmp, sizeof(tmp), "%d 0-16", rtp_code);
1962  attr = pjmedia_sdp_attr_create(pool, "fmtp", pj_cstr(&stmp, tmp));
1963  media->attr[media->attr_count++] = attr;
1964  }
1965 
1966  if (media->desc.fmt_count == PJMEDIA_MAX_SDP_FMT) {
1967  break;
1968  }
1969  }
1970  }
1971 
1972 
1973  /* If no formats were actually added to the media stream don't add it to the SDP */
1974  if (!media->desc.fmt_count) {
1975  SCOPE_EXIT_RTN_VALUE(1, "No formats added to stream\n");
1976  }
1977 
1978  /* If ptime is set add it as an attribute */
1979  min_packet_size = ast_rtp_codecs_get_framing(ast_rtp_instance_get_codecs(session_media->rtp));
1980  if (!min_packet_size) {
1981  min_packet_size = ast_format_cap_get_framing(caps);
1982  }
1983  if (min_packet_size) {
1984  snprintf(tmp, sizeof(tmp), "%d", min_packet_size);
1985  attr = pjmedia_sdp_attr_create(pool, "ptime", pj_cstr(&stmp, tmp));
1986  media->attr[media->attr_count++] = attr;
1987  }
1988 
1989  if (max_packet_size) {
1990  snprintf(tmp, sizeof(tmp), "%d", max_packet_size);
1991  attr = pjmedia_sdp_attr_create(pool, "maxptime", pj_cstr(&stmp, tmp));
1992  media->attr[media->attr_count++] = attr;
1993  }
1994 
1995  attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr);
1996  if (session_media->locally_held) {
1997  if (session_media->remotely_held) {
1998  attr->name = STR_INACTIVE; /* To place on hold a recvonly stream, send inactive */
1999  } else {
2000  attr->name = STR_SENDONLY; /* Send sendonly to initate a local hold */
2001  }
2002  } else {
2003  if (session_media->remotely_held) {
2004  attr->name = STR_RECVONLY; /* Remote has sent sendonly, reply recvonly */
2005  } else if (ast_stream_get_state(stream) == AST_STREAM_STATE_SENDONLY) {
2006  attr->name = STR_SENDONLY; /* Stream has requested sendonly */
2007  } else if (ast_stream_get_state(stream) == AST_STREAM_STATE_RECVONLY) {
2008  attr->name = STR_RECVONLY; /* Stream has requested recvonly */
2009  } else if (ast_stream_get_state(stream) == AST_STREAM_STATE_INACTIVE) {
2010  attr->name = STR_INACTIVE; /* Stream has requested inactive */
2011  } else {
2012  attr->name = STR_SENDRECV; /* No hold in either direction */
2013  }
2014  }
2015  media->attr[media->attr_count++] = attr;
2016 
2017  /* If we've got rtcp-mux enabled, add it unless we received an offer without it */
2018  if (session->endpoint->media.rtcp_mux && session_media->remote_rtcp_mux) {
2019  attr = pjmedia_sdp_attr_create(pool, "rtcp-mux", NULL);
2020  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
2021  }
2022 
2023  add_ssrc_to_stream(session, session_media, pool, media);
2024  add_msid_to_stream(session, session_media, pool, media, stream);
2025  add_rtcp_fb_to_stream(session, session_media, pool, media);
2026  add_extmap_to_stream(session, session_media, pool, media);
2027 
2028  /* Add the media stream to the SDP */
2029  sdp->media[sdp->media_count++] = media;
2030 
2031  SCOPE_EXIT_RTN_VALUE(1, "RC: 1\n");
2032 }
2033 
2035 {
2036  struct ast_frame *f;
2037 
2038  if (!session_media->rtp) {
2039  return &ast_null_frame;
2040  }
2041 
2042  f = ast_rtp_instance_read(session_media->rtp, 0);
2043  if (!f) {
2044  return NULL;
2045  }
2046 
2047  ast_rtp_instance_set_last_rx(session_media->rtp, time(NULL));
2048 
2049  return f;
2050 }
2051 
2053 {
2054  struct ast_frame *f;
2055 
2056  if (!session_media->rtp) {
2057  return &ast_null_frame;
2058  }
2059 
2060  f = ast_rtp_instance_read(session_media->rtp, 1);
2061  if (!f) {
2062  return NULL;
2063  }
2064 
2065  ast_rtp_instance_set_last_rx(session_media->rtp, time(NULL));
2066 
2067  return f;
2068 }
2069 
2070 static int media_session_rtp_write_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct ast_frame *frame)
2071 {
2072  if (!session_media->rtp) {
2073  return 0;
2074  }
2075 
2076  return ast_rtp_instance_write(session_media->rtp, frame);
2077 }
2078 
2080  struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *local,
2081  const struct pjmedia_sdp_session *remote, int index, struct ast_stream *asterisk_stream)
2082 {
2083  RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free);
2084  struct pjmedia_sdp_media *remote_stream = remote->media[index];
2085  enum ast_media_type media_type = session_media->type;
2086  char host[NI_MAXHOST];
2087  int res;
2088  struct ast_sip_session_media *session_media_transport;
2089  SCOPE_ENTER(1, "%s Stream: %s\n", ast_sip_session_get_name(session),
2090  ast_str_tmp(128, ast_stream_to_str(asterisk_stream, &STR_TMP)));
2091 
2092  if (!session->channel) {
2093  SCOPE_EXIT_RTN_VALUE(1, "No channel\n");
2094  }
2095 
2096  /* Ensure incoming transport is compatible with the endpoint's configuration */
2097  if (!session->endpoint->media.rtp.use_received_transport &&
2099  SCOPE_EXIT_RTN_VALUE(-1, "Incompatible transport\n");
2100  }
2101 
2102  /* Create an RTP instance if need be */
2103  if (!session_media->rtp && create_rtp(session, session_media, local)) {
2104  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create rtp\n");
2105  }
2106 
2107  process_ssrc_attributes(session, session_media, remote_stream);
2108  process_extmap_attributes(session, session_media, remote_stream);
2109 
2110  session_media_transport = ast_sip_session_media_get_transport(session, session_media);
2111 
2112  if (session_media_transport == session_media || !session_media->bundled) {
2113  session_media->remote_rtcp_mux = (pjmedia_sdp_media_find_attr2(remote_stream, "rtcp-mux", NULL) != NULL);
2114  set_ice_components(session, session_media);
2115 
2116  enable_rtcp(session, session_media, remote_stream);
2117 
2118  res = setup_media_encryption(session, session_media, remote, remote_stream);
2119  if (!session->endpoint->media.rtp.encryption_optimistic && res) {
2120  /* If optimistic encryption is disabled and crypto should have been enabled but was not
2121  * this session must fail.
2122  */
2123  SCOPE_EXIT_RTN_VALUE(-1, "Incompatible crypto\n");
2124  }
2125 
2126  if (!remote_stream->conn && !remote->conn) {
2127  SCOPE_EXIT_RTN_VALUE(1, "No connection info\n");
2128  }
2129 
2130  ast_copy_pj_str(host, remote_stream->conn ? &remote_stream->conn->addr : &remote->conn->addr, sizeof(host));
2131 
2132  /* Ensure that the address provided is valid */
2133  if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC) <= 0) {
2134  /* The provided host was actually invalid so we error out this negotiation */
2135  SCOPE_EXIT_RTN_VALUE(-1, "Host invalid\n");
2136  }
2137 
2138  /* Apply connection information to the RTP instance */
2139  ast_sockaddr_set_port(addrs, remote_stream->desc.port);
2140  ast_rtp_instance_set_remote_address(session_media->rtp, addrs);
2141 
2143  ast_sip_session_media_add_read_callback(session, session_media, ast_rtp_instance_fd(session_media->rtp, 0),
2145  if (!session->endpoint->media.rtcp_mux || !session_media->remote_rtcp_mux) {
2146  ast_sip_session_media_add_read_callback(session, session_media, ast_rtp_instance_fd(session_media->rtp, 1),
2148  }
2149 
2150  /* If ICE support is enabled find all the needed attributes */
2151  process_ice_attributes(session, session_media, remote, remote_stream);
2152  } else {
2153  /* This is bundled with another session, so mark it as such */
2154  ast_rtp_instance_bundle(session_media->rtp, session_media_transport->rtp);
2156  enable_rtcp(session, session_media, remote_stream);
2157  }
2158 
2159  if (set_caps(session, session_media, session_media_transport, remote_stream, 0, asterisk_stream)) {
2160  SCOPE_EXIT_RTN_VALUE(-1, "set_caps failed\n");
2161  }
2162 
2163  /* Set the channel uniqueid on the RTP instance now that it is becoming active */
2164  ast_channel_lock(session->channel);
2166  ast_channel_unlock(session->channel);
2167 
2168  /* Ensure the RTP instance is active */
2169  ast_rtp_instance_set_stream_num(session_media->rtp, ast_stream_get_position(asterisk_stream));
2170  ast_rtp_instance_activate(session_media->rtp);
2171 
2172  /* audio stream handles music on hold */
2174  if ((pjmedia_sdp_neg_was_answer_remote(session->inv_session->neg) == PJ_FALSE)
2175  && (session->inv_session->state == PJSIP_INV_STATE_CONFIRMED)) {
2177  }
2178  SCOPE_EXIT_RTN_VALUE(1, "moh\n");
2179  }
2180 
2181  set_session_media_remotely_held(session_media, session, remote_stream, asterisk_stream, addrs);
2182 
2183  if (session_media->remotely_held_changed) {
2184  if (session_media->remotely_held) {
2185  /* The remote side has put us on hold */
2186  ast_queue_hold(session->channel, session->endpoint->mohsuggest);
2187  ast_rtp_instance_stop(session_media->rtp);
2189  session_media->remotely_held_changed = 0;
2190  } else {
2191  /* The remote side has taken us off hold */
2192  ast_queue_unhold(session->channel);
2194  session_media->remotely_held_changed = 0;
2195  }
2196  } else if ((pjmedia_sdp_neg_was_answer_remote(session->inv_session->neg) == PJ_FALSE)
2197  && (session->inv_session->state == PJSIP_INV_STATE_CONFIRMED)) {
2199  }
2200 
2201  /* This purposely resets the encryption to the configured in case it gets added later */
2202  session_media->encryption = session->endpoint->media.rtp.encryption;
2203 
2204  if (session->endpoint->media.rtp.keepalive > 0 &&
2205  (session_media->type == AST_MEDIA_TYPE_AUDIO ||
2206  session_media->type == AST_MEDIA_TYPE_VIDEO)) {
2207  ast_rtp_instance_set_keepalive(session_media->rtp, session->endpoint->media.rtp.keepalive);
2208  /* Schedule the initial keepalive early in case this is being used to punch holes through
2209  * a NAT. This way there won't be an awkward delay before media starts flowing in some
2210  * scenarios.
2211  */
2212  AST_SCHED_DEL(sched, session_media->keepalive_sched_id);
2214  session_media, 1);
2215  }
2216 
2217  /* As the channel lock is not held during this process the scheduled item won't block if
2218  * it is hanging up the channel at the same point we are applying this negotiated SDP.
2219  */
2220  AST_SCHED_DEL(sched, session_media->timeout_sched_id);
2221 
2222  /* Due to the fact that we only ever have one scheduled timeout item for when we are both
2223  * off hold and on hold we don't need to store the two timeouts differently on the RTP
2224  * instance itself.
2225  */
2226  ast_rtp_instance_set_timeout(session_media->rtp, 0);
2227  if (session->endpoint->media.rtp.timeout && !session_media->remotely_held) {
2228  ast_rtp_instance_set_timeout(session_media->rtp, session->endpoint->media.rtp.timeout);
2229  } else if (session->endpoint->media.rtp.timeout_hold && session_media->remotely_held) {
2230  ast_rtp_instance_set_timeout(session_media->rtp, session->endpoint->media.rtp.timeout_hold);
2231  }
2232 
2233  if (ast_rtp_instance_get_timeout(session_media->rtp)) {
2235  session_media, 1);
2236  }
2237 
2238  SCOPE_EXIT_RTN_VALUE(1, "Handled\n");
2239 }
2240 
2241 /*! \brief Function which updates the media stream with external media address, if applicable */
2242 static void change_outgoing_sdp_stream_media_address(pjsip_tx_data *tdata, struct pjmedia_sdp_media *stream, struct ast_sip_transport *transport)
2243 {
2245  char host[NI_MAXHOST];
2246  struct ast_sockaddr our_sdp_addr = { { 0, } };
2247 
2248  /* If the stream has been rejected there will be no connection line */
2249  if (!stream->conn || !transport_state) {
2250  return;
2251  }
2252 
2253  ast_copy_pj_str(host, &stream->conn->addr, sizeof(host));
2254  ast_sockaddr_parse(&our_sdp_addr, host, PARSE_PORT_FORBID);
2255 
2256  /* Reversed check here. We don't check the remote endpoint being
2257  * in our local net, but whether our outgoing session IP is
2258  * local. If it is not, we won't do rewriting. No localnet
2259  * configured? Always rewrite. */
2260  if (ast_sip_transport_is_nonlocal(transport_state, &our_sdp_addr) && transport_state->localnet) {
2261  return;
2262  }
2263  ast_debug(5, "Setting media address to %s\n", ast_sockaddr_stringify_addr_remote(&transport_state->external_media_address));
2264  pj_strdup2(tdata->pool, &stream->conn->addr, ast_sockaddr_stringify_addr_remote(&transport_state->external_media_address));
2265 }
2266 
2267 /*! \brief Function which stops the RTP instance */
2268 static void stream_stop(struct ast_sip_session_media *session_media)
2269 {
2270  if (!session_media->rtp) {
2271  return;
2272  }
2273 
2274  AST_SCHED_DEL(sched, session_media->keepalive_sched_id);
2275  AST_SCHED_DEL(sched, session_media->timeout_sched_id);
2276  ast_rtp_instance_stop(session_media->rtp);
2277 }
2278 
2279 /*! \brief Function which destroys the RTP instance when session ends */
2280 static void stream_destroy(struct ast_sip_session_media *session_media)
2281 {
2282  if (session_media->rtp) {
2283  stream_stop(session_media);
2284  ast_rtp_instance_destroy(session_media->rtp);
2285  }
2286  session_media->rtp = NULL;
2287 }
2288 
2289 /*! \brief SDP handler for 'audio' media stream */
2291  .id = STR_AUDIO,
2292  .negotiate_incoming_sdp_stream = negotiate_incoming_sdp_stream,
2293  .create_outgoing_sdp_stream = create_outgoing_sdp_stream,
2294  .apply_negotiated_sdp_stream = apply_negotiated_sdp_stream,
2295  .change_outgoing_sdp_stream_media_address = change_outgoing_sdp_stream_media_address,
2296  .stream_stop = stream_stop,
2297  .stream_destroy = stream_destroy,
2298 };
2299 
2300 /*! \brief SDP handler for 'video' media stream */
2302  .id = STR_VIDEO,
2303  .negotiate_incoming_sdp_stream = negotiate_incoming_sdp_stream,
2304  .create_outgoing_sdp_stream = create_outgoing_sdp_stream,
2305  .apply_negotiated_sdp_stream = apply_negotiated_sdp_stream,
2306  .change_outgoing_sdp_stream_media_address = change_outgoing_sdp_stream_media_address,
2307  .stream_stop = stream_stop,
2308  .stream_destroy = stream_destroy,
2309 };
2310 
2311 static int video_info_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
2312 {
2313  struct pjsip_transaction *tsx;
2314  pjsip_tx_data *tdata;
2315 
2316  if (!session->channel
2317  || !ast_sip_are_media_types_equal(&rdata->msg_info.msg->body->content_type,
2319  return 0;
2320  }
2321 
2322  tsx = pjsip_rdata_get_tsx(rdata);
2323 
2325 
2326  if (pjsip_dlg_create_response(session->inv_session->dlg, rdata, 200, NULL, &tdata) == PJ_SUCCESS) {
2327  pjsip_dlg_send_response(session->inv_session->dlg, tsx, tdata);
2328  }
2329 
2330  return 0;
2331 }
2332 
2334  .method = "INFO",
2335  .incoming_request = video_info_incoming_request,
2336 };
2337 
2338 /*! \brief Unloads the sdp RTP/AVP module from Asterisk */
2339 static int unload_module(void)
2340 {
2344 
2345  if (sched) {
2347  }
2348 
2349  return 0;
2350 }
2351 
2352 /*!
2353  * \brief Load the module
2354  *
2355  * Module loading including tests for configuration or dependencies.
2356  * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
2357  * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
2358  * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the
2359  * configuration file or other non-critical problem return
2360  * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
2361  */
2362 static int load_module(void)
2363 {
2364  if (ast_check_ipv6()) {
2365  ast_sockaddr_parse(&address_rtp, "::", 0);
2366  } else {
2367  ast_sockaddr_parse(&address_rtp, "0.0.0.0", 0);
2368  }
2369 
2370  if (!(sched = ast_sched_context_create())) {
2371  ast_log(LOG_ERROR, "Unable to create scheduler context.\n");
2372  goto end;
2373  }
2374 
2376  ast_log(LOG_ERROR, "Unable to create scheduler context thread.\n");
2377  goto end;
2378  }
2379 
2381  ast_log(LOG_ERROR, "Unable to register SDP handler for %s stream type\n", STR_AUDIO);
2382  goto end;
2383  }
2384 
2386  ast_log(LOG_ERROR, "Unable to register SDP handler for %s stream type\n", STR_VIDEO);
2387  goto end;
2388  }
2389 
2391 
2392  return AST_MODULE_LOAD_SUCCESS;
2393 end:
2394  unload_module();
2395 
2396  return AST_MODULE_LOAD_DECLINE;
2397 }
2398 
2399 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP SDP RTP/AVP stream handler",
2400  .support_level = AST_MODULE_SUPPORT_CORE,
2401  .load = load_module,
2402  .unload = unload_module,
2403  .load_pri = AST_MODPRI_CHANNEL_DRIVER,
2404  .requires = "res_pjsip,res_pjsip_session",
2405 );
Access Control of various sorts.
enum queue_result id
Definition: app_queue.c:1640
Asterisk main include file. File version handling, generic pbx functions.
static struct ast_mansession session
#define ast_free(a)
Definition: astmm.h:180
#define ast_strndup(str, len)
A wrapper for strndup()
Definition: astmm.h:256
#define ast_log
Definition: astobj2.c:42
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
static int tmp()
Definition: bt_open.c:389
Internal Asterisk hangup causes.
#define AST_CAUSE_REQUESTED_CHAN_UNAVAIL
Definition: causes.h:125
static snd_pcm_format_t format
Definition: chan_alsa.c:106
static struct ast_sockaddr media_address
Definition: chan_sip.c:1139
General Asterisk PBX channel definitions.
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.
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
@ AST_SOFTHANGUP_DEV
Definition: channel.h:1121
#define ast_channel_lock(chan)
Definition: channel.h:2922
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1225
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:1133
const char * ast_channel_name(const struct ast_channel *chan)
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5839
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10731
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
Definition: channel.c:2470
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Definition: channel.c:1210
int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
Queue a hold frame.
Definition: channel.c:1185
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition: channel.c:5880
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1448
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
#define ast_channel_unlock(chan)
Definition: channel.h:2923
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_UP
Definition: channelstate.h:42
static struct ao2_container * codecs
Registered codecs.
Definition: codec.c:48
ast_media_type
Types of media.
Definition: codec.h:30
@ AST_MEDIA_TYPE_AUDIO
Definition: codec.h:32
@ AST_MEDIA_TYPE_UNKNOWN
Definition: codec.h:31
@ AST_MEDIA_TYPE_VIDEO
Definition: codec.h:33
const char * ast_codec_media_type2str(enum ast_media_type type)
Conversion function to take a media type and turn it into a string.
Definition: codec.c:347
Convenient Signal Processing routines.
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1773
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
int ast_dsp_get_features(struct ast_dsp *dsp)
Get features.
Definition: dsp.c:1767
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1758
char * end
Definition: eagi_proxy.c:73
char * address
Definition: f2c.h:59
Media Format API.
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
enum ast_media_type ast_format_get_type(const struct ast_format *format)
Get the media type of a format.
Definition: format.c:354
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
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
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
Media Format Cache API.
Format Capabilities API.
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:324
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
unsigned int ast_format_cap_get_framing(const struct ast_format_cap *cap)
Get the global framing.
Definition: format_cap.c:438
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
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
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
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
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
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
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
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
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition: format_cap.h:99
void ast_format_cap_set_framing(struct ast_format_cap *cap, unsigned int framing)
Set the global framing.
Definition: format_cap.c:136
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
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
static const char name[]
Definition: format_mp3.c:68
direction
@ AST_CONTROL_VIDUPDATE
@ AST_CONTROL_UPDATE_RTP_PEER
struct ast_frame ast_null_frame
Definition: main/frame.c:79
#define ast_debug(level,...)
Log a DEBUG message.
#define SCOPE_EXIT_RTN(...)
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
#define SCOPE_ENTER(level,...)
#define LOG_ERROR
#define LOG_NOTICE
#define LOG_WARNING
A set of macros to manage forward-linked lists.
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
Asterisk module definitions.
@ AST_MODFLAG_LOAD_ORDER
Definition: module.h:317
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:543
@ AST_MODPRI_CHANNEL_DRIVER
Definition: module.h:327
@ AST_MODULE_SUPPORT_CORE
Definition: module.h:121
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
Network socket handling.
@ AST_AF_UNSPEC
Definition: netsock2.h:54
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
#define AST_SOCKADDR_STR_ADDR
Definition: netsock2.h:198
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:517
int ast_sockaddr_is_any(const struct ast_sockaddr *addr)
Determine if the address type is unspecified, or "any" address.
Definition: netsock2.c:534
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
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
char * ast_sockaddr_stringify_fmt(const struct ast_sockaddr *addr, int format)
Convert a socket address to a string.
Definition: netsock2.c:65
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized,...
Definition: netsock2.h:127
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:532
pjsip_media_type pjsip_media_type_application_media_control_xml
Definition: res_pjsip.c:2635
ast_sip_session_media_encryption
Definition: res_pjsip.h:525
@ AST_SIP_MEDIA_ENCRYPT_SDES
Definition: res_pjsip.h:531
@ AST_SIP_MEDIA_TRANSPORT_INVALID
Definition: res_pjsip.h:527
@ AST_SIP_MEDIA_ENCRYPT_NONE
Definition: res_pjsip.h:529
@ AST_SIP_MEDIA_ENCRYPT_DTLS
Definition: res_pjsip.h:533
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:2035
int ast_sip_are_media_types_equal(pjsip_media_type *a, pjsip_media_type *b)
Compare pjsip media types.
Definition: res_pjsip.c:2053
@ AST_SIP_DTMF_AUTO_INFO
Definition: res_pjsip.h:440
@ AST_SIP_DTMF_AUTO
Definition: res_pjsip.h:438
@ AST_SIP_DTMF_INBAND
Definition: res_pjsip.h:434
@ AST_SIP_DTMF_RFC_4733
Definition: res_pjsip.h:432
#define ast_sip_transport_is_nonlocal(transport_state, addr)
Definition: res_pjsip.h:178
struct ast_sip_transport_state * ast_sip_get_transport_state(const char *transport_id)
Retrieve transport state.
const char * ast_sip_get_host_ip_string(int af)
Retrieve the local host address in string form.
Definition: res_pjsip.c:2296
static int send_keepalive(const void *data)
static void apply_dtls_attrib(struct ast_sip_session_media *session_media, pjmedia_sdp_attr *attr)
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.
static void set_session_media_remotely_held(struct ast_sip_session_media *session_media, const struct ast_sip_session *session, const pjmedia_sdp_media *media, const struct ast_stream *stream, const struct ast_sockaddr *addrs)
static void check_ice_support(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *remote_stream)
Function which checks for ice attributes in an audio stream.
static 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.
static struct ast_sched_context * sched
Scheduler for RTCP purposes.
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)
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.
static int set_caps(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct ast_sip_session_media *session_media_transport, const struct pjmedia_sdp_media *stream, int is_offer, struct ast_stream *asterisk_stream)
static pjmedia_sdp_attr * generate_rtpmap_attr(struct ast_sip_session *session, pjmedia_sdp_media *media, pj_pool_t *pool, int rtp_code, int asterisk_format, struct ast_format *format, int code)
static int media_session_rtp_write_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct ast_frame *frame)
static int rtp_check_timeout(const void *data)
Check whether RTP is being received or not.
static const char STR_AUDIO[]
static struct ast_sip_session_sdp_handler audio_sdp_handler
SDP handler for 'audio' media stream.
static int apply_cap_to_bundled(struct ast_sip_session_media *session_media, struct ast_sip_session_media *session_media_transport, struct ast_stream *asterisk_stream, struct ast_format_cap *joint)
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.
static void add_extmap_to_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media)
static int setup_media_encryption(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream)
static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp_media *stream, struct ast_rtp_codecs *codecs, struct ast_sip_session_media *session_media, struct ast_format_cap *astformats)
static void stream_stop(struct ast_sip_session_media *session_media)
Function which stops the RTP instance.
static pjmedia_sdp_attr * generate_fmtp_attr(pj_pool_t *pool, struct ast_format *format, int rtp_code)
static struct ast_frame * media_session_rtp_read_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
static int setup_srtp(struct ast_sip_session_media *session_media)
static void stream_destroy(struct ast_sip_session_media *session_media)
Function which destroys the RTP instance when session ends.
static int parse_dtls_attrib(struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream)
static const char STR_VIDEO[]
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.
static struct ast_frame * media_session_rtcp_read_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
static int media_stream_has_crypto(const struct pjmedia_sdp_media *stream)
figure out if media stream has crypto lines for sdes
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.
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.
static void process_ice_auth_attrb(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream)
static struct ast_format_cap * set_incoming_call_offer_cap(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *stream)
static void add_rtcp_fb_to_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media)
static struct ast_sockaddr address_rtp
Address for RTP.
static void add_msid_to_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media, struct ast_stream *stream)
static struct ast_sip_session_sdp_handler video_sdp_handler
SDP handler for 'video' media stream.
static int load_module(void)
Load the module.
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
static int unload_module(void)
Unloads the sdp RTP/AVP module from Asterisk.
static int video_info_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
static struct ast_sip_session_supplement video_info_supplement
static int add_crypto_to_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media)
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.
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.
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.
static int setup_sdes_srtp(struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *stream)
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.
static int setup_dtls_srtp(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
static void set_ice_components(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
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.
void ast_sip_session_unregister_sdp_handler(struct ast_sip_session_sdp_handler *handler, const char *stream_type)
Unregister an SDP handler.
int ast_sip_session_register_sdp_handler(struct ast_sip_session_sdp_handler *handler, const char *stream_type)
Register an SDP handler.
int ast_sip_session_is_pending_stream_default(const struct ast_sip_session *session, const struct ast_stream *stream)
Determines if a provided pending stream will be the default stream or not.
int ast_sip_session_media_add_read_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media, int fd, ast_sip_session_media_read_cb callback)
Set a read callback for a media session with a specific file descriptor.
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
#define ast_sip_session_register_supplement(supplement)
struct ast_sip_session_media * ast_sip_session_media_get_transport(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
Retrieve the underlying media session that is acting as transport for a media session.
void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement)
Unregister a an supplement to SIP session processing.
Definition: pjsip_session.c:63
int ast_sip_session_media_set_write_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media, ast_sip_session_media_write_cb callback)
Set a write callback for a media session.
struct ast_format_cap * ast_sip_session_create_joint_call_cap(const struct ast_sip_session *session, enum ast_media_type media_type, const struct ast_format_cap *remote)
Create joint capabilities.
static uint32_t keepalive
Definition: res_pktccops.c:162
@ AST_AES_CM_128_HMAC_SHA1_80
Definition: res_srtp.h:58
@ AST_AES_CM_128_HMAC_SHA1_32
Definition: res_srtp.h:59
#define NULL
Definition: resample.c:96
Pluggable RTP Architecture.
ast_rtp_dtls_setup
DTLS setup types.
Definition: rtp_engine.h:513
@ AST_RTP_DTLS_SETUP_PASSIVE
Definition: rtp_engine.h:515
@ AST_RTP_DTLS_SETUP_HOLDCONN
Definition: rtp_engine.h:517
@ AST_RTP_DTLS_SETUP_ACTPASS
Definition: rtp_engine.h:516
@ AST_RTP_DTLS_SETUP_ACTIVE
Definition: rtp_engine.h:514
struct ast_rtp_instance * ast_rtp_instance_new(const char *engine_name, struct ast_sched_context *sched, const struct ast_sockaddr *sa, void *data)
Create a new RTP instance.
Definition: rtp_engine.c:465
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:727
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:2014
@ AST_RTP_ICE_ROLE_CONTROLLING
Definition: rtp_engine.h:470
@ AST_RTP_ICE_ROLE_CONTROLLED
Definition: rtp_engine.h:469
void ast_rtp_codecs_payloads_destroy(struct ast_rtp_codecs *codecs)
Destroy the contents of an RTP codecs structure (but not the structure itself)
Definition: rtp_engine.c:974
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
Definition: rtp_engine.c:458
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:2129
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:1915
const char * ast_rtp_instance_get_cname(struct ast_rtp_instance *rtp)
Retrieve the CNAME used in RTCP SDES items.
Definition: rtp_engine.c:3784
const char * ast_rtp_instance_extmap_get_uri(struct ast_rtp_instance *instance, int id)
Retrieve the URI for an RTP extension id.
Definition: rtp_engine.c:946
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:2883
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:3766
ast_rtp_dtls_hash
DTLS fingerprint hashes.
Definition: rtp_engine.h:527
@ AST_RTP_DTLS_HASH_SHA1
Definition: rtp_engine.h:529
@ AST_RTP_DTLS_HASH_SHA256
Definition: rtp_engine.h:528
@ AST_RTP_DTMF_MODE_RFC2833
Definition: rtp_engine.h:152
@ AST_RTP_DTMF_MODE_INBAND
Definition: rtp_engine.h:154
@ AST_RTP_DTMF_MODE_NONE
Definition: rtp_engine.h:150
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:2115
void ast_rtp_instance_stop(struct ast_rtp_instance *instance)
Stop an RTP instance.
Definition: rtp_engine.c:2175
#define AST_RTP_DTMF
Definition: rtp_engine.h:266
ast_rtp_instance_rtcp
Definition: rtp_engine.h:255
@ AST_RTP_INSTANCE_RTCP_MUX
Definition: rtp_engine.h:261
@ AST_RTP_INSTANCE_RTCP_STANDARD
Definition: rtp_engine.h:259
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:1216
size_t ast_rtp_instance_extmap_count(struct ast_rtp_instance *instance)
Get the number of known unique identifiers.
Definition: rtp_engine.c:899
int ast_rtp_instance_extmap_enable(struct ast_rtp_instance *instance, int id, enum ast_rtp_extension extension, enum ast_rtp_extension_direction direction)
Enable support for an RTP extension on an instance.
Definition: rtp_engine.c:732
@ AST_RTP_INSTANCE_STAT_REMOTE_SSRC
Definition: rtp_engine.h:246
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:3823
int ast_rtp_instance_get_keepalive(struct ast_rtp_instance *instance)
Get the RTP keepalive interval.
Definition: rtp_engine.c:2687
int ast_rtp_instance_get_timeout(struct ast_rtp_instance *instance)
Get the RTP timeout value.
Definition: rtp_engine.c:2677
#define ast_debug_rtp(sublevel,...)
Log debug level RTP information.
Definition: rtp_engine.h:2860
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:3797
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:1529
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:1550
time_t ast_rtp_instance_get_last_tx(const struct ast_rtp_instance *rtp)
Get the last RTP transmission time.
Definition: rtp_engine.c:3751
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:1293
void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
Set the value of an RTP instance property.
Definition: rtp_engine.c:705
void ast_rtp_instance_get_local_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the local address that we are expecting RTP on.
Definition: rtp_engine.c:643
int ast_rtp_instance_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:2438
@ AST_RTP_ICE_CANDIDATE_TYPE_RELAYED
Definition: rtp_engine.h:458
@ AST_RTP_ICE_CANDIDATE_TYPE_SRFLX
Definition: rtp_engine.h:457
@ AST_RTP_ICE_CANDIDATE_TYPE_HOST
Definition: rtp_engine.h:456
enum ast_rtp_extension ast_rtp_instance_extmap_get_extension(struct ast_rtp_instance *instance, int id)
Retrieve the extension for an RTP extension id.
Definition: rtp_engine.c:910
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
Definition: rtp_engine.c:568
ast_rtp_extension
Known RTP extensions.
Definition: rtp_engine.h:542
@ AST_RTP_EXTENSION_TRANSPORT_WIDE_CC
Definition: rtp_engine.h:548
@ AST_RTP_EXTENSION_ABS_SEND_TIME
Definition: rtp_engine.h:546
@ AST_RTP_EXTENSION_UNSUPPORTED
Definition: rtp_engine.h:544
struct ast_frame * ast_rtp_instance_read(struct ast_rtp_instance *instance, int rtcp)
Receive a frame over RTP.
Definition: rtp_engine.c:578
#define ast_rtp_instance_set_remote_address(instance, address)
Set the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1080
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:2764
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:3814
ast_rtp_options
Definition: rtp_engine.h:142
@ AST_RTP_OPT_G726_NONSTANDARD
Definition: rtp_engine.h:144
@ AST_RTP_DTLS_CONNECTION_NEW
Definition: rtp_engine.h:522
@ AST_RTP_DTLS_CONNECTION_EXISTING
Definition: rtp_engine.h:523
int ast_rtp_codecs_payloads_initialize(struct ast_rtp_codecs *codecs)
Initialize an RTP codecs structure.
Definition: rtp_engine.c:958
@ AST_RTP_PROPERTY_NAT
Definition: rtp_engine.h:115
@ AST_RTP_PROPERTY_RETRANS_RECV
Definition: rtp_engine.h:127
@ AST_RTP_PROPERTY_RETRANS_SEND
Definition: rtp_engine.h:129
@ AST_RTP_PROPERTY_RTCP
Definition: rtp_engine.h:123
@ AST_RTP_PROPERTY_ASYMMETRIC_CODEC
Definition: rtp_engine.h:125
@ AST_RTP_PROPERTY_DTMF
Definition: rtp_engine.h:117
@ AST_RTP_PROPERTY_REMB
Definition: rtp_engine.h:131
#define AST_RTP_PT_LAST_STATIC
Definition: rtp_engine.h:89
#define ast_debug_ice(sublevel,...)
Log debug level ICE information.
Definition: rtp_engine.h:2898
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:2639
time_t ast_rtp_instance_get_last_rx(const struct ast_rtp_instance *rtp)
Get the last RTP reception time.
Definition: rtp_engine.c:3761
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:2161
void ast_rtp_instance_set_channel_id(struct ast_rtp_instance *instance, const char *uniqueid)
Set the channel that owns this RTP instance.
Definition: rtp_engine.c:553
ast_rtp_extension_direction
Directions for RTP extensions.
Definition: rtp_engine.h:769
@ AST_RTP_EXTENSION_DIRECTION_SENDRECV
Definition: rtp_engine.h:773
@ AST_RTP_EXTENSION_DIRECTION_NONE
Definition: rtp_engine.h:771
@ AST_RTP_EXTENSION_DIRECTION_INACTIVE
Definition: rtp_engine.h:779
@ AST_RTP_EXTENSION_DIRECTION_RECVONLY
Definition: rtp_engine.h:777
@ AST_RTP_EXTENSION_DIRECTION_SENDONLY
Definition: rtp_engine.h:775
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:3003
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:1495
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:1335
#define AST_RTP_CODECS_NULL_INIT
Definition: rtp_engine.h:716
int ast_rtp_instance_extmap_get_id(struct ast_rtp_instance *instance, enum ast_rtp_extension extension)
Retrieve the id for an RTP extension.
Definition: rtp_engine.c:886
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:1984
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:2152
int ast_rtp_instance_extmap_negotiate(struct ast_rtp_instance *instance, int id, enum ast_rtp_extension_direction direction, const char *uri, const char *attributes)
Negotiate received RTP extension information.
Definition: rtp_engine.c:818
void ast_rtp_instance_extmap_clear(struct ast_rtp_instance *instance)
Clear negotiated RTP extension information.
Definition: rtp_engine.c:862
#define AST_RTP_MAX
Definition: rtp_engine.h:272
const char * ast_rtp_instance_get_channel_id(struct ast_rtp_instance *instance)
Get the unique ID of the channel that owns this RTP instance.
Definition: rtp_engine.c:548
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:2184
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:1561
void ast_rtp_instance_set_keepalive(struct ast_rtp_instance *instance, int timeout)
Set the RTP keepalive interval.
Definition: rtp_engine.c:2672
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:3771
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:1865
enum ast_rtp_extension_direction ast_rtp_instance_extmap_get_direction(struct ast_rtp_instance *instance, int id)
Retrieve the negotiated direction for an RTP extension id.
Definition: rtp_engine.c:930
void 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:1249
void ast_rtp_instance_set_timeout(struct ast_rtp_instance *instance, int timeout)
Set the RTP timeout value.
Definition: rtp_engine.c:2662
Scheduler Routines (derived from cheops)
#define AST_SCHED_DEL(sched, id)
Remove a scheduler entry.
Definition: sched.h:46
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:238
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
Definition: sched.c:271
int ast_sched_start_thread(struct ast_sched_context *con)
Start a thread for processing scheduler entries.
Definition: sched.c:197
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
SRTP and SDP Security descriptions.
struct ast_sdp_srtp * ast_sdp_srtp_alloc(void)
allocate a ast_sdp_srtp structure
Definition: sdp_srtp.c:41
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
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_sdp_crypto * ast_sdp_crypto_alloc(void)
Initialize an return an ast_sdp_crypto struct.
Definition: sdp_srtp.c:71
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
#define AST_SRTP_CRYPTO_OFFER_OK
Definition: sdp_srtp.h:45
media_type
Media types generate different "dummy answers" for not accepting the offer of a media stream....
Definition: sip.h:486
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition: sorcery.c:1853
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
Media Stream API.
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_stream_set_metadata(struct ast_stream *stream, const char *m_key, const char *value)
Set a stream metadata value.
Definition: stream.c:460
@ AST_STREAM_STATE_RECVONLY
Set when the stream is receiving media only.
Definition: stream.h:90
@ AST_STREAM_STATE_INACTIVE
Set when the stream is not sending OR receiving media.
Definition: stream.h:94
@ AST_STREAM_STATE_REMOVED
Set when the stream has been removed/declined.
Definition: stream.h:78
@ AST_STREAM_STATE_SENDONLY
Set when the stream is sending media only.
Definition: stream.h:86
int ast_stream_get_position(const struct ast_stream *stream)
Get the position of the stream in the topology.
Definition: stream.c:500
void ast_stream_set_state(struct ast_stream *stream, enum ast_stream_state state)
Set the state of a stream.
Definition: stream.c:380
enum ast_stream_state ast_stream_get_state(const struct ast_stream *stream)
Get the current state of a stream.
Definition: stream.c:373
int ast_stream_get_group(const struct ast_stream *stream)
Get the stream group that a stream is part of.
Definition: stream.c:1077
enum ast_media_type ast_stream_get_type(const struct ast_stream *stream)
Get the media type of a stream.
Definition: stream.c:316
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
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
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
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:1117
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:739
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ast_str_tmp(init_len, __expr)
Provides a temporary ast_str and returns a copy of its buffer.
Definition: strings.h:1167
#define ast_str_alloca(init_len)
Definition: strings.h:826
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:640
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:1091
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:711
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:406
Generic container type.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
Main Channel structure associated with a channel.
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
Definition of a media format.
Definition: format.c:43
Data structure associated with a single frame of data.
Structure that represents the optional DTLS SRTP support within an RTP engine.
Definition: rtp_engine.h:570
int(* set_configuration)(struct ast_rtp_instance *instance, const struct ast_rtp_dtls_cfg *dtls_cfg)
Definition: rtp_engine.h:572
enum ast_rtp_dtls_setup(* get_setup)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:582
enum ast_rtp_dtls_hash(* get_fingerprint_hash)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:588
const char *(* get_fingerprint)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:590
void(* reset)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:578
void(* set_fingerprint)(struct ast_rtp_instance *instance, enum ast_rtp_dtls_hash hash, const char *fingerprint)
Definition: rtp_engine.h:586
enum ast_rtp_dtls_connection(* get_connection)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:580
void(* set_setup)(struct ast_rtp_instance *instance, enum ast_rtp_dtls_setup setup)
Definition: rtp_engine.h:584
Structure for an ICE candidate.
Definition: rtp_engine.h:474
struct ast_sockaddr address
Definition: rtp_engine.h:479
enum ast_rtp_ice_component_type id
Definition: rtp_engine.h:476
struct ast_sockaddr relay_address
Definition: rtp_engine.h:480
enum ast_rtp_ice_candidate_type type
Definition: rtp_engine.h:481
Structure that represents the optional ICE support within an RTP engine.
Definition: rtp_engine.h:485
void(* ice_lite)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:501
struct ao2_container *(* get_local_candidates)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:499
void(* stop)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:493
const char *(* get_password)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:497
void(* change_components)(struct ast_rtp_instance *instance, int num_components)
Definition: rtp_engine.h:509
void(* set_authentication)(struct ast_rtp_instance *instance, const char *ufrag, const char *password)
Definition: rtp_engine.h:487
void(* start)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:491
const char *(* get_ufrag)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:495
void(* add_remote_candidate)(struct ast_rtp_instance *instance, const struct ast_rtp_engine_ice_candidate *candidate)
Definition: rtp_engine.h:489
void(* set_role)(struct ast_rtp_instance *instance, enum ast_rtp_ice_role role)
Definition: rtp_engine.h:503
unsigned int remote_ssrc
Definition: rtp_engine.h:424
structure for secure RTP audio
Definition: sdp_srtp.h:38
struct ast_sdp_srtp::@308 sdp_srtp_list
struct ast_sdp_crypto * crypto
Definition: sdp_srtp.h:40
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:806
An entity with which Asterisk communicates.
Definition: res_pjsip.h:854
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:887
enum ast_sip_session_media_encryption encryption
Definition: res_pjsip.h:749
unsigned int encryption_optimistic
Definition: res_pjsip.h:751
A structure containing SIP session media information.
struct ast_sdp_srtp * srtp
Holds SRTP information.
unsigned int remotely_held_changed
Stream is held by remote side changed during this negotiation.
char label[AST_UUID_STR_LEN]
Track label.
unsigned int remote_ice
Does remote support ice.
enum ast_media_type type
Media type of this session media.
unsigned int locally_held
Stream is on hold by local side.
unsigned int remote_rtcp_mux
Does remote support rtcp_mux.
int timeout_sched_id
Scheduler ID for RTP timeout.
int stream_num
The stream number to place into any resulting frames.
int bundle_group
The bundle group the stream belongs to.
unsigned int remotely_held
Stream is on hold by remote side.
struct ast_rtp_instance * rtp
RTP instance itself.
enum ast_sip_session_media_encryption encryption
What type of encryption is in use on this stream.
struct ast_sockaddr direct_media_addr
Direct media address.
char mslabel[AST_UUID_STR_LEN]
Media stream label.
pj_str_t transport
The media transport in use for this stream.
unsigned int bundled
Whether this stream is currently bundled or not.
unsigned int changed
The underlying session has been changed in some fashion.
int keepalive_sched_id
Scheduler ID for RTP keepalive.
A handler for SDPs in SIP sessions.
A supplement to SIP message processing.
A structure describing a SIP session.
Structure for SIP transport information.
Definition: res_pjsip.h:103
struct pjsip_transport * transport
Transport itself.
Definition: res_pjsip.h:105
Transport to bind to.
Definition: res_pjsip.h:187
Socket address structure.
Definition: netsock2.h:97
Support for dynamic strings.
Definition: strings.h:604
structure to hold extensions
Definition: sched.c:76
int value
Definition: syslog.c:37
static struct test_options options
Utility functions.
#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:936
#define ast_assert(a)
Definition: utils.h:734
#define ast_set_flag(p, flag)
Definition: utils.h:70
int ast_check_ipv6(void)
Test that an OS supports IPv6 Networking.
Definition: main/utils.c:2688
#define AST_UUID_STR_LEN
Definition: uuid.h:27
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
Definition: uuid.c:141
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680