Asterisk - The Open Source Telephony Project  18.5.0
Functions | Variables
res_pjsip_sdp_rtp.c File Reference

SIP SDP media stream handling. More...

#include "asterisk.h"
#include <pjsip.h>
#include <pjsip_ua.h>
#include <pjmedia.h>
#include <pjlib.h>
#include "asterisk/utils.h"
#include "asterisk/module.h"
#include "asterisk/format.h"
#include "asterisk/format_cap.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/netsock2.h"
#include "asterisk/channel.h"
#include "asterisk/causes.h"
#include "asterisk/sched.h"
#include "asterisk/acl.h"
#include "asterisk/sdp_srtp.h"
#include "asterisk/dsp.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stream.h"
#include "asterisk/logger_category.h"
#include "asterisk/format_cache.h"
#include "asterisk/res_pjsip.h"
#include "asterisk/res_pjsip_session.h"
#include "asterisk/res_pjsip_session_caps.h"
Include dependency graph for res_pjsip_sdp_rtp.c:

Go to the source code of this file.

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
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 add_extmap_to_stream (struct ast_sip_session *session, struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media)
 
static void 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. More...
 
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 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 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. More...
 
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 apply_dtls_attrib (struct ast_sip_session_media *session_media, pjmedia_sdp_attr *attr)
 
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)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
static pjmedia_sdp_attr * generate_fmtp_attr (pj_pool_t *pool, struct ast_format *format, int rtp_code)
 
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 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)
 
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 More...
 
static int load_module (void)
 Load the module. More...
 
static struct ast_framemedia_session_rtcp_read_callback (struct ast_sip_session *session, struct ast_sip_session_media *session_media)
 
static struct ast_framemedia_session_rtp_read_callback (struct ast_sip_session *session, struct ast_sip_session_media *session_media)
 
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 media_stream_has_crypto (const struct pjmedia_sdp_media *stream)
 figure out if media stream has crypto lines for sdes More...
 
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. More...
 
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 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. More...
 
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. More...
 
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 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. More...
 
static int rtp_check_timeout (const void *data)
 Check whether RTP is being received or not. More...
 
static int send_keepalive (const void *data)
 
static int set_caps (struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct ast_sip_session_media *session_media_transport, const struct pjmedia_sdp_media *stream, int is_offer, struct ast_stream *asterisk_stream)
 
static void set_ice_components (struct ast_sip_session *session, struct ast_sip_session_media *session_media)
 
static struct ast_format_capset_incoming_call_offer_cap (struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *stream)
 
static int setup_dtls_srtp (struct ast_sip_session *session, struct ast_sip_session_media *session_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 int setup_sdes_srtp (struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *stream)
 
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. More...
 
static void stream_stop (struct ast_sip_session_media *session_media)
 Function which stops the RTP instance. More...
 
static int unload_module (void)
 Unloads the sdp RTP/AVP module from Asterisk. More...
 
static int video_info_incoming_request (struct ast_sip_session *session, struct pjsip_rx_data *rdata)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP SDP RTP/AVP stream handler" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .requires = "res_pjsip,res_pjsip_session", }
 
static struct ast_sockaddr address_rtp
 Address for RTP. More...
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_sip_session_sdp_handler audio_sdp_handler
 SDP handler for 'audio' media stream. More...
 
static struct ast_sched_contextsched
 Scheduler for RTCP purposes. More...
 
static const char STR_AUDIO [] = "audio"
 
static const char STR_VIDEO [] = "video"
 
static struct ast_sip_session_supplement video_info_supplement
 
static struct ast_sip_session_sdp_handler video_sdp_handler
 SDP handler for 'video' media stream. More...
 

Detailed Description

SIP SDP media stream handling.

Author
Joshua Colp jcolp[email protected]@dig[email protected]ium.c[email protected]om

Definition in file res_pjsip_sdp_rtp.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 2390 of file res_pjsip_sdp_rtp.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 2390 of file res_pjsip_sdp_rtp.c.

◆ add_crypto_to_stream()

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

Definition at line 1580 of file res_pjsip_sdp_rtp.c.

References ast_free, AST_LIST_NEXT, AST_RTP_DTLS_CONNECTION_EXISTING, AST_RTP_DTLS_CONNECTION_NEW, AST_RTP_DTLS_HASH_SHA1, AST_RTP_DTLS_HASH_SHA256, AST_RTP_DTLS_SETUP_ACTIVE, AST_RTP_DTLS_SETUP_ACTPASS, AST_RTP_DTLS_SETUP_HOLDCONN, AST_RTP_DTLS_SETUP_PASSIVE, ast_rtp_instance_get_dtls(), ast_sdp_srtp_alloc(), ast_sdp_srtp_get_attrib(), AST_SIP_MEDIA_ENCRYPT_DTLS, AST_SIP_MEDIA_ENCRYPT_NONE, AST_SIP_MEDIA_ENCRYPT_SDES, AST_SIP_MEDIA_TRANSPORT_INVALID, ast_str_buffer(), ast_str_create, ast_str_set(), ast_rtp_dtls_cfg::default_setup, ast_sip_media_rtp_configuration::dtls_cfg, ast_sip_session_media::encryption, ast_sip_session::endpoint, ast_rtp_engine_dtls::get_connection, ast_rtp_engine_dtls::get_fingerprint, ast_rtp_engine_dtls::get_fingerprint_hash, ast_rtp_engine_dtls::get_setup, ast_sip_session::inv_session, ast_sip_endpoint::media, RAII_VAR, ast_sip_session_media::rtp, ast_sip_endpoint_media_configuration::rtp, ast_sdp_srtp::sdp_srtp_list, setup_dtls_srtp(), ast_sip_session_media::srtp, ast_sip_media_rtp_configuration::srtp_tag_32, and tmp().

Referenced by create_outgoing_sdp_stream().

1583 {
1584  pj_str_t stmp;
1585  pjmedia_sdp_attr *attr;
1586  enum ast_rtp_dtls_hash hash;
1587  const char *crypto_attribute;
1588  struct ast_rtp_engine_dtls *dtls;
1589  struct ast_sdp_srtp *tmp;
1590  static const pj_str_t STR_NEW = { "new", 3 };
1591  static const pj_str_t STR_EXISTING = { "existing", 8 };
1592  static const pj_str_t STR_ACTIVE = { "active", 6 };
1593  static const pj_str_t STR_PASSIVE = { "passive", 7 };
1594  static const pj_str_t STR_ACTPASS = { "actpass", 7 };
1595  static const pj_str_t STR_HOLDCONN = { "holdconn", 8 };
1596  enum ast_rtp_dtls_setup setup;
1597 
1598  switch (session_media->encryption) {
1601  break;
1603  if (!session_media->srtp) {
1604  session_media->srtp = ast_sdp_srtp_alloc();
1605  if (!session_media->srtp) {
1606  return -1;
1607  }
1608  }
1609 
1610  tmp = session_media->srtp;
1611 
1612  do {
1613  crypto_attribute = ast_sdp_srtp_get_attrib(tmp,
1614  0 /* DTLS running? No */,
1615  session->endpoint->media.rtp.srtp_tag_32 /* 32 byte tag length? */);
1616  if (!crypto_attribute) {
1617  /* No crypto attribute to add, bad news */
1618  return -1;
1619  }
1620 
1621  attr = pjmedia_sdp_attr_create(pool, "crypto",
1622  pj_cstr(&stmp, crypto_attribute));
1623  media->attr[media->attr_count++] = attr;
1624  } while ((tmp = AST_LIST_NEXT(tmp, sdp_srtp_list)));
1625 
1626  break;
1628  if (setup_dtls_srtp(session, session_media)) {
1629  return -1;
1630  }
1631 
1632  dtls = ast_rtp_instance_get_dtls(session_media->rtp);
1633  if (!dtls) {
1634  return -1;
1635  }
1636 
1637  switch (dtls->get_connection(session_media->rtp)) {
1639  attr = pjmedia_sdp_attr_create(pool, "connection", &STR_NEW);
1640  media->attr[media->attr_count++] = attr;
1641  break;
1643  attr = pjmedia_sdp_attr_create(pool, "connection", &STR_EXISTING);
1644  media->attr[media->attr_count++] = attr;
1645  break;
1646  default:
1647  break;
1648  }
1649 
1650  /* If this is an answer we need to use our current state, if it's an offer we need to use
1651  * the configured value.
1652  */
1653  if (session->inv_session->neg
1654  && pjmedia_sdp_neg_get_state(session->inv_session->neg) != PJMEDIA_SDP_NEG_STATE_DONE) {
1655  setup = dtls->get_setup(session_media->rtp);
1656  } else {
1657  setup = session->endpoint->media.rtp.dtls_cfg.default_setup;
1658  }
1659 
1660  switch (setup) {
1662  attr = pjmedia_sdp_attr_create(pool, "setup", &STR_ACTIVE);
1663  media->attr[media->attr_count++] = attr;
1664  break;
1666  attr = pjmedia_sdp_attr_create(pool, "setup", &STR_PASSIVE);
1667  media->attr[media->attr_count++] = attr;
1668  break;
1670  attr = pjmedia_sdp_attr_create(pool, "setup", &STR_ACTPASS);
1671  media->attr[media->attr_count++] = attr;
1672  break;
1674  attr = pjmedia_sdp_attr_create(pool, "setup", &STR_HOLDCONN);
1675  break;
1676  default:
1677  break;
1678  }
1679 
1680  hash = dtls->get_fingerprint_hash(session_media->rtp);
1681  crypto_attribute = dtls->get_fingerprint(session_media->rtp);
1682  if (crypto_attribute && (hash == AST_RTP_DTLS_HASH_SHA1 || hash == AST_RTP_DTLS_HASH_SHA256)) {
1683  RAII_VAR(struct ast_str *, fingerprint, ast_str_create(64), ast_free);
1684  if (!fingerprint) {
1685  return -1;
1686  }
1687 
1688  if (hash == AST_RTP_DTLS_HASH_SHA1) {
1689  ast_str_set(&fingerprint, 0, "SHA-1 %s", crypto_attribute);
1690  } else {
1691  ast_str_set(&fingerprint, 0, "SHA-256 %s", crypto_attribute);
1692  }
1693 
1694  attr = pjmedia_sdp_attr_create(pool, "fingerprint", pj_cstr(&stmp, ast_str_buffer(fingerprint)));
1695  media->attr[media->attr_count++] = attr;
1696  }
1697  break;
1698  }
1699 
1700  return 0;
1701 }
structure for secure RTP audio
Definition: sdp_srtp.h:37
struct ast_sip_endpoint * endpoint
const char *(* get_fingerprint)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:590
struct ast_rtp_dtls_cfg dtls_cfg
DTLS-SRTP configuration information.
Definition: res_pjsip.h:707
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static int tmp()
Definition: bt_open.c:389
static pj_pool_t * pool
Global memory pool for configuration and timers.
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
static int setup_dtls_srtp(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
struct pjsip_inv_session * inv_session
enum ast_rtp_dtls_hash(* get_fingerprint_hash)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:588
enum ast_rtp_dtls_setup(* get_setup)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:582
enum ast_sip_session_media_encryption encryption
What type of encryption is in use on this stream.
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
enum ast_rtp_dtls_connection(* get_connection)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:580
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:764
struct ast_sdp_srtp * srtp
Holds SRTP information.
Structure that represents the optional DTLS SRTP support within an RTP engine.
Definition: rtp_engine.h:570
ast_rtp_dtls_setup
DTLS setup types.
Definition: rtp_engine.h:513
enum ast_rtp_dtls_setup default_setup
Definition: rtp_engine.h:557
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
struct ast_rtp_engine_dtls * ast_rtp_instance_get_dtls(struct ast_rtp_instance *instance)
Obtain a pointer to the DTLS support present on an RTP instance.
Definition: rtp_engine.c:3011
ast_rtp_dtls_hash
DTLS fingerprint hashes.
Definition: rtp_engine.h:527
#define ast_free(a)
Definition: astmm.h:182
struct ast_sdp_srtp * ast_sdp_srtp_alloc(void)
allocate a ast_sdp_srtp structure
Definition: sdp_srtp.c:41
struct ast_sdp_srtp::@318 sdp_srtp_list
struct ast_rtp_instance * rtp
RTP instance itself.
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
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ add_extmap_to_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

Definition at line 1354 of file res_pjsip_sdp_rtp.c.

References AST_MEDIA_TYPE_VIDEO, AST_RTP_EXTENSION_DIRECTION_INACTIVE, AST_RTP_EXTENSION_DIRECTION_NONE, AST_RTP_EXTENSION_DIRECTION_RECVONLY, AST_RTP_EXTENSION_DIRECTION_SENDONLY, AST_RTP_EXTENSION_DIRECTION_SENDRECV, AST_RTP_EXTENSION_UNSUPPORTED, ast_rtp_instance_extmap_count(), ast_rtp_instance_extmap_get_direction(), ast_rtp_instance_extmap_get_extension(), ast_rtp_instance_extmap_get_uri(), ast_sip_session::endpoint, ast_sip_endpoint::media, ast_sip_session_media::rtp, ast_sip_session_media::type, and ast_sip_endpoint_media_configuration::webrtc.

Referenced by create_outgoing_sdp_stream().

1356 {
1357  int idx;
1358  char extmap_value[256];
1359 
1360  if (!session->endpoint->media.webrtc || session_media->type != AST_MEDIA_TYPE_VIDEO) {
1361  return;
1362  }
1363 
1364  /* RTP extension local unique identifiers start at '1' */
1365  for (idx = 1; idx <= ast_rtp_instance_extmap_count(session_media->rtp); ++idx) {
1367  const char *direction_str = "";
1368  pj_str_t stmp;
1369  pjmedia_sdp_attr *attr;
1370 
1371  /* If this is an unsupported RTP extension we can't place it into the SDP */
1372  if (extension == AST_RTP_EXTENSION_UNSUPPORTED) {
1373  continue;
1374  }
1375 
1376  switch (ast_rtp_instance_extmap_get_direction(session_media->rtp, idx)) {
1378  /* Lack of a direction indicates sendrecv, so we leave it out */
1379  direction_str = "";
1380  break;
1382  direction_str = "/sendonly";
1383  break;
1385  direction_str = "/recvonly";
1386  break;
1388  /* It is impossible for a "none" direction extension to be negotiated but just in case
1389  * we treat it as inactive.
1390  */
1392  direction_str = "/inactive";
1393  break;
1394  }
1395 
1396  snprintf(extmap_value, sizeof(extmap_value), "%d%s %s", idx, direction_str,
1397  ast_rtp_instance_extmap_get_uri(session_media->rtp, idx));
1398  attr = pjmedia_sdp_attr_create(pool, "extmap", pj_cstr(&stmp, extmap_value));
1399  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1400  }
1401 }
struct ast_sip_endpoint * endpoint
size_t ast_rtp_instance_extmap_count(struct ast_rtp_instance *instance)
Get the number of known unique identifiers.
Definition: rtp_engine.c:899
static pj_pool_t * pool
Global memory pool for configuration and timers.
ast_rtp_extension
Known RTP extensions.
Definition: rtp_engine.h:542
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
structure to hold extensions
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
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
enum ast_media_type type
Media type of this session media.
struct ast_rtp_instance * rtp
RTP instance itself.
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

◆ add_ice_to_stream()

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 
)
static

Function which adds ICE attributes to a media stream.

Definition at line 675 of file res_pjsip_sdp_rtp.c.

References ast_rtp_engine_ice_candidate::address, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_free, AST_RTP_ICE_CANDIDATE_TYPE_HOST, AST_RTP_ICE_CANDIDATE_TYPE_RELAYED, AST_RTP_ICE_CANDIDATE_TYPE_SRFLX, ast_rtp_instance_get_ice(), ast_sockaddr_isnull(), ast_sockaddr_stringify_addr_remote(), ast_sockaddr_stringify_port(), ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_sip_session::endpoint, ast_rtp_engine_ice_candidate::foundation, ast_rtp_engine_ice::get_local_candidates, ast_rtp_engine_ice::get_password, ast_rtp_engine_ice::get_ufrag, ast_sip_media_rtp_configuration::ice_support, ast_rtp_engine_ice_candidate::id, ast_sip_endpoint::media, password, ast_rtp_engine_ice_candidate::priority, ast_rtp_engine_ice_candidate::relay_address, ast_sip_session_media::remote_ice, ast_sip_session_media::rtp, ast_sip_endpoint_media_configuration::rtp, ast_rtp_engine_ice::stop, ast_rtp_engine_ice_candidate::transport, and ast_rtp_engine_ice_candidate::type.

Referenced by create_outgoing_sdp_stream().

677 {
678  struct ast_rtp_engine_ice *ice;
679  struct ao2_container *candidates;
680  const char *username, *password;
681  pj_str_t stmp;
682  pjmedia_sdp_attr *attr;
683  struct ao2_iterator it_candidates;
684  struct ast_rtp_engine_ice_candidate *candidate;
685 
686  if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) {
687  return;
688  }
689 
690  if (!session_media->remote_ice) {
691  ice->stop(session_media->rtp);
692  return;
693  }
694 
695  if ((username = ice->get_ufrag(session_media->rtp))) {
696  attr = pjmedia_sdp_attr_create(pool, "ice-ufrag", pj_cstr(&stmp, username));
697  media->attr[media->attr_count++] = attr;
698  }
699 
700  if ((password = ice->get_password(session_media->rtp))) {
701  attr = pjmedia_sdp_attr_create(pool, "ice-pwd", pj_cstr(&stmp, password));
702  media->attr[media->attr_count++] = attr;
703  }
704 
705  if (!include_candidates) {
706  return;
707  }
708 
709  candidates = ice->get_local_candidates(session_media->rtp);
710  if (!candidates) {
711  return;
712  }
713 
714  it_candidates = ao2_iterator_init(candidates, 0);
715  for (; (candidate = ao2_iterator_next(&it_candidates)); ao2_ref(candidate, -1)) {
716  struct ast_str *attr_candidate = ast_str_create(128);
717 
718  ast_str_set(&attr_candidate, -1, "%s %u %s %d %s ", candidate->foundation, candidate->id, candidate->transport,
719  candidate->priority, ast_sockaddr_stringify_addr_remote(&candidate->address));
720  ast_str_append(&attr_candidate, -1, "%s typ ", ast_sockaddr_stringify_port(&candidate->address));
721 
722  switch (candidate->type) {
724  ast_str_append(&attr_candidate, -1, "host");
725  break;
727  ast_str_append(&attr_candidate, -1, "srflx");
728  break;
730  ast_str_append(&attr_candidate, -1, "relay");
731  break;
732  }
733 
734  if (!ast_sockaddr_isnull(&candidate->relay_address)) {
735  ast_str_append(&attr_candidate, -1, " raddr %s rport", ast_sockaddr_stringify_addr_remote(&candidate->relay_address));
736  ast_str_append(&attr_candidate, -1, " %s", ast_sockaddr_stringify_port(&candidate->relay_address));
737  }
738 
739  attr = pjmedia_sdp_attr_create(pool, "candidate", pj_cstr(&stmp, ast_str_buffer(attr_candidate)));
740  media->attr[media->attr_count++] = attr;
741 
742  ast_free(attr_candidate);
743  }
744 
745  ao2_iterator_destroy(&it_candidates);
746  ao2_ref(candidates, -1);
747 }
struct ast_sip_endpoint * endpoint
static char * ast_sockaddr_stringify_addr_remote(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:317
const char *(* get_password)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:497
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static pj_pool_t * pool
Global memory pool for configuration and timers.
struct ast_rtp_engine_ice * ast_rtp_instance_get_ice(struct ast_rtp_instance *instance)
Obtain a pointer to the ICE support present on an RTP instance.
Definition: rtp_engine.c:2891
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
void(* stop)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:493
Structure for an ICE candidate.
Definition: rtp_engine.h:474
static struct ast_str * password
Definition: cdr_mysql.c:77
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
enum ast_rtp_ice_candidate_type type
Definition: rtp_engine.h:481
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
static char * ast_sockaddr_stringify_port(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return a port only.
Definition: netsock2.h:362
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:764
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_sockaddr relay_address
Definition: rtp_engine.h:480
const char *(* get_ufrag)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:495
struct ao2_container *(* get_local_candidates)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:499
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
enum ast_rtp_ice_component_type id
Definition: rtp_engine.h:476
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
#define ast_free(a)
Definition: astmm.h:182
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ast_rtp_instance * rtp
RTP instance itself.
Structure that represents the optional ICE support within an RTP engine.
Definition: rtp_engine.h:485
struct ast_sockaddr address
Definition: rtp_engine.h:479
Generic container type.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
unsigned int remote_ice
Does remote support ice.

◆ add_msid_to_stream()

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

Definition at line 1272 of file res_pjsip_sdp_rtp.c.

References ast_codec_media_type2str(), ast_copy_string(), ast_debug, ast_stream_get_group(), ast_stream_get_metadata(), ast_stream_get_type(), ast_stream_set_metadata(), ast_strlen_zero, ast_uuid_generate_str(), AST_UUID_STR_LEN, AST_VECTOR_GET, ast_sip_session::endpoint, ast_sip_session_media::label, ast_sip_endpoint::media, ast_sip_session_media::mslabel, ast_sip_session::pending_media_state, and ast_sip_endpoint_media_configuration::webrtc.

Referenced by create_outgoing_sdp_stream().

1275 {
1276  pj_str_t stmp;
1277  pjmedia_sdp_attr *attr;
1278  char msid[(AST_UUID_STR_LEN * 2) + 2];
1279  const char *stream_label = ast_stream_get_metadata(stream, "SDP:LABEL");
1280 
1281  if (!session->endpoint->media.webrtc) {
1282  return;
1283  }
1284 
1285  if (ast_strlen_zero(session_media->mslabel)) {
1286  /* If this stream is grouped with another then use its media stream label if possible */
1287  if (ast_stream_get_group(stream) != -1) {
1288  struct ast_sip_session_media *group_session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, ast_stream_get_group(stream));
1289 
1290  ast_copy_string(session_media->mslabel, group_session_media->mslabel, sizeof(session_media->mslabel));
1291  }
1292 
1293  if (ast_strlen_zero(session_media->mslabel)) {
1294  ast_uuid_generate_str(session_media->mslabel, sizeof(session_media->mslabel));
1295  }
1296  }
1297 
1298  if (ast_strlen_zero(session_media->label)) {
1299  ast_uuid_generate_str(session_media->label, sizeof(session_media->label));
1300  /* add for stream identification to replace stream_name */
1301  ast_stream_set_metadata(stream, "MSID:LABEL", session_media->label);
1302  }
1303 
1304  snprintf(msid, sizeof(msid), "%s %s", session_media->mslabel, session_media->label);
1305  ast_debug(3, "Stream msid: %p %s %s\n", stream,
1307  attr = pjmedia_sdp_attr_create(pool, "msid", pj_cstr(&stmp, msid));
1308  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1309 
1310  /* 'label' must come after 'msid' */
1311  if (!ast_strlen_zero(stream_label)) {
1312  ast_debug(3, "Stream Label: %p %s %s\n", stream,
1313  ast_codec_media_type2str(ast_stream_get_type(stream)), stream_label);
1314  attr = pjmedia_sdp_attr_create(pool, "label", pj_cstr(&stmp, stream_label));
1315  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1316  }
1317 }
struct ast_sip_endpoint * endpoint
struct ast_sip_session_media_state * pending_media_state
#define AST_UUID_STR_LEN
Definition: uuid.h:27
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
const char * ast_codec_media_type2str(enum ast_media_type type)
Conversion function to take a media type and turn it into a string.
Definition: codec.c:347
static pj_pool_t * pool
Global memory pool for configuration and timers.
char mslabel[AST_UUID_STR_LEN]
Media stream label.
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
Definition: uuid.c:143
A structure containing SIP session media information.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_stream_set_metadata(struct ast_stream *stream, const char *m_key, const char *value)
Set a stream metadata value.
Definition: stream.c:460
const char * ast_stream_get_metadata(const struct ast_stream *stream, const char *m_key)
Get a stream metadata value.
Definition: stream.c:423
char label[AST_UUID_STR_LEN]
Track label.

◆ add_rtcp_fb_to_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

Definition at line 1319 of file res_pjsip_sdp_rtp.c.

References AST_MEDIA_TYPE_VIDEO, ast_sip_session::endpoint, ast_sip_endpoint::media, ast_sip_session_media::type, and ast_sip_endpoint_media_configuration::webrtc.

Referenced by create_outgoing_sdp_stream().

1321 {
1322  pj_str_t stmp;
1323  pjmedia_sdp_attr *attr;
1324 
1325  if (!session->endpoint->media.webrtc) {
1326  return;
1327  }
1328 
1329  /* transport-cc is supposed to be for the entire transport, and any media sources so
1330  * while the header does not appear in audio streams and isn't negotiated there, we still
1331  * place this attribute in as Chrome does.
1332  */
1333  attr = pjmedia_sdp_attr_create(pool, "rtcp-fb", pj_cstr(&stmp, "* transport-cc"));
1334  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1335 
1336  if (session_media->type != AST_MEDIA_TYPE_VIDEO) {
1337  return;
1338  }
1339 
1340  /*
1341  * For now just automatically add it the stream even though it hasn't
1342  * necessarily been negotiated.
1343  */
1344  attr = pjmedia_sdp_attr_create(pool, "rtcp-fb", pj_cstr(&stmp, "* ccm fir"));
1345  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1346 
1347  attr = pjmedia_sdp_attr_create(pool, "rtcp-fb", pj_cstr(&stmp, "* goog-remb"));
1348  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1349 
1350  attr = pjmedia_sdp_attr_create(pool, "rtcp-fb", pj_cstr(&stmp, "* nack"));
1351  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1352 }
struct ast_sip_endpoint * endpoint
static pj_pool_t * pool
Global memory pool for configuration and timers.
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
enum ast_media_type type
Media type of this session media.

◆ add_ssrc_to_stream()

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 
)
static

Function which adds ssrc attributes to a media stream.

Definition at line 1202 of file res_pjsip_sdp_rtp.c.

References ast_rtp_instance_get_cname(), ast_rtp_instance_get_ssrc(), ast_sip_endpoint_media_configuration::bundle, ast_sip_session_media::bundle_group, ast_sip_session::endpoint, ast_sip_endpoint::media, ast_sip_session_media::rtp, and tmp().

Referenced by create_outgoing_sdp_stream().

1203 {
1204  pj_str_t stmp;
1205  pjmedia_sdp_attr *attr;
1206  char tmp[128];
1207 
1208  if (!session->endpoint->media.bundle || session_media->bundle_group == -1) {
1209  return;
1210  }
1211 
1212  snprintf(tmp, sizeof(tmp), "%u cname:%s", ast_rtp_instance_get_ssrc(session_media->rtp), ast_rtp_instance_get_cname(session_media->rtp));
1213  attr = pjmedia_sdp_attr_create(pool, "ssrc", pj_cstr(&stmp, tmp));
1214  media->attr[media->attr_count++] = attr;
1215 }
struct ast_sip_endpoint * endpoint
static int tmp()
Definition: bt_open.c:389
static pj_pool_t * pool
Global memory pool for configuration and timers.
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
unsigned int ast_rtp_instance_get_ssrc(struct ast_rtp_instance *rtp)
Retrieve the local SSRC value that we will be using.
Definition: rtp_engine.c:3778
int bundle_group
The bundle group the stream belongs to.
struct ast_rtp_instance * rtp
RTP instance itself.
const char * ast_rtp_instance_get_cname(struct ast_rtp_instance *rtp)
Retrieve the CNAME used in RTCP SDES items.
Definition: rtp_engine.c:3791

◆ apply_cap_to_bundled()

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

Definition at line 407 of file res_pjsip_sdp_rtp.c.

References ao2_ref, ast_format_cap_count(), ast_format_cap_get_format(), ast_rtp_codecs_payload_code(), ast_rtp_codecs_payload_set_rx(), ast_rtp_instance_get_codecs(), ast_stream_set_formats(), ast_sip_session_media::bundled, format, and ast_sip_session_media::rtp.

Referenced by negotiate_incoming_sdp_stream(), and set_caps().

410 {
411  if (!joint) {
412  return -1;
413  }
414 
415  ast_stream_set_formats(asterisk_stream, joint);
416 
417  /* If this is a bundled stream then apply the payloads to RTP instance acting as transport to prevent conflicts */
418  if (session_media_transport != session_media && session_media->bundled) {
419  int index;
420 
421  for (index = 0; index < ast_format_cap_count(joint); ++index) {
422  struct ast_format *format = ast_format_cap_get_format(joint, index);
423  int rtp_code;
424 
425  /* Ensure this payload is in the bundle group transport codecs, this purposely doesn't check the return value for
426  * things as the format is guaranteed to have a payload already.
427  */
428  rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media->rtp), 1, format, 0);
429  ast_rtp_codecs_payload_set_rx(ast_rtp_instance_get_codecs(session_media_transport->rtp), rtp_code, format);
430 
431  ao2_ref(format, -1);
432  }
433  }
434 
435  return 0;
436 }
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
Definition of a media format.
Definition: format.c:43
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
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
unsigned int bundled
Whether this stream is currently bundled or not.
int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, int asterisk_format, struct ast_format *format, int code)
Retrieve a rx mapped payload type based on whether it is an Asterisk format and the code...
Definition: rtp_engine.c:1873
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_rtp_instance * rtp
RTP instance itself.
int ast_rtp_codecs_payload_set_rx(struct ast_rtp_codecs *codecs, int code, struct ast_format *format)
Set a payload code for use with a specific Asterisk format.
Definition: rtp_engine.c:1923
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
static snd_pcm_format_t format
Definition: chan_alsa.c:102

◆ apply_dtls_attrib()

static void apply_dtls_attrib ( struct ast_sip_session_media session_media,
pjmedia_sdp_attr *  attr 
)
static

Definition at line 1050 of file res_pjsip_sdp_rtp.c.

References ast_copy_pj_str(), ast_log, AST_RTP_DTLS_HASH_SHA1, AST_RTP_DTLS_HASH_SHA256, AST_RTP_DTLS_SETUP_ACTIVE, AST_RTP_DTLS_SETUP_ACTPASS, AST_RTP_DTLS_SETUP_HOLDCONN, AST_RTP_DTLS_SETUP_PASSIVE, ast_rtp_instance_get_dtls(), LOG_WARNING, ast_rtp_engine_dtls::reset, ast_sip_session_media::rtp, ast_rtp_engine_dtls::set_fingerprint, ast_rtp_engine_dtls::set_setup, and value.

Referenced by parse_dtls_attrib().

1052 {
1053  struct ast_rtp_engine_dtls *dtls = ast_rtp_instance_get_dtls(session_media->rtp);
1054  pj_str_t *value;
1055 
1056  if (!attr->value.ptr || !dtls) {
1057  return;
1058  }
1059 
1060  value = pj_strtrim(&attr->value);
1061 
1062  if (!pj_strcmp2(&attr->name, "setup")) {
1063  if (!pj_stricmp2(value, "active")) {
1064  dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_ACTIVE);
1065  } else if (!pj_stricmp2(value, "passive")) {
1066  dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_PASSIVE);
1067  } else if (!pj_stricmp2(value, "actpass")) {
1068  dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_ACTPASS);
1069  } else if (!pj_stricmp2(value, "holdconn")) {
1070  dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_HOLDCONN);
1071  } else {
1072  ast_log(LOG_WARNING, "Unsupported setup attribute value '%*s'\n", (int)value->slen, value->ptr);
1073  }
1074  } else if (!pj_strcmp2(&attr->name, "connection")) {
1075  if (!pj_stricmp2(value, "new")) {
1076  dtls->reset(session_media->rtp);
1077  } else if (!pj_stricmp2(value, "existing")) {
1078  /* Do nothing */
1079  } else {
1080  ast_log(LOG_WARNING, "Unsupported connection attribute value '%*s'\n", (int)value->slen, value->ptr);
1081  }
1082  } else if (!pj_strcmp2(&attr->name, "fingerprint")) {
1083  char hash_value[256], hash[32];
1084  char fingerprint_text[value->slen + 1];
1085  ast_copy_pj_str(fingerprint_text, value, sizeof(fingerprint_text));
1086  if (sscanf(fingerprint_text, "%31s %255s", hash, hash_value) == 2) {
1087  if (!strcasecmp(hash, "sha-1")) {
1088  dtls->set_fingerprint(session_media->rtp, AST_RTP_DTLS_HASH_SHA1, hash_value);
1089  } else if (!strcasecmp(hash, "sha-256")) {
1090  dtls->set_fingerprint(session_media->rtp, AST_RTP_DTLS_HASH_SHA256, hash_value);
1091  } else {
1092  ast_log(LOG_WARNING, "Unsupported fingerprint hash type '%s'\n",
1093  hash);
1094  }
1095  }
1096  }
1097 }
#define LOG_WARNING
Definition: logger.h:274
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:5240
int value
Definition: syslog.c:37
#define ast_log
Definition: astobj2.c:42
void(* set_fingerprint)(struct ast_rtp_instance *instance, enum ast_rtp_dtls_hash hash, const char *fingerprint)
Definition: rtp_engine.h:586
Structure that represents the optional DTLS SRTP support within an RTP engine.
Definition: rtp_engine.h:570
struct ast_rtp_engine_dtls * ast_rtp_instance_get_dtls(struct ast_rtp_instance *instance)
Obtain a pointer to the DTLS support present on an RTP instance.
Definition: rtp_engine.c:3011
void(* reset)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:578
void(* set_setup)(struct ast_rtp_instance *instance, enum ast_rtp_dtls_setup setup)
Definition: rtp_engine.h:584
struct ast_rtp_instance * rtp
RTP instance itself.

◆ apply_negotiated_sdp_stream()

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

Definition at line 2065 of file res_pjsip_sdp_rtp.c.

References AST_AF_UNSPEC, ast_channel_lock, ast_channel_uniqueid(), ast_channel_unlock, AST_CONTROL_UPDATE_RTP_PEER, ast_copy_pj_str(), ast_free, AST_MEDIA_TYPE_AUDIO, ast_null_frame, ast_queue_control(), ast_queue_frame(), ast_queue_hold(), ast_queue_unhold(), ast_rtp_instance_activate(), ast_rtp_instance_bundle(), ast_rtp_instance_fd(), ast_rtp_instance_get_timeout(), ast_rtp_instance_set_channel_id(), ast_rtp_instance_set_keepalive(), ast_rtp_instance_set_remote_address, ast_rtp_instance_set_stream_num(), ast_rtp_instance_set_timeout(), ast_rtp_instance_stop(), ast_sched_add_variable(), AST_SCHED_DEL, AST_SIP_MEDIA_TRANSPORT_INVALID, ast_sip_session_get_name(), ast_sip_session_media_add_read_callback(), ast_sip_session_media_get_transport(), ast_sip_session_media_set_write_callback(), ast_sockaddr_resolve(), ast_sockaddr_set_port, ast_str_tmp, ast_stream_get_position(), ast_stream_to_str(), ast_sip_session_media::bundled, ast_sip_session::channel, check_endpoint_media_transport(), create_rtp(), enable_rtcp(), ast_sip_session_media::encryption, ast_sip_media_rtp_configuration::encryption, ast_sip_media_rtp_configuration::encryption_optimistic, ast_sip_session::endpoint, host, ast_sip_session::inv_session, ast_sip_media_rtp_configuration::keepalive, ast_sip_session_media::keepalive_sched_id, ast_sip_endpoint::media, media_session_rtcp_read_callback(), media_session_rtp_read_callback(), media_session_rtp_write_callback(), ast_sip_endpoint::mohsuggest, NULL, PARSE_PORT_FORBID, process_extmap_attributes(), process_ice_attributes(), process_ssrc_attributes(), RAII_VAR, ast_sip_session_media::remote_rtcp_mux, ast_sip_session_media::remotely_held, ast_sip_session_media::remotely_held_changed, ast_sip_endpoint_media_configuration::rtcp_mux, ast_sip_session_media::rtp, ast_sip_endpoint_media_configuration::rtp, rtp_check_timeout(), SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, send_keepalive(), set_caps(), set_ice_components(), setup_media_encryption(), ast_sip_media_rtp_configuration::timeout, ast_sip_media_rtp_configuration::timeout_hold, ast_sip_session_media::timeout_sched_id, ast_sip_session_media::type, and ast_sip_media_rtp_configuration::use_received_transport.

2068 {
2069  RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free);
2070  struct pjmedia_sdp_media *remote_stream = remote->media[index];
2071  enum ast_media_type media_type = session_media->type;
2072  char host[NI_MAXHOST];
2073  int res;
2074  struct ast_sip_session_media *session_media_transport;
2075  SCOPE_ENTER(1, "%s Stream: %s\n", ast_sip_session_get_name(session),
2076  ast_str_tmp(128, ast_stream_to_str(asterisk_stream, &STR_TMP)));
2077 
2078  if (!session->channel) {
2079  SCOPE_EXIT_RTN_VALUE(1, "No channel\n");
2080  }
2081 
2082  /* Ensure incoming transport is compatible with the endpoint's configuration */
2083  if (!session->endpoint->media.rtp.use_received_transport &&
2085  SCOPE_EXIT_RTN_VALUE(-1, "Incompatible transport\n");
2086  }
2087 
2088  /* Create an RTP instance if need be */
2089  if (!session_media->rtp && create_rtp(session, session_media, local)) {
2090  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create rtp\n");
2091  }
2092 
2093  process_ssrc_attributes(session, session_media, remote_stream);
2094  process_extmap_attributes(session, session_media, remote_stream);
2095 
2096  session_media_transport = ast_sip_session_media_get_transport(session, session_media);
2097 
2098  if (session_media_transport == session_media || !session_media->bundled) {
2099  session_media->remote_rtcp_mux = (pjmedia_sdp_media_find_attr2(remote_stream, "rtcp-mux", NULL) != NULL);
2100  set_ice_components(session, session_media);
2101 
2102  enable_rtcp(session, session_media, remote_stream);
2103 
2104  res = setup_media_encryption(session, session_media, remote, remote_stream);
2105  if (!session->endpoint->media.rtp.encryption_optimistic && res) {
2106  /* If optimistic encryption is disabled and crypto should have been enabled but was not
2107  * this session must fail.
2108  */
2109  SCOPE_EXIT_RTN_VALUE(-1, "Incompatible crypto\n");
2110  }
2111 
2112  if (!remote_stream->conn && !remote->conn) {
2113  SCOPE_EXIT_RTN_VALUE(1, "No connection info\n");
2114  }
2115 
2116  ast_copy_pj_str(host, remote_stream->conn ? &remote_stream->conn->addr : &remote->conn->addr, sizeof(host));
2117 
2118  /* Ensure that the address provided is valid */
2119  if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC) <= 0) {
2120  /* The provided host was actually invalid so we error out this negotiation */
2121  SCOPE_EXIT_RTN_VALUE(-1, "Host invalid\n");
2122  }
2123 
2124  /* Apply connection information to the RTP instance */
2125  ast_sockaddr_set_port(addrs, remote_stream->desc.port);
2126  ast_rtp_instance_set_remote_address(session_media->rtp, addrs);
2127 
2129  ast_sip_session_media_add_read_callback(session, session_media, ast_rtp_instance_fd(session_media->rtp, 0),
2131  if (!session->endpoint->media.rtcp_mux || !session_media->remote_rtcp_mux) {
2132  ast_sip_session_media_add_read_callback(session, session_media, ast_rtp_instance_fd(session_media->rtp, 1),
2134  }
2135 
2136  /* If ICE support is enabled find all the needed attributes */
2137  process_ice_attributes(session, session_media, remote, remote_stream);
2138  } else {
2139  /* This is bundled with another session, so mark it as such */
2140  ast_rtp_instance_bundle(session_media->rtp, session_media_transport->rtp);
2142  enable_rtcp(session, session_media, remote_stream);
2143  }
2144 
2145  if (set_caps(session, session_media, session_media_transport, remote_stream, 0, asterisk_stream)) {
2146  SCOPE_EXIT_RTN_VALUE(-1, "set_caps failed\n");
2147  }
2148 
2149  /* Set the channel uniqueid on the RTP instance now that it is becoming active */
2150  ast_channel_lock(session->channel);
2152  ast_channel_unlock(session->channel);
2153 
2154  /* Ensure the RTP instance is active */
2155  ast_rtp_instance_set_stream_num(session_media->rtp, ast_stream_get_position(asterisk_stream));
2156  ast_rtp_instance_activate(session_media->rtp);
2157 
2158  /* audio stream handles music on hold */
2159  if (media_type != AST_MEDIA_TYPE_AUDIO) {
2160  if ((pjmedia_sdp_neg_was_answer_remote(session->inv_session->neg) == PJ_FALSE)
2161  && (session->inv_session->state == PJSIP_INV_STATE_CONFIRMED)) {
2163  }
2164  SCOPE_EXIT_RTN_VALUE(1, "moh\n");
2165  }
2166 
2167  if (session_media->remotely_held_changed) {
2168  if (session_media->remotely_held) {
2169  /* The remote side has put us on hold */
2170  ast_queue_hold(session->channel, session->endpoint->mohsuggest);
2171  ast_rtp_instance_stop(session_media->rtp);
2173  session_media->remotely_held_changed = 0;
2174  } else {
2175  /* The remote side has taken us off hold */
2176  ast_queue_unhold(session->channel);
2178  session_media->remotely_held_changed = 0;
2179  }
2180  } else if ((pjmedia_sdp_neg_was_answer_remote(session->inv_session->neg) == PJ_FALSE)
2181  && (session->inv_session->state == PJSIP_INV_STATE_CONFIRMED)) {
2183  }
2184 
2185  /* This purposely resets the encryption to the configured in case it gets added later */
2186  session_media->encryption = session->endpoint->media.rtp.encryption;
2187 
2188  if (session->endpoint->media.rtp.keepalive > 0 &&
2189  session_media->type == AST_MEDIA_TYPE_AUDIO) {
2190  ast_rtp_instance_set_keepalive(session_media->rtp, session->endpoint->media.rtp.keepalive);
2191  /* Schedule the initial keepalive early in case this is being used to punch holes through
2192  * a NAT. This way there won't be an awkward delay before media starts flowing in some
2193  * scenarios.
2194  */
2195  AST_SCHED_DEL(sched, session_media->keepalive_sched_id);
2197  session_media, 1);
2198  }
2199 
2200  /* As the channel lock is not held during this process the scheduled item won't block if
2201  * it is hanging up the channel at the same point we are applying this negotiated SDP.
2202  */
2203  AST_SCHED_DEL(sched, session_media->timeout_sched_id);
2204 
2205  /* Due to the fact that we only ever have one scheduled timeout item for when we are both
2206  * off hold and on hold we don't need to store the two timeouts differently on the RTP
2207  * instance itself.
2208  */
2209  ast_rtp_instance_set_timeout(session_media->rtp, 0);
2210  if (session->endpoint->media.rtp.timeout && !session_media->remotely_held) {
2211  ast_rtp_instance_set_timeout(session_media->rtp, session->endpoint->media.rtp.timeout);
2212  } else if (session->endpoint->media.rtp.timeout_hold && session_media->remotely_held) {
2213  ast_rtp_instance_set_timeout(session_media->rtp, session->endpoint->media.rtp.timeout_hold);
2214  }
2215 
2216  if (ast_rtp_instance_get_timeout(session_media->rtp)) {
2218  ast_rtp_instance_get_timeout(session_media->rtp) * 1000, rtp_check_timeout,
2219  session_media, 1);
2220  }
2221 
2222  SCOPE_EXIT_RTN_VALUE(1, "Handled\n");
2223 }
unsigned int encryption_optimistic
Definition: res_pjsip.h:713
int ast_rtp_instance_activate(struct ast_rtp_instance *instance)
Indicate to the RTP engine that packets are now expected to be sent/received on the RTP instance...
Definition: rtp_engine.c:2647
#define ast_channel_lock(chan)
Definition: channel.h:2945
struct ast_sip_endpoint * endpoint
const char * ast_stream_to_str(const struct ast_stream *stream, struct ast_str **buf)
Get a string representing the stream for debugging/display purposes.
Definition: stream.c:337
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.
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
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
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.
media_type
Media types generate different "dummy answers" for not accepting the offer of a media stream...
Definition: sip.h:489
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.
int ast_rtp_instance_bundle(struct ast_rtp_instance *child, struct ast_rtp_instance *parent)
Request that an RTP instance be bundled with another.
Definition: rtp_engine.c:3804
int ast_rtp_instance_get_timeout(struct ast_rtp_instance *instance)
Get the RTP timeout value.
Definition: rtp_engine.c:2685
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Definition: channel.c:1216
static struct ast_frame * media_session_rtcp_read_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
Definition: sched.c:76
int ast_sched_add_variable(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data, int variable) attribute_warn_unused_result
Adds a scheduled event with rescheduling support.
Definition: sched.c:524
void ast_rtp_instance_set_timeout(struct ast_rtp_instance *instance, int timeout)
Set the RTP timeout value.
Definition: rtp_engine.c:2670
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:5240
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)
#define NULL
Definition: resample.c:96
struct pjsip_inv_session * inv_session
Socket address structure.
Definition: netsock2.h:97
void ast_rtp_instance_set_stream_num(struct ast_rtp_instance *instance, int stream_num)
Set the stream number for an RTP instance.
Definition: rtp_engine.c:3830
unsigned int use_received_transport
Definition: res_pjsip.h:705
enum ast_sip_session_media_encryption encryption
What type of encryption is in use on this stream.
unsigned int bundled
Whether this stream is currently bundled or not.
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
void ast_rtp_instance_stop(struct ast_rtp_instance *instance)
Stop an RTP instance.
Definition: rtp_engine.c:2183
static char host[256]
Definition: muted.c:77
static int rtp_check_timeout(const void *data)
Check whether RTP is being received or not.
#define AST_SCHED_DEL(sched, id)
Remove a scheduler entry.
Definition: sched.h:46
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
static int media_session_rtp_write_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct ast_frame *frame)
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:764
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.
struct ast_channel * channel
int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
Queue a hold frame.
Definition: channel.c:1191
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1139
const char * ast_channel_uniqueid(const struct ast_channel *chan)
enum ast_sip_session_media_encryption encryption
Definition: res_pjsip.h:711
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_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
#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
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.
unsigned int remotely_held
Stream is on hold by remote side.
#define ast_channel_unlock(chan)
Definition: channel.h:2946
int timeout_sched_id
Scheduler ID for RTP timeout.
static struct ast_frame * media_session_rtp_read_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
#define ast_free(a)
Definition: astmm.h:182
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.
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
Get the file descriptor for an RTP session (or RTCP)
Definition: rtp_engine.c:2192
int keepalive_sched_id
Scheduler ID for RTP keepalive.
A structure containing SIP session media information.
static int send_keepalive(const void *data)
void ast_rtp_instance_set_keepalive(struct ast_rtp_instance *instance, int timeout)
Set the RTP keepalive interval.
Definition: rtp_engine.c:2680
struct ast_frame ast_null_frame
Definition: main/frame.c:79
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
static enum ast_sip_session_media_encryption check_endpoint_media_transport(struct ast_sip_endpoint *endpoint, const struct pjmedia_sdp_media *stream)
Checks whether the encryption offered in SDP is compatible with the endpoint&#39;s configuration.
enum ast_media_type type
Media type of this session media.
unsigned int remotely_held_changed
Stream is held by remote side changed during this negotiation.
struct ast_rtp_instance * rtp
RTP instance itself.
static void set_ice_components(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
const ast_string_field mohsuggest
Definition: res_pjsip.h:823
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.
ast_media_type
Types of media.
Definition: codec.h:30
unsigned int remote_rtcp_mux
Does remote support rtcp_mux.
int ast_stream_get_position(const struct ast_stream *stream)
Get the position of the stream in the topology.
Definition: stream.c:500
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)
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 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.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 2390 of file res_pjsip_sdp_rtp.c.

◆ change_outgoing_sdp_stream_media_address()

static void change_outgoing_sdp_stream_media_address ( pjsip_tx_data *  tdata,
struct pjmedia_sdp_media *  stream,
struct ast_sip_transport transport 
)
static

Function which updates the media stream with external media address, if applicable.

Definition at line 2226 of file res_pjsip_sdp_rtp.c.

References ao2_cleanup, ast_copy_pj_str(), ast_debug, ast_sip_get_transport_state(), ast_sip_transport_is_nonlocal, ast_sockaddr_parse(), ast_sockaddr_stringify_addr_remote(), ast_sorcery_object_get_id(), host, PARSE_PORT_FORBID, and RAII_VAR.

2227 {
2229  char host[NI_MAXHOST];
2230  struct ast_sockaddr our_sdp_addr = { { 0, } };
2231 
2232  /* If the stream has been rejected there will be no connection line */
2233  if (!stream->conn || !transport_state) {
2234  return;
2235  }
2236 
2237  ast_copy_pj_str(host, &stream->conn->addr, sizeof(host));
2238  ast_sockaddr_parse(&our_sdp_addr, host, PARSE_PORT_FORBID);
2239 
2240  /* Reversed check here. We don't check the remote endpoint being
2241  * in our local net, but whether our outgoing session IP is
2242  * local. If it is not, we won't do rewriting. No localnet
2243  * configured? Always rewrite. */
2244  if (ast_sip_transport_is_nonlocal(transport_state, &our_sdp_addr) && transport_state->localnet) {
2245  return;
2246  }
2247  ast_debug(5, "Setting media address to %s\n", ast_sockaddr_stringify_addr_remote(&transport_state->external_media_address));
2248  pj_strdup2(tdata->pool, &stream->conn->addr, ast_sockaddr_stringify_addr_remote(&transport_state->external_media_address));
2249 }
#define ast_sip_transport_is_nonlocal(transport_state, addr)
Definition: res_pjsip.h:162
static char * ast_sockaddr_stringify_addr_remote(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:317
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:5240
Socket address structure.
Definition: netsock2.h:97
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char host[256]
Definition: muted.c:77
Structure for SIP transport information.
Definition: res_pjsip.h:87
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
struct ast_sip_transport_state * ast_sip_get_transport_state(const char *transport_id)
Retrieve transport state.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ check_endpoint_media_transport()

static enum ast_sip_session_media_encryption check_endpoint_media_transport ( struct ast_sip_endpoint endpoint,
const struct pjmedia_sdp_media *  stream 
)
static

Checks whether the encryption offered in SDP is compatible with the endpoint's configuration.

Definition at line 970 of file res_pjsip_sdp_rtp.c.

References AST_SIP_MEDIA_ENCRYPT_NONE, AST_SIP_MEDIA_TRANSPORT_INVALID, ast_sip_media_rtp_configuration::encryption, ast_sip_media_rtp_configuration::encryption_optimistic, ast_sip_media_rtp_configuration::force_avp, get_media_encryption_type(), ast_sip_endpoint::media, ast_sip_endpoint_media_configuration::rtp, and ast_sip_media_rtp_configuration::use_avpf.

Referenced by apply_negotiated_sdp_stream(), and negotiate_incoming_sdp_stream().

973 {
974  enum ast_sip_session_media_encryption incoming_encryption;
975  char transport_end = stream->desc.transport.ptr[stream->desc.transport.slen - 1];
976  unsigned int optimistic;
977 
978  if ((transport_end == 'F' && !endpoint->media.rtp.use_avpf)
979  || (transport_end != 'F' && endpoint->media.rtp.use_avpf)) {
981  }
982 
983  incoming_encryption = get_media_encryption_type(stream->desc.transport, stream, &optimistic);
984 
985  if (incoming_encryption == endpoint->media.rtp.encryption) {
986  return incoming_encryption;
987  }
988 
989  if (endpoint->media.rtp.force_avp ||
990  endpoint->media.rtp.encryption_optimistic) {
991  return incoming_encryption;
992  }
993 
994  /* If an optimistic offer has been made but encryption is not enabled consider it as having
995  * no offer of crypto at all instead of invalid so the session proceeds.
996  */
997  if (optimistic) {
999  }
1000 
1002 }
unsigned int encryption_optimistic
Definition: res_pjsip.h:713
ast_sip_session_media_encryption
Definition: res_pjsip.h:504
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:764
enum ast_sip_session_media_encryption encryption
Definition: res_pjsip.h:711
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

◆ check_ice_support()

static void check_ice_support ( struct ast_sip_session session,
struct ast_sip_session_media session_media,
const struct pjmedia_sdp_media *  remote_stream 
)
static

Function which checks for ice attributes in an audio stream.

Definition at line 750 of file res_pjsip_sdp_rtp.c.

References ast_rtp_instance_get_ice(), ast_sip_session::endpoint, ast_sip_media_rtp_configuration::ice_support, ast_sip_endpoint::media, ast_sip_session_media::remote_ice, ast_sip_session_media::rtp, and ast_sip_endpoint_media_configuration::rtp.

Referenced by negotiate_incoming_sdp_stream().

752 {
753  struct ast_rtp_engine_ice *ice;
754  const pjmedia_sdp_attr *attr;
755  unsigned int attr_i;
756 
757  if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) {
758  session_media->remote_ice = 0;
759  return;
760  }
761 
762  /* Find all of the candidates */
763  for (attr_i = 0; attr_i < remote_stream->attr_count; ++attr_i) {
764  attr = remote_stream->attr[attr_i];
765  if (!pj_strcmp2(&attr->name, "candidate")) {
766  session_media->remote_ice = 1;
767  break;
768  }
769  }
770 
771  if (attr_i == remote_stream->attr_count) {
772  session_media->remote_ice = 0;
773  }
774 }
struct ast_sip_endpoint * endpoint
struct ast_rtp_engine_ice * ast_rtp_instance_get_ice(struct ast_rtp_instance *instance)
Obtain a pointer to the ICE support present on an RTP instance.
Definition: rtp_engine.c:2891
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:764
struct ast_rtp_instance * rtp
RTP instance itself.
Structure that represents the optional ICE support within an RTP engine.
Definition: rtp_engine.h:485
unsigned int remote_ice
Does remote support ice.

◆ create_outgoing_sdp_stream()

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 
)
static

Function which creates an outgoing stream.

Definition at line 1704 of file res_pjsip_sdp_rtp.c.

References add_crypto_to_stream(), add_extmap_to_stream(), add_ice_to_stream(), add_msid_to_stream(), add_rtcp_fb_to_stream(), add_ssrc_to_stream(), ast_sip_endpoint_media_configuration::address, ao2_cleanup, ao2_ref, ast_codec_media_type2str(), ast_format_cap_alloc, ast_format_cap_append_from_cap(), ast_format_cap_count(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_compatible(), ast_format_cap_get_format(), ast_format_cap_get_framing(), ast_format_get_maximum_ms(), ast_format_get_name(), ast_format_get_type(), ast_log, AST_MEDIA_TYPE_VIDEO, ast_rtp_codecs_get_framing(), ast_rtp_codecs_payload_code(), ast_rtp_codecs_payload_set_rx(), AST_RTP_DTMF, ast_rtp_instance_change_source(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_local_address(), ast_rtp_instance_get_ssrc(), AST_RTP_MAX, ast_sdp_get_rtp_profile(), AST_SIP_DTMF_AUTO, AST_SIP_DTMF_AUTO_INFO, AST_SIP_DTMF_RFC_4733, ast_sip_get_host_ip_string(), AST_SIP_MEDIA_ENCRYPT_SDES, ast_sip_session_get_name(), ast_sip_session_is_pending_stream_default(), ast_sip_session_media_get_transport(), ast_sockaddr_isnull(), ast_sockaddr_port, AST_SOCKADDR_STR_ADDR, ast_sockaddr_stringify_fmt(), ast_str_tmp, ast_stream_get_formats(), ast_stream_get_position(), ast_stream_get_state(), ast_stream_set_state(), AST_STREAM_STATE_INACTIVE, AST_STREAM_STATE_RECVONLY, AST_STREAM_STATE_REMOVED, AST_STREAM_STATE_SENDONLY, ast_stream_to_str(), ast_strlen_zero, AST_VECTOR_GET, ast_sip_session_media::bundle_group, ast_sip_session_media::bundled, ast_sip_endpoint_media_configuration::codecs, create_rtp(), ast_sip_session_media::direct_media_addr, ast_sip_session::direct_media_cap, ast_sip_session::dtmf, enable_rtcp(), ast_sip_session_media::encryption, ast_sip_media_rtp_configuration::encryption_optimistic, ast_sip_session::endpoint, ast_sip_media_rtp_configuration::force_avp, format, generate_fmtp_attr(), generate_rtpmap_attr(), ast_sip_session::inv_session, ast_sip_media_rtp_configuration::ipv6, ast_sip_session_media::locally_held, LOG_ERROR, LOG_WARNING, ast_sip_endpoint::media, NULL, ast_sip_session::pending_media_state, pool, RAII_VAR, ast_sip_session_media::remote_rtcp_mux, ast_sip_session_media::remotely_held, ast_sip_endpoint_media_configuration::rtcp_mux, ast_sip_session_media::rtp, ast_sip_endpoint_media_configuration::rtp, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, set_ice_components(), ast_sip_session_media::stream_num, tmp(), ast_sip_session_media::transport, ast_sip_session_media::type, and ast_sip_media_rtp_configuration::use_avpf.

1706 {
1707  pj_pool_t *pool = session->inv_session->pool_prov;
1708  static const pj_str_t STR_RTP_AVP = { "RTP/AVP", 7 };
1709  static const pj_str_t STR_IN = { "IN", 2 };
1710  static const pj_str_t STR_IP4 = { "IP4", 3};
1711  static const pj_str_t STR_IP6 = { "IP6", 3};
1712  static const pj_str_t STR_SENDRECV = { "sendrecv", 8 };
1713  static const pj_str_t STR_SENDONLY = { "sendonly", 8 };
1714  static const pj_str_t STR_INACTIVE = { "inactive", 8 };
1715  static const pj_str_t STR_RECVONLY = { "recvonly", 8 };
1716  pjmedia_sdp_media *media;
1717  const char *hostip = NULL;
1718  struct ast_sockaddr addr;
1719  char tmp[512];
1720  pj_str_t stmp;
1721  pjmedia_sdp_attr *attr;
1722  int index = 0;
1723  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;
1724  int min_packet_size = 0, max_packet_size = 0;
1725  int rtp_code;
1726  RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup);
1727  enum ast_media_type media_type = session_media->type;
1728  struct ast_sip_session_media *session_media_transport;
1729  pj_sockaddr ip;
1730  int direct_media_enabled = !ast_sockaddr_isnull(&session_media->direct_media_addr) &&
1732  SCOPE_ENTER(1, "%s Type: %s %s\n", ast_sip_session_get_name(session),
1733  ast_codec_media_type2str(media_type), ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)));
1734 
1735  media = pj_pool_zalloc(pool, sizeof(struct pjmedia_sdp_media));
1736  if (!media) {
1737  SCOPE_EXIT_RTN_VALUE(-1, "Pool alloc failure\n");
1738  }
1739  pj_strdup2(pool, &media->desc.media, ast_codec_media_type2str(session_media->type));
1740 
1741  /* If this is a removed (or declined) stream OR if no formats exist then construct a minimal stream in SDP */
1744  media->desc.port = 0;
1745  media->desc.port_count = 1;
1746 
1747  if (remote && remote->media[ast_stream_get_position(stream)]) {
1748  pjmedia_sdp_media *remote_media = remote->media[ast_stream_get_position(stream)];
1749  int index;
1750 
1751  media->desc.transport = remote_media->desc.transport;
1752 
1753  /* Preserve existing behavior by copying the formats provided from the offer */
1754  for (index = 0; index < remote_media->desc.fmt_count; ++index) {
1755  media->desc.fmt[index] = remote_media->desc.fmt[index];
1756  }
1757  media->desc.fmt_count = remote_media->desc.fmt_count;
1758  } else {
1759  /* This is actually an offer so put a dummy payload in that is ignored and sane transport */
1760  media->desc.transport = STR_RTP_AVP;
1761  pj_strdup2(pool, &media->desc.fmt[media->desc.fmt_count++], "32");
1762  }
1763 
1764  sdp->media[sdp->media_count++] = media;
1766 
1767  SCOPE_EXIT_RTN_VALUE(1, "Stream removed or no formats\n");
1768  }
1769 
1770  if (!session_media->rtp && create_rtp(session, session_media, sdp)) {
1771  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create rtp\n");
1772  }
1773 
1774  /* If this stream has not been bundled already it is new and we need to ensure there is no SSRC conflict */
1775  if (session_media->bundle_group != -1 && !session_media->bundled) {
1776  for (index = 0; index < sdp->media_count; ++index) {
1777  struct ast_sip_session_media *other_session_media;
1778 
1779  other_session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, index);
1780  if (!other_session_media->rtp || other_session_media->bundle_group != session_media->bundle_group) {
1781  continue;
1782  }
1783 
1784  if (ast_rtp_instance_get_ssrc(session_media->rtp) == ast_rtp_instance_get_ssrc(other_session_media->rtp)) {
1785  ast_rtp_instance_change_source(session_media->rtp);
1786  /* Start the conflict check over again */
1787  index = -1;
1788  continue;
1789  }
1790  }
1791  }
1792 
1793  session_media_transport = ast_sip_session_media_get_transport(session, session_media);
1794 
1795  if (session_media_transport == session_media || !session_media->bundled) {
1796  set_ice_components(session, session_media);
1797  enable_rtcp(session, session_media, NULL);
1798 
1799  /* Crypto has to be added before setting the media transport so that SRTP is properly
1800  * set up according to the configuration. This ends up changing the media transport.
1801  */
1802  if (add_crypto_to_stream(session, session_media, pool, media)) {
1803  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't add crypto\n");
1804  }
1805 
1806  if (pj_strlen(&session_media->transport)) {
1807  /* If a transport has already been specified use it */
1808  media->desc.transport = session_media->transport;
1809  } else {
1810  media->desc.transport = pj_str(ast_sdp_get_rtp_profile(
1811  /* Optimistic encryption places crypto in the normal RTP/AVP profile */
1812  !session->endpoint->media.rtp.encryption_optimistic &&
1813  (session_media->encryption == AST_SIP_MEDIA_ENCRYPT_SDES),
1814  session_media->rtp, session->endpoint->media.rtp.use_avpf,
1815  session->endpoint->media.rtp.force_avp));
1816  }
1817 
1818  media->conn = pj_pool_zalloc(pool, sizeof(struct pjmedia_sdp_conn));
1819  if (!media->conn) {
1820  SCOPE_EXIT_RTN_VALUE(-1, "Pool alloc failure\n");
1821  }
1822 
1823  /* Add connection level details */
1824  if (direct_media_enabled) {
1826  } else if (ast_strlen_zero(session->endpoint->media.address)) {
1827  hostip = ast_sip_get_host_ip_string(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET());
1828  } else {
1829  hostip = session->endpoint->media.address;
1830  }
1831 
1832  if (ast_strlen_zero(hostip)) {
1833  ast_log(LOG_ERROR, "No local host IP available for stream %s\n",
1834  ast_codec_media_type2str(session_media->type));
1835  SCOPE_EXIT_RTN_VALUE(-1, "No local host ip\n");
1836  }
1837 
1838  media->conn->net_type = STR_IN;
1839  /* Assume that the connection will use IPv4 until proven otherwise */
1840  media->conn->addr_type = STR_IP4;
1841  pj_strdup2(pool, &media->conn->addr, hostip);
1842 
1843  if ((pj_sockaddr_parse(pj_AF_UNSPEC(), 0, &media->conn->addr, &ip) == PJ_SUCCESS) &&
1844  (ip.addr.sa_family == pj_AF_INET6())) {
1845  media->conn->addr_type = STR_IP6;
1846  }
1847 
1848  /* Add ICE attributes and candidates */
1849  add_ice_to_stream(session, session_media, pool, media, 1);
1850 
1851  ast_rtp_instance_get_local_address(session_media->rtp, &addr);
1852  media->desc.port = direct_media_enabled ? ast_sockaddr_port(&session_media->direct_media_addr) : (pj_uint16_t) ast_sockaddr_port(&addr);
1853  media->desc.port_count = 1;
1854  } else {
1855  pjmedia_sdp_media *bundle_group_stream = sdp->media[session_media_transport->stream_num];
1856 
1857  /* As this is in a bundle group it shares the same details as the group instance */
1858  media->desc.transport = bundle_group_stream->desc.transport;
1859  media->conn = bundle_group_stream->conn;
1860  media->desc.port = bundle_group_stream->desc.port;
1861 
1862  if (add_crypto_to_stream(session, session_media_transport, pool, media)) {
1863  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't add crypto\n");
1864  }
1865 
1866  add_ice_to_stream(session, session_media_transport, pool, media, 0);
1867 
1868  enable_rtcp(session, session_media, NULL);
1869  }
1870 
1872  ast_log(LOG_ERROR, "Failed to allocate %s capabilities\n",
1873  ast_codec_media_type2str(session_media->type));
1874  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create caps\n");
1875  }
1876 
1877  if (direct_media_enabled) {
1879  } else {
1880  ast_format_cap_append_from_cap(caps, ast_stream_get_formats(stream), media_type);
1881  }
1882 
1883  for (index = 0; index < ast_format_cap_count(caps); ++index) {
1884  struct ast_format *format = ast_format_cap_get_format(caps, index);
1885 
1886  if (ast_format_get_type(format) != media_type) {
1887  ao2_ref(format, -1);
1888  continue;
1889  }
1890 
1891  /* If this stream is not a transport we need to use the transport codecs structure for payload management to prevent
1892  * conflicts.
1893  */
1894  if (session_media_transport != session_media) {
1895  if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media_transport->rtp), 1, format, 0)) == -1) {
1896  ast_log(LOG_WARNING,"Unable to get rtp codec payload code for %s\n", ast_format_get_name(format));
1897  ao2_ref(format, -1);
1898  continue;
1899  }
1900  /* Our instance has to match the payload number though */
1901  ast_rtp_codecs_payload_set_rx(ast_rtp_instance_get_codecs(session_media->rtp), rtp_code, format);
1902  } else {
1903  if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media->rtp), 1, format, 0)) == -1) {
1904  ast_log(LOG_WARNING,"Unable to get rtp codec payload code for %s\n", ast_format_get_name(format));
1905  ao2_ref(format, -1);
1906  continue;
1907  }
1908  }
1909 
1910  if ((attr = generate_rtpmap_attr(session, media, pool, rtp_code, 1, format, 0))) {
1911  media->attr[media->attr_count++] = attr;
1912  }
1913 
1914  if ((attr = generate_fmtp_attr(pool, format, rtp_code))) {
1915  media->attr[media->attr_count++] = attr;
1916  }
1917 
1918  if (ast_format_get_maximum_ms(format) &&
1919  ((ast_format_get_maximum_ms(format) < max_packet_size) || !max_packet_size)) {
1920  max_packet_size = ast_format_get_maximum_ms(format);
1921  }
1922  ao2_ref(format, -1);
1923 
1924  if (media->desc.fmt_count == PJMEDIA_MAX_SDP_FMT) {
1925  break;
1926  }
1927  }
1928 
1929  /* Add non-codec formats */
1930  if (ast_sip_session_is_pending_stream_default(session, stream) && media_type != AST_MEDIA_TYPE_VIDEO
1931  && media->desc.fmt_count < PJMEDIA_MAX_SDP_FMT) {
1932  for (index = 1LL; index <= AST_RTP_MAX; index <<= 1) {
1933  if (!(noncodec & index)) {
1934  continue;
1935  }
1936  rtp_code = ast_rtp_codecs_payload_code(
1937  ast_rtp_instance_get_codecs(session_media->rtp), 0, NULL, index);
1938  if (rtp_code == -1) {
1939  continue;
1940  }
1941 
1942  if ((attr = generate_rtpmap_attr(session, media, pool, rtp_code, 0, NULL, index))) {
1943  media->attr[media->attr_count++] = attr;
1944  }
1945 
1946  if (index == AST_RTP_DTMF) {
1947  snprintf(tmp, sizeof(tmp), "%d 0-16", rtp_code);
1948  attr = pjmedia_sdp_attr_create(pool, "fmtp", pj_cstr(&stmp, tmp));
1949  media->attr[media->attr_count++] = attr;
1950  }
1951 
1952  if (media->desc.fmt_count == PJMEDIA_MAX_SDP_FMT) {
1953  break;
1954  }
1955  }
1956  }
1957 
1958 
1959  /* If no formats were actually added to the media stream don't add it to the SDP */
1960  if (!media->desc.fmt_count) {
1961  SCOPE_EXIT_RTN_VALUE(1, "No formats added to stream\n");
1962  }
1963 
1964  /* If ptime is set add it as an attribute */
1965  min_packet_size = ast_rtp_codecs_get_framing(ast_rtp_instance_get_codecs(session_media->rtp));
1966  if (!min_packet_size) {
1967  min_packet_size = ast_format_cap_get_framing(caps);
1968  }
1969  if (min_packet_size) {
1970  snprintf(tmp, sizeof(tmp), "%d", min_packet_size);
1971  attr = pjmedia_sdp_attr_create(pool, "ptime", pj_cstr(&stmp, tmp));
1972  media->attr[media->attr_count++] = attr;
1973  }
1974 
1975  if (max_packet_size) {
1976  snprintf(tmp, sizeof(tmp), "%d", max_packet_size);
1977  attr = pjmedia_sdp_attr_create(pool, "maxptime", pj_cstr(&stmp, tmp));
1978  media->attr[media->attr_count++] = attr;
1979  }
1980 
1981  attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr);
1982  if (session_media->locally_held) {
1983  if (session_media->remotely_held) {
1984  attr->name = STR_INACTIVE; /* To place on hold a recvonly stream, send inactive */
1985  } else {
1986  attr->name = STR_SENDONLY; /* Send sendonly to initate a local hold */
1987  }
1988  } else {
1989  if (session_media->remotely_held) {
1990  attr->name = STR_RECVONLY; /* Remote has sent sendonly, reply recvonly */
1991  } else if (ast_stream_get_state(stream) == AST_STREAM_STATE_SENDONLY) {
1992  attr->name = STR_SENDONLY; /* Stream has requested sendonly */
1993  } else if (ast_stream_get_state(stream) == AST_STREAM_STATE_RECVONLY) {
1994  attr->name = STR_RECVONLY; /* Stream has requested recvonly */
1995  } else if (ast_stream_get_state(stream) == AST_STREAM_STATE_INACTIVE) {
1996  attr->name = STR_INACTIVE; /* Stream has requested inactive */
1997  } else {
1998  attr->name = STR_SENDRECV; /* No hold in either direction */
1999  }
2000  }
2001  media->attr[media->attr_count++] = attr;
2002 
2003  /* If we've got rtcp-mux enabled, add it unless we received an offer without it */
2004  if (session->endpoint->media.rtcp_mux && session_media->remote_rtcp_mux) {
2005  attr = pjmedia_sdp_attr_create(pool, "rtcp-mux", NULL);
2006  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
2007  }
2008 
2009  add_ssrc_to_stream(session, session_media, pool, media);
2010  add_msid_to_stream(session, session_media, pool, media, stream);
2011  add_rtcp_fb_to_stream(session, session_media, pool, media);
2012  add_extmap_to_stream(session, session_media, pool, media);
2013 
2014  /* Add the media stream to the SDP */
2015  sdp->media[sdp->media_count++] = media;
2016 
2017  SCOPE_EXIT_RTN_VALUE(1, "RC: 1\n");
2018 }
unsigned int encryption_optimistic
Definition: res_pjsip.h:713
struct ast_sip_endpoint * endpoint
const char * ast_stream_to_str(const struct ast_stream *stream, struct ast_str **buf)
Get a string representing the stream for debugging/display purposes.
Definition: stream.c:337
static void enable_rtcp(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *remote_media)
Enable RTCP on an RTP session.
enum ast_media_type ast_format_get_type(const struct ast_format *format)
Get the media type of a format.
Definition: format.c:354
unsigned int ast_format_cap_get_framing(const struct ast_format_cap *cap)
Get the global framing.
Definition: format_cap.c:438
unsigned int locally_held
Stream is on hold by local side.
struct ast_sip_session_media_state * pending_media_state
struct ast_sockaddr direct_media_addr
Direct media address.
static int create_rtp(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const pjmedia_sdp_session *sdp)
Internal function which creates an RTP instance.
void ast_rtp_instance_change_source(struct ast_rtp_instance *instance)
Indicate a new source of audio has dropped in and the ssrc should change.
Definition: rtp_engine.c:2160
media_type
Media types generate different "dummy answers" for not accepting the offer of a media stream...
Definition: sip.h:489
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.
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:727
#define LOG_WARNING
Definition: logger.h:274
static int tmp()
Definition: bt_open.c:389
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
pj_str_t transport
The media transport in use for this stream.
static pj_pool_t * pool
Global memory pool for configuration and timers.
struct ast_format_cap * codecs
Definition: res_pjsip.h:770
Set when the stream has been removed/declined.
Definition: stream.h:78
const ast_string_field address
Definition: res_pjsip.h:758
Definition of a media format.
Definition: format.c:43
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)
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
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
Set when the stream is not sending OR receiving media.
Definition: stream.h:94
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
#define NULL
Definition: resample.c:96
struct pjsip_inv_session * inv_session
Socket address structure.
Definition: netsock2.h:97
unsigned int ast_rtp_codecs_get_framing(struct ast_rtp_codecs *codecs)
Get the framing used for a set of codecs.
Definition: rtp_engine.c:1569
struct ast_format_cap * direct_media_cap
enum ast_sip_session_media_encryption encryption
What type of encryption is in use on this stream.
unsigned int bundled
Whether this stream is currently bundled or not.
#define ast_strlen_zero(foo)
Definition: strings.h:52
const char * ast_sip_get_host_ip_string(int af)
Retrieve the local host address in string form.
Definition: res_pjsip.c:5473
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
#define AST_RTP_MAX
Definition: rtp_engine.h:272
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
static pjmedia_sdp_attr * generate_fmtp_attr(pj_pool_t *pool, struct ast_format *format, int rtp_code)
#define ast_log
Definition: astobj2.c:42
int ast_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.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, int asterisk_format, struct ast_format *format, int code)
Retrieve a rx mapped payload type based on whether it is an Asterisk format and the code...
Definition: rtp_engine.c:1873
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:764
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static void add_ssrc_to_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media)
Function which adds ssrc attributes to a media stream.
const struct ast_format_cap * ast_stream_get_formats(const struct ast_stream *stream)
Get the current negotiated formats of a stream.
Definition: stream.c:330
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
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)
int stream_num
The stream number to place into any resulting frames.
#define LOG_ERROR
Definition: logger.h:285
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
enum ast_sip_dtmf_mode dtmf
unsigned int ast_rtp_instance_get_ssrc(struct ast_rtp_instance *rtp)
Retrieve the local SSRC value that we will be using.
Definition: rtp_engine.c:3778
char * ast_sockaddr_stringify_fmt(const struct ast_sockaddr *addr, int format)
Convert a socket address to a string.
Definition: netsock2.c:65
unsigned int remotely_held
Stream is on hold by remote side.
Set when the stream is sending media only.
Definition: stream.h:86
static void add_ice_to_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media, unsigned int include_candidates)
Function which adds ICE attributes to a media stream.
void ast_stream_set_state(struct ast_stream *stream, enum ast_stream_state state)
Set the state of a stream.
Definition: stream.c:380
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
int bundle_group
The bundle group the stream belongs to.
A structure containing SIP session media information.
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
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
enum ast_media_type type
Media type of this session media.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_rtp_instance * rtp
RTP instance itself.
#define AST_SOCKADDR_STR_ADDR
Definition: netsock2.h:202
static void set_ice_components(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
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
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)
int ast_rtp_codecs_payload_set_rx(struct ast_rtp_codecs *codecs, int code, struct ast_format *format)
Set a payload code for use with a specific Asterisk format.
Definition: rtp_engine.c:1923
ast_media_type
Types of media.
Definition: codec.h:30
unsigned int remote_rtcp_mux
Does remote support rtcp_mux.
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
struct ast_format * ast_format_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_stream_get_position(const struct ast_stream *stream)
Get the position of the stream in the topology.
Definition: stream.c:500
#define AST_RTP_DTMF
Definition: rtp_engine.h:266
int ast_format_cap_get_compatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2, struct ast_format_cap *result)
Find the compatible formats between two capabilities structures.
Definition: format_cap.c:630
static snd_pcm_format_t format
Definition: chan_alsa.c:102
Set when the stream is receiving media only.
Definition: stream.h:90
enum ast_stream_state ast_stream_get_state(const struct ast_stream *stream)
Get the current state of a stream.
Definition: stream.c:373
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 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)

◆ create_rtp()

static int create_rtp ( struct ast_sip_session session,
struct ast_sip_session_media session_media,
const pjmedia_sdp_session *  sdp 
)
static

Internal function which creates an RTP instance.

Definition at line 228 of file res_pjsip_sdp_rtp.c.

References ast_sip_endpoint_media_configuration::address, address_rtp, ao2_ref, ast_debug_rtp, ast_log, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_VIDEO, AST_RTP_DTMF_MODE_INBAND, AST_RTP_DTMF_MODE_RFC2833, AST_RTP_EXTENSION_ABS_SEND_TIME, AST_RTP_EXTENSION_DIRECTION_SENDRECV, AST_RTP_EXTENSION_TRANSPORT_WIDE_CC, ast_rtp_instance_dtmf_mode_set(), ast_rtp_instance_get_ice(), ast_rtp_instance_new(), ast_rtp_instance_set_last_rx(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_qos(), AST_RTP_PROPERTY_ASYMMETRIC_CODEC, AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_NAT, AST_RTP_PROPERTY_REMB, AST_RTP_PROPERTY_RETRANS_RECV, AST_RTP_PROPERTY_RETRANS_SEND, AST_SIP_DTMF_AUTO, AST_SIP_DTMF_AUTO_INFO, AST_SIP_DTMF_INBAND, AST_SIP_DTMF_RFC_4733, ast_sip_get_sorcery(), ast_sip_get_transport_state(), ast_sockaddr_parse(), ast_sorcery_object_get_id(), ast_sorcery_retrieve_by_id(), ast_strlen_zero, ast_sip_endpoint::asymmetric_rtp_codec, ast_sip_endpoint_media_configuration::bind_rtp_to_media_address, ast_sip_endpoint_media_configuration::cos_audio, ast_sip_endpoint_media_configuration::cos_video, ast_sip_session::dtmf, enable_rtp_extension(), ast_sip_session::endpoint, ast_sip_media_rtp_configuration::engine, ast_sip_transport_state::host, ast_sip_media_rtp_configuration::ice_support, LOG_ERROR, ast_sip_endpoint::media, media_address, NULL, ast_sip_session_media::rtp, ast_sip_endpoint_media_configuration::rtp, ast_rtp_engine_ice::stop, ast_sip_media_rtp_configuration::symmetric, ast_sip_endpoint_media_configuration::tos_audio, ast_sip_endpoint_media_configuration::tos_video, ast_sip_endpoint::transport, ast_sip_session_media::type, and ast_sip_endpoint_media_configuration::webrtc.

Referenced by apply_negotiated_sdp_stream(), create_outgoing_sdp_stream(), and negotiate_incoming_sdp_stream().

230 {
231  struct ast_rtp_engine_ice *ice;
232  struct ast_sockaddr temp_media_address;
234 
236  if (ast_sockaddr_parse(&temp_media_address, session->endpoint->media.address, 0)) {
237  ast_debug_rtp(1, "Endpoint %s: Binding RTP media to %s\n",
239  session->endpoint->media.address);
240  media_address = &temp_media_address;
241  } else {
242  ast_debug_rtp(1, "Endpoint %s: RTP media address invalid: %s\n",
244  session->endpoint->media.address);
245  }
246  } else {
247  struct ast_sip_transport *transport;
248 
249  transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport",
250  session->endpoint->transport);
251  if (transport) {
252  struct ast_sip_transport_state *trans_state;
253 
254  trans_state = ast_sip_get_transport_state(ast_sorcery_object_get_id(transport));
255  if (trans_state) {
256  char hoststr[PJ_INET6_ADDRSTRLEN];
257 
258  pj_sockaddr_print(&trans_state->host, hoststr, sizeof(hoststr), 0);
259  if (ast_sockaddr_parse(&temp_media_address, hoststr, 0)) {
260  ast_debug_rtp(1, "Transport %s bound to %s: Using it for RTP media.\n",
261  session->endpoint->transport, hoststr);
262  media_address = &temp_media_address;
263  } else {
264  ast_debug_rtp(1, "Transport %s bound to %s: Invalid for RTP media.\n",
265  session->endpoint->transport, hoststr);
266  }
267  ao2_ref(trans_state, -1);
268  }
269  ao2_ref(transport, -1);
270  }
271  }
272 
273  if (!(session_media->rtp = ast_rtp_instance_new(session->endpoint->media.rtp.engine, sched, media_address, NULL))) {
274  ast_log(LOG_ERROR, "Unable to create RTP instance using RTP engine '%s'\n", session->endpoint->media.rtp.engine);
275  return -1;
276  }
277 
280 
281  if (!session->endpoint->media.rtp.ice_support && (ice = ast_rtp_instance_get_ice(session_media->rtp))) {
282  ice->stop(session_media->rtp);
283  }
284 
285  if (session->dtmf == AST_SIP_DTMF_RFC_4733 || session->dtmf == AST_SIP_DTMF_AUTO || session->dtmf == AST_SIP_DTMF_AUTO_INFO) {
288  } else if (session->dtmf == AST_SIP_DTMF_INBAND) {
290  }
291 
292  if (session_media->type == AST_MEDIA_TYPE_AUDIO &&
293  (session->endpoint->media.tos_audio || session->endpoint->media.cos_audio)) {
294  ast_rtp_instance_set_qos(session_media->rtp, session->endpoint->media.tos_audio,
295  session->endpoint->media.cos_audio, "SIP RTP Audio");
296  } else if (session_media->type == AST_MEDIA_TYPE_VIDEO) {
300  if (session->endpoint->media.webrtc) {
303  }
304  if (session->endpoint->media.tos_video || session->endpoint->media.cos_video) {
305  ast_rtp_instance_set_qos(session_media->rtp, session->endpoint->media.tos_video,
306  session->endpoint->media.cos_video, "SIP RTP Video");
307  }
308  }
309 
310  ast_rtp_instance_set_last_rx(session_media->rtp, time(NULL));
311 
312  return 0;
313 }
struct ast_sip_endpoint * endpoint
int ast_rtp_instance_dtmf_mode_set(struct ast_rtp_instance *instance, enum ast_rtp_dtmf_mode dtmf_mode)
Set the DTMF mode that should be used.
Definition: rtp_engine.c:2123
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
const ast_string_field transport
Definition: res_pjsip.h:817
int ast_rtp_instance_set_qos(struct ast_rtp_instance *instance, int tos, int cos, const char *desc)
Set QoS parameters on an RTP session.
Definition: rtp_engine.c:2169
unsigned int asymmetric_rtp_codec
Definition: res_pjsip.h:891
Definition: sched.c:76
struct ast_rtp_engine_ice * ast_rtp_instance_get_ice(struct ast_rtp_instance *instance)
Obtain a pointer to the ICE support present on an RTP instance.
Definition: rtp_engine.c:2891
const ast_string_field address
Definition: res_pjsip.h:758
void(* stop)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:493
#define NULL
Definition: resample.c:96
Socket address structure.
Definition: netsock2.h:97
static struct ast_sockaddr address_rtp
Address for RTP.
static void enable_rtp_extension(struct ast_sip_session *session, struct ast_sip_session_media *session_media, enum ast_rtp_extension extension, enum ast_rtp_extension_direction direction, const pjmedia_sdp_session *sdp)
Enable an RTP extension on an RTP session.
#define ast_strlen_zero(foo)
Definition: strings.h:52
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
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
static struct ast_sockaddr media_address
Definition: chan_sip.c:1132
#define ast_log
Definition: astobj2.c:42
Structure for SIP transport information.
Definition: res_pjsip.h:87
#define ast_debug_rtp(sublevel,...)
Log debug level RTP information.
Definition: rtp_engine.h:2860
const ast_string_field engine
Definition: res_pjsip.h:691
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:764
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
#define LOG_ERROR
Definition: logger.h:285
Transport to bind to.
Definition: res_pjsip.h:171
enum ast_sip_dtmf_mode dtmf
struct ast_sip_transport_state * ast_sip_get_transport_state(const char *transport_id)
Retrieve transport state.
enum ast_media_type type
Media type of this session media.
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
struct ast_rtp_instance * rtp
RTP instance itself.
Structure that represents the optional ICE support within an RTP engine.
Definition: rtp_engine.h:485
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
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
void ast_rtp_instance_set_last_rx(struct ast_rtp_instance *rtp, time_t time)
Set the last RTP reception time.
Definition: rtp_engine.c:3773

◆ enable_rtcp()

static void enable_rtcp ( struct ast_sip_session session,
struct ast_sip_session_media session_media,
const struct pjmedia_sdp_media *  remote_media 
)
static

Enable RTCP on an RTP session.

Definition at line 165 of file res_pjsip_sdp_rtp.c.

References AST_RTP_INSTANCE_RTCP_MUX, AST_RTP_INSTANCE_RTCP_STANDARD, ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_RTCP, ast_sip_session::endpoint, ast_sip_endpoint::media, ast_sip_session_media::remote_rtcp_mux, ast_sip_endpoint_media_configuration::rtcp_mux, and ast_sip_session_media::rtp.

Referenced by apply_negotiated_sdp_stream(), create_outgoing_sdp_stream(), and negotiate_incoming_sdp_stream().

167 {
168  enum ast_rtp_instance_rtcp rtcp_type;
169 
170  if (session->endpoint->media.rtcp_mux && session_media->remote_rtcp_mux) {
171  rtcp_type = AST_RTP_INSTANCE_RTCP_MUX;
172  } else {
173  rtcp_type = AST_RTP_INSTANCE_RTCP_STANDARD;
174  }
175 
176  ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_RTCP, rtcp_type);
177 }
struct ast_sip_endpoint * endpoint
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
ast_rtp_instance_rtcp
Definition: rtp_engine.h:255
struct ast_rtp_instance * rtp
RTP instance itself.
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
unsigned int remote_rtcp_mux
Does remote support rtcp_mux.

◆ enable_rtp_extension()

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 
)
static

Enable an RTP extension on an RTP session.

Definition at line 182 of file res_pjsip_sdp_rtp.c.

References ast_rtp_instance_extmap_count(), ast_rtp_instance_extmap_enable(), ast_rtp_instance_extmap_get_id(), AST_VECTOR_GET, AST_VECTOR_SIZE, ast_sip_session_media::bundle_group, ast_sip_session::pending_media_state, and ast_sip_session_media::rtp.

Referenced by create_rtp().

185 {
186  int id = -1;
187 
188  /* For a bundle group the local unique identifier space is shared across all streams within
189  * it.
190  */
191  if (session_media->bundle_group != -1) {
192  int index;
193 
194  for (index = 0; index < sdp->media_count; ++index) {
195  struct ast_sip_session_media *other_session_media;
196  int other_id;
197 
198  if (index >= AST_VECTOR_SIZE(&session->pending_media_state->sessions)) {
199  break;
200  }
201 
202  other_session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, index);
203  if (!other_session_media->rtp || other_session_media->bundle_group != session_media->bundle_group) {
204  continue;
205  }
206 
207  other_id = ast_rtp_instance_extmap_get_id(other_session_media->rtp, extension);
208  if (other_id == -1) {
209  /* Worst case we have to fall back to the highest available free local unique identifier
210  * for the bundle group.
211  */
212  other_id = ast_rtp_instance_extmap_count(other_session_media->rtp) + 1;
213  if (id < other_id) {
214  id = other_id;
215  }
216  continue;
217  }
218 
219  id = other_id;
220  break;
221  }
222  }
223 
225 }
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
struct ast_sip_session_media_state * pending_media_state
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
structure to hold extensions
int bundle_group
The bundle group the stream belongs to.
A structure containing SIP session media information.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
struct ast_rtp_instance * rtp
RTP instance itself.
direction
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ generate_fmtp_attr()

static pjmedia_sdp_attr* generate_fmtp_attr ( pj_pool_t *  pool,
struct ast_format format,
int  rtp_code 
)
static

Definition at line 649 of file res_pjsip_sdp_rtp.c.

References ast_format_generate_sdp_fmtp(), ast_str_alloca, ast_str_buffer(), ast_str_strlen(), NULL, and tmp().

Referenced by create_outgoing_sdp_stream().

650 {
651  struct ast_str *fmtp0 = ast_str_alloca(256);
652  pj_str_t fmtp1;
653  pjmedia_sdp_attr *attr = NULL;
654  char *tmp;
655 
656  ast_format_generate_sdp_fmtp(format, rtp_code, &fmtp0);
657  if (ast_str_strlen(fmtp0)) {
658  tmp = ast_str_buffer(fmtp0) + ast_str_strlen(fmtp0) - 1;
659  /* remove any carriage return line feeds */
660  while (*tmp == '\r' || *tmp == '\n') --tmp;
661  *++tmp = '\0';
662  /* ast...generate gives us everything, just need value */
663  tmp = strchr(ast_str_buffer(fmtp0), ':');
664  if (tmp && tmp[1] != '\0') {
665  fmtp1 = pj_str(tmp + 1);
666  } else {
667  fmtp1 = pj_str(ast_str_buffer(fmtp0));
668  }
669  attr = pjmedia_sdp_attr_create(pool, "fmtp", &fmtp1);
670  }
671  return attr;
672 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static int tmp()
Definition: bt_open.c:389
static pj_pool_t * pool
Global memory pool for configuration and timers.
#define ast_str_alloca(init_len)
Definition: strings.h:800
#define NULL
Definition: resample.c:96
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
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

◆ generate_rtpmap_attr()

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

Definition at line 614 of file res_pjsip_sdp_rtp.c.

References ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), AST_RTP_OPT_G726_NONSTANDARD, AST_RTP_PT_LAST_STATIC, ast_sip_session::endpoint, ast_sip_endpoint_media_configuration::g726_non_standard, ast_sip_endpoint::media, NULL, options, and tmp().

Referenced by create_outgoing_sdp_stream().

616 {
617 #ifndef HAVE_PJSIP_ENDPOINT_COMPACT_FORM
618  extern pj_bool_t pjsip_use_compact_form;
619 #else
620  pj_bool_t pjsip_use_compact_form = pjsip_cfg()->endpt.use_compact_form;
621 #endif
622  pjmedia_sdp_rtpmap rtpmap;
623  pjmedia_sdp_attr *attr = NULL;
624  char tmp[64];
627 
628  snprintf(tmp, sizeof(tmp), "%d", rtp_code);
629  pj_strdup2(pool, &media->desc.fmt[media->desc.fmt_count++], tmp);
630 
631  if (rtp_code <= AST_RTP_PT_LAST_STATIC && pjsip_use_compact_form) {
632  return NULL;
633  }
634 
635  rtpmap.pt = media->desc.fmt[media->desc.fmt_count - 1];
636  rtpmap.clock_rate = ast_rtp_lookup_sample_rate2(asterisk_format, format, code);
637  pj_strdup2(pool, &rtpmap.enc_name, ast_rtp_lookup_mime_subtype2(asterisk_format, format, code, options));
638  if (!pj_stricmp2(&rtpmap.enc_name, "opus")) {
639  pj_cstr(&rtpmap.param, "2");
640  } else {
641  pj_cstr(&rtpmap.param, NULL);
642  }
643 
644  pjmedia_sdp_rtpmap_to_attr(pool, &rtpmap, &attr);
645 
646  return attr;
647 }
struct ast_sip_endpoint * endpoint
ast_rtp_options
Definition: rtp_engine.h:142
#define AST_RTP_PT_LAST_STATIC
Definition: rtp_engine.h:89
static int tmp()
Definition: bt_open.c:389
static pj_pool_t * pool
Global memory pool for configuration and timers.
#define NULL
Definition: resample.c:96
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
const char * ast_rtp_lookup_mime_subtype2(const int asterisk_format, const struct ast_format *format, int code, enum ast_rtp_options options)
Retrieve mime subtype information on a payload.
Definition: rtp_engine.c:1992
unsigned int ast_rtp_lookup_sample_rate2(int asterisk_format, const struct ast_format *format, int code)
Get the sample rate associated with known RTP payload types.
Definition: rtp_engine.c:2022
static struct test_options options

◆ get_codecs()

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 
)
static

Definition at line 315 of file res_pjsip_sdp_rtp.c.

References ao2_ref, ast_copy_pj_str(), ast_format_parse_sdp_fmtp(), ast_rtp_codecs_get_payload_format(), ast_rtp_codecs_payload_replace_format(), ast_rtp_codecs_payloads_initialize(), ast_rtp_codecs_payloads_set_m_type(), ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_rtp_codecs_set_framing(), AST_RTP_DTMF_MODE_INBAND, AST_RTP_DTMF_MODE_NONE, AST_RTP_DTMF_MODE_RFC2833, ast_rtp_instance_dtmf_mode_set(), ast_rtp_instance_set_prop(), AST_RTP_OPT_G726_NONSTANDARD, AST_RTP_PROPERTY_DTMF, AST_SIP_DTMF_AUTO, AST_SIP_DTMF_AUTO_INFO, ast_sip_session_get_name(), ast_sip_session::dtmf, ast_sip_session::endpoint, format, ast_sip_endpoint_media_configuration::g726_non_standard, ast_sip_session::inv_session, ast_sip_endpoint::media, name, NULL, options, ast_sip_session_media::rtp, ast_sip_endpoint_media_configuration::rtp, SCOPE_ENTER, SCOPE_EXIT_RTN, and ast_sip_media_rtp_configuration::use_ptime.

Referenced by set_caps(), and set_incoming_call_offer_cap().

317 {
318  pjmedia_sdp_attr *attr;
319  pjmedia_sdp_rtpmap *rtpmap;
320  pjmedia_sdp_fmtp fmtp;
321  struct ast_format *format;
322  int i, num = 0, tel_event = 0;
323  char name[256];
324  char media[20];
325  char fmt_param[256];
328  SCOPE_ENTER(1, "%s\n", ast_sip_session_get_name(session));
329 
331 
332  /* Iterate through provided formats */
333  for (i = 0; i < stream->desc.fmt_count; ++i) {
334  /* The payload is kept as a string for things like t38 but for video it is always numerical */
335  ast_rtp_codecs_payloads_set_m_type(codecs, NULL, pj_strtoul(&stream->desc.fmt[i]));
336  /* Look for the optional rtpmap attribute */
337  if (!(attr = pjmedia_sdp_media_find_attr2(stream, "rtpmap", &stream->desc.fmt[i]))) {
338  continue;
339  }
340 
341  /* Interpret the attribute as an rtpmap */
342  if ((pjmedia_sdp_attr_to_rtpmap(session->inv_session->pool_prov, attr, &rtpmap)) != PJ_SUCCESS) {
343  continue;
344  }
345 
346  ast_copy_pj_str(name, &rtpmap->enc_name, sizeof(name));
347  if (strcmp(name, "telephone-event") == 0) {
348  tel_event++;
349  }
350 
351  ast_copy_pj_str(media, (pj_str_t*)&stream->desc.media, sizeof(media));
353  pj_strtoul(&stream->desc.fmt[i]), media, name, options, rtpmap->clock_rate);
354  /* Look for an optional associated fmtp attribute */
355  if (!(attr = pjmedia_sdp_media_find_attr2(stream, "fmtp", &rtpmap->pt))) {
356  continue;
357  }
358 
359  if ((pjmedia_sdp_attr_get_fmtp(attr, &fmtp)) == PJ_SUCCESS) {
360  ast_copy_pj_str(fmt_param, &fmtp.fmt, sizeof(fmt_param));
361  if (sscanf(fmt_param, "%30d", &num) != 1) {
362  continue;
363  }
364 
365  if ((format = ast_rtp_codecs_get_payload_format(codecs, num))) {
366  struct ast_format *format_parsed;
367 
368  ast_copy_pj_str(fmt_param, &fmtp.fmt_param, sizeof(fmt_param));
369 
370  format_parsed = ast_format_parse_sdp_fmtp(format, fmt_param);
371  if (format_parsed) {
372  ast_rtp_codecs_payload_replace_format(codecs, num, format_parsed);
373  ao2_ref(format_parsed, -1);
374  }
375 
376  ao2_ref(format, -1);
377  }
378  }
379  }
380  if (!tel_event && (session->dtmf == AST_SIP_DTMF_AUTO)) {
383  }
384 
385  if (session->dtmf == AST_SIP_DTMF_AUTO_INFO) {
386  if (tel_event) {
389  } else {
392  }
393  }
394 
395 
396  /* Get the packetization, if it exists */
397  if ((attr = pjmedia_sdp_media_find_attr2(stream, "ptime", NULL))) {
398  unsigned long framing = pj_strtoul(pj_strltrim(&attr->value));
399  if (framing && session->endpoint->media.rtp.use_ptime) {
400  ast_rtp_codecs_set_framing(codecs, framing);
401  }
402  }
403 
404  SCOPE_EXIT_RTN();
405 }
struct ast_sip_endpoint * endpoint
ast_rtp_options
Definition: rtp_engine.h:142
int ast_rtp_codecs_payload_replace_format(struct ast_rtp_codecs *codecs, int payload, struct ast_format *format)
Update the format associated with a tx payload type in a codecs structure.
Definition: rtp_engine.c:1503
int ast_rtp_instance_dtmf_mode_set(struct ast_rtp_instance *instance, enum ast_rtp_dtmf_mode dtmf_mode)
Set the DTMF mode that should be used.
Definition: rtp_engine.c:2123
Definition of a media format.
Definition: format.c:43
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:5240
void ast_rtp_codecs_set_framing(struct ast_rtp_codecs *codecs, unsigned int framing)
Set the framing used for a set of codecs.
Definition: rtp_engine.c:1558
#define NULL
Definition: resample.c:96
struct pjsip_inv_session * inv_session
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
struct ast_format * ast_rtp_codecs_get_payload_format(struct ast_rtp_codecs *codecs, int payload)
Retrieve the actual ast_format stored on the codecs structure for a specific tx payload type...
Definition: rtp_engine.c:1537
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:764
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
enum ast_sip_dtmf_mode dtmf
#define SCOPE_EXIT_RTN(...)
Scope Exit with return.
Definition: logger.h:854
static const char name[]
Definition: cdr_mysql.c:74
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
int ast_rtp_codecs_payloads_initialize(struct ast_rtp_codecs *codecs)
Initialize an RTP codecs structure.
Definition: rtp_engine.c:958
struct ast_rtp_instance * rtp
RTP instance itself.
int ast_rtp_codecs_payloads_set_rtpmap_type_rate(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int pt, char *mimetype, char *mimesubtype, enum ast_rtp_options options, unsigned int sample_rate)
Set tx payload type to a known MIME media type for a codec with a specific sample rate...
Definition: rtp_engine.c:1343
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
struct ast_format * ast_format_parse_sdp_fmtp(const struct ast_format *format, const char *attributes)
This function is used to have a media format aware module parse and interpret SDP attribute informati...
Definition: format.c:286
static struct test_options options
static snd_pcm_format_t format
Definition: chan_alsa.c:102
void ast_rtp_codecs_payloads_set_m_type(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload)
Record tx payload type information that was seen in an m= SDP line.
Definition: rtp_engine.c:1301

◆ get_media_encryption_type()

static enum ast_sip_session_media_encryption get_media_encryption_type ( pj_str_t  transport,
const struct pjmedia_sdp_media *  stream,
unsigned int *  optimistic 
)
static

figure out media transport encryption type from the media transport string

Definition at line 938 of file res_pjsip_sdp_rtp.c.

References ast_free, AST_SIP_MEDIA_ENCRYPT_DTLS, AST_SIP_MEDIA_ENCRYPT_NONE, AST_SIP_MEDIA_ENCRYPT_SDES, AST_SIP_MEDIA_TRANSPORT_INVALID, ast_strndup, media_stream_has_crypto(), and RAII_VAR.

Referenced by check_endpoint_media_transport().

940 {
941  RAII_VAR(char *, transport_str, ast_strndup(transport.ptr, transport.slen), ast_free);
942 
943  *optimistic = 0;
944 
945  if (!transport_str) {
947  }
948  if (strstr(transport_str, "UDP/TLS")) {
950  } else if (strstr(transport_str, "SAVP")) {
952  } else if (media_stream_has_crypto(stream)) {
953  *optimistic = 1;
955  } else {
957  }
958 }
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_strndup(str, len)
A wrapper for strndup()
Definition: astmm.h:258
#define ast_free(a)
Definition: astmm.h:182
static int media_stream_has_crypto(const struct pjmedia_sdp_media *stream)
figure out if media stream has crypto lines for sdes

◆ load_module()

static int load_module ( void  )
static

Load the module.

Module loading including tests for configuration or dependencies. This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails tests return AST_MODULE_LOAD_FAILURE. If the module can not load the configuration file or other non-critical problem return AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.

Definition at line 2347 of file res_pjsip_sdp_rtp.c.

References address_rtp, ast_check_ipv6(), ast_log, AST_MODFLAG_LOAD_ORDER, AST_MODPRI_CHANNEL_DRIVER, AST_MODULE_INFO(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, AST_MODULE_SUPPORT_CORE, ast_sched_context_create(), ast_sched_start_thread(), ast_sip_session_register_sdp_handler(), ast_sip_session_register_supplement, ast_sockaddr_parse(), ASTERISK_GPL_KEY, end, LOG_ERROR, STR_AUDIO, STR_VIDEO, and unload_module().

2348 {
2349  if (ast_check_ipv6()) {
2350  ast_sockaddr_parse(&address_rtp, "::", 0);
2351  } else {
2352  ast_sockaddr_parse(&address_rtp, "0.0.0.0", 0);
2353  }
2354 
2355  if (!(sched = ast_sched_context_create())) {
2356  ast_log(LOG_ERROR, "Unable to create scheduler context.\n");
2357  goto end;
2358  }
2359 
2361  ast_log(LOG_ERROR, "Unable to create scheduler context thread.\n");
2362  goto end;
2363  }
2364 
2366  ast_log(LOG_ERROR, "Unable to register SDP handler for %s stream type\n", STR_AUDIO);
2367  goto end;
2368  }
2369 
2371  ast_log(LOG_ERROR, "Unable to register SDP handler for %s stream type\n", STR_VIDEO);
2372  goto end;
2373  }
2374 
2376 
2377  return AST_MODULE_LOAD_SUCCESS;
2378 end:
2379  unload_module();
2380 
2381  return AST_MODULE_LOAD_DECLINE;
2382 }
int ast_sched_start_thread(struct ast_sched_context *con)
Start a thread for processing scheduler entries.
Definition: sched.c:195
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
Definition: sched.c:76
static const char STR_VIDEO[]
char * end
Definition: eagi_proxy.c:73
static struct ast_sockaddr address_rtp
Address for RTP.
static int unload_module(void)
Unloads the sdp RTP/AVP module from Asterisk.
static struct ast_sip_session_sdp_handler video_sdp_handler
SDP handler for &#39;video&#39; media stream.
#define ast_log
Definition: astobj2.c:42
int ast_sip_session_register_sdp_handler(struct ast_sip_session_sdp_handler *handler, const char *stream_type)
Register an SDP handler.
int ast_check_ipv6(void)
Test that an OS supports IPv6 Networking.
Definition: main/utils.c:2540
static struct ast_sip_session_supplement video_info_supplement
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:236
#define LOG_ERROR
Definition: logger.h:285
static struct ast_sip_session_sdp_handler audio_sdp_handler
SDP handler for &#39;audio&#39; media stream.
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static const char STR_AUDIO[]
#define ast_sip_session_register_supplement(supplement)

◆ media_session_rtcp_read_callback()

static struct ast_frame* media_session_rtcp_read_callback ( struct ast_sip_session session,
struct ast_sip_session_media session_media 
)
static

Definition at line 2038 of file res_pjsip_sdp_rtp.c.

References ast_null_frame, ast_rtp_instance_read(), ast_rtp_instance_set_last_rx(), NULL, and ast_sip_session_media::rtp.

Referenced by apply_negotiated_sdp_stream().

2039 {
2040  struct ast_frame *f;
2041 
2042  if (!session_media->rtp) {
2043  return &ast_null_frame;
2044  }
2045 
2046  f = ast_rtp_instance_read(session_media->rtp, 1);
2047  if (!f) {
2048  return NULL;
2049  }
2050 
2051  ast_rtp_instance_set_last_rx(session_media->rtp, time(NULL));
2052 
2053  return f;
2054 }
#define NULL
Definition: resample.c:96
struct ast_frame ast_null_frame
Definition: main/frame.c:79
struct ast_rtp_instance * rtp
RTP instance itself.
Data structure associated with a single frame of data.
void ast_rtp_instance_set_last_rx(struct ast_rtp_instance *rtp, time_t time)
Set the last RTP reception time.
Definition: rtp_engine.c:3773
struct ast_frame * ast_rtp_instance_read(struct ast_rtp_instance *instance, int rtcp)
Receive a frame over RTP.
Definition: rtp_engine.c:578

◆ media_session_rtp_read_callback()

static struct ast_frame* media_session_rtp_read_callback ( struct ast_sip_session session,
struct ast_sip_session_media session_media 
)
static

Definition at line 2020 of file res_pjsip_sdp_rtp.c.

References ast_null_frame, ast_rtp_instance_read(), ast_rtp_instance_set_last_rx(), NULL, and ast_sip_session_media::rtp.

Referenced by apply_negotiated_sdp_stream().

2021 {
2022  struct ast_frame *f;
2023 
2024  if (!session_media->rtp) {
2025  return &ast_null_frame;
2026  }
2027 
2028  f = ast_rtp_instance_read(session_media->rtp, 0);
2029  if (!f) {
2030  return NULL;
2031  }
2032 
2033  ast_rtp_instance_set_last_rx(session_media->rtp, time(NULL));
2034 
2035  return f;
2036 }
#define NULL
Definition: resample.c:96
struct ast_frame ast_null_frame
Definition: main/frame.c:79
struct ast_rtp_instance * rtp
RTP instance itself.
Data structure associated with a single frame of data.
void ast_rtp_instance_set_last_rx(struct ast_rtp_instance *rtp, time_t time)
Set the last RTP reception time.
Definition: rtp_engine.c:3773
struct ast_frame * ast_rtp_instance_read(struct ast_rtp_instance *instance, int rtcp)
Receive a frame over RTP.
Definition: rtp_engine.c:578

◆ media_session_rtp_write_callback()

static int media_session_rtp_write_callback ( struct ast_sip_session session,
struct ast_sip_session_media session_media,
struct ast_frame frame 
)
static

Definition at line 2056 of file res_pjsip_sdp_rtp.c.

References ast_rtp_instance_write(), and ast_sip_session_media::rtp.

Referenced by apply_negotiated_sdp_stream().

2057 {
2058  if (!session_media->rtp) {
2059  return 0;
2060  }
2061 
2062  return ast_rtp_instance_write(session_media->rtp, frame);
2063 }
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
struct ast_rtp_instance * rtp
RTP instance itself.

◆ media_stream_has_crypto()

static int media_stream_has_crypto ( const struct pjmedia_sdp_media *  stream)
static

figure out if media stream has crypto lines for sdes

Definition at line 918 of file res_pjsip_sdp_rtp.c.

Referenced by get_media_encryption_type().

919 {
920  int i;
921 
922  for (i = 0; i < stream->attr_count; i++) {
923  pjmedia_sdp_attr *attr;
924 
925  /* check the stream for the required crypto attribute */
926  attr = stream->attr[i];
927  if (pj_strcmp2(&attr->name, "crypto")) {
928  continue;
929  }
930 
931  return 1;
932  }
933 
934  return 0;
935 }

◆ negotiate_incoming_sdp_stream()

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 
)
static

Function which negotiates an incoming media stream.

Definition at line 1462 of file res_pjsip_sdp_rtp.c.

References ao2_cleanup, apply_cap_to_bundled(), AST_AF_UNSPEC, ast_codec_media_type2str(), ast_copy_pj_str(), ast_debug, ast_format_cap_has_type(), ast_free, AST_MEDIA_TYPE_AUDIO, ast_rtp_instance_bundle(), AST_SIP_MEDIA_ENCRYPT_NONE, AST_SIP_MEDIA_ENCRYPT_SDES, AST_SIP_MEDIA_TRANSPORT_INVALID, ast_sip_session_get_name(), ast_sip_session_is_pending_stream_default(), ast_sip_session_media_get_transport(), ast_sockaddr_is_any(), ast_sockaddr_isnull(), ast_sockaddr_resolve(), ast_sip_session_media::bundled, check_endpoint_media_transport(), check_ice_support(), ast_sip_endpoint_media_configuration::codecs, create_rtp(), enable_rtcp(), ast_sip_session_media::encryption, ast_sip_media_rtp_configuration::encryption_optimistic, ast_sip_session::endpoint, host, ast_sip_session::inv_session, ast_sip_endpoint::media, NULL, PARSE_PORT_FORBID, process_extmap_attributes(), process_ice_auth_attrb(), process_ssrc_attributes(), RAII_VAR, ast_sip_session_media::remote_ice, ast_sip_session_media::remote_rtcp_mux, ast_sip_session_media::remotely_held, ast_sip_session_media::remotely_held_changed, ast_sip_session_media::rtp, ast_sip_endpoint_media_configuration::rtp, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, set_ice_components(), set_incoming_call_offer_cap(), setup_media_encryption(), ast_sip_session_media::transport, ast_sip_session_media::type, and ast_sip_media_rtp_configuration::use_received_transport.

1465 {
1466  char host[NI_MAXHOST];
1467  RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free);
1468  pjmedia_sdp_media *stream = sdp->media[index];
1469  struct ast_sip_session_media *session_media_transport;
1470  enum ast_media_type media_type = session_media->type;
1472  struct ast_format_cap *joint;
1473  int res;
1474  SCOPE_ENTER(1, "%s\n", ast_sip_session_get_name(session));
1475 
1476  /* If no type formats have been configured reject this stream */
1477  if (!ast_format_cap_has_type(session->endpoint->media.codecs, media_type)) {
1478  ast_debug(3, "Endpoint has no codecs for media type '%s', declining stream\n",
1479  ast_codec_media_type2str(session_media->type));
1480  SCOPE_EXIT_RTN_VALUE(0, "Endpoint has no codecs\n");
1481  }
1482 
1483  /* Ensure incoming transport is compatible with the endpoint's configuration */
1484  if (!session->endpoint->media.rtp.use_received_transport) {
1485  encryption = check_endpoint_media_transport(session->endpoint, stream);
1486 
1487  if (encryption == AST_SIP_MEDIA_TRANSPORT_INVALID) {
1488  SCOPE_EXIT_RTN_VALUE(-1, "Incompatible transport\n");
1489  }
1490  }
1491 
1492  ast_copy_pj_str(host, stream->conn ? &stream->conn->addr : &sdp->conn->addr, sizeof(host));
1493 
1494  /* Ensure that the address provided is valid */
1495  if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC) <= 0) {
1496  /* The provided host was actually invalid so we error out this negotiation */
1497  SCOPE_EXIT_RTN_VALUE(-1, "Invalid host\n");
1498  }
1499 
1500  /* Using the connection information create an appropriate RTP instance */
1501  if (!session_media->rtp && create_rtp(session, session_media, sdp)) {
1502  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create rtp\n");
1503  }
1504 
1505  process_ssrc_attributes(session, session_media, stream);
1506  process_extmap_attributes(session, session_media, stream);
1507  session_media_transport = ast_sip_session_media_get_transport(session, session_media);
1508 
1509  if (session_media_transport == session_media || !session_media->bundled) {
1510  /* If this media session is carrying actual traffic then set up those aspects */
1511  session_media->remote_rtcp_mux = (pjmedia_sdp_media_find_attr2(stream, "rtcp-mux", NULL) != NULL);
1512  set_ice_components(session, session_media);
1513 
1514  enable_rtcp(session, session_media, stream);
1515 
1516  res = setup_media_encryption(session, session_media, sdp, stream);
1517  if (res) {
1518  if (!session->endpoint->media.rtp.encryption_optimistic ||
1519  !pj_strncmp2(&stream->desc.transport, "RTP/SAVP", 8)) {
1520  /* If optimistic encryption is disabled and crypto should have been enabled
1521  * but was not this session must fail. This must also fail if crypto was
1522  * required in the offer but could not be set up.
1523  */
1524  SCOPE_EXIT_RTN_VALUE(-1, "Incompatible crypto\n");
1525  }
1526  /* There is no encryption, sad. */
1527  session_media->encryption = AST_SIP_MEDIA_ENCRYPT_NONE;
1528  }
1529 
1530  /* If we've been explicitly configured to use the received transport OR if
1531  * encryption is on and crypto is present use the received transport.
1532  * This is done in case of optimistic because it may come in as RTP/AVP or RTP/SAVP depending
1533  * on the configuration of the remote endpoint (optimistic themselves or mandatory).
1534  */
1535  if ((session->endpoint->media.rtp.use_received_transport) ||
1536  ((encryption == AST_SIP_MEDIA_ENCRYPT_SDES) && !res)) {
1537  pj_strdup(session->inv_session->pool, &session_media->transport, &stream->desc.transport);
1538  }
1539  } else {
1540  /* This is bundled with another session, so mark it as such */
1541  ast_rtp_instance_bundle(session_media->rtp, session_media_transport->rtp);
1542 
1543  enable_rtcp(session, session_media, stream);
1544  }
1545 
1546  /* If ICE support is enabled find all the needed attributes */
1547  check_ice_support(session, session_media, stream);
1548 
1549  /* If ICE support is enabled then check remote ICE started? */
1550  if (session_media->remote_ice) {
1551  process_ice_auth_attrb(session, session_media, sdp, stream);
1552  }
1553 
1554  if (ast_sip_session_is_pending_stream_default(session, asterisk_stream) && media_type == AST_MEDIA_TYPE_AUDIO) {
1555  /* Check if incomming SDP is changing the remotely held state */
1556  if (ast_sockaddr_isnull(addrs) ||
1557  ast_sockaddr_is_any(addrs) ||
1558  pjmedia_sdp_media_find_attr2(stream, "sendonly", NULL) ||
1559  pjmedia_sdp_media_find_attr2(stream, "inactive", NULL)) {
1560  if (!session_media->remotely_held) {
1561  session_media->remotely_held = 1;
1562  session_media->remotely_held_changed = 1;
1563  }
1564  } else if (session_media->remotely_held) {
1565  session_media->remotely_held = 0;
1566  session_media->remotely_held_changed = 1;
1567  }
1568  }
1569 
1570  joint = set_incoming_call_offer_cap(session, session_media, stream);
1571  res = apply_cap_to_bundled(session_media, session_media_transport, asterisk_stream, joint);
1572  ao2_cleanup(joint);
1573  if (res != 0) {
1574  SCOPE_EXIT_RTN_VALUE(0, "Something failed\n");
1575  }
1576 
1578 }
unsigned int encryption_optimistic
Definition: res_pjsip.h:713
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)
struct ast_sip_endpoint * endpoint
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.
ast_sip_session_media_encryption
Definition: res_pjsip.h:504
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.
media_type
Media types generate different "dummy answers" for not accepting the offer of a media stream...
Definition: sip.h:489
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.
int ast_rtp_instance_bundle(struct ast_rtp_instance *child, struct ast_rtp_instance *parent)
Request that an RTP instance be bundled with another.
Definition: rtp_engine.c:3804
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 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.
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
pj_str_t transport
The media transport in use for this stream.
struct ast_format_cap * codecs
Definition: res_pjsip.h:770
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:5240
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)
#define NULL
Definition: resample.c:96
struct pjsip_inv_session * inv_session
Socket address structure.
Definition: netsock2.h:97
unsigned int use_received_transport
Definition: res_pjsip.h:705
enum ast_sip_session_media_encryption encryption
What type of encryption is in use on this 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)
unsigned int bundled
Whether this stream is currently bundled or not.
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
int ast_sockaddr_is_any(const struct ast_sockaddr *addr)
Determine if the address type is unspecified, or "any" address.
Definition: netsock2.c:534
static char host[256]
Definition: muted.c:77
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.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:764
static void process_extmap_attributes(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *remote_stream)
Function which processes extmap attributes in a stream.
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
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.
unsigned int remotely_held
Stream is on hold by remote side.
#define ast_free(a)
Definition: astmm.h:182
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
A structure containing SIP session media information.
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
static enum ast_sip_session_media_encryption check_endpoint_media_transport(struct ast_sip_endpoint *endpoint, const struct pjmedia_sdp_media *stream)
Checks whether the encryption offered in SDP is compatible with the endpoint&#39;s configuration.
enum ast_media_type type
Media type of this session media.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
unsigned int remotely_held_changed
Stream is held by remote side changed during this negotiation.
struct ast_rtp_instance * rtp
RTP instance itself.
static void set_ice_components(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
ast_media_type
Types of media.
Definition: codec.h:30
unsigned int remote_rtcp_mux
Does remote support rtcp_mux.
int ast_format_cap_has_type(const struct ast_format_cap *cap, enum ast_media_type type)
Find out if the capabilities structure has any formats of a specific type.
Definition: format_cap.c:615
int ast_sockaddr_resolve(struct ast_sockaddr **addrs, const char *str, int flags, int family)
Parses a string with an IPv4 or IPv6 address and place results into an array.
Definition: netsock2.c:280
unsigned int remote_ice
Does remote support ice.

◆ parse_dtls_attrib()

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

Definition at line 1099 of file res_pjsip_sdp_rtp.c.

References apply_dtls_attrib(), ast_set_flag, AST_SRTP_CRYPTO_OFFER_OK, and ast_sip_session_media::srtp.

Referenced by setup_media_encryption().

1102 {
1103  int i;
1104 
1105  for (i = 0; i < sdp->attr_count; i++) {
1106  apply_dtls_attrib(session_media, sdp->attr[i]);
1107  }
1108 
1109  for (i = 0; i < stream->attr_count; i++) {
1110  apply_dtls_attrib(session_media, stream->attr[i]);
1111  }
1112 
1113  ast_set_flag(session_media->srtp, AST_SRTP_CRYPTO_OFFER_OK);
1114 
1115  return 0;
1116 }
static void apply_dtls_attrib(struct ast_sip_session_media *session_media, pjmedia_sdp_attr *attr)
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define AST_SRTP_CRYPTO_OFFER_OK
Definition: sdp_srtp.h:44
struct ast_sdp_srtp * srtp
Holds SRTP information.

◆ process_extmap_attributes()

static void process_extmap_attributes ( struct ast_sip_session session,
struct ast_sip_session_media session_media,
const struct pjmedia_sdp_media *  remote_stream 
)
static

Function which processes extmap attributes in a stream.

Definition at line 1404 of file res_pjsip_sdp_rtp.c.

References ast_copy_pj_str(), AST_MEDIA_TYPE_VIDEO, AST_RTP_EXTENSION_DIRECTION_INACTIVE, AST_RTP_EXTENSION_DIRECTION_RECVONLY, AST_RTP_EXTENSION_DIRECTION_SENDONLY, AST_RTP_EXTENSION_DIRECTION_SENDRECV, ast_rtp_instance_extmap_clear(), ast_rtp_instance_extmap_negotiate(), ast_strlen_zero, ast_sip_session::endpoint, id, ast_sip_endpoint::media, ast_sip_session_media::rtp, ast_sip_session_media::type, and ast_sip_endpoint_media_configuration::webrtc.

Referenced by apply_negotiated_sdp_stream(), and negotiate_incoming_sdp_stream().

1406 {
1407  int index;
1408 
1409  if (!session->endpoint->media.webrtc || session_media->type != AST_MEDIA_TYPE_VIDEO) {
1410  return;
1411  }
1412 
1413  ast_rtp_instance_extmap_clear(session_media->rtp);
1414 
1415  for (index = 0; index < remote_stream->attr_count; ++index) {
1416  pjmedia_sdp_attr *attr = remote_stream->attr[index];
1417  char attr_value[pj_strlen(&attr->value) + 1];
1418  char *uri;
1419  int id;
1420  char direction_str[10] = "";
1421  char *attributes;
1423 
1424  /* We only care about extmap attributes */
1425  if (pj_strcmp2(&attr->name, "extmap")) {
1426  continue;
1427  }
1428 
1429  ast_copy_pj_str(attr_value, &attr->value, sizeof(attr_value));
1430 
1431  /* Split the combined unique identifier and direction away from the URI and attributes for easier parsing */
1432  uri = strchr(attr_value, ' ');
1433  if (ast_strlen_zero(uri)) {
1434  continue;
1435  }
1436  *uri++ = '\0';
1437 
1438  if ((sscanf(attr_value, "%30d%9s", &id, direction_str) < 1) || (id < 1)) {
1439  /* We require at a minimum the unique identifier */
1440  continue;
1441  }
1442 
1443  /* Convert from the string to the internal representation */
1444  if (!strcasecmp(direction_str, "/sendonly")) {
1446  } else if (!strcasecmp(direction_str, "/recvonly")) {
1448  } else if (!strcasecmp(direction_str, "/inactive")) {
1450  }
1451 
1452  attributes = strchr(uri, ' ');
1453  if (!ast_strlen_zero(attributes)) {
1454  *attributes++ = '\0';
1455  }
1456 
1457  ast_rtp_instance_extmap_negotiate(session_media->rtp, id, direction, uri, attributes);
1458  }
1459 }
struct ast_sip_endpoint * endpoint
void ast_rtp_instance_extmap_clear(struct ast_rtp_instance *instance)
Clear negotiated RTP extension information.
Definition: rtp_engine.c:862
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:5240
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
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
ast_rtp_extension_direction
Directions for RTP extensions.
Definition: rtp_engine.h:769
enum ast_media_type type
Media type of this session media.
struct ast_rtp_instance * rtp
RTP instance itself.
enum queue_result id
Definition: app_queue.c:1507
direction

◆ process_ice_attributes()

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 
)
static

Function which processes ICE attributes in an audio stream.

Definition at line 814 of file res_pjsip_sdp_rtp.c.

References ast_rtp_engine_ice::add_remote_candidate, ast_rtp_engine_ice_candidate::address, ast_copy_pj_str(), ast_debug_ice, AST_RTP_ICE_CANDIDATE_TYPE_HOST, AST_RTP_ICE_CANDIDATE_TYPE_RELAYED, AST_RTP_ICE_CANDIDATE_TYPE_SRFLX, AST_RTP_ICE_ROLE_CONTROLLED, AST_RTP_ICE_ROLE_CONTROLLING, ast_rtp_instance_get_ice(), ast_sockaddr_parse(), ast_sockaddr_set_port, ast_strlen_zero, ast_sip_session::endpoint, ast_rtp_engine_ice_candidate::foundation, ast_rtp_engine_ice::ice_lite, ast_sip_media_rtp_configuration::ice_support, ast_rtp_engine_ice_candidate::id, ast_sip_session::inv_session, ast_sip_endpoint::media, NULL, PARSE_PORT_FORBID, ast_rtp_engine_ice_candidate::priority, ast_rtp_engine_ice_candidate::relay_address, ast_sip_session_media::remote_rtcp_mux, ast_sip_endpoint_media_configuration::rtcp_mux, ast_sip_session_media::rtp, ast_sip_endpoint_media_configuration::rtp, ast_rtp_engine_ice::set_authentication, ast_rtp_engine_ice::set_role, ast_rtp_engine_ice::start, ast_rtp_engine_ice_candidate::transport, and ast_rtp_engine_ice_candidate::type.

Referenced by apply_negotiated_sdp_stream().

816 {
817  struct ast_rtp_engine_ice *ice;
818  const pjmedia_sdp_attr *attr;
819  char attr_value[256];
820  unsigned int attr_i;
821 
822  /* If ICE support is not enabled or available exit early */
823  if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) {
824  return;
825  }
826 
827  ast_debug_ice(2, "(%p) ICE process attributes\n", session_media->rtp);
828 
829  attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-ufrag", NULL);
830  if (!attr) {
831  attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-ufrag", NULL);
832  }
833  if (attr) {
834  ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
835  ice->set_authentication(session_media->rtp, attr_value, NULL);
836  } else {
837  ast_debug_ice(2, "(%p) ICE no, or invalid ice-ufrag\n", session_media->rtp);
838  return;
839  }
840 
841  attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-pwd", NULL);
842  if (!attr) {
843  attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-pwd", NULL);
844  }
845  if (attr) {
846  ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
847  ice->set_authentication(session_media->rtp, NULL, attr_value);
848  } else {
849  ast_debug_ice(2, "(%p) ICE no, or invalid ice-pwd\n", session_media->rtp);
850  return;
851  }
852 
853  if (pjmedia_sdp_media_find_attr2(remote_stream, "ice-lite", NULL)) {
854  ice->ice_lite(session_media->rtp);
855  }
856 
857  /* Find all of the candidates */
858  for (attr_i = 0; attr_i < remote_stream->attr_count; ++attr_i) {
859  char foundation[33], transport[32], address[PJ_INET6_ADDRSTRLEN + 1], cand_type[6], relay_address[PJ_INET6_ADDRSTRLEN + 1] = "";
860  unsigned int port, relay_port = 0;
861  struct ast_rtp_engine_ice_candidate candidate = { 0, };
862 
863  attr = remote_stream->attr[attr_i];
864 
865  /* If this is not a candidate line skip it */
866  if (pj_strcmp2(&attr->name, "candidate")) {
867  continue;
868  }
869 
870  ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
871 
872  if (sscanf(attr_value, "%32s %30u %31s %30u %46s %30u typ %5s %*s %23s %*s %30u", foundation, &candidate.id, transport,
873  (unsigned *)&candidate.priority, address, &port, cand_type, relay_address, &relay_port) < 7) {
874  /* Candidate did not parse properly */
875  continue;
876  }
877 
878  if (session->endpoint->media.rtcp_mux && session_media->remote_rtcp_mux && candidate.id > 1) {
879  /* Remote side may have offered RTP and RTCP candidates. However, if we're using RTCP MUX,
880  * then we should ignore RTCP candidates.
881  */
882  continue;
883  }
884 
885  candidate.foundation = foundation;
886  candidate.transport = transport;
887 
888  ast_sockaddr_parse(&candidate.address, address, PARSE_PORT_FORBID);
889  ast_sockaddr_set_port(&candidate.address, port);
890 
891  if (!strcasecmp(cand_type, "host")) {
893  } else if (!strcasecmp(cand_type, "srflx")) {
895  } else if (!strcasecmp(cand_type, "relay")) {
897  } else {
898  continue;
899  }
900 
901  if (!ast_strlen_zero(relay_address)) {
902  ast_sockaddr_parse(&candidate.relay_address, relay_address, PARSE_PORT_FORBID);
903  }
904 
905  if (relay_port) {
906  ast_sockaddr_set_port(&candidate.relay_address, relay_port);
907  }
908 
909  ice->add_remote_candidate(session_media->rtp, &candidate);
910  }
911 
912  ice->set_role(session_media->rtp, pjmedia_sdp_neg_was_answer_remote(session->inv_session->neg) == PJ_TRUE ?
914  ice->start(session_media->rtp);
915 }
struct ast_sip_endpoint * endpoint
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
char * address
Definition: f2c.h:59
struct ast_rtp_engine_ice * ast_rtp_instance_get_ice(struct ast_rtp_instance *instance)
Obtain a pointer to the ICE support present on an RTP instance.
Definition: rtp_engine.c:2891
void(* add_remote_candidate)(struct ast_rtp_instance *instance, const struct ast_rtp_engine_ice_candidate *candidate)
Definition: rtp_engine.h:489
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:5240
#define NULL
Definition: resample.c:96
struct pjsip_inv_session * inv_session
Structure for an ICE candidate.
Definition: rtp_engine.h:474
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
enum ast_rtp_ice_candidate_type type
Definition: rtp_engine.h:481
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:764
struct ast_sockaddr relay_address
Definition: rtp_engine.h:480
void(* set_authentication)(struct ast_rtp_instance *instance, const char *ufrag, const char *password)
Definition: rtp_engine.h:487
void(* set_role)(struct ast_rtp_instance *instance, enum ast_rtp_ice_role role)
Definition: rtp_engine.h:503
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
enum ast_rtp_ice_component_type id
Definition: rtp_engine.h:476
#define ast_debug_ice(sublevel,...)
Log debug level ICE information.
Definition: rtp_engine.h:2898
void(* start)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:491
struct ast_rtp_instance * rtp
RTP instance itself.
Structure that represents the optional ICE support within an RTP engine.
Definition: rtp_engine.h:485
unsigned int remote_rtcp_mux
Does remote support rtcp_mux.
struct ast_sockaddr address
Definition: rtp_engine.h:479
void(* ice_lite)(struct ast_rtp_instance *instance)
Definition: rtp_engine.h:501

◆ process_ice_auth_attrb()

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

Definition at line 776 of file res_pjsip_sdp_rtp.c.

References ast_copy_pj_str(), ast_rtp_instance_get_ice(), ast_sip_session::endpoint, ast_sip_media_rtp_configuration::ice_support, ast_sip_endpoint::media, NULL, ast_sip_session_media::rtp, ast_sip_endpoint_media_configuration::rtp, and ast_rtp_engine_ice::set_authentication.

Referenced by negotiate_incoming_sdp_stream().

778 {
779  struct ast_rtp_engine_ice *ice;
780  const pjmedia_sdp_attr *ufrag_attr, *passwd_attr;
781  char ufrag_attr_value[256];
782  char passwd_attr_value[256];
783 
784  /* If ICE support is not enabled or available exit early */
785  if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) {
786  return;
787  }
788 
789  ufrag_attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-ufrag", NULL);
790  if (!ufrag_attr) {
791  ufrag_attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-ufrag", NULL);
792  }
793  if (ufrag_attr) {
794  ast_copy_pj_str(ufrag_attr_value, (pj_str_t*)&ufrag_attr->value, sizeof(ufrag_attr_value));
795  } else {
796  return;
797  }
798  passwd_attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-pwd", NULL);
799  if (!passwd_attr) {
800  passwd_attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-pwd", NULL);
801  }
802  if (passwd_attr) {
803  ast_copy_pj_str(passwd_attr_value, (pj_str_t*)&passwd_attr->value, sizeof(passwd_attr_value));
804  } else {
805  return;
806  }
807 
808  if (ufrag_attr && passwd_attr) {
809  ice->set_authentication(session_media->rtp, ufrag_attr_value, passwd_attr_value);
810  }
811 }
struct ast_sip_endpoint * endpoint
struct ast_rtp_engine_ice * ast_rtp_instance_get_ice(struct ast_rtp_instance *instance)
Obtain a pointer to the ICE support present on an RTP instance.
Definition: rtp_engine.c:2891
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:5240
#define NULL
Definition: resample.c:96
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:764
void(* set_authentication)(struct ast_rtp_instance *instance, const char *ufrag, const char *password)
Definition: rtp_engine.h:487
struct ast_rtp_instance * rtp
RTP instance itself.
Structure that represents the optional ICE support within an RTP engine.
Definition: rtp_engine.h:485

◆ process_ssrc_attributes()

static void process_ssrc_attributes ( struct ast_sip_session session,
struct ast_sip_session_media session_media,
const struct pjmedia_sdp_media *  remote_stream 
)
static

Function which processes ssrc attributes in a stream.

Definition at line 1218 of file res_pjsip_sdp_rtp.c.

References ast_sip_session::active_media_state, ast_copy_pj_str(), ast_rtp_instance_get_stats(), ast_rtp_instance_set_remote_ssrc(), AST_RTP_INSTANCE_STAT_REMOTE_SSRC, ast_sip_endpoint_media_configuration::bundle, ast_sip_session_media::changed, ast_sip_session::endpoint, ast_sip_session::inv_session, ast_sip_endpoint::media, NULL, ast_rtp_instance_stats::remote_ssrc, and ast_sip_session_media::rtp.

Referenced by apply_negotiated_sdp_stream(), and negotiate_incoming_sdp_stream().

1220 {
1221  int index;
1222 
1223  if (!session->endpoint->media.bundle) {
1224  return;
1225  }
1226 
1227  for (index = 0; index < remote_stream->attr_count; ++index) {
1228  pjmedia_sdp_attr *attr = remote_stream->attr[index];
1229  char attr_value[pj_strlen(&attr->value) + 1];
1230  char *ssrc_attribute_name, *ssrc_attribute_value = NULL;
1231  unsigned int ssrc;
1232 
1233  /* We only care about ssrc attributes */
1234  if (pj_strcmp2(&attr->name, "ssrc")) {
1235  continue;
1236  }
1237 
1238  ast_copy_pj_str(attr_value, &attr->value, sizeof(attr_value));
1239 
1240  if ((ssrc_attribute_name = strchr(attr_value, ' '))) {
1241  /* This has an actual attribute */
1242  *ssrc_attribute_name++ = '\0';
1243  ssrc_attribute_value = strchr(ssrc_attribute_name, ':');
1244  if (ssrc_attribute_value) {
1245  /* Values are actually optional according to the spec */
1246  *ssrc_attribute_value++ = '\0';
1247  }
1248  }
1249 
1250  if (sscanf(attr_value, "%30u", &ssrc) < 1) {
1251  continue;
1252  }
1253 
1254  /* If we are currently negotiating as a result of the remote side renegotiating then
1255  * determine if the source for this stream has changed.
1256  */
1257  if (pjmedia_sdp_neg_get_state(session->inv_session->neg) == PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER &&
1258  session->active_media_state) {
1259  struct ast_rtp_instance_stats stats = { 0, };
1260 
1261  if (!ast_rtp_instance_get_stats(session_media->rtp, &stats, AST_RTP_INSTANCE_STAT_REMOTE_SSRC) &&
1262  stats.remote_ssrc != ssrc) {
1263  session_media->changed = 1;
1264  }
1265  }
1266 
1267  ast_rtp_instance_set_remote_ssrc(session_media->rtp, ssrc);
1268  break;
1269  }
1270 }
struct ast_sip_endpoint * endpoint
int ast_rtp_instance_get_stats(struct ast_rtp_instance *instance, struct ast_rtp_instance_stats *stats, enum ast_rtp_instance_stat stat)
Retrieve statistics about an RTP instance.
Definition: rtp_engine.c:2446
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:5240
#define NULL
Definition: resample.c:96
struct pjsip_inv_session * inv_session
struct ast_sip_session_media_state * active_media_state
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
void ast_rtp_instance_set_remote_ssrc(struct ast_rtp_instance *rtp, unsigned int ssrc)
Set the remote SSRC for an RTP instance.
Definition: rtp_engine.c:3821
unsigned int changed
The underlying session has been changed in some fashion.
struct ast_rtp_instance * rtp
RTP instance itself.
unsigned int remote_ssrc
Definition: rtp_engine.h:424

◆ rtp_check_timeout()

static int rtp_check_timeout ( const void *  data)
static

Check whether RTP is being received or not.

Definition at line 105 of file res_pjsip_sdp_rtp.c.

References AST_CAUSE_REQUESTED_CHAN_UNAVAIL, ast_channel_get_by_name(), ast_channel_hangupcause_set(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_channel_unref, ast_codec_media_type2str(), ast_debug_rtp, ast_log, ast_rtp_instance_get_channel_id(), ast_rtp_instance_get_last_rx(), ast_rtp_instance_get_timeout(), ast_sockaddr_isnull(), ast_softhangup(), AST_SOFTHANGUP_DEV, ast_sip_session_media::direct_media_addr, LOG_NOTICE, NULL, ast_sip_session_media::rtp, timeout, and ast_sip_session_media::type.

Referenced by apply_negotiated_sdp_stream().

106 {
107  struct ast_sip_session_media *session_media = (struct ast_sip_session_media *)data;
108  struct ast_rtp_instance *rtp = session_media->rtp;
109  int elapsed;
110  int timeout;
111  struct ast_channel *chan;
112 
113  if (!rtp) {
114  return 0;
115  }
116 
118  if (!chan) {
119  return 0;
120  }
121 
122  /* Get channel lock to make sure that we access a consistent set of values
123  * (last_rx and direct_media_addr) - the lock is held when values are modified
124  * (see send_direct_media_request()/check_for_rtp_changes() in chan_pjsip.c). We
125  * are trying to avoid a situation where direct_media_addr has been reset but the
126  * last-rx time was not set yet.
127  */
128  ast_channel_lock(chan);
129 
130  elapsed = time(NULL) - ast_rtp_instance_get_last_rx(rtp);
131  timeout = ast_rtp_instance_get_timeout(rtp);
132  if (elapsed < timeout) {
133  ast_channel_unlock(chan);
134  ast_channel_unref(chan);
135  return (timeout - elapsed) * 1000;
136  }
137 
138  /* Last RTP packet was received too long ago
139  * - disconnect channel unless direct media is in use.
140  */
141  if (!ast_sockaddr_isnull(&session_media->direct_media_addr)) {
142  ast_debug_rtp(3, "(%p) RTP not disconnecting channel '%s' for lack of %s RTP activity in %d seconds "
143  "since direct media is in use\n", rtp, ast_channel_name(chan),
144  ast_codec_media_type2str(session_media->type), elapsed);
145  ast_channel_unlock(chan);
146  ast_channel_unref(chan);
147  return timeout * 1000; /* recheck later, direct media may have ended then */
148  }
149 
150  ast_log(LOG_NOTICE, "Disconnecting channel '%s' for lack of %s RTP activity in %d seconds\n",
151  ast_channel_name(chan), ast_codec_media_type2str(session_media->type), elapsed);
152 
155 
156  ast_channel_unlock(chan);
157  ast_channel_unref(chan);
158 
159  return 0;
160 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
struct ast_sockaddr direct_media_addr
Direct media address.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
int ast_rtp_instance_get_timeout(struct ast_rtp_instance *instance)
Get the RTP timeout value.
Definition: rtp_engine.c:2685
static int timeout
Definition: cdr_mysql.c:86
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
#define NULL
Definition: resample.c:96
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
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_log
Definition: astobj2.c:42
#define ast_debug_rtp(sublevel,...)
Log debug level RTP information.
Definition: rtp_engine.h:2860
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2476
#define LOG_NOTICE
Definition: logger.h:263
#define ast_channel_unlock(chan)
Definition: channel.h:2946
time_t ast_rtp_instance_get_last_rx(const struct ast_rtp_instance *rtp)
Definition: rtp_engine.c:3768
A structure containing SIP session media information.
#define AST_CAUSE_REQUESTED_CHAN_UNAVAIL
Definition: causes.h:124
enum ast_media_type type
Media type of this session media.
struct ast_rtp_instance * rtp
RTP instance itself.
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454

◆ send_keepalive()

static int send_keepalive ( const void *  data)
static

Definition at line 71 of file res_pjsip_sdp_rtp.c.

References ast_debug_rtp, ast_rtp_instance_get_keepalive(), ast_rtp_instance_get_last_tx(), ast_rtp_instance_sendcng(), ast_sockaddr_isnull(), ast_sip_session_media::direct_media_addr, keepalive, NULL, and ast_sip_session_media::rtp.

Referenced by apply_negotiated_sdp_stream().

72 {
73  struct ast_sip_session_media *session_media = (struct ast_sip_session_media *) data;
74  struct ast_rtp_instance *rtp = session_media->rtp;
75  int keepalive;
76  time_t interval;
77  int send_keepalive;
78 
79  if (!rtp) {
80  return 0;
81  }
82 
83  keepalive = ast_rtp_instance_get_keepalive(rtp);
84 
85  if (!ast_sockaddr_isnull(&session_media->direct_media_addr)) {
86  ast_debug_rtp(3, "(%p) RTP not sending keepalive since direct media is in use\n", rtp);
87  return keepalive * 1000;
88  }
89 
90  interval = time(NULL) - ast_rtp_instance_get_last_tx(rtp);
91  send_keepalive = interval >= keepalive;
92 
93  ast_debug_rtp(3, "(%p) RTP it has been %d seconds since RTP was last sent. %sending keepalive\n",
94  rtp, (int) interval, send_keepalive ? "S" : "Not s");
95 
96  if (send_keepalive) {
98  return keepalive * 1000;
99  }
100 
101  return (keepalive - interval) * 1000;
102 }
struct ast_sockaddr direct_media_addr
Direct media address.
static uint32_t keepalive
Definition: res_pktccops.c:160
#define NULL
Definition: resample.c:96
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_debug_rtp(sublevel,...)
Log debug level RTP information.
Definition: rtp_engine.h:2860
time_t ast_rtp_instance_get_last_tx(const struct ast_rtp_instance *rtp)
Get the last RTP transmission time.
Definition: rtp_engine.c:3758
int ast_rtp_instance_sendcng(struct ast_rtp_instance *instance, int level)
Send a comfort noise packet to the RTP instance.
Definition: rtp_engine.c:2772
A structure containing SIP session media information.
static int send_keepalive(const void *data)
struct ast_rtp_instance * rtp
RTP instance itself.
int ast_rtp_instance_get_keepalive(struct ast_rtp_instance *instance)
Get the RTP keepalive interval.
Definition: rtp_engine.c:2695

◆ set_caps()

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

Definition at line 485 of file res_pjsip_sdp_rtp.c.

References ao2_cleanup, ao2_ref, apply_cap_to_bundled(), ast_channel_is_bridged(), ast_channel_lock, ast_channel_nativeformats(), ast_channel_nativeformats_set(), ast_channel_readformat(), ast_channel_set_unbridged_nolock(), ast_channel_unlock, ast_channel_writeformat(), ast_codec_media_type2str(), ast_dsp_free(), ast_dsp_get_features(), ast_dsp_set_features(), ast_format_cap_alloc, ast_format_cap_append, ast_format_cap_append_from_cap(), ast_format_cap_count(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_best_by_type(), ast_format_cap_get_compatible(), ast_format_cap_get_format(), ast_format_cap_get_framing(), ast_format_cap_get_names(), AST_FORMAT_CAP_NAMES_LEN, ast_format_cap_remove_by_type(), ast_log, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_UNKNOWN, AST_RTP_CODECS_NULL_INIT, ast_rtp_codecs_payload_formats(), ast_rtp_codecs_payloads_copy(), ast_rtp_codecs_payloads_destroy(), ast_rtp_codecs_payloads_xover(), AST_RTP_DTMF_MODE_RFC2833, ast_rtp_instance_dtmf_mode_get(), ast_rtp_instance_get_codecs(), ast_set_read_format(), ast_set_write_format(), AST_SIP_DTMF_AUTO, AST_SIP_DTMF_AUTO_INFO, ast_sip_session_get_name(), ast_sip_session_is_pending_stream_default(), ast_sockaddr_isnull(), ast_str_alloca, ast_sip_endpoint::asymmetric_rtp_codec, ast_sip_session::channel, ast_sip_endpoint_media_configuration::codecs, ast_sip_session_media::direct_media_addr, ast_sip_session::direct_media_cap, ast_sip_session::dsp, DSP_FEATURE_DIGIT_DETECT, ast_sip_session::dtmf, ast_sip_session::endpoint, get_codecs(), LOG_ERROR, LOG_NOTICE, ast_sip_endpoint::media, NULL, ast_sip_endpoint::preferred_codec_only, RAII_VAR, ast_sip_session_media::rtp, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, and ast_sip_session_media::type.

Referenced by apply_negotiated_sdp_stream().

490 {
491  RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup);
492  RAII_VAR(struct ast_format_cap *, peer, NULL, ao2_cleanup);
493  RAII_VAR(struct ast_format_cap *, joint, NULL, ao2_cleanup);
494  enum ast_media_type media_type = session_media->type;
496  int fmts = 0;
497  int direct_media_enabled = !ast_sockaddr_isnull(&session_media->direct_media_addr) &&
499  int dsp_features = 0;
500  SCOPE_ENTER(1, "%s %s\n", ast_sip_session_get_name(session), is_offer ? "OFFER" : "ANSWER");
501 
505  ast_log(LOG_ERROR, "Failed to allocate %s capabilities\n",
506  ast_codec_media_type2str(session_media->type));
507  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create %s capabilities\n",
508  ast_codec_media_type2str(session_media->type));
509  }
510 
511  /* get the endpoint capabilities */
512  if (direct_media_enabled) {
514  } else {
515  ast_format_cap_append_from_cap(caps, session->endpoint->media.codecs, media_type);
516  }
517 
518  /* get the capabilities on the peer */
519  get_codecs(session, stream, &codecs, session_media);
520  ast_rtp_codecs_payload_formats(&codecs, peer, &fmts);
521 
522  /* get the joint capabilities between peer and endpoint */
523  ast_format_cap_get_compatible(caps, peer, joint);
524  if (!ast_format_cap_count(joint)) {
527 
529  ast_log(LOG_NOTICE, "No joint capabilities for '%s' media stream between our configuration(%s) and incoming SDP(%s)\n",
530  ast_codec_media_type2str(session_media->type),
531  ast_format_cap_get_names(caps, &usbuf),
532  ast_format_cap_get_names(peer, &thembuf));
533  SCOPE_EXIT_RTN_VALUE(-1, "No joint capabilities for '%s' media stream between our configuration(%s) and incoming SDP(%s)\n",
534  ast_codec_media_type2str(session_media->type),
535  ast_format_cap_get_names(caps, &usbuf),
536  ast_format_cap_get_names(peer, &thembuf));
537  }
538 
539  if (is_offer) {
540  /*
541  * Setup rx payload type mapping to prefer the mapping
542  * from the peer that the RFC says we SHOULD use.
543  */
544  ast_rtp_codecs_payloads_xover(&codecs, &codecs, NULL);
545  }
547  session_media->rtp);
548 
549  apply_cap_to_bundled(session_media, session_media_transport, asterisk_stream, joint);
550 
551  if (session->channel && ast_sip_session_is_pending_stream_default(session, asterisk_stream)) {
552  ast_channel_lock(session->channel);
556  ast_format_cap_remove_by_type(caps, media_type);
557 
558  if (session->endpoint->preferred_codec_only){
559  struct ast_format *preferred_fmt = ast_format_cap_get_format(joint, 0);
560  ast_format_cap_append(caps, preferred_fmt, 0);
561  ao2_ref(preferred_fmt, -1);
562  } else if (!session->endpoint->asymmetric_rtp_codec) {
563  struct ast_format *best;
564  /*
565  * If we don't allow the sending codec to be changed on our side
566  * then get the best codec from the joint capabilities of the media
567  * type and use only that. This ensures the core won't start sending
568  * out a format that we aren't currently sending.
569  */
570 
571  best = ast_format_cap_get_best_by_type(joint, media_type);
572  if (best) {
574  ao2_ref(best, -1);
575  }
576  } else {
577  ast_format_cap_append_from_cap(caps, joint, media_type);
578  }
579 
580  /*
581  * Apply the new formats to the channel, potentially changing
582  * raw read/write formats and translation path while doing so.
583  */
584  ast_channel_nativeformats_set(session->channel, caps);
585  if (media_type == AST_MEDIA_TYPE_AUDIO) {
588  }
589 
590  if ( ((session->dtmf == AST_SIP_DTMF_AUTO) || (session->dtmf == AST_SIP_DTMF_AUTO_INFO) )
592  && (session->dsp)) {
593  dsp_features = ast_dsp_get_features(session->dsp);
594  dsp_features &= ~DSP_FEATURE_DIGIT_DETECT;
595  if (dsp_features) {
596  ast_dsp_set_features(session->dsp, dsp_features);
597  } else {
598  ast_dsp_free(session->dsp);
599  session->dsp = NULL;
600  }
601  }
602 
603  if (ast_channel_is_bridged(session->channel)) {
605  }
606 
607  ast_channel_unlock(session->channel);
608  }
609 
612 }
void ast_rtp_codecs_payload_formats(struct ast_rtp_codecs *codecs, struct ast_format_cap *astformats, int *nonastformats)
Retrieve all formats that were found.
Definition: rtp_engine.c:1580
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)
#define ast_channel_lock(chan)
Definition: channel.h:2945
struct ast_sip_endpoint * endpoint
unsigned int ast_format_cap_get_framing(const struct ast_format_cap *cap)
Get the global framing.
Definition: format_cap.c:438
struct ast_sockaddr direct_media_addr
Direct media address.
media_type
Media types generate different "dummy answers" for not accepting the offer of a media stream...
Definition: sip.h:489
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)
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1770
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:727
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
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
unsigned int asymmetric_rtp_codec
Definition: res_pjsip.h:891
void ast_rtp_codecs_payloads_xover(struct ast_rtp_codecs *src, struct ast_rtp_codecs *dest, struct ast_rtp_instance *instance)
Crossover copy the tx payload mapping of src to the rx payload mapping of dest.
Definition: rtp_engine.c:1257
struct ast_format_cap * codecs
Definition: res_pjsip.h:770
Definition of a media format.
Definition: format.c:43
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition: format_cap.c:395
struct ast_format * ast_format_cap_get_best_by_type(const struct ast_format_cap *cap, enum ast_media_type type)
Get the most preferred format for a particular media type.
Definition: format_cap.c:417
#define ast_str_alloca(init_len)
Definition: strings.h:800
#define AST_RTP_CODECS_NULL_INIT
Definition: rtp_engine.h:716
#define NULL
Definition: resample.c:96
struct ast_format_cap * direct_media_cap
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
struct ast_dsp * dsp
#define ast_log
Definition: astobj2.c:42
int ast_dsp_get_features(struct ast_dsp *dsp)
Get features.
Definition: dsp.c:1764
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_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5849
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
static struct ao2_container * codecs
Registered codecs.
Definition: codec.c:48
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_channel * channel
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition: channel.c:5890
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...
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition: format_cap.c:525
#define LOG_ERROR
Definition: logger.h:285
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
enum ast_sip_dtmf_mode dtmf
#define LOG_NOTICE
Definition: logger.h:263
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10746
unsigned int preferred_codec_only
Definition: res_pjsip.h:889
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1755
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
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
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
void ast_rtp_codecs_payloads_copy(struct ast_rtp_codecs *src, struct ast_rtp_codecs *dest, struct ast_rtp_instance *instance)
Copy payload information from one RTP instance to another.
Definition: rtp_engine.c:1224
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
enum ast_media_type type
Media type of this session media.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_rtp_instance * rtp
RTP instance itself.
enum ast_rtp_dtmf_mode ast_rtp_instance_dtmf_mode_get(struct ast_rtp_instance *instance)
Get the DTMF mode of an RTP instance.
Definition: rtp_engine.c:2137
ast_media_type
Types of media.
Definition: codec.h:30
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition: format_cap.c:400
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
int ast_format_cap_get_compatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2, struct ast_format_cap *result)
Find the compatible formats between two capabilities structures.
Definition: format_cap.c:630

◆ set_ice_components()

static void set_ice_components ( struct ast_sip_session session,
struct ast_sip_session_media session_media 
)
static

Definition at line 1181 of file res_pjsip_sdp_rtp.c.

References ast_assert, ast_rtp_instance_get_ice(), ast_rtp_engine_ice::change_components, ast_sip_session::endpoint, ast_sip_media_rtp_configuration::ice_support, ast_sip_endpoint::media, NULL, ast_sip_session_media::remote_rtcp_mux, ast_sip_endpoint_media_configuration::rtcp_mux, ast_sip_session_media::rtp, and ast_sip_endpoint_media_configuration::rtp.

Referenced by apply_negotiated_sdp_stream(), create_outgoing_sdp_stream(), and negotiate_incoming_sdp_stream().

1182 {
1183  struct ast_rtp_engine_ice *ice;
1184 
1185  ast_assert(session_media->rtp != NULL);
1186 
1187  ice = ast_rtp_instance_get_ice(session_media->rtp);
1188  if (!session->endpoint->media.rtp.ice_support || !ice) {
1189  return;
1190  }
1191 
1192  if (session->endpoint->media.rtcp_mux && session_media->remote_rtcp_mux) {
1193  /* We both support RTCP mux. Only one ICE component necessary */
1194  ice->change_components(session_media->rtp, 1);
1195  } else {
1196  /* They either don't support RTCP mux or we don't know if they do yet. */
1197  ice->change_components(session_media->rtp, 2);
1198  }
1199 }
struct ast_sip_endpoint * endpoint
struct ast_rtp_engine_ice * ast_rtp_instance_get_ice(struct ast_rtp_instance *instance)
Obtain a pointer to the ICE support present on an RTP instance.
Definition: rtp_engine.c:2891
void(* change_components)(struct ast_rtp_instance *instance, int num_components)
Definition: rtp_engine.h:509
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:764
struct ast_rtp_instance * rtp
RTP instance itself.
Structure that represents the optional ICE support within an RTP engine.
Definition: rtp_engine.h:485
unsigned int remote_rtcp_mux
Does remote support rtcp_mux.

◆ set_incoming_call_offer_cap()

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

Definition at line 438 of file res_pjsip_sdp_rtp.c.

References ao2_cleanup, ao2_ref, ast_codec_media_type2str(), ast_format_cap_alloc, ast_format_cap_empty(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_log, AST_RTP_CODECS_NULL_INIT, ast_rtp_codecs_payload_formats(), ast_rtp_codecs_payloads_copy(), ast_rtp_codecs_payloads_destroy(), ast_rtp_codecs_payloads_xover(), ast_rtp_instance_get_codecs(), ast_sip_session_create_joint_call_cap(), ast_sip_session_get_name(), get_codecs(), LOG_ERROR, NULL, ast_sip_session_media::rtp, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, and ast_sip_session_media::type.

Referenced by negotiate_incoming_sdp_stream().

441 {
442  struct ast_format_cap *incoming_call_offer_cap;
443  struct ast_format_cap *remote;
445  int fmts = 0;
446  SCOPE_ENTER(1, "%s\n", ast_sip_session_get_name(session));
447 
448 
450  if (!remote) {
451  ast_log(LOG_ERROR, "Failed to allocate %s incoming remote capabilities\n",
452  ast_codec_media_type2str(session_media->type));
453  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't allocate caps\n");
454  }
455 
456  /* Get the peer's capabilities*/
457  get_codecs(session, stream, &codecs, session_media);
458  ast_rtp_codecs_payload_formats(&codecs, remote, &fmts);
459 
460  incoming_call_offer_cap = ast_sip_session_create_joint_call_cap(
461  session, session_media->type, remote);
462 
463  ao2_ref(remote, -1);
464 
465  if (!incoming_call_offer_cap || ast_format_cap_empty(incoming_call_offer_cap)) {
466  ao2_cleanup(incoming_call_offer_cap);
468  SCOPE_EXIT_RTN_VALUE(NULL, "No incoming call offer caps\n");
469  }
470 
471  /*
472  * Setup rx payload type mapping to prefer the mapping
473  * from the peer that the RFC says we SHOULD use.
474  */
475  ast_rtp_codecs_payloads_xover(&codecs, &codecs, NULL);
476 
478  ast_rtp_instance_get_codecs(session_media->rtp), session_media->rtp);
479 
481 
482  SCOPE_EXIT_RTN_VALUE(incoming_call_offer_cap);
483 }
void ast_rtp_codecs_payload_formats(struct ast_rtp_codecs *codecs, struct ast_format_cap *astformats, int *nonastformats)
Retrieve all formats that were found.
Definition: rtp_engine.c:1580
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 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_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
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
void ast_rtp_codecs_payloads_xover(struct ast_rtp_codecs *src, struct ast_rtp_codecs *dest, struct ast_rtp_instance *instance)
Crossover copy the tx payload mapping of src to the rx payload mapping of dest.
Definition: rtp_engine.c:1257
#define AST_RTP_CODECS_NULL_INIT
Definition: rtp_engine.h:716
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
static struct ao2_container * codecs
Registered codecs.
Definition: codec.c:48
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
#define LOG_ERROR
Definition: logger.h:285
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
void ast_rtp_codecs_payloads_destroy(struct ast_rtp_codecs *codecs)
Destroy the contents of an RTP codecs structure (but not the structure itself)
Definition: rtp_engine.c:974
void ast_rtp_codecs_payloads_copy(struct ast_rtp_codecs *src, struct ast_rtp_codecs *dest, struct ast_rtp_instance *instance)
Copy payload information from one RTP instance to another.
Definition: rtp_engine.c:1224
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
enum ast_media_type type
Media type of this session media.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_rtp_instance * rtp
RTP instance itself.
int ast_format_cap_empty(const struct ast_format_cap *cap)
Determine if a format cap has no formats in it.
Definition: format_cap.c:746

◆ setup_dtls_srtp()

static int setup_dtls_srtp ( struct ast_sip_session session,
struct ast_sip_session_media session_media 
)
static

Definition at line 1023 of file res_pjsip_sdp_rtp.c.

References AST_AES_CM_128_HMAC_SHA1_32, AST_AES_CM_128_HMAC_SHA1_80, ast_log, ast_rtp_instance_get_dtls(), ast_sip_media_rtp_configuration::dtls_cfg, ast_rtp_dtls_cfg::enabled, ast_sip_session::endpoint, LOG_ERROR, ast_sip_endpoint::media, ast_sip_session_media::rtp, ast_sip_endpoint_media_configuration::rtp, ast_rtp_engine_dtls::set_configuration, setup_srtp(), ast_sip_media_rtp_configuration::srtp_tag_32, and ast_rtp_dtls_cfg::suite.

Referenced by add_crypto_to_stream(), and setup_media_encryption().

1025 {
1026  struct ast_rtp_engine_dtls *dtls;
1027 
1028  if (!session->endpoint->media.rtp.dtls_cfg.enabled || !session_media->rtp) {
1029  return -1;
1030  }
1031 
1032  dtls = ast_rtp_instance_get_dtls(session_media->rtp);
1033  if (!dtls) {
1034  return -1;
1035  }
1036 
1038  if (dtls->set_configuration(session_media->rtp, &session->endpoint->media.rtp.dtls_cfg)) {
1039  ast_log(LOG_ERROR, "Attempted to set an invalid DTLS-SRTP configuration on RTP instance '%p'\n",
1040  session_media->rtp);
1041  return -1;
1042  }
1043 
1044  if (setup_srtp(session_media)) {
1045  return -1;
1046  }
1047  return 0;
1048 }
struct ast_sip_endpoint * endpoint
int(* set_configuration)(struct ast_rtp_instance *instance, const struct ast_rtp_dtls_cfg *dtls_cfg)
Definition: rtp_engine.h:572
struct ast_rtp_dtls_cfg dtls_cfg
DTLS-SRTP configuration information.
Definition: res_pjsip.h:707
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
#define ast_log
Definition: astobj2.c:42
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:764
Structure that represents the optional DTLS SRTP support within an RTP engine.
Definition: rtp_engine.h:570
unsigned int enabled
Definition: rtp_engine.h:555
#define LOG_ERROR
Definition: logger.h:285
struct ast_rtp_engine_dtls * ast_rtp_instance_get_dtls(struct ast_rtp_instance *instance)
Obtain a pointer to the DTLS support present on an RTP instance.
Definition: rtp_engine.c:3011
static int setup_srtp(struct ast_sip_session_media *session_media)
struct ast_rtp_instance * rtp
RTP instance itself.
enum ast_srtp_suite suite
Definition: rtp_engine.h:558

◆ setup_media_encryption()

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

Definition at line 1154 of file res_pjsip_sdp_rtp.c.

References AST_SIP_MEDIA_ENCRYPT_DTLS, AST_SIP_MEDIA_ENCRYPT_NONE, AST_SIP_MEDIA_ENCRYPT_SDES, AST_SIP_MEDIA_TRANSPORT_INVALID, ast_sip_session_media::encryption, parse_dtls_attrib(), setup_dtls_srtp(), and setup_sdes_srtp().

Referenced by apply_negotiated_sdp_stream(), and negotiate_incoming_sdp_stream().

1158 {
1159  switch (session_media->encryption) {
1161  if (setup_sdes_srtp(session_media, stream)) {
1162  return -1;
1163  }
1164  break;
1166  if (setup_dtls_srtp(session, session_media)) {
1167  return -1;
1168  }
1169  if (parse_dtls_attrib(session_media, sdp, stream)) {
1170  return -1;
1171  }
1172  break;
1175  break;
1176  }
1177 
1178  return 0;
1179 }
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 int setup_sdes_srtp(struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *stream)
static int setup_dtls_srtp(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
enum ast_sip_session_media_encryption encryption
What type of encryption is in use on this stream.

◆ setup_sdes_srtp()

static int setup_sdes_srtp ( struct ast_sip_session_media session_media,
const struct pjmedia_sdp_media *  stream 
)
static

Definition at line 1118 of file res_pjsip_sdp_rtp.c.

References ast_free, ast_log, ast_sdp_crypto_process(), ast_strndup, LOG_WARNING, NULL, RAII_VAR, ast_sip_session_media::rtp, setup_srtp(), and ast_sip_session_media::srtp.

Referenced by setup_media_encryption().

1120 {
1121  int i;
1122 
1123  for (i = 0; i < stream->attr_count; i++) {
1124  pjmedia_sdp_attr *attr;
1125  RAII_VAR(char *, crypto_str, NULL, ast_free);
1126 
1127  /* check the stream for the required crypto attribute */
1128  attr = stream->attr[i];
1129  if (pj_strcmp2(&attr->name, "crypto")) {
1130  continue;
1131  }
1132 
1133  crypto_str = ast_strndup(attr->value.ptr, attr->value.slen);
1134  if (!crypto_str) {
1135  return -1;
1136  }
1137 
1138  if (setup_srtp(session_media)) {
1139  return -1;
1140  }
1141 
1142  if (!ast_sdp_crypto_process(session_media->rtp, session_media->srtp, crypto_str)) {
1143  /* found a valid crypto attribute */
1144  return 0;
1145  }
1146 
1147  ast_log(LOG_WARNING, "Ignoring crypto offer with unsupported parameters: %s\n", crypto_str);
1148  }
1149 
1150  /* no usable crypto attributes found */
1151  return -1;
1152 }
#define LOG_WARNING
Definition: logger.h:274
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
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ast_sdp_srtp * srtp
Holds SRTP information.
#define ast_strndup(str, len)
A wrapper for strndup()
Definition: astmm.h:258
#define ast_free(a)
Definition: astmm.h:182
static int setup_srtp(struct ast_sip_session_media *session_media)
struct ast_rtp_instance * rtp
RTP instance itself.

◆ setup_srtp()

static int setup_srtp ( struct ast_sip_session_media session_media)
static

Definition at line 1004 of file res_pjsip_sdp_rtp.c.

References ast_sdp_crypto_alloc(), ast_sdp_srtp_alloc(), ast_sdp_srtp::crypto, and ast_sip_session_media::srtp.

Referenced by setup_dtls_srtp(), and setup_sdes_srtp().

1005 {
1006  if (!session_media->srtp) {
1007  session_media->srtp = ast_sdp_srtp_alloc();
1008  if (!session_media->srtp) {
1009  return -1;
1010  }
1011  }
1012 
1013  if (!session_media->srtp->crypto) {
1014  session_media->srtp->crypto = ast_sdp_crypto_alloc();
1015  if (!session_media->srtp->crypto) {
1016  return -1;
1017  }
1018  }
1019 
1020  return 0;
1021 }
struct ast_sdp_crypto * crypto
Definition: sdp_srtp.h:39
struct ast_sdp_srtp * srtp
Holds SRTP information.
struct ast_sdp_srtp * ast_sdp_srtp_alloc(void)
allocate a ast_sdp_srtp structure
Definition: sdp_srtp.c:41
struct ast_sdp_crypto * ast_sdp_crypto_alloc(void)
Initialize an return an ast_sdp_crypto struct.
Definition: sdp_srtp.c:71

◆ stream_destroy()

static void stream_destroy ( struct ast_sip_session_media session_media)
static

Function which destroys the RTP instance when session ends.

Definition at line 2264 of file res_pjsip_sdp_rtp.c.

References ast_rtp_instance_destroy(), NULL, ast_sip_session_media::rtp, and stream_stop().

2265 {
2266  if (session_media->rtp) {
2267  stream_stop(session_media);
2268  ast_rtp_instance_destroy(session_media->rtp);
2269  }
2270  session_media->rtp = NULL;
2271 }
#define NULL
Definition: resample.c:96
static void stream_stop(struct ast_sip_session_media *session_media)
Function which stops the RTP instance.
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
Definition: rtp_engine.c:458
struct ast_rtp_instance * rtp
RTP instance itself.

◆ stream_stop()

static void stream_stop ( struct ast_sip_session_media session_media)
static

Function which stops the RTP instance.

Definition at line 2252 of file res_pjsip_sdp_rtp.c.

References ast_rtp_instance_stop(),