Asterisk - The Open Source Telephony Project GIT-master-57e2743
Loading...
Searching...
No Matches
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.
 
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.
 
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)
 
static int assign_unique_bundle_payload (struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct ast_sip_session_media *session_media_transport, const pjmedia_sdp_session *sdp, const pjmedia_sdp_media *media, struct ast_format *format)
 Assign a payload type that is unique across the generated BUNDLE group.
 
struct ast_module * AST_MODULE_SELF_SYM (void)
 
static int bundle_payload_type_used (struct ast_sip_session *session, const pjmedia_sdp_session *sdp, const pjmedia_sdp_media *media, int bundle_group, int payload)
 Determine whether a payload type is already advertised in a BUNDLE group.
 
static void change_outgoing_sdp_stream_media_address (pjsip_tx_data *tdata, struct pjmedia_sdp_media *stream, struct ast_sip_transport *transport)
 Function which updates the media stream with external media address, if applicable.
 
static enum ast_sip_session_media_encryption check_endpoint_media_transport (struct ast_sip_endpoint *endpoint, const struct pjmedia_sdp_media *stream)
 Checks whether the encryption offered in SDP is compatible with the endpoint's configuration.
 
static void check_ice_support (struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *remote_stream)
 Function which checks for ice attributes in an audio stream.
 
static int create_outgoing_sdp_stream (struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_session *remote, struct ast_stream *stream)
 Function which creates an outgoing stream.
 
static int create_rtp (struct ast_sip_session *session, struct ast_sip_session_media *session_media, const pjmedia_sdp_session *sdp)
 Internal function which creates an RTP instance.
 
static void enable_rtcp (struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *remote_media)
 Enable RTCP on an RTP session.
 
static void enable_rtp_extension (struct ast_sip_session *session, struct ast_sip_session_media *session_media, enum ast_rtp_extension extension, enum ast_rtp_extension_direction direction, const pjmedia_sdp_session *sdp)
 Enable an RTP extension on an RTP session.
 
static int ensure_payload_type_mapping (struct ast_rtp_codecs *codecs, int payload, struct ast_format *format)
 Ensure an RTP codecs structure can receive a format using a payload type.
 
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 pjmedia_sdp_attr * generate_rtpmap_attr2 (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 sample_rate)
 
static int generating_local_offer (const struct ast_sip_session *session)
 Determine whether the SDP currently being generated is a local offer.
 
static void get_codecs (struct ast_sip_session *session, const struct pjmedia_sdp_media *stream, struct ast_rtp_codecs *codecs, struct ast_sip_session_media *session_media, struct ast_format_cap *astformats)
 
static enum ast_sip_session_media_encryption get_media_encryption_type (pj_str_t transport, const struct pjmedia_sdp_media *stream, unsigned int *optimistic)
 figure out media transport encryption type from the media transport string
 
static int load_module (void)
 Load the module.
 
static struct ast_frame * media_session_rtcp_read_callback (struct ast_sip_session *session, struct ast_sip_session_media *session_media)
 
static struct ast_frame * media_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
 
static int negotiate_incoming_sdp_stream (struct ast_sip_session *session, struct ast_sip_session_media *session_media, const pjmedia_sdp_session *sdp, int index, struct ast_stream *asterisk_stream)
 Function which negotiates an incoming media stream.
 
static 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 payload_type_compatible (struct ast_rtp_codecs *codecs, int payload, struct ast_format *format)
 Check whether a payload slot is either free or already mapped to the requested format.
 
static void process_extmap_attributes (struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *remote_stream)
 Function which processes extmap attributes in a stream.
 
static void process_ice_attributes (struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream)
 Function which processes ICE attributes in an audio stream.
 
static 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.
 
static int rtp_check_timeout (const void *data)
 Check whether RTP is being received or not.
 
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_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 set_session_media_remotely_held (struct ast_sip_session_media *session_media, const struct ast_sip_session *session, const pjmedia_sdp_media *media, const struct ast_stream *stream, const struct ast_sockaddr *addrs)
 
static 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.
 
static void stream_stop (struct ast_sip_session_media *session_media)
 Function which stops the RTP instance.
 
static int unload_module (void)
 Unloads the sdp RTP/AVP module from Asterisk.
 
static int video_info_incoming_request (struct ast_sip_session *session, struct pjsip_rx_data *rdata)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP SDP RTP/AVP stream handler" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .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.
 
static const struct ast_module_info * ast_module_info = &__mod_info
 
static struct ast_sip_session_sdp_handler audio_sdp_handler
 SDP handler for 'audio' media stream.
 
static struct ast_sched_context * sched
 Scheduler for RTCP purposes.
 
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.
 

Detailed Description

SIP SDP media stream handling.

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in file res_pjsip_sdp_rtp.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 2735 of file res_pjsip_sdp_rtp.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 2735 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 1823 of file res_pjsip_sdp_rtp.c.

1826{
1827 pj_str_t stmp;
1828 pjmedia_sdp_attr *attr;
1829 enum ast_rtp_dtls_hash hash;
1830 const char *crypto_attribute;
1831 struct ast_rtp_engine_dtls *dtls;
1832 struct ast_sdp_srtp *tmp;
1833 static const pj_str_t STR_NEW = { "new", 3 };
1834 static const pj_str_t STR_EXISTING = { "existing", 8 };
1835 static const pj_str_t STR_ACTIVE = { "active", 6 };
1836 static const pj_str_t STR_PASSIVE = { "passive", 7 };
1837 static const pj_str_t STR_ACTPASS = { "actpass", 7 };
1838 static const pj_str_t STR_HOLDCONN = { "holdconn", 8 };
1839 static const pj_str_t STR_MEDSECREQ = { "requested", 9 };
1840 enum ast_rtp_dtls_setup setup;
1841
1842 switch (session_media->encryption) {
1845 break;
1847 if (!session_media->srtp) {
1848 session_media->srtp = ast_sdp_srtp_alloc();
1849 if (!session_media->srtp) {
1850 return -1;
1851 }
1852 }
1853
1854 tmp = session_media->srtp;
1855
1856 do {
1857 crypto_attribute = ast_sdp_srtp_get_attrib(tmp,
1858 0 /* DTLS running? No */,
1859 session->endpoint->media.rtp.srtp_tag_32 /* 32 byte tag length? */);
1860 if (!crypto_attribute) {
1861 /* No crypto attribute to add, bad news */
1862 return -1;
1863 }
1864
1865 attr = pjmedia_sdp_attr_create(pool, "crypto",
1866 pj_cstr(&stmp, crypto_attribute));
1867 media->attr[media->attr_count++] = attr;
1868 } while ((tmp = AST_LIST_NEXT(tmp, sdp_srtp_list)));
1869
1870 if (session->endpoint->security_negotiation == AST_SIP_SECURITY_NEG_MEDIASEC) {
1871 attr = pjmedia_sdp_attr_create(pool, "3ge2ae", &STR_MEDSECREQ);
1872 media->attr[media->attr_count++] = attr;
1873 }
1874
1875 break;
1877 if (setup_dtls_srtp(session, session_media)) {
1878 return -1;
1879 }
1880
1881 dtls = ast_rtp_instance_get_dtls(session_media->rtp);
1882 if (!dtls) {
1883 return -1;
1884 }
1885
1886 switch (dtls->get_connection(session_media->rtp)) {
1888 attr = pjmedia_sdp_attr_create(pool, "connection", &STR_NEW);
1889 media->attr[media->attr_count++] = attr;
1890 break;
1892 attr = pjmedia_sdp_attr_create(pool, "connection", &STR_EXISTING);
1893 media->attr[media->attr_count++] = attr;
1894 break;
1895 default:
1896 break;
1897 }
1898
1899 /* If this is an answer we need to use our current state, if it's an offer we need to use
1900 * the configured value.
1901 */
1902 if (session->inv_session->neg
1903 && pjmedia_sdp_neg_get_state(session->inv_session->neg) != PJMEDIA_SDP_NEG_STATE_DONE) {
1904 setup = dtls->get_setup(session_media->rtp);
1905 } else {
1906 setup = session->endpoint->media.rtp.dtls_cfg.default_setup;
1907 }
1908
1909 switch (setup) {
1911 attr = pjmedia_sdp_attr_create(pool, "setup", &STR_ACTIVE);
1912 media->attr[media->attr_count++] = attr;
1913 break;
1915 attr = pjmedia_sdp_attr_create(pool, "setup", &STR_PASSIVE);
1916 media->attr[media->attr_count++] = attr;
1917 break;
1919 attr = pjmedia_sdp_attr_create(pool, "setup", &STR_ACTPASS);
1920 media->attr[media->attr_count++] = attr;
1921 break;
1923 attr = pjmedia_sdp_attr_create(pool, "setup", &STR_HOLDCONN);
1924 break;
1925 default:
1926 break;
1927 }
1928
1929 hash = dtls->get_fingerprint_hash(session_media->rtp);
1930 crypto_attribute = dtls->get_fingerprint(session_media->rtp);
1931 if (crypto_attribute && (hash == AST_RTP_DTLS_HASH_SHA1 || hash == AST_RTP_DTLS_HASH_SHA256)) {
1932 RAII_VAR(struct ast_str *, fingerprint, ast_str_create(64), ast_free);
1933 if (!fingerprint) {
1934 return -1;
1935 }
1936
1937 if (hash == AST_RTP_DTLS_HASH_SHA1) {
1938 ast_str_set(&fingerprint, 0, "SHA-1 %s", crypto_attribute);
1939 } else {
1940 ast_str_set(&fingerprint, 0, "SHA-256 %s", crypto_attribute);
1941 }
1942
1943 attr = pjmedia_sdp_attr_create(pool, "fingerprint", pj_cstr(&stmp, ast_str_buffer(fingerprint)));
1944 media->attr[media->attr_count++] = attr;
1945 }
1946 break;
1947 }
1948
1949 return 0;
1950}
static struct ast_mansession session
#define ast_free(a)
Definition astmm.h:180
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
@ AST_SIP_MEDIA_ENCRYPT_SDES
Definition res_pjsip.h:741
@ AST_SIP_MEDIA_TRANSPORT_INVALID
Definition res_pjsip.h:737
@ AST_SIP_MEDIA_ENCRYPT_NONE
Definition res_pjsip.h:739
@ AST_SIP_MEDIA_ENCRYPT_DTLS
Definition res_pjsip.h:743
@ AST_SIP_SECURITY_NEG_MEDIASEC
Definition res_pjsip.h:357
static int setup_dtls_srtp(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
ast_rtp_dtls_setup
DTLS setup types.
Definition rtp_engine.h:564
@ AST_RTP_DTLS_SETUP_PASSIVE
Definition rtp_engine.h:566
@ AST_RTP_DTLS_SETUP_HOLDCONN
Definition rtp_engine.h:568
@ AST_RTP_DTLS_SETUP_ACTPASS
Definition rtp_engine.h:567
@ AST_RTP_DTLS_SETUP_ACTIVE
Definition rtp_engine.h:565
ast_rtp_dtls_hash
DTLS fingerprint hashes.
Definition rtp_engine.h:578
@ AST_RTP_DTLS_HASH_SHA1
Definition rtp_engine.h:580
@ AST_RTP_DTLS_HASH_SHA256
Definition rtp_engine.h:579
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.
@ AST_RTP_DTLS_CONNECTION_NEW
Definition rtp_engine.h:573
@ AST_RTP_DTLS_CONNECTION_EXISTING
Definition rtp_engine.h:574
const char * ast_sdp_srtp_get_attrib(struct ast_sdp_srtp *srtp, int dtls_enabled, int default_taglen_32)
Get the crypto attribute line for the srtp structure.
Definition sdp_srtp.c:95
struct ast_sdp_srtp * ast_sdp_srtp_alloc(void)
allocate a ast_sdp_srtp structure
Definition sdp_srtp.c:41
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition strings.h:659
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition strings.h:1113
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition strings.h:761
Structure that represents the optional DTLS SRTP support within an RTP engine.
Definition rtp_engine.h:621
enum ast_rtp_dtls_setup(* get_setup)(struct ast_rtp_instance *instance)
Definition rtp_engine.h:633
enum ast_rtp_dtls_hash(* get_fingerprint_hash)(struct ast_rtp_instance *instance)
Definition rtp_engine.h:639
const char *(* get_fingerprint)(struct ast_rtp_instance *instance)
Definition rtp_engine.h:641
enum ast_rtp_dtls_connection(* get_connection)(struct ast_rtp_instance *instance)
Definition rtp_engine.h:631
structure for secure RTP audio
Definition sdp_srtp.h:38
struct ast_sdp_srtp::@297 sdp_srtp_list
struct ast_sdp_srtp * srtp
Holds SRTP information.
struct ast_rtp_instance * rtp
RTP instance itself.
enum ast_sip_session_media_encryption encryption
What type of encryption is in use on this stream.
Support for dynamic strings.
Definition strings.h:623
#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:981

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_SIP_SECURITY_NEG_MEDIASEC, ast_str_buffer(), ast_str_create, ast_str_set(), ast_sip_session_media::encryption, 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, RAII_VAR, ast_sip_session_media::rtp, ast_sdp_srtp::sdp_srtp_list, session, setup_dtls_srtp(), and ast_sip_session_media::srtp.

Referenced by create_outgoing_sdp_stream().

◆ 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 1587 of file res_pjsip_sdp_rtp.c.

1589{
1590 int idx;
1591 char extmap_value[256];
1592
1593 if (!session->endpoint->media.webrtc || session_media->type != AST_MEDIA_TYPE_VIDEO) {
1594 return;
1595 }
1596
1597 /* RTP extension local unique identifiers start at '1' */
1598 for (idx = 1; idx <= ast_rtp_instance_extmap_count(session_media->rtp); ++idx) {
1600 const char *direction_str = "";
1601 pj_str_t stmp;
1602 pjmedia_sdp_attr *attr;
1603
1604 /* If this is an unsupported RTP extension we can't place it into the SDP */
1606 continue;
1607 }
1608
1609 switch (ast_rtp_instance_extmap_get_direction(session_media->rtp, idx)) {
1611 /* Lack of a direction indicates sendrecv, so we leave it out */
1612 direction_str = "";
1613 break;
1615 direction_str = "/sendonly";
1616 break;
1618 direction_str = "/recvonly";
1619 break;
1621 /* It is impossible for a "none" direction extension to be negotiated but just in case
1622 * we treat it as inactive.
1623 */
1625 direction_str = "/inactive";
1626 break;
1627 }
1628
1629 snprintf(extmap_value, sizeof(extmap_value), "%d%s %s", idx, direction_str,
1630 ast_rtp_instance_extmap_get_uri(session_media->rtp, idx));
1631 attr = pjmedia_sdp_attr_create(pool, "extmap", pj_cstr(&stmp, extmap_value));
1632 pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1633 }
1634}
@ AST_MEDIA_TYPE_VIDEO
Definition codec.h:33
size_t ast_rtp_instance_extmap_count(struct ast_rtp_instance *instance)
Get the number of known unique identifiers.
Definition rtp_engine.c:950
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:961
ast_rtp_extension
Known RTP extensions.
Definition rtp_engine.h:593
@ AST_RTP_EXTENSION_UNSUPPORTED
Definition rtp_engine.h:595
@ AST_RTP_EXTENSION_DIRECTION_SENDRECV
Definition rtp_engine.h:831
@ AST_RTP_EXTENSION_DIRECTION_NONE
Definition rtp_engine.h:829
@ AST_RTP_EXTENSION_DIRECTION_INACTIVE
Definition rtp_engine.h:837
@ AST_RTP_EXTENSION_DIRECTION_RECVONLY
Definition rtp_engine.h:835
@ AST_RTP_EXTENSION_DIRECTION_SENDONLY
Definition rtp_engine.h:833
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:997
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:981
enum ast_media_type type
Media type of this session media.
structure to hold extensions

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_media::rtp, session, and ast_sip_session_media::type.

Referenced by create_outgoing_sdp_stream().

◆ 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 908 of file res_pjsip_sdp_rtp.c.

910{
911 struct ast_rtp_engine_ice *ice;
912 struct ao2_container *candidates;
913 const char *username, *password;
914 pj_str_t stmp;
915 pjmedia_sdp_attr *attr;
916 struct ao2_iterator it_candidates;
917 struct ast_rtp_engine_ice_candidate *candidate;
918
919 if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) {
920 return;
921 }
922
923 if (!session_media->remote_ice) {
924 ice->stop(session_media->rtp);
925 return;
926 }
927
928 if ((username = ice->get_ufrag(session_media->rtp))) {
929 attr = pjmedia_sdp_attr_create(pool, "ice-ufrag", pj_cstr(&stmp, username));
930 media->attr[media->attr_count++] = attr;
931 }
932
933 if ((password = ice->get_password(session_media->rtp))) {
934 attr = pjmedia_sdp_attr_create(pool, "ice-pwd", pj_cstr(&stmp, password));
935 media->attr[media->attr_count++] = attr;
936 }
937
938 if (!include_candidates) {
939 return;
940 }
941
942 candidates = ice->get_local_candidates(session_media->rtp);
943 if (!candidates) {
944 return;
945 }
946
947 it_candidates = ao2_iterator_init(candidates, 0);
948 for (; (candidate = ao2_iterator_next(&it_candidates)); ao2_ref(candidate, -1)) {
949 struct ast_str *attr_candidate = ast_str_create(128);
950
951 ast_str_set(&attr_candidate, -1, "%s %u %s %d %s ", candidate->foundation, candidate->id, candidate->transport,
952 candidate->priority, ast_sockaddr_stringify_addr_remote(&candidate->address));
953 ast_str_append(&attr_candidate, -1, "%s typ ", ast_sockaddr_stringify_port(&candidate->address));
954
955 switch (candidate->type) {
957 ast_str_append(&attr_candidate, -1, "host");
958 break;
960 ast_str_append(&attr_candidate, -1, "srflx");
961 break;
963 ast_str_append(&attr_candidate, -1, "relay");
964 break;
965 }
966
967 if (!ast_sockaddr_isnull(&candidate->relay_address)) {
968 ast_str_append(&attr_candidate, -1, " raddr %s rport", ast_sockaddr_stringify_addr_remote(&candidate->relay_address));
969 ast_str_append(&attr_candidate, -1, " %s", ast_sockaddr_stringify_port(&candidate->relay_address));
970 }
971
972 attr = pjmedia_sdp_attr_create(pool, "candidate", pj_cstr(&stmp, ast_str_buffer(attr_candidate)));
973 media->attr[media->attr_count++] = attr;
974
975 ast_free(attr_candidate);
976 }
977
978 ao2_iterator_destroy(&it_candidates);
979 ao2_ref(candidates, -1);
980}
#define ao2_iterator_next(iter)
Definition astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition astobj2.h:459
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized,...
Definition netsock2.h:127
static char * ast_sockaddr_stringify_port(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return a port only.
Definition netsock2.h:358
static char * ast_sockaddr_stringify_addr_remote(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition netsock2.h:313
@ AST_RTP_ICE_CANDIDATE_TYPE_RELAYED
Definition rtp_engine.h:509
@ AST_RTP_ICE_CANDIDATE_TYPE_SRFLX
Definition rtp_engine.h:508
@ AST_RTP_ICE_CANDIDATE_TYPE_HOST
Definition rtp_engine.h:507
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.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition strings.h:1139
Generic container type.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition astobj2.h:1821
Structure for an ICE candidate.
Definition rtp_engine.h:525
struct ast_sockaddr address
Definition rtp_engine.h:530
enum ast_rtp_ice_component_type id
Definition rtp_engine.h:527
struct ast_sockaddr relay_address
Definition rtp_engine.h:531
enum ast_rtp_ice_candidate_type type
Definition rtp_engine.h:532
Structure that represents the optional ICE support within an RTP engine.
Definition rtp_engine.h:536
void(* stop)(struct ast_rtp_instance *instance)
Definition rtp_engine.h:544
const char *(* get_ufrag)(struct ast_rtp_instance *instance)
Definition rtp_engine.h:546
const char *(* get_password)(struct ast_rtp_instance *instance)
Definition rtp_engine.h:548
struct ao2_container *(* get_local_candidates)(struct ast_rtp_instance *instance)
Definition rtp_engine.h:550
unsigned int remote_ice
Does remote support ice.

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_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_rtp_engine_ice_candidate::id, ast_rtp_engine_ice_candidate::priority, ast_rtp_engine_ice_candidate::relay_address, ast_sip_session_media::remote_ice, ast_sip_session_media::rtp, session, ast_rtp_engine_ice::stop, ast_rtp_engine_ice_candidate::transport, and ast_rtp_engine_ice_candidate::type.

Referenced by create_outgoing_sdp_stream().

◆ 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 1505 of file res_pjsip_sdp_rtp.c.

1508{
1509 pj_str_t stmp;
1510 pjmedia_sdp_attr *attr;
1511 char msid[(AST_UUID_STR_LEN * 2) + 2];
1512 const char *stream_label = ast_stream_get_metadata(stream, "SDP:LABEL");
1513
1514 if (!session->endpoint->media.webrtc) {
1515 return;
1516 }
1517
1518 if (ast_strlen_zero(session_media->mslabel)) {
1519 /* If this stream is grouped with another then use its media stream label if possible */
1520 if (ast_stream_get_group(stream) != -1) {
1521 struct ast_sip_session_media *group_session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, ast_stream_get_group(stream));
1522
1523 ast_copy_string(session_media->mslabel, group_session_media->mslabel, sizeof(session_media->mslabel));
1524 }
1525
1526 if (ast_strlen_zero(session_media->mslabel)) {
1527 ast_uuid_generate_str(session_media->mslabel, sizeof(session_media->mslabel));
1528 }
1529 }
1530
1531 if (ast_strlen_zero(session_media->label)) {
1532 ast_uuid_generate_str(session_media->label, sizeof(session_media->label));
1533 /* add for stream identification to replace stream_name */
1534 ast_stream_set_metadata(stream, "MSID:LABEL", session_media->label);
1535 }
1536
1537 snprintf(msid, sizeof(msid), "%s %s", session_media->mslabel, session_media->label);
1538 ast_debug(3, "Stream msid: %p %s %s\n", stream,
1540 attr = pjmedia_sdp_attr_create(pool, "msid", pj_cstr(&stmp, msid));
1541 pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1542
1543 /* 'label' must come after 'msid' */
1544 if (!ast_strlen_zero(stream_label)) {
1545 ast_debug(3, "Stream Label: %p %s %s\n", stream,
1546 ast_codec_media_type2str(ast_stream_get_type(stream)), stream_label);
1547 attr = pjmedia_sdp_attr_create(pool, "label", pj_cstr(&stmp, stream_label));
1548 pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1549 }
1550}
const char * ast_codec_media_type2str(enum ast_media_type type)
Conversion function to take a media type and turn it into a string.
Definition codec.c:348
#define ast_debug(level,...)
Log a DEBUG message.
const char * ast_stream_get_metadata(const struct ast_stream *stream, const char *m_key)
Get a stream metadata value.
Definition stream.c:423
int ast_stream_set_metadata(struct ast_stream *stream, const char *m_key, const char *value)
Set a stream metadata value.
Definition stream.c:460
int ast_stream_get_group(const struct ast_stream *stream)
Get the stream group that a stream is part of.
Definition stream.c:1080
enum ast_media_type ast_stream_get_type(const struct ast_stream *stream)
Get the media type of a stream.
Definition stream.c:316
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition strings.h:65
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition strings.h:425
A structure containing SIP session media information.
char label[AST_UUID_STR_LEN]
Track label.
char mslabel[AST_UUID_STR_LEN]
Media stream label.
#define AST_UUID_STR_LEN
Definition uuid.h:27
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
Definition uuid.c:141
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition vector.h:708

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_media::label, ast_sip_session_media::mslabel, and session.

Referenced by create_outgoing_sdp_stream().

◆ 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 1552 of file res_pjsip_sdp_rtp.c.

1554{
1555 pj_str_t stmp;
1556 pjmedia_sdp_attr *attr;
1557
1558 if (!session->endpoint->media.webrtc) {
1559 return;
1560 }
1561
1562 /* transport-cc is supposed to be for the entire transport, and any media sources so
1563 * while the header does not appear in audio streams and isn't negotiated there, we still
1564 * place this attribute in as Chrome does.
1565 */
1566 attr = pjmedia_sdp_attr_create(pool, "rtcp-fb", pj_cstr(&stmp, "* transport-cc"));
1567 pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1568
1569 if (session_media->type != AST_MEDIA_TYPE_VIDEO) {
1570 return;
1571 }
1572
1573 /*
1574 * For now just automatically add it the stream even though it hasn't
1575 * necessarily been negotiated.
1576 */
1577 attr = pjmedia_sdp_attr_create(pool, "rtcp-fb", pj_cstr(&stmp, "* ccm fir"));
1578 pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1579
1580 attr = pjmedia_sdp_attr_create(pool, "rtcp-fb", pj_cstr(&stmp, "* goog-remb"));
1581 pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1582
1583 attr = pjmedia_sdp_attr_create(pool, "rtcp-fb", pj_cstr(&stmp, "* nack"));
1584 pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
1585}

References AST_MEDIA_TYPE_VIDEO, session, and ast_sip_session_media::type.

Referenced by create_outgoing_sdp_stream().

◆ 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 1435 of file res_pjsip_sdp_rtp.c.

1436{
1437 pj_str_t stmp;
1438 pjmedia_sdp_attr *attr;
1439 char tmp[128];
1440
1441 if (!session->endpoint->media.bundle || session_media->bundle_group == -1) {
1442 return;
1443 }
1444
1445 snprintf(tmp, sizeof(tmp), "%u cname:%s", ast_rtp_instance_get_ssrc(session_media->rtp), ast_rtp_instance_get_cname(session_media->rtp));
1446 attr = pjmedia_sdp_attr_create(pool, "ssrc", pj_cstr(&stmp, tmp));
1447 media->attr[media->attr_count++] = attr;
1448}
const char * ast_rtp_instance_get_cname(struct ast_rtp_instance *rtp)
Retrieve the CNAME used in RTCP SDES items.
unsigned int ast_rtp_instance_get_ssrc(struct ast_rtp_instance *rtp)
Retrieve the local SSRC value that we will be using.
int bundle_group
The bundle group the stream belongs to.

References ast_rtp_instance_get_cname(), ast_rtp_instance_get_ssrc(), session, and ast_rtp_engine_ice::start.

Referenced by create_outgoing_sdp_stream().

◆ 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 588 of file res_pjsip_sdp_rtp.c.

591{
592 if (!joint) {
593 return -1;
594 }
595
596 ast_stream_set_formats(asterisk_stream, joint);
597
598 /* If this is a bundled stream then apply the payloads to RTP instance acting as transport to prevent conflicts */
599 if (session_media_transport != session_media && session_media->bundled) {
600 int index;
601
602 for (index = 0; index < ast_format_cap_count(joint); ++index) {
603 struct ast_format *format = ast_format_cap_get_format(joint, index);
604 int rtp_code;
605
606 /* Ensure this payload is in the bundle group transport codecs, this purposely doesn't check the return value for
607 * things as the format is guaranteed to have a payload already.
608 */
609 rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media->rtp), 1, format, 0);
610 ast_rtp_codecs_payload_set_rx(ast_rtp_instance_get_codecs(session_media_transport->rtp), rtp_code, format);
611
612 ao2_ref(format, -1);
613 }
614 }
615
616 return 0;
617}
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:408
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:403
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.
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:778
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.
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
Definition of a media format.
Definition format.c:43
unsigned int bundled
Whether this stream is currently bundled or not.

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, and ast_sip_session_media::rtp.

Referenced by negotiate_incoming_sdp_stream(), and set_caps().

◆ apply_dtls_attrib()

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

Definition at line 1283 of file res_pjsip_sdp_rtp.c.

1285{
1286 struct ast_rtp_engine_dtls *dtls = ast_rtp_instance_get_dtls(session_media->rtp);
1287 pj_str_t *value;
1288
1289 if (!attr->value.ptr || !dtls) {
1290 return;
1291 }
1292
1293 value = pj_strtrim(&attr->value);
1294
1295 if (!pj_strcmp2(&attr->name, "setup")) {
1296 if (!pj_stricmp2(value, "active")) {
1297 dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_ACTIVE);
1298 } else if (!pj_stricmp2(value, "passive")) {
1299 dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_PASSIVE);
1300 } else if (!pj_stricmp2(value, "actpass")) {
1301 dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_ACTPASS);
1302 } else if (!pj_stricmp2(value, "holdconn")) {
1303 dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_HOLDCONN);
1304 } else {
1305 ast_log(LOG_WARNING, "Unsupported setup attribute value '%*s'\n", (int)value->slen, value->ptr);
1306 }
1307 } else if (!pj_strcmp2(&attr->name, "connection")) {
1308 if (!pj_stricmp2(value, "new")) {
1309 dtls->reset(session_media->rtp);
1310 } else if (!pj_stricmp2(value, "existing")) {
1311 /* Do nothing */
1312 } else {
1313 ast_log(LOG_WARNING, "Unsupported connection attribute value '%*s'\n", (int)value->slen, value->ptr);
1314 }
1315 } else if (!pj_strcmp2(&attr->name, "fingerprint")) {
1316 char hash_value[256], hash[32];
1317 char fingerprint_text[value->slen + 1];
1318 ast_copy_pj_str(fingerprint_text, value, sizeof(fingerprint_text));
1319 if (sscanf(fingerprint_text, "%31s %255s", hash, hash_value) == 2) {
1320 if (!strcasecmp(hash, "sha-1")) {
1321 dtls->set_fingerprint(session_media->rtp, AST_RTP_DTLS_HASH_SHA1, hash_value);
1322 } else if (!strcasecmp(hash, "sha-256")) {
1323 dtls->set_fingerprint(session_media->rtp, AST_RTP_DTLS_HASH_SHA256, hash_value);
1324 } else {
1325 ast_log(LOG_WARNING, "Unsupported fingerprint hash type '%s'\n",
1326 hash);
1327 }
1328 }
1329 }
1330}
#define ast_log
Definition astobj2.c:42
#define LOG_WARNING
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:2221
void(* reset)(struct ast_rtp_instance *instance)
Definition rtp_engine.h:629
void(* set_fingerprint)(struct ast_rtp_instance *instance, enum ast_rtp_dtls_hash hash, const char *fingerprint)
Definition rtp_engine.h:637
void(* set_setup)(struct ast_rtp_instance *instance, enum ast_rtp_dtls_setup setup)
Definition rtp_engine.h:635
int value
Definition syslog.c:37

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().

◆ 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 2402 of file res_pjsip_sdp_rtp.c.

2405{
2406 RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free);
2407 struct pjmedia_sdp_media *remote_stream = remote->media[index];
2408 enum ast_media_type media_type = session_media->type;
2409 char host[NI_MAXHOST];
2410 int res;
2411 int rtp_timeout;
2412 struct ast_sip_session_media *session_media_transport;
2413 SCOPE_ENTER(1, "%s Stream: %s\n", ast_sip_session_get_name(session),
2414 ast_str_tmp(128, ast_stream_to_str(asterisk_stream, &STR_TMP)));
2415
2416 if (!session->channel) {
2417 SCOPE_EXIT_RTN_VALUE(1, "No channel\n");
2418 }
2419
2420 /* Ensure incoming transport is compatible with the endpoint's configuration */
2421 if (!session->endpoint->media.rtp.use_received_transport &&
2423 SCOPE_EXIT_RTN_VALUE(-1, "Incompatible transport\n");
2424 }
2425
2426 /* Create an RTP instance if need be */
2427 if (!session_media->rtp && create_rtp(session, session_media, local)) {
2428 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create rtp\n");
2429 }
2430
2431 process_ssrc_attributes(session, session_media, remote_stream);
2432 process_extmap_attributes(session, session_media, remote_stream);
2433
2434 session_media_transport = ast_sip_session_media_get_transport(session, session_media);
2435
2436 if (session_media_transport == session_media || !session_media->bundled) {
2437 session_media->remote_rtcp_mux = (pjmedia_sdp_media_find_attr2(remote_stream, "rtcp-mux", NULL) != NULL);
2438 set_ice_components(session, session_media);
2439
2440 enable_rtcp(session, session_media, remote_stream);
2441
2442 res = setup_media_encryption(session, session_media, remote, remote_stream);
2443 if (!session->endpoint->media.rtp.encryption_optimistic && res) {
2444 /* If optimistic encryption is disabled and crypto should have been enabled but was not
2445 * this session must fail.
2446 */
2447 SCOPE_EXIT_RTN_VALUE(-1, "Incompatible crypto\n");
2448 }
2449
2450 if (!remote_stream->conn && !remote->conn) {
2451 SCOPE_EXIT_RTN_VALUE(1, "No connection info\n");
2452 }
2453
2454 ast_copy_pj_str(host, remote_stream->conn ? &remote_stream->conn->addr : &remote->conn->addr, sizeof(host));
2455
2456 /* Ensure that the address provided is valid */
2457 if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC) <= 0) {
2458 /* The provided host was actually invalid so we error out this negotiation */
2459 SCOPE_EXIT_RTN_VALUE(-1, "Host invalid\n");
2460 }
2461
2462 /* Apply connection information to the RTP instance */
2463 ast_sockaddr_set_port(addrs, remote_stream->desc.port);
2464 ast_rtp_instance_set_remote_address(session_media->rtp, addrs);
2465
2469 if (!session->endpoint->media.rtcp_mux || !session_media->remote_rtcp_mux) {
2472 }
2473
2474 /* If ICE support is enabled find all the needed attributes */
2475 process_ice_attributes(session, session_media, remote, remote_stream);
2476 } else {
2477 /* This is bundled with another session, so mark it as such */
2478 ast_rtp_instance_bundle(session_media->rtp, session_media_transport->rtp);
2480 enable_rtcp(session, session_media, remote_stream);
2481 }
2482
2483 if (set_caps(session, session_media, session_media_transport, remote_stream, 0, asterisk_stream)) {
2484 SCOPE_EXIT_RTN_VALUE(-1, "set_caps failed\n");
2485 }
2486
2487 /* Set the channel uniqueid on the RTP instance now that it is becoming active */
2488 ast_channel_lock(session->channel);
2490 ast_channel_unlock(session->channel);
2491
2492 /* Ensure the RTP instance is active */
2493 ast_rtp_instance_set_stream_num(session_media->rtp, ast_stream_get_position(asterisk_stream));
2494 ast_rtp_instance_activate(session_media->rtp);
2495
2496 /* audio stream handles music on hold */
2497 if (media_type != AST_MEDIA_TYPE_AUDIO && media_type != AST_MEDIA_TYPE_VIDEO) {
2498 if ((pjmedia_sdp_neg_was_answer_remote(session->inv_session->neg) == PJ_FALSE)
2499 && (session->inv_session->state == PJSIP_INV_STATE_CONFIRMED)) {
2501 }
2502 SCOPE_EXIT_RTN_VALUE(1, "moh\n");
2503 }
2504
2505 set_session_media_remotely_held(session_media, session, remote_stream, asterisk_stream, addrs);
2506
2507 if (session_media->remotely_held_changed) {
2508 if (session_media->remotely_held) {
2509 /* The remote side has put us on hold */
2510 if (!session->endpoint->suppress_moh_on_sendonly) {
2511 ast_queue_hold(session->channel, session->endpoint->mohsuggest);
2512 ast_rtp_instance_stop(session_media->rtp);
2514 }
2515 session_media->remotely_held_changed = 0;
2516 } else {
2517 /* The remote side has taken us off hold */
2518 if (!session->endpoint->suppress_moh_on_sendonly) {
2519 ast_queue_unhold(session->channel);
2521 }
2522 session_media->remotely_held_changed = 0;
2523 }
2524 } else if ((pjmedia_sdp_neg_was_answer_remote(session->inv_session->neg) == PJ_FALSE)
2525 && (session->inv_session->state == PJSIP_INV_STATE_CONFIRMED)) {
2527 }
2528
2529 /* This purposely resets the encryption to the configured in case it gets added later */
2530 session_media->encryption = session->endpoint->media.rtp.encryption;
2531
2532 if (session->endpoint->media.rtp.keepalive > 0 &&
2533 (session_media->type == AST_MEDIA_TYPE_AUDIO ||
2534 session_media->type == AST_MEDIA_TYPE_VIDEO)) {
2535 ast_rtp_instance_set_keepalive(session_media->rtp, session->endpoint->media.rtp.keepalive);
2536 /* Schedule the initial keepalive early in case this is being used to punch holes through
2537 * a NAT. This way there won't be an awkward delay before media starts flowing in some
2538 * scenarios.
2539 */
2540 AST_SCHED_DEL(sched, session_media->keepalive_sched_id);
2542 session_media, 1);
2543 }
2544
2545 /* As the channel lock is not held during this process the scheduled item won't block if
2546 * it is hanging up the channel at the same point we are applying this negotiated SDP.
2547 */
2548 AST_SCHED_DEL(sched, session_media->timeout_sched_id);
2549
2550 /* Due to the fact that we only ever have one scheduled timeout item for when we are both
2551 * off hold and on hold we don't need to store the two timeouts differently on the RTP
2552 * instance itself.
2553 */
2554 ast_rtp_instance_set_timeout(session_media->rtp, 0);
2555 if (session->endpoint->media.rtp.timeout && !session_media->remotely_held && !session_media->locally_held) {
2556 ast_rtp_instance_set_timeout(session_media->rtp, session->endpoint->media.rtp.timeout);
2557 } else if (session->endpoint->media.rtp.timeout_hold && (session_media->remotely_held || session_media->locally_held)) {
2558 ast_rtp_instance_set_timeout(session_media->rtp, session->endpoint->media.rtp.timeout_hold);
2559 }
2560
2561 rtp_timeout = ast_rtp_instance_get_timeout(session_media->rtp);
2562
2563 if (rtp_timeout) {
2564 session_media->timeout_sched_id = ast_sched_add_variable(sched, rtp_timeout*1000, rtp_check_timeout,
2565 session_media, 1);
2566 }
2567
2568 SCOPE_EXIT_RTN_VALUE(1, "Handled\n");
2569}
static PGconn * conn
Definition cdr_pgsql.c:87
#define ast_channel_lock(chan)
Definition channel.h:2983
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition channel.c:1289
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
Definition channel.c:1171
const char * ast_channel_uniqueid(const struct ast_channel *chan)
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Definition channel.c:1274
int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
Queue a hold frame.
Definition channel.c:1249
#define ast_channel_unlock(chan)
Definition channel.h:2984
ast_media_type
Types of media.
Definition codec.h:30
@ AST_MEDIA_TYPE_AUDIO
Definition codec.h:32
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
#define SCOPE_ENTER(level,...)
@ AST_CONTROL_UPDATE_RTP_PEER
struct ast_frame ast_null_frame
Definition main/frame.c:79
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
@ AST_AF_UNSPEC
Definition netsock2.h:54
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition netsock2.h:532
static int send_keepalive(const void *data)
static void set_session_media_remotely_held(struct ast_sip_session_media *session_media, const struct ast_sip_session *session, const pjmedia_sdp_media *media, const struct ast_stream *stream, const struct ast_sockaddr *addrs)
static enum ast_sip_session_media_encryption check_endpoint_media_transport(struct ast_sip_endpoint *endpoint, const struct pjmedia_sdp_media *stream)
Checks whether the encryption offered in SDP is compatible with the endpoint's configuration.
static struct ast_frame * media_session_rtcp_read_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
static void process_ice_attributes(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream)
Function which processes ICE attributes in an audio stream.
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 int media_session_rtp_write_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct ast_frame *frame)
static int rtp_check_timeout(const void *data)
Check whether RTP is being received or not.
static int setup_media_encryption(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream)
static void process_extmap_attributes(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *remote_stream)
Function which processes extmap attributes in a stream.
static struct ast_frame * media_session_rtp_read_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
static void enable_rtcp(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *remote_media)
Enable RTCP on an RTP session.
static int create_rtp(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const pjmedia_sdp_session *sdp)
Internal function which creates an RTP instance.
static void set_ice_components(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
static void process_ssrc_attributes(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *remote_stream)
Function which processes ssrc attributes in a stream.
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.
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_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.
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
#define NULL
Definition resample.c:96
void ast_rtp_instance_stop(struct ast_rtp_instance *instance)
Stop an RTP instance.
void ast_rtp_instance_set_stream_num(struct ast_rtp_instance *instance, int stream_num)
Set the stream number for an RTP instance.
int ast_rtp_instance_get_timeout(struct ast_rtp_instance *instance)
Get the RTP timeout value.
int ast_rtp_instance_bundle(struct ast_rtp_instance *child, struct ast_rtp_instance *parent)
Request that an RTP instance be bundled with another.
#define ast_rtp_instance_set_remote_address(instance, address)
Set the address of the remote endpoint that we are sending RTP to.
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.
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:604
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
Get the file descriptor for an RTP session (or RTCP)
void ast_rtp_instance_set_keepalive(struct ast_rtp_instance *instance, int timeout)
Set the RTP keepalive interval.
void ast_rtp_instance_set_timeout(struct ast_rtp_instance *instance, int timeout)
Set the RTP timeout value.
#define AST_SCHED_DEL(sched, id)
Remove a scheduler entry.
Definition sched.h:46
int ast_sched_add_variable(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data, int variable) attribute_warn_unused_result
Adds a scheduled event with rescheduling support.
Definition sched.c:526
const char * ast_stream_to_str(const struct ast_stream *stream, struct ast_str **buf)
Get a string representing the stream for debugging/display purposes.
Definition stream.c:337
int ast_stream_get_position(const struct ast_stream *stream)
Get the position of the stream in the topology.
Definition stream.c:500
#define ast_str_tmp(init_len, __expr)
Provides a temporary ast_str and returns a copy of its buffer.
Definition strings.h:1189
unsigned int remotely_held_changed
Stream is held by remote side changed during this negotiation.
unsigned int locally_held
Stream is on hold by local side.
unsigned int remote_rtcp_mux
Does remote support rtcp_mux.
int timeout_sched_id
Scheduler ID for RTP timeout.
unsigned int remotely_held
Stream is on hold by remote side.
int keepalive_sched_id
Scheduler ID for RTP keepalive.
Socket address structure.
Definition netsock2.h:97
Definition sched.c:76

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_MEDIA_TYPE_VIDEO, 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, check_endpoint_media_transport(), create_rtp(), enable_rtcp(), ast_sip_session_media::encryption, ast_sip_session_media::keepalive_sched_id, ast_sip_session_media::locally_held, media_session_rtcp_read_callback(), media_session_rtp_read_callback(), media_session_rtp_write_callback(), 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_session_media::rtp, rtp_check_timeout(), SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, send_keepalive(), session, set_caps(), set_ice_components(), set_session_media_remotely_held(), setup_media_encryption(), ast_sip_session_media::timeout_sched_id, and ast_sip_session_media::type.

◆ assign_unique_bundle_payload()

static int assign_unique_bundle_payload ( struct ast_sip_session *  session,
struct ast_sip_session_media *  session_media,
struct ast_sip_session_media *  session_media_transport,
const pjmedia_sdp_session *  sdp,
const pjmedia_sdp_media *  media,
struct ast_format *  format 
)
static

Assign a payload type that is unique across the generated BUNDLE group.

Definition at line 520 of file res_pjsip_sdp_rtp.c.

525{
526 struct ast_rtp_codecs *transport_codecs =
527 ast_rtp_instance_get_codecs(session_media_transport->rtp);
528 struct ast_rtp_codecs *stream_codecs =
529 ast_rtp_instance_get_codecs(session_media->rtp);
530 int preferred;
531 int candidate;
532 int offset;
533
534 preferred = ast_rtp_codecs_payload_code(stream_codecs, 1, format, 0);
535 if (preferred < 0) {
536 return -1;
537 }
538
539 /* Preserve the stream's normal payload when it is not used by another m= section. */
540 if (!bundle_payload_type_used(session, sdp, media, session_media->bundle_group, preferred)
541 && payload_type_compatible(transport_codecs, preferred, format)
542 && payload_type_compatible(stream_codecs, preferred, format)) {
543 candidate = preferred;
544 goto configure;
545 }
546
547 /* Remap duplicate static or dynamic payloads into the dynamic range. */
548 candidate = preferred >= AST_RTP_PT_FIRST_DYNAMIC
549 ? preferred + 1 : AST_RTP_PT_FIRST_DYNAMIC;
550 for (offset = 0; offset < AST_RTP_MAX_PT - AST_RTP_PT_FIRST_DYNAMIC; ++offset) {
551 if (candidate >= AST_RTP_MAX_PT) {
552 candidate = AST_RTP_PT_FIRST_DYNAMIC;
553 }
554
555 if (!bundle_payload_type_used(session, sdp, media, session_media->bundle_group, candidate)
556 && payload_type_compatible(transport_codecs, candidate, format)
557 && payload_type_compatible(stream_codecs, candidate, format)) {
558 goto configure;
559 }
560
561 ++candidate;
562 }
563
564 ast_log(LOG_WARNING, "No unique dynamic RTP payload type available for bundled stream %s format %s\n",
565 S_OR(session_media->mid, "<unknown>"), ast_format_get_name(format));
566 return -1;
567
568configure:
569 if (ensure_payload_type_mapping(transport_codecs, candidate, format)
570 || ensure_payload_type_mapping(stream_codecs, candidate, format)) {
571 ast_log(LOG_WARNING, "Unable to configure RTP payload type %d for bundled stream %s format %s\n",
572 candidate, S_OR(session_media->mid, "<unknown>"), ast_format_get_name(format));
573 return -1;
574 }
575
576 ast_debug(2, "Assigned RTP payload type %d to bundled stream %s format %s\n",
577 candidate, S_OR(session_media->mid, "<unknown>"), ast_format_get_name(format));
578 return candidate;
579}
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition format.c:334
static int bundle_payload_type_used(struct ast_sip_session *session, const pjmedia_sdp_session *sdp, const pjmedia_sdp_media *media, int bundle_group, int payload)
Determine whether a payload type is already advertised in a BUNDLE group.
static int ensure_payload_type_mapping(struct ast_rtp_codecs *codecs, int payload, struct ast_format *format)
Ensure an RTP codecs structure can receive a format using a payload type.
static int payload_type_compatible(struct ast_rtp_codecs *codecs, int payload, struct ast_format *format)
Check whether a payload slot is either free or already mapped to the requested format.
#define AST_RTP_MAX_PT
Definition rtp_engine.h:83
#define AST_RTP_PT_FIRST_DYNAMIC
Definition rtp_engine.h:92
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition strings.h:80
char * mid
Media identifier for this stream (may be shared across multiple streams)

References ast_debug, ast_format_get_name(), ast_log, ast_rtp_codecs_payload_code(), ast_rtp_instance_get_codecs(), AST_RTP_MAX_PT, AST_RTP_PT_FIRST_DYNAMIC, ast_sip_session_media::bundle_group, bundle_payload_type_used(), ensure_payload_type_mapping(), LOG_WARNING, ast_sip_session_media::mid, payload_type_compatible(), ast_sip_session_media::rtp, S_OR, and session.

Referenced by create_outgoing_sdp_stream().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 2735 of file res_pjsip_sdp_rtp.c.

◆ bundle_payload_type_used()

static int bundle_payload_type_used ( struct ast_sip_session *  session,
const pjmedia_sdp_session *  sdp,
const pjmedia_sdp_media *  media,
int  bundle_group,
int  payload 
)
static

Determine whether a payload type is already advertised in a BUNDLE group.

Definition at line 446 of file res_pjsip_sdp_rtp.c.

449{
450 int media_index;
451
452 for (media_index = 0; media_index < sdp->media_count; ++media_index) {
453 struct ast_sip_session_media *other_session_media;
454 int format_index;
455
456 if (media_index >= AST_VECTOR_SIZE(&session->pending_media_state->sessions)) {
457 break;
458 }
459
460 other_session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, media_index);
461 if (!other_session_media || other_session_media->bundle_group != bundle_group) {
462 continue;
463 }
464
465 for (format_index = 0; format_index < sdp->media[media_index]->desc.fmt_count; ++format_index) {
466 if (pj_strtoul(&sdp->media[media_index]->desc.fmt[format_index]) == payload) {
467 return 1;
468 }
469 }
470 }
471
472 /* The current media section is not in the SDP yet, so inspect it separately. */
473 for (media_index = 0; media_index < media->desc.fmt_count; ++media_index) {
474 if (pj_strtoul(&media->desc.fmt[media_index]) == payload) {
475 return 1;
476 }
477 }
478
479 return 0;
480}
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition vector.h:637

References AST_VECTOR_GET, AST_VECTOR_SIZE, ast_sip_session_media::bundle_group, and session.

Referenced by assign_unique_bundle_payload().

◆ 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 2572 of file res_pjsip_sdp_rtp.c.

2573{
2575 char host[NI_MAXHOST];
2576 struct ast_sockaddr our_sdp_addr = { { 0, } };
2577
2578 /* If the stream has been rejected there will be no connection line */
2579 if (!stream->conn || !transport_state) {
2580 return;
2581 }
2582
2583 ast_copy_pj_str(host, &stream->conn->addr, sizeof(host));
2584 ast_sockaddr_parse(&our_sdp_addr, host, PARSE_PORT_FORBID);
2585
2586 /* Reversed check here. We don't check the remote endpoint being
2587 * in our local net, but whether our outgoing session IP is
2588 * local. If it is not, we won't do rewriting. No localnet
2589 * configured? Always rewrite. */
2590 if (ast_sip_transport_is_nonlocal(transport_state, &our_sdp_addr) && transport_state->localnet) {
2591 return;
2592 }
2593 ast_debug(5, "Setting media address to %s\n", ast_sockaddr_stringify_addr_remote(&transport_state->external_media_address));
2594 pj_strdup2(tdata->pool, &stream->conn->addr, ast_sockaddr_stringify_addr_remote(&transport_state->external_media_address));
2595}
#define ao2_cleanup(obj)
Definition astobj2.h:1934
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition netsock2.c:230
#define ast_sip_transport_is_nonlocal(transport_state, addr)
Definition res_pjsip.h:210
struct ast_sip_transport_state * ast_sip_get_transport_state(const char *transport_id)
Retrieve transport state.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition sorcery.c:2381
Structure for SIP transport information.
Definition res_pjsip.h:117

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(), PARSE_PORT_FORBID, RAII_VAR, and ast_sip_session_media::transport.

◆ 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 1203 of file res_pjsip_sdp_rtp.c.

1206{
1207 enum ast_sip_session_media_encryption incoming_encryption;
1208 char transport_end = stream->desc.transport.ptr[stream->desc.transport.slen - 1];
1209 unsigned int optimistic;
1210
1211 if ((transport_end == 'F' && !endpoint->media.rtp.use_avpf)
1212 || (transport_end != 'F' && endpoint->media.rtp.use_avpf)) {
1214 }
1215
1216 incoming_encryption = get_media_encryption_type(stream->desc.transport, stream, &optimistic);
1217
1218 if (incoming_encryption == endpoint->media.rtp.encryption) {
1219 return incoming_encryption;
1220 }
1221
1222 if (endpoint->media.rtp.force_avp ||
1223 endpoint->media.rtp.encryption_optimistic) {
1224 return incoming_encryption;
1225 }
1226
1227 /* If an optimistic offer has been made but encryption is not enabled consider it as having
1228 * no offer of crypto at all instead of invalid so the session proceeds.
1229 */
1230 if (optimistic) {
1232 }
1233
1235}
ast_sip_session_media_encryption
Definition res_pjsip.h:735
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
struct ast_sip_media_rtp_configuration rtp
Definition res_pjsip.h:1019
struct ast_sip_endpoint_media_configuration media
Definition res_pjsip.h:1100
enum ast_sip_session_media_encryption encryption
Definition res_pjsip.h:958

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().

◆ 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 983 of file res_pjsip_sdp_rtp.c.

985{
986 struct ast_rtp_engine_ice *ice;
987 const pjmedia_sdp_attr *attr;
988 unsigned int attr_i;
989
990 if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) {
991 session_media->remote_ice = 0;
992 return;
993 }
994
995 /* Find all of the candidates */
996 for (attr_i = 0; attr_i < remote_stream->attr_count; ++attr_i) {
997 attr = remote_stream->attr[attr_i];
998 if (!pj_strcmp2(&attr->name, "candidate")) {
999 session_media->remote_ice = 1;
1000 break;
1001 }
1002 }
1003
1004 if (attr_i == remote_stream->attr_count) {
1005 session_media->remote_ice = 0;
1006 }
1007}
void(* start)(struct ast_rtp_instance *instance)
Definition rtp_engine.h:542

References ast_rtp_instance_get_ice(), session, and ast_rtp_engine_ice::start.

Referenced by negotiate_incoming_sdp_stream().

◆ 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 1953 of file res_pjsip_sdp_rtp.c.

1955{
1956 pj_pool_t *pool = session->inv_session->pool_prov;
1957 static const pj_str_t STR_RTP_AVP = { "RTP/AVP", 7 };
1958 static const pj_str_t STR_IN = { "IN", 2 };
1959 static const pj_str_t STR_IP4 = { "IP4", 3};
1960 static const pj_str_t STR_IP6 = { "IP6", 3};
1961 static const pj_str_t STR_SENDRECV = { "sendrecv", 8 };
1962 static const pj_str_t STR_SENDONLY = { "sendonly", 8 };
1963 static const pj_str_t STR_INACTIVE = { "inactive", 8 };
1964 static const pj_str_t STR_RECVONLY = { "recvonly", 8 };
1965 pjmedia_sdp_media *media;
1966 const char *hostip = NULL;
1967 struct ast_sockaddr addr;
1968 char tmp[512];
1969 pj_str_t stmp;
1970 pjmedia_sdp_attr *attr;
1971 int index = 0;
1972 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;
1973 int min_packet_size = 0, max_packet_size = 0;
1974 int rtp_code;
1975 RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup);
1976 enum ast_media_type media_type = session_media->type;
1977 struct ast_sip_session_media *session_media_transport;
1978 pj_sockaddr ip;
1979 int direct_media_enabled = !ast_sockaddr_isnull(&session_media->direct_media_addr) &&
1980 ast_format_cap_count(session->direct_media_cap);
1981
1982 /* Keep track of the sample rates for offered codecs so we can build matching
1983 RFC 2833/4733 payload offers. */
1984 AST_VECTOR(, int) sample_rates;
1985 /* In case we can't init the sample rates, still try to do the rest. */
1986 int build_dtmf_sample_rates = 1;
1987
1988 SCOPE_ENTER(1, "%s Type: %s %s\n", ast_sip_session_get_name(session),
1989 ast_codec_media_type2str(media_type), ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)));
1990
1991 media = pj_pool_zalloc(pool, sizeof(struct pjmedia_sdp_media));
1992 if (!media) {
1993 SCOPE_EXIT_RTN_VALUE(-1, "Pool alloc failure\n");
1994 }
1995 pj_strdup2(pool, &media->desc.media, ast_codec_media_type2str(session_media->type));
1996
1997 /* If this is a removed (or declined) stream OR if no formats exist then construct a minimal stream in SDP */
2000 media->desc.port = 0;
2001 media->desc.port_count = 1;
2002
2003 if (remote && remote->media[ast_stream_get_position(stream)]) {
2004 pjmedia_sdp_media *remote_media = remote->media[ast_stream_get_position(stream)];
2005 int index;
2006
2007 media->desc.transport = remote_media->desc.transport;
2008
2009 /* Preserve existing behavior by copying the formats provided from the offer */
2010 for (index = 0; index < remote_media->desc.fmt_count; ++index) {
2011 media->desc.fmt[index] = remote_media->desc.fmt[index];
2012 }
2013 media->desc.fmt_count = remote_media->desc.fmt_count;
2014 } else {
2015 /* This is actually an offer so put a dummy payload in that is ignored and sane transport */
2016 media->desc.transport = STR_RTP_AVP;
2017 pj_strdup2(pool, &media->desc.fmt[media->desc.fmt_count++], "32");
2018 }
2019
2020 sdp->media[sdp->media_count++] = media;
2022
2023 SCOPE_EXIT_RTN_VALUE(1, "Stream removed or no formats\n");
2024 }
2025
2026 if (!session_media->rtp && create_rtp(session, session_media, sdp)) {
2027 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create rtp\n");
2028 }
2029
2030 /* If this stream has not been bundled already it is new and we need to ensure there is no SSRC conflict */
2031 if (session_media->bundle_group != -1 && !session_media->bundled) {
2032 for (index = 0; index < sdp->media_count; ++index) {
2033 struct ast_sip_session_media *other_session_media;
2034
2035 other_session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, index);
2036 if (!other_session_media->rtp || other_session_media->bundle_group != session_media->bundle_group) {
2037 continue;
2038 }
2039
2040 if (ast_rtp_instance_get_ssrc(session_media->rtp) == ast_rtp_instance_get_ssrc(other_session_media->rtp)) {
2041 ast_rtp_instance_change_source(session_media->rtp);
2042 /* Start the conflict check over again */
2043 index = -1;
2044 continue;
2045 }
2046 }
2047 }
2048
2049 session_media_transport = ast_sip_session_media_get_transport(session, session_media);
2050
2051 if (session_media_transport == session_media || !session_media->bundled) {
2052 set_ice_components(session, session_media);
2053 enable_rtcp(session, session_media, NULL);
2054
2055 /* Crypto has to be added before setting the media transport so that SRTP is properly
2056 * set up according to the configuration. This ends up changing the media transport.
2057 */
2058 if (add_crypto_to_stream(session, session_media, pool, media)) {
2059 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't add crypto\n");
2060 }
2061
2062 if (pj_strlen(&session_media->transport)) {
2063 /* If a transport has already been specified use it */
2064 media->desc.transport = session_media->transport;
2065 } else {
2066 media->desc.transport = pj_str(ast_sdp_get_rtp_profile(
2067 /* Optimistic encryption places crypto in the normal RTP/AVP profile */
2068 !session->endpoint->media.rtp.encryption_optimistic &&
2069 (session_media->encryption == AST_SIP_MEDIA_ENCRYPT_SDES),
2070 session_media->rtp, session->endpoint->media.rtp.use_avpf,
2071 session->endpoint->media.rtp.force_avp));
2072 }
2073
2074 media->conn = pj_pool_zalloc(pool, sizeof(struct pjmedia_sdp_conn));
2075 if (!media->conn) {
2076 SCOPE_EXIT_RTN_VALUE(-1, "Pool alloc failure\n");
2077 }
2078
2079 /* Add connection level details */
2080 if (direct_media_enabled) {
2082 } else if (ast_strlen_zero(session->endpoint->media.address)) {
2083 hostip = ast_sip_get_host_ip_string(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET());
2084 } else {
2085 hostip = session->endpoint->media.address;
2086 }
2087
2088 if (ast_strlen_zero(hostip)) {
2089 ast_log(LOG_ERROR, "No local host IP available for stream %s\n",
2090 ast_codec_media_type2str(session_media->type));
2091 SCOPE_EXIT_RTN_VALUE(-1, "No local host ip\n");
2092 }
2093
2094 media->conn->net_type = STR_IN;
2095 /* Assume that the connection will use IPv4 until proven otherwise */
2096 media->conn->addr_type = STR_IP4;
2097 pj_strdup2(pool, &media->conn->addr, hostip);
2098
2099 if ((pj_sockaddr_parse(pj_AF_UNSPEC(), 0, &media->conn->addr, &ip) == PJ_SUCCESS) &&
2100 (ip.addr.sa_family == pj_AF_INET6())) {
2101 media->conn->addr_type = STR_IP6;
2102 }
2103
2104 /* Add ICE attributes and candidates */
2105 add_ice_to_stream(session, session_media, pool, media, 1);
2106
2107 ast_rtp_instance_get_local_address(session_media->rtp, &addr);
2108 media->desc.port = direct_media_enabled ? ast_sockaddr_port(&session_media->direct_media_addr) : (pj_uint16_t) ast_sockaddr_port(&addr);
2109 media->desc.port_count = 1;
2110 } else {
2111 pjmedia_sdp_media *bundle_group_stream = sdp->media[session_media_transport->stream_num];
2112
2113 /* As this is in a bundle group it shares the same details as the group instance */
2114 media->desc.transport = bundle_group_stream->desc.transport;
2115 media->conn = bundle_group_stream->conn;
2116 media->desc.port = bundle_group_stream->desc.port;
2117
2118 if (add_crypto_to_stream(session, session_media_transport, pool, media)) {
2119 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't add crypto\n");
2120 }
2121
2122 add_ice_to_stream(session, session_media_transport, pool, media, 0);
2123
2124 enable_rtcp(session, session_media, NULL);
2125 }
2126
2128 ast_log(LOG_ERROR, "Failed to allocate %s capabilities\n",
2129 ast_codec_media_type2str(session_media->type));
2130 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create caps\n");
2131 }
2132
2133 if (direct_media_enabled) {
2134 ast_format_cap_get_compatible(session->endpoint->media.codecs, session->direct_media_cap, caps);
2135 } else {
2136 ast_format_cap_append_from_cap(caps, ast_stream_get_formats(stream), media_type);
2137 }
2138
2139 /* Init the sample rates before we start adding them. Assume we will have at least one. */
2140 if (AST_VECTOR_INIT(&sample_rates, 1)) {
2141 ast_log(LOG_ERROR, "Unable to add dtmf formats to SDP!\n");
2142 build_dtmf_sample_rates = 0;
2143 }
2144
2145 for (index = 0; index < ast_format_cap_count(caps); ++index) {
2146 struct ast_format *format = ast_format_cap_get_format(caps, index);
2147
2148 if (ast_format_get_type(format) != media_type) {
2149 ao2_ref(format, -1);
2150 continue;
2151 }
2152
2153 /* It is possible for some formats not to have SDP information available for them
2154 * and if this is the case, skip over them so the SDP can still be created.
2155 */
2156 if (!ast_rtp_lookup_sample_rate2(1, format, 0)) {
2157 ast_log(LOG_WARNING, "Format '%s' can not be added to SDP, consider disallowing it on endpoint '%s'\n",
2159 ao2_ref(format, -1);
2160 continue;
2161 }
2162
2163 /* If this stream is not a transport we need to use the transport codecs structure for payload management to prevent
2164 * conflicts.
2165 */
2166 if (session_media_transport != session_media) {
2168 rtp_code = assign_unique_bundle_payload(session, session_media,
2169 session_media_transport, sdp, media, format);
2170 } else {
2171 rtp_code = ast_rtp_codecs_payload_code(
2172 ast_rtp_instance_get_codecs(session_media_transport->rtp), 1, format, 0);
2173 if (rtp_code != -1) {
2174 /* Our instance has to match the offered payload number. */
2176 ast_rtp_instance_get_codecs(session_media->rtp), rtp_code, format);
2177 }
2178 }
2179
2180 if (rtp_code == -1) {
2181 ast_log(LOG_WARNING,"Unable to get rtp codec payload code for %s\n", ast_format_get_name(format));
2182 ao2_ref(format, -1);
2183 continue;
2184 }
2185 } else {
2186 if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media->rtp), 1, format, 0)) == -1) {
2187 ast_log(LOG_WARNING,"Unable to get rtp codec payload code for %s\n", ast_format_get_name(format));
2188 ao2_ref(format, -1);
2189 continue;
2190 }
2191 }
2192
2193 if ((attr = generate_rtpmap_attr(session, media, pool, rtp_code, 1, format, 0))) {
2194 int i, added = 0;
2195 int newrate = ast_rtp_lookup_sample_rate2(1, format, 0);
2196 if (build_dtmf_sample_rates) {
2197 for (i = 0; i < AST_VECTOR_SIZE(&sample_rates); i++) {
2198 /* Only add if we haven't already processed this sample rate. For instance
2199 A-law and u-law 'share' one 8K DTMF payload type. */
2200 if (newrate == AST_VECTOR_GET(&sample_rates, i)) {
2201 added = 1;
2202 break;
2203 }
2204 }
2205
2206 if (!added) {
2207 AST_VECTOR_APPEND(&sample_rates, newrate);
2208 }
2209 }
2210 media->attr[media->attr_count++] = attr;
2211 }
2212
2213 if ((attr = generate_fmtp_attr(pool, format, rtp_code))) {
2214 media->attr[media->attr_count++] = attr;
2215 }
2216
2217 if (ast_format_get_maximum_ms(format) &&
2218 ((ast_format_get_maximum_ms(format) < max_packet_size) || !max_packet_size)) {
2219 max_packet_size = ast_format_get_maximum_ms(format);
2220 }
2221 ao2_ref(format, -1);
2222
2223 if (media->desc.fmt_count == PJMEDIA_MAX_SDP_FMT) {
2224 break;
2225 }
2226 }
2227
2228 /* Add non-codec formats */
2230 && media->desc.fmt_count < PJMEDIA_MAX_SDP_FMT) {
2231 for (index = 1LL; index <= AST_RTP_MAX; index <<= 1) {
2232 if (!(noncodec & index)) {
2233 continue;
2234 }
2235
2236 if (index != AST_RTP_DTMF) {
2237 rtp_code = ast_rtp_codecs_payload_code(
2238 ast_rtp_instance_get_codecs(session_media->rtp), 0, NULL, index);
2239 if (rtp_code == -1) {
2240 continue;
2241 } else if ((attr = generate_rtpmap_attr(session, media, pool, rtp_code, 0, NULL, index))) {
2242 media->attr[media->attr_count++] = attr;
2243 }
2244 } else if (build_dtmf_sample_rates) {
2245 /*
2246 * Walk through the possible bitrates for the RFC 2833/4733 digits and generate the rtpmap
2247 * attributes.
2248 */
2249 int i, found_default_offer = 0;
2250 for (i = 0; i < AST_VECTOR_SIZE(&sample_rates); i++) {
2252 ast_rtp_instance_get_codecs(session_media->rtp), 0, NULL, index, AST_VECTOR_GET(&sample_rates, i));
2253
2254 if (rtp_code == -1) {
2255 continue;
2256 }
2257
2258 if (AST_VECTOR_GET(&sample_rates, i) == DEFAULT_DTMF_SAMPLE_RATE_MS) {
2259 /* we found and added a default offer, so no need to include a default one.*/
2260 found_default_offer = 1;
2261 }
2262
2263 if ((attr = generate_rtpmap_attr2(session, media, pool, rtp_code, 0, NULL, index, AST_VECTOR_GET(&sample_rates, i)))) {
2264 media->attr[media->attr_count++] = attr;
2265 snprintf(tmp, sizeof(tmp), "%d 0-16", (rtp_code));
2266 attr = pjmedia_sdp_attr_create(pool, "fmtp", pj_cstr(&stmp, tmp));
2267 media->attr[media->attr_count++] = attr;
2268 }
2269 }
2270
2271 /* If we weren't able to add any matching RFC 2833/4733, assume this endpoint is using a
2272 * mismatched 8K offer and try to add one as a fall-back/default.
2273 */
2274 if (!found_default_offer) {
2277
2278 if (rtp_code != -1 && (attr = generate_rtpmap_attr2(session, media, pool, rtp_code, 0, NULL, index, DEFAULT_DTMF_SAMPLE_RATE_MS))) {
2279 media->attr[media->attr_count++] = attr;
2280 snprintf(tmp, sizeof(tmp), "%d 0-16", (rtp_code));
2281 attr = pjmedia_sdp_attr_create(pool, "fmtp", pj_cstr(&stmp, tmp));
2282 media->attr[media->attr_count++] = attr;
2283 }
2284 }
2285 }
2286
2287 if (media->desc.fmt_count == PJMEDIA_MAX_SDP_FMT) {
2288 break;
2289 }
2290 }
2291 }
2292
2293 /* we are done with the sample rates */
2294 AST_VECTOR_FREE(&sample_rates);
2295
2296 /* If no formats were actually added to the media stream don't add it to the SDP */
2297 if (!media->desc.fmt_count) {
2298 SCOPE_EXIT_RTN_VALUE(1, "No formats added to stream\n");
2299 }
2300
2301 /* If ptime is set add it as an attribute */
2302 min_packet_size = ast_rtp_codecs_get_framing(ast_rtp_instance_get_codecs(session_media->rtp));
2303 if (!min_packet_size) {
2304 min_packet_size = ast_format_cap_get_framing(caps);
2305 }
2306 if (min_packet_size) {
2307 snprintf(tmp, sizeof(tmp), "%d", min_packet_size);
2308 attr = pjmedia_sdp_attr_create(pool, "ptime", pj_cstr(&stmp, tmp));
2309 media->attr[media->attr_count++] = attr;
2310 }
2311
2312 if (max_packet_size) {
2313 snprintf(tmp, sizeof(tmp), "%d", max_packet_size);
2314 attr = pjmedia_sdp_attr_create(pool, "maxptime", pj_cstr(&stmp, tmp));
2315 media->attr[media->attr_count++] = attr;
2316 }
2317
2318 attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr);
2319 if (session_media->locally_held) {
2320 if (session_media->remotely_held) {
2321 attr->name = STR_INACTIVE; /* To place on hold a recvonly stream, send inactive */
2322 } else {
2323 attr->name = STR_SENDONLY; /* Send sendonly to initate a local hold */
2324 }
2325 } else {
2326 if (session_media->remotely_held) {
2327 attr->name = STR_RECVONLY; /* Remote has sent sendonly, reply recvonly */
2328 } else if (ast_stream_get_state(stream) == AST_STREAM_STATE_SENDONLY) {
2329 attr->name = STR_SENDONLY; /* Stream has requested sendonly */
2330 } else if (ast_stream_get_state(stream) == AST_STREAM_STATE_RECVONLY) {
2331 attr->name = STR_RECVONLY; /* Stream has requested recvonly */
2332 } else if (ast_stream_get_state(stream) == AST_STREAM_STATE_INACTIVE) {
2333 attr->name = STR_INACTIVE; /* Stream has requested inactive */
2334 } else {
2335 attr->name = STR_SENDRECV; /* No hold in either direction */
2336 }
2337 }
2338 media->attr[media->attr_count++] = attr;
2339
2340 /* If we've got rtcp-mux enabled, add it unless we received an offer without it */
2341 if (session->endpoint->media.rtcp_mux && session_media->remote_rtcp_mux) {
2342 attr = pjmedia_sdp_attr_create(pool, "rtcp-mux", NULL);
2343 pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
2344 }
2345
2346 add_ssrc_to_stream(session, session_media, pool, media);
2347 add_msid_to_stream(session, session_media, pool, media, stream);
2348 add_rtcp_fb_to_stream(session, session_media, pool, media);
2349 add_extmap_to_stream(session, session_media, pool, media);
2350
2351 /* Add the media stream to the SDP */
2352 sdp->media[sdp->media_count++] = media;
2353
2354 SCOPE_EXIT_RTN_VALUE(1, "RC: 1\n");
2355}
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_get_maximum_ms(const struct ast_format *format)
Get the maximum amount of media carried in this format.
Definition format.c:369
unsigned int ast_format_cap_get_framing(const struct ast_format_cap *cap)
Get the global framing.
Definition format_cap.c:446
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:636
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition format_cap.h:38
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
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition format_cap.h:49
#define LOG_ERROR
char * ast_sockaddr_stringify_fmt(const struct ast_sockaddr *addr, int format)
Convert a socket address to a string.
Definition netsock2.c:65
#define AST_SOCKADDR_STR_ADDR
Definition netsock2.h:198
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition netsock2.h:517
const char * ast_sip_get_host_ip_string(int af)
Retrieve the local host address in string form.
Definition res_pjsip.c:2513
@ AST_SIP_DTMF_AUTO_INFO
Definition res_pjsip.h:560
@ AST_SIP_DTMF_AUTO
Definition res_pjsip.h:558
@ AST_SIP_DTMF_RFC_4733
Definition res_pjsip.h:552
static pjmedia_sdp_attr * generate_rtpmap_attr2(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 sample_rate)
static int assign_unique_bundle_payload(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct ast_sip_session_media *session_media_transport, const pjmedia_sdp_session *sdp, const pjmedia_sdp_media *media, struct ast_format *format)
Assign a payload type that is unique across the generated BUNDLE group.
static int generating_local_offer(const struct ast_sip_session *session)
Determine whether the SDP currently being generated is a local offer.
static void add_ice_to_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media, unsigned int include_candidates)
Function which adds ICE attributes to a media stream.
static void add_extmap_to_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media)
static 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_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 pjmedia_sdp_attr * generate_rtpmap_attr(struct ast_sip_session *session, pjmedia_sdp_media *media, pj_pool_t *pool, int rtp_code, int asterisk_format, struct ast_format *format, int code)
static int 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_ssrc_to_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media)
Function which adds ssrc attributes to a media stream.
static pjmedia_sdp_attr * generate_fmtp_attr(pj_pool_t *pool, struct ast_format *format, int rtp_code)
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.
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.
#define AST_RTP_DTMF
Definition rtp_engine.h:294
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:694
int ast_rtp_codecs_payload_code_sample_rate(struct ast_rtp_codecs *codecs, int asterisk_format, struct ast_format *format, int code, unsigned int sample_rate)
Retrieve a rx mapped payload type based on whether it is an Asterisk format, the code and the sample ...
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.
#define AST_RTP_MAX
Definition rtp_engine.h:300
unsigned int ast_rtp_codecs_get_framing(struct ast_rtp_codecs *codecs)
Get the framing used for a set of codecs.
#define DEFAULT_DTMF_SAMPLE_RATE_MS
Definition rtp_engine.h:110
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
@ AST_STREAM_STATE_RECVONLY
Set when the stream is receiving media only.
Definition stream.h:90
@ AST_STREAM_STATE_INACTIVE
Set when the stream is not sending OR receiving media.
Definition stream.h:94
@ AST_STREAM_STATE_REMOVED
Set when the stream has been removed/declined.
Definition stream.h:78
@ AST_STREAM_STATE_SENDONLY
Set when the stream is sending media only.
Definition stream.h:86
void ast_stream_set_state(struct ast_stream *stream, enum ast_stream_state state)
Set the state of a stream.
Definition stream.c:380
enum ast_stream_state ast_stream_get_state(const struct ast_stream *stream)
Get the current state of a stream.
Definition stream.c:373
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
Format capabilities structure, holds formats + preference order + etc.
Definition format_cap.c:54
int stream_num
The stream number to place into any resulting frames.
struct ast_sockaddr direct_media_addr
Direct media address.
pj_str_t transport
The media transport in use for this stream.
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition vector.h:185
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition vector.h:124
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition vector.h:267
#define AST_VECTOR(name, type)
Define a vector structure.
Definition vector.h:44

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(), ao2_cleanup, ao2_ref, assign_unique_bundle_payload(), 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_code_sample_rate(), 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_lookup_sample_rate2(), 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_sorcery_object_get_id(), 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, AST_VECTOR_APPEND, AST_VECTOR_FREE, AST_VECTOR_GET, AST_VECTOR_INIT, AST_VECTOR_SIZE, ast_sip_session_media::bundle_group, ast_sip_session_media::bundled, create_rtp(), DEFAULT_DTMF_SAMPLE_RATE_MS, ast_sip_session_media::direct_media_addr, enable_rtcp(), ast_sip_session_media::encryption, generate_fmtp_attr(), generate_rtpmap_attr(), generate_rtpmap_attr2(), generating_local_offer(), ast_sip_session_media::locally_held, LOG_ERROR, LOG_WARNING, NULL, RAII_VAR, ast_sip_session_media::remote_rtcp_mux, ast_sip_session_media::remotely_held, ast_sip_session_media::rtp, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, session, set_ice_components(), ast_sip_session_media::stream_num, ast_sip_session_media::transport, and ast_sip_session_media::type.

◆ 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 225 of file res_pjsip_sdp_rtp.c.

227{
228 struct ast_rtp_engine_ice *ice;
229 struct ast_sockaddr temp_media_address;
230 struct ast_sockaddr *media_address = &address_rtp;
231
232 if (session->endpoint->media.bind_rtp_to_media_address && !ast_strlen_zero(session->endpoint->media.address)) {
233 if (ast_sockaddr_parse(&temp_media_address, session->endpoint->media.address, 0)) {
234 ast_debug_rtp(1, "Endpoint %s: Binding RTP media to %s\n",
236 session->endpoint->media.address);
237 media_address = &temp_media_address;
238 } else {
239 ast_debug_rtp(1, "Endpoint %s: RTP media address invalid: %s\n",
241 session->endpoint->media.address);
242 }
243 } else {
244 struct ast_sip_transport *transport;
245
246 transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport",
247 session->endpoint->transport);
248 if (transport) {
249 struct ast_sip_transport_state *trans_state;
250
252 if (trans_state) {
253 char hoststr[PJ_INET6_ADDRSTRLEN];
254
255 pj_sockaddr_print(&trans_state->host, hoststr, sizeof(hoststr), 0);
256 if (ast_sockaddr_parse(&temp_media_address, hoststr, 0)) {
257 ast_debug_rtp(1, "Transport %s bound to %s: Using it for RTP media.\n",
258 session->endpoint->transport, hoststr);
259 media_address = &temp_media_address;
260 } else {
261 ast_debug_rtp(1, "Transport %s bound to %s: Invalid for RTP media.\n",
262 session->endpoint->transport, hoststr);
263 }
264 ao2_ref(trans_state, -1);
265 }
266 ao2_ref(transport, -1);
267 }
268 }
269
270 if (session->endpoint->media.rtp.port_start && session->endpoint->media.rtp.port_end) {
272 .port_start = session->endpoint->media.rtp.port_start,
273 .port_end = session->endpoint->media.rtp.port_end,
274 };
275 if (!(session_media->rtp = ast_rtp_instance_new_with_options(
276 session->endpoint->media.rtp.engine, sched, media_address, NULL,
277 &options))) {
278 ast_log(LOG_ERROR, "Unable to create RTP instance using RTP engine '%s' with port range %u-%u\n",
279 session->endpoint->media.rtp.engine,
280 session->endpoint->media.rtp.port_start,
281 session->endpoint->media.rtp.port_end);
282 return -1;
283 }
284 } else {
285 if (!(session_media->rtp = ast_rtp_instance_new(session->endpoint->media.rtp.engine, sched, media_address, NULL))) {
286 ast_log(LOG_ERROR, "Unable to create RTP instance using RTP engine '%s'\n", session->endpoint->media.rtp.engine);
287 return -1;
288 }
289 }
290
291 ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_NAT, session->endpoint->media.rtp.symmetric);
292 ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_ASYMMETRIC_CODEC, session->endpoint->asymmetric_rtp_codec);
293
294 if (!session->endpoint->media.rtp.ice_support && (ice = ast_rtp_instance_get_ice(session_media->rtp))) {
295 ice->stop(session_media->rtp);
296 }
297
301 } else if (session->dtmf == AST_SIP_DTMF_INBAND) {
303 }
304
305 if (session_media->type == AST_MEDIA_TYPE_AUDIO &&
306 (session->endpoint->media.tos_audio || session->endpoint->media.cos_audio)) {
307 ast_rtp_instance_set_qos(session_media->rtp, session->endpoint->media.tos_audio,
308 session->endpoint->media.cos_audio, "SIP RTP Audio");
309 } else if (session_media->type == AST_MEDIA_TYPE_VIDEO) {
310 ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_RETRANS_RECV, session->endpoint->media.webrtc);
311 ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_RETRANS_SEND, session->endpoint->media.webrtc);
312 ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_REMB, session->endpoint->media.webrtc);
313 if (session->endpoint->media.webrtc) {
316 }
317 if (session->endpoint->media.tos_video || session->endpoint->media.cos_video) {
318 ast_rtp_instance_set_qos(session_media->rtp, session->endpoint->media.tos_video,
319 session->endpoint->media.cos_video, "SIP RTP Video");
320 }
321 }
322
323 ast_rtp_instance_set_last_rx(session_media->rtp, time(NULL));
324
325 return 0;
326}
@ AST_SIP_DTMF_INBAND
Definition res_pjsip.h:554
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
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.
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:497
void ast_rtp_instance_set_last_rx(struct ast_rtp_instance *rtp, time_t time)
Set the last RTP reception time.
@ AST_RTP_DTMF_MODE_RFC2833
Definition rtp_engine.h:155
@ AST_RTP_DTMF_MODE_INBAND
Definition rtp_engine.h:157
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.
#define ast_debug_rtp(sublevel,...)
Log debug level RTP information.
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:756
struct ast_rtp_instance * ast_rtp_instance_new_with_options(const char *engine_name, struct ast_sched_context *sched, const struct ast_sockaddr *sa, void *data, const struct ast_rtp_instance_options *options)
Create a new RTP instance with additional options.
Definition rtp_engine.c:505
@ AST_RTP_EXTENSION_TRANSPORT_WIDE_CC
Definition rtp_engine.h:599
@ AST_RTP_EXTENSION_ABS_SEND_TIME
Definition rtp_engine.h:597
@ AST_RTP_PROPERTY_NAT
Definition rtp_engine.h:118
@ AST_RTP_PROPERTY_RETRANS_RECV
Definition rtp_engine.h:130
@ AST_RTP_PROPERTY_RETRANS_SEND
Definition rtp_engine.h:132
@ AST_RTP_PROPERTY_ASYMMETRIC_CODEC
Definition rtp_engine.h:128
@ AST_RTP_PROPERTY_DTMF
Definition rtp_engine.h:120
@ AST_RTP_PROPERTY_REMB
Definition rtp_engine.h:134
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.
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:1917
Options for creating a new RTP instance.
Definition rtp_engine.h:994
struct pjsip_transport * transport
Transport itself.
Definition res_pjsip.h:119
Transport to bind to.
Definition res_pjsip.h:219
static struct test_options options

References 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_new_with_options(), 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(), enable_rtp_extension(), ast_sip_transport_state::host, LOG_ERROR, NULL, options, ast_sip_session_media::rtp, session, ast_rtp_engine_ice::stop, ast_sip_transport_state::transport, and ast_sip_session_media::type.

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

◆ 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 162 of file res_pjsip_sdp_rtp.c.

164{
165 enum ast_rtp_instance_rtcp rtcp_type;
166
167 if (session->endpoint->media.rtcp_mux && session_media->remote_rtcp_mux) {
168 rtcp_type = AST_RTP_INSTANCE_RTCP_MUX;
169 } else {
171 }
172
173 ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_RTCP, rtcp_type);
174}
ast_rtp_instance_rtcp
Definition rtp_engine.h:283
@ AST_RTP_INSTANCE_RTCP_MUX
Definition rtp_engine.h:289
@ AST_RTP_INSTANCE_RTCP_STANDARD
Definition rtp_engine.h:287
@ AST_RTP_PROPERTY_RTCP
Definition rtp_engine.h:126

References AST_RTP_INSTANCE_RTCP_MUX, AST_RTP_INSTANCE_RTCP_STANDARD, ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_RTCP, ast_sip_session_media::remote_rtcp_mux, ast_sip_session_media::rtp, and session.

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

◆ 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 179 of file res_pjsip_sdp_rtp.c.

182{
183 int id = -1;
184
185 /* For a bundle group the local unique identifier space is shared across all streams within
186 * it.
187 */
188 if (session_media->bundle_group != -1) {
189 int index;
190
191 for (index = 0; index < sdp->media_count; ++index) {
192 struct ast_sip_session_media *other_session_media;
193 int other_id;
194
195 if (index >= AST_VECTOR_SIZE(&session->pending_media_state->sessions)) {
196 break;
197 }
198
199 other_session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, index);
200 if (!other_session_media->rtp || other_session_media->bundle_group != session_media->bundle_group) {
201 continue;
202 }
203
204 other_id = ast_rtp_instance_extmap_get_id(other_session_media->rtp, extension);
205 if (other_id == -1) {
206 /* Worst case we have to fall back to the highest available free local unique identifier
207 * for the bundle group.
208 */
209 other_id = ast_rtp_instance_extmap_count(other_session_media->rtp) + 1;
210 if (id < other_id) {
211 id = other_id;
212 }
213 continue;
214 }
215
216 id = other_id;
217 break;
218 }
219 }
220
222}
direction
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:783
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:937

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_media::rtp, and session.

Referenced by create_rtp().

◆ ensure_payload_type_mapping()

static int ensure_payload_type_mapping ( struct ast_rtp_codecs *  codecs,
int  payload,
struct ast_format *  format 
)
static

Ensure an RTP codecs structure can receive a format using a payload type.

Definition at line 502 of file res_pjsip_sdp_rtp.c.

504{
506 int matches;
507
509 if (type) {
510 matches = type->asterisk_format
512 ao2_ref(type, -1);
513 return matches ? 0 : -1;
514 }
515
516 return ast_rtp_codecs_payload_set_rx(codecs, payload, format) < 0 ? -1 : 0;
517}
static const char type[]
static struct ao2_container * codecs
Registered codecs.
Definition codec.c:48
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition format.c:201
@ AST_FORMAT_CMP_EQUAL
Definition format.h:36
struct ast_rtp_payload_type * ast_rtp_codecs_get_payload(struct ast_rtp_codecs *codecs, int payload)
Retrieve rx payload mapped information by payload type.
struct ast_format * format
Definition rtp_engine.h:306

References ao2_ref, ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_rtp_codecs_get_payload(), ast_rtp_codecs_payload_set_rx(), codecs, ast_rtp_payload_type::format, ast_rtp_payload_type::payload, and type.

Referenced by assign_unique_bundle_payload().

◆ 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 882 of file res_pjsip_sdp_rtp.c.

883{
884 struct ast_str *fmtp0 = ast_str_alloca(256);
885 pj_str_t fmtp1;
886 pjmedia_sdp_attr *attr = NULL;
887 char *tmp;
888
889 ast_format_generate_sdp_fmtp(format, rtp_code, &fmtp0);
890 if (ast_str_strlen(fmtp0)) {
891 tmp = ast_str_buffer(fmtp0) + ast_str_strlen(fmtp0) - 1;
892 /* remove any carriage return line feeds */
893 while (*tmp == '\r' || *tmp == '\n') --tmp;
894 *++tmp = '\0';
895 /* ast...generate gives us everything, just need value */
896 tmp = strchr(ast_str_buffer(fmtp0), ':');
897 if (tmp && tmp[1] != '\0') {
898 fmtp1 = pj_str(tmp + 1);
899 } else {
900 fmtp1 = pj_str(ast_str_buffer(fmtp0));
901 }
902 attr = pjmedia_sdp_attr_create(pool, "fmtp", &fmtp1);
903 }
904 return attr;
905}
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
size_t attribute_pure ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition strings.h:730
#define ast_str_alloca(init_len)
Definition strings.h:848

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

Referenced by create_outgoing_sdp_stream().

◆ 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 811 of file res_pjsip_sdp_rtp.c.

813{
814#ifndef HAVE_PJSIP_ENDPOINT_COMPACT_FORM
815 extern pj_bool_t pjsip_use_compact_form;
816#else
817 pj_bool_t pjsip_use_compact_form = pjsip_cfg()->endpt.use_compact_form;
818#endif
819 pjmedia_sdp_rtpmap rtpmap;
820 pjmedia_sdp_attr *attr = NULL;
821 char tmp[64];
822 enum ast_rtp_options options = session->endpoint->media.g726_non_standard ?
824
825 snprintf(tmp, sizeof(tmp), "%d", rtp_code);
826 pj_strdup2(pool, &media->desc.fmt[media->desc.fmt_count++], tmp);
827
828 if (rtp_code <= AST_RTP_PT_LAST_STATIC && pjsip_use_compact_form) {
829 return NULL;
830 }
831
832 rtpmap.pt = media->desc.fmt[media->desc.fmt_count - 1];
833 rtpmap.clock_rate = ast_rtp_lookup_sample_rate2(asterisk_format, format, code);
834 pj_strdup2(pool, &rtpmap.enc_name, ast_rtp_lookup_mime_subtype2(asterisk_format, format, code, options));
835 if (!pj_stricmp2(&rtpmap.enc_name, "opus")) {
836 pj_cstr(&rtpmap.param, "2");
837 } else {
838 pj_cstr(&rtpmap.param, NULL);
839 }
840
841 pjmedia_sdp_rtpmap_to_attr(pool, &rtpmap, &attr);
842
843 return attr;
844}
ast_rtp_options
Definition rtp_engine.h:145
@ AST_RTP_OPT_G726_NONSTANDARD
Definition rtp_engine.h:147
#define AST_RTP_PT_LAST_STATIC
Definition rtp_engine.h:89
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.

References ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), AST_RTP_OPT_G726_NONSTANDARD, AST_RTP_PT_LAST_STATIC, NULL, options, and session.

Referenced by create_outgoing_sdp_stream().

◆ generate_rtpmap_attr2()

static pjmedia_sdp_attr * generate_rtpmap_attr2 ( 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  sample_rate 
)
static

Definition at line 847 of file res_pjsip_sdp_rtp.c.

849{
850#ifndef HAVE_PJSIP_ENDPOINT_COMPACT_FORM
851 extern pj_bool_t pjsip_use_compact_form;
852#else
853 pj_bool_t pjsip_use_compact_form = pjsip_cfg()->endpt.use_compact_form;
854#endif
855 pjmedia_sdp_rtpmap rtpmap;
856 pjmedia_sdp_attr *attr = NULL;
857 char tmp[64];
858 enum ast_rtp_options options = session->endpoint->media.g726_non_standard ?
860
861 snprintf(tmp, sizeof(tmp), "%d", rtp_code);
862 pj_strdup2(pool, &media->desc.fmt[media->desc.fmt_count++], tmp);
863
864 if (rtp_code <= AST_RTP_PT_LAST_STATIC && pjsip_use_compact_form) {
865 return NULL;
866 }
867
868 rtpmap.pt = media->desc.fmt[media->desc.fmt_count - 1];
869 rtpmap.clock_rate = sample_rate;
870 pj_strdup2(pool, &rtpmap.enc_name, ast_rtp_lookup_mime_subtype2(asterisk_format, format, code, options));
871 if (!pj_stricmp2(&rtpmap.enc_name, "opus")) {
872 pj_cstr(&rtpmap.param, "2");
873 } else {
874 pj_cstr(&rtpmap.param, NULL);
875 }
876
877 pjmedia_sdp_rtpmap_to_attr(pool, &rtpmap, &attr);
878
879 return attr;
880}

References ast_rtp_lookup_mime_subtype2(), AST_RTP_OPT_G726_NONSTANDARD, AST_RTP_PT_LAST_STATIC, NULL, options, and session.

Referenced by create_outgoing_sdp_stream().

◆ generating_local_offer()

static int generating_local_offer ( const struct ast_sip_session *  session)
static

Determine whether the SDP currently being generated is a local offer.

Definition at line 582 of file res_pjsip_sdp_rtp.c.

583{
584 return !session->inv_session->neg
585 || pjmedia_sdp_neg_get_state(session->inv_session->neg) == PJMEDIA_SDP_NEG_STATE_DONE;
586}

References session.

Referenced by create_outgoing_sdp_stream().

◆ 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,
struct ast_format_cap *  astformats 
)
static

Definition at line 328 of file res_pjsip_sdp_rtp.c.

330{
331 pjmedia_sdp_attr *attr;
332 pjmedia_sdp_rtpmap *rtpmap;
333 pjmedia_sdp_fmtp fmtp;
334 struct ast_format *format;
335 int i, num = 0, tel_event = 0;
336 char name[256];
337 char media[20];
338 char fmt_param[256];
339 enum ast_rtp_options options = session->endpoint->media.g726_non_standard ?
342
344
346
347 /* Iterate through provided formats */
348 for (i = 0; i < stream->desc.fmt_count; ++i) {
349 /* The payload is kept as a string for things like t38 but for video it is always numerical */
350 ast_rtp_codecs_payloads_set_m_type(codecs, NULL, pj_strtoul(&stream->desc.fmt[i]));
351 /* Look for the optional rtpmap attribute */
352 if (!(attr = pjmedia_sdp_media_find_attr2(stream, "rtpmap", &stream->desc.fmt[i]))) {
353 continue;
354 }
355
356 /* Interpret the attribute as an rtpmap */
357 if ((pjmedia_sdp_attr_to_rtpmap(session->inv_session->pool_prov, attr, &rtpmap)) != PJ_SUCCESS) {
358 continue;
359 }
360
361 ast_copy_pj_str(name, &rtpmap->enc_name, sizeof(name));
362 if (strcmp(name, "telephone-event") == 0) {
363 if (tel_event == 0) {
364 int dtmf_rate = 0, dtmf_code = 0;
365 char dtmf_pt[8];
366 ast_copy_pj_str(dtmf_pt, &rtpmap->pt, sizeof(dtmf_pt));
367 dtmf_code = atoi(dtmf_pt);
368 dtmf_rate = rtpmap->clock_rate;
370 }
371 tel_event++;
372 }
373
374 ast_copy_pj_str(media, (pj_str_t*)&stream->desc.media, sizeof(media));
376 pj_strtoul(&stream->desc.fmt[i]), media, name, options, rtpmap->clock_rate);
377 /* Look for an optional associated fmtp attribute */
378 if (!(attr = pjmedia_sdp_media_find_attr2(stream, "fmtp", &rtpmap->pt))) {
379 continue;
380 }
381
382 if ((pjmedia_sdp_attr_get_fmtp(attr, &fmtp)) == PJ_SUCCESS) {
383 ast_copy_pj_str(fmt_param, &fmtp.fmt, sizeof(fmt_param));
384 if (sscanf(fmt_param, "%30d", &num) != 1) {
385 continue;
386 }
387
388 if ((format = ast_rtp_codecs_get_payload_format(codecs, num))) {
389 struct ast_format *format_parsed;
390
391 ast_copy_pj_str(fmt_param, &fmtp.fmt_param, sizeof(fmt_param));
392
393 format_parsed = ast_format_parse_sdp_fmtp(format, fmt_param);
394 if (format_parsed) {
396 ao2_ref(format_parsed, -1);
397 }
398 ao2_ref(format, -1);
399 }
400 }
401 }
402
403 /* Parsing done, now fill the ast_format_cap struct in the correct order */
404 for (i = 0; i < stream->desc.fmt_count; ++i) {
405 if ((format = ast_rtp_codecs_get_payload_format(codecs, pj_strtoul(&stream->desc.fmt[i])))) {
406 ast_format_cap_append(astformats, format, 0);
407 ao2_ref(format, -1);
408 }
409 }
410
411 if (session->dtmf == AST_SIP_DTMF_AUTO) {
412 if (tel_event) {
415 } else {
418 }
419 }
420
421 if (session->dtmf == AST_SIP_DTMF_AUTO_INFO) {
422 if (tel_event) {
425 } else {
428 }
429 }
430
431
432 /* Get the packetization, if it exists */
433 if ((attr = pjmedia_sdp_media_find_attr2(stream, "ptime", NULL))) {
434 unsigned long framing = pj_strtoul(pj_strltrim(&attr->value));
435 if (framing && session->endpoint->media.rtp.use_ptime) {
437 ast_format_cap_set_framing(astformats, framing);
438 }
439 }
440
442}
@ AST_MEDIA_TYPE_UNKNOWN
Definition codec.h:31
struct ast_format * ast_format_parse_sdp_fmtp(const struct ast_format *format, const char *attributes)
This function is used to have a media format aware module parse and interpret SDP attribute informati...
Definition format.c:286
void ast_format_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:531
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition format_cap.h:99
void ast_format_cap_set_framing(struct ast_format_cap *cap, unsigned int framing)
Set the global framing.
Definition format_cap.c:136
static const char name[]
Definition format_mp3.c:68
#define SCOPE_EXIT_RTN(...)
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.
@ AST_RTP_DTMF_MODE_NONE
Definition rtp_engine.h:153
void ast_rtp_codecs_set_framing(struct ast_rtp_codecs *codecs, unsigned int framing)
Set the framing used for a set of codecs.
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.
int ast_rtp_codecs_payloads_initialize(struct ast_rtp_codecs *codecs)
Initialize an RTP codecs structure.
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.
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.
int ast_rtp_codecs_set_preferred_dtmf_format(struct ast_rtp_codecs *codecs, int pt, int rate)
Set the preferred dtmf format pt and sample rate.

References ao2_ref, ast_copy_pj_str(), ast_format_cap_append, ast_format_cap_remove_by_type(), ast_format_cap_set_framing(), ast_format_parse_sdp_fmtp(), AST_MEDIA_TYPE_UNKNOWN, 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_codecs_set_preferred_dtmf_format(), 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(), codecs, name, NULL, options, ast_sip_session_media::rtp, SCOPE_ENTER, SCOPE_EXIT_RTN, and session.

Referenced by set_caps(), and set_incoming_call_offer_cap().

◆ 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 1171 of file res_pjsip_sdp_rtp.c.

1173{
1174 RAII_VAR(char *, transport_str, ast_strndup(transport.ptr, transport.slen), ast_free);
1175
1176 *optimistic = 0;
1177
1178 if (!transport_str) {
1180 }
1181 if (strstr(transport_str, "UDP/TLS")) {
1183 } else if (strstr(transport_str, "SAVP")) {
1185 } else if (media_stream_has_crypto(stream)) {
1186 *optimistic = 1;
1188 } else {
1190 }
1191}
#define ast_strndup(str, len)
A wrapper for strndup()
Definition astmm.h:256
static int media_stream_has_crypto(const struct pjmedia_sdp_media *stream)
figure out if media stream has crypto lines for sdes

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(), RAII_VAR, and ast_rtp_engine_ice_candidate::transport.

Referenced by check_endpoint_media_transport().

◆ 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 2692 of file res_pjsip_sdp_rtp.c.

2693{
2694 if (ast_check_ipv6()) {
2696 } else {
2697 ast_sockaddr_parse(&address_rtp, "0.0.0.0", 0);
2698 }
2699
2700 if (!(sched = ast_sched_context_create())) {
2701 ast_log(LOG_ERROR, "Unable to create scheduler context.\n");
2702 goto end;
2703 }
2704
2706 ast_log(LOG_ERROR, "Unable to create scheduler context thread.\n");
2707 goto end;
2708 }
2709
2711 ast_log(LOG_ERROR, "Unable to register SDP handler for %s stream type\n", STR_AUDIO);
2712 goto end;
2713 }
2714
2716 ast_log(LOG_ERROR, "Unable to register SDP handler for %s stream type\n", STR_VIDEO);
2717 goto end;
2718 }
2719
2721
2723end:
2724 unload_module();
2725
2727}
char * end
Definition eagi_proxy.c:73
@ AST_MODULE_LOAD_SUCCESS
Definition module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition module.h:78
static const char STR_AUDIO[]
static struct ast_sip_session_sdp_handler audio_sdp_handler
SDP handler for 'audio' media stream.
static const char STR_VIDEO[]
static struct ast_sip_session_sdp_handler video_sdp_handler
SDP handler for 'video' media stream.
static int unload_module(void)
Unloads the sdp RTP/AVP module from Asterisk.
static struct ast_sip_session_supplement video_info_supplement
int ast_sip_session_register_sdp_handler(struct ast_sip_session_sdp_handler *handler, const char *stream_type)
Register an SDP handler.
#define ast_sip_session_register_supplement(supplement)
int ast_sched_start_thread(struct ast_sched_context *con)
Start a thread for processing scheduler entries.
Definition sched.c:197
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition sched.c:238
int ast_check_ipv6(void)
Test that an OS supports IPv6 Networking.
Definition utils.c:2826

References address_rtp, ast_check_ipv6(), ast_log, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_sched_context_create(), ast_sched_start_thread(), ast_sip_session_register_sdp_handler(), ast_sip_session_register_supplement, ast_sockaddr_parse(), audio_sdp_handler, end, LOG_ERROR, STR_AUDIO, STR_VIDEO, unload_module(), video_info_supplement, and video_sdp_handler.

◆ 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 2375 of file res_pjsip_sdp_rtp.c.

2376{
2377 struct ast_frame *f;
2378
2379 if (!session_media->rtp) {
2380 return &ast_null_frame;
2381 }
2382
2383 f = ast_rtp_instance_read(session_media->rtp, 1);
2384 if (!f) {
2385 return NULL;
2386 }
2387
2388 ast_rtp_instance_set_last_rx(session_media->rtp, time(NULL));
2389
2390 return f;
2391}
struct ast_frame * ast_rtp_instance_read(struct ast_rtp_instance *instance, int rtcp)
Receive a frame over RTP.
Definition rtp_engine.c:629
Data structure associated with a single frame of data.

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().

◆ 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 2357 of file res_pjsip_sdp_rtp.c.

2358{
2359 struct ast_frame *f;
2360
2361 if (!session_media->rtp) {
2362 return &ast_null_frame;
2363 }
2364
2365 f = ast_rtp_instance_read(session_media->rtp, 0);
2366 if (!f) {
2367 return NULL;
2368 }
2369
2370 ast_rtp_instance_set_last_rx(session_media->rtp, time(NULL));
2371
2372 return f;
2373}

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().

◆ 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 2393 of file res_pjsip_sdp_rtp.c.

2394{
2395 if (!session_media->rtp) {
2396 return 0;
2397 }
2398
2399 return ast_rtp_instance_write(session_media->rtp, frame);
2400}
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
Definition rtp_engine.c:619

References ast_rtp_instance_write(), and ast_sip_session_media::rtp.

Referenced by apply_negotiated_sdp_stream().

◆ 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 1151 of file res_pjsip_sdp_rtp.c.

1152{
1153 int i;
1154
1155 for (i = 0; i < stream->attr_count; i++) {
1156 pjmedia_sdp_attr *attr;
1157
1158 /* check the stream for the required crypto attribute */
1159 attr = stream->attr[i];
1160 if (pj_strcmp2(&attr->name, "crypto")) {
1161 continue;
1162 }
1163
1164 return 1;
1165 }
1166
1167 return 0;
1168}

Referenced by get_media_encryption_type().

◆ 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 1718 of file res_pjsip_sdp_rtp.c.

1721{
1722 char host[NI_MAXHOST];
1723 RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free);
1724 pjmedia_sdp_media *stream = sdp->media[index];
1725 struct ast_sip_session_media *session_media_transport;
1726 enum ast_media_type media_type = session_media->type;
1728 struct ast_format_cap *joint;
1729 int res;
1731
1732 /* If no type formats have been configured reject this stream */
1733 if (!ast_format_cap_has_type(session->endpoint->media.codecs, media_type)) {
1734 ast_debug(3, "Endpoint has no codecs for media type '%s', declining stream\n",
1735 ast_codec_media_type2str(session_media->type));
1736 SCOPE_EXIT_RTN_VALUE(0, "Endpoint has no codecs\n");
1737 }
1738
1739 /* Ensure incoming transport is compatible with the endpoint's configuration */
1740 if (!session->endpoint->media.rtp.use_received_transport) {
1741 encryption = check_endpoint_media_transport(session->endpoint, stream);
1742
1743 if (encryption == AST_SIP_MEDIA_TRANSPORT_INVALID) {
1744 SCOPE_EXIT_RTN_VALUE(-1, "Incompatible transport\n");
1745 }
1746 }
1747
1748 ast_copy_pj_str(host, stream->conn ? &stream->conn->addr : &sdp->conn->addr, sizeof(host));
1749
1750 /* Ensure that the address provided is valid */
1751 if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC) <= 0) {
1752 /* The provided host was actually invalid so we error out this negotiation */
1753 SCOPE_EXIT_RTN_VALUE(-1, "Invalid host\n");
1754 }
1755
1756 /* Using the connection information create an appropriate RTP instance */
1757 if (!session_media->rtp && create_rtp(session, session_media, sdp)) {
1758 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create rtp\n");
1759 }
1760
1761 process_ssrc_attributes(session, session_media, stream);
1762 process_extmap_attributes(session, session_media, stream);
1763 session_media_transport = ast_sip_session_media_get_transport(session, session_media);
1764
1765 if (session_media_transport == session_media || !session_media->bundled) {
1766 /* If this media session is carrying actual traffic then set up those aspects */
1767 session_media->remote_rtcp_mux = (pjmedia_sdp_media_find_attr2(stream, "rtcp-mux", NULL) != NULL);
1768 set_ice_components(session, session_media);
1769
1770 enable_rtcp(session, session_media, stream);
1771
1772 res = setup_media_encryption(session, session_media, sdp, stream);
1773 if (res) {
1774 if (!session->endpoint->media.rtp.encryption_optimistic ||
1775 !pj_strncmp2(&stream->desc.transport, "RTP/SAVP", 8)) {
1776 /* If optimistic encryption is disabled and crypto should have been enabled
1777 * but was not this session must fail. This must also fail if crypto was
1778 * required in the offer but could not be set up.
1779 */
1780 SCOPE_EXIT_RTN_VALUE(-1, "Incompatible crypto\n");
1781 }
1782 /* There is no encryption, sad. */
1783 session_media->encryption = AST_SIP_MEDIA_ENCRYPT_NONE;
1784 }
1785
1786 /* If we've been explicitly configured to use the received transport OR if
1787 * encryption is on and crypto is present use the received transport.
1788 * This is done in case of optimistic because it may come in as RTP/AVP or RTP/SAVP depending
1789 * on the configuration of the remote endpoint (optimistic themselves or mandatory).
1790 */
1791 if ((session->endpoint->media.rtp.use_received_transport) ||
1792 ((encryption == AST_SIP_MEDIA_ENCRYPT_SDES) && !res)) {
1793 pj_strdup(session->inv_session->pool, &session_media->transport, &stream->desc.transport);
1794 }
1795 } else {
1796 /* This is bundled with another session, so mark it as such */
1797 ast_rtp_instance_bundle(session_media->rtp, session_media_transport->rtp);
1798
1799 enable_rtcp(session, session_media, stream);
1800 }
1801
1802 /* If ICE support is enabled find all the needed attributes */
1803 check_ice_support(session, session_media, stream);
1804
1805 /* If ICE support is enabled then check remote ICE started? */
1806 if (session_media->remote_ice) {
1807 process_ice_auth_attrb(session, session_media, sdp, stream);
1808 }
1809
1810 /* Check if incoming SDP is changing the remotely held state */
1811 set_session_media_remotely_held(session_media, session, stream, asterisk_stream, addrs);
1812
1813 joint = set_incoming_call_offer_cap(session, session_media, stream);
1814 res = apply_cap_to_bundled(session_media, session_media_transport, asterisk_stream, joint);
1815 ao2_cleanup(joint);
1816 if (res != 0) {
1817 SCOPE_EXIT_RTN_VALUE(0, "Something failed\n");
1818 }
1819
1821}
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:621
static void check_ice_support(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *remote_stream)
Function which checks for ice attributes in an audio stream.
static int 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 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 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)

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_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_media_get_transport(), ast_sockaddr_resolve(), ast_sip_session_media::bundled, check_endpoint_media_transport(), check_ice_support(), create_rtp(), enable_rtcp(), ast_sip_session_media::encryption, 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::rtp, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, session, set_ice_components(), set_incoming_call_offer_cap(), set_session_media_remotely_held(), setup_media_encryption(), ast_sip_session_media::transport, and ast_sip_session_media::type.

◆ 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 1332 of file res_pjsip_sdp_rtp.c.

1335{
1336 int i;
1337
1338 for (i = 0; i < sdp->attr_count; i++) {
1339 apply_dtls_attrib(session_media, sdp->attr[i]);
1340 }
1341
1342 for (i = 0; i < stream->attr_count; i++) {
1343 apply_dtls_attrib(session_media, stream->attr[i]);
1344 }
1345
1347
1348 return 0;
1349}
static void apply_dtls_attrib(struct ast_sip_session_media *session_media, pjmedia_sdp_attr *attr)
#define AST_SRTP_CRYPTO_OFFER_OK
Definition sdp_srtp.h:45
#define ast_set_flag(p, flag)
Definition utils.h:71

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

Referenced by setup_media_encryption().

◆ payload_type_compatible()

static int payload_type_compatible ( struct ast_rtp_codecs *  codecs,
int  payload,
struct ast_format *  format 
)
static

Check whether a payload slot is either free or already mapped to the requested format.

Definition at line 483 of file res_pjsip_sdp_rtp.c.

485{
487 int compatible;
488
490 if (!type) {
491 return 1;
492 }
493
494 compatible = type->asterisk_format
496 ao2_ref(type, -1);
497
498 return compatible;
499}

References ao2_ref, ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_rtp_codecs_get_payload(), codecs, ast_rtp_payload_type::format, ast_rtp_payload_type::payload, and type.

Referenced by assign_unique_bundle_payload().

◆ 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 1637 of file res_pjsip_sdp_rtp.c.

1639{
1640 int index;
1641
1642 if (!session->endpoint->media.webrtc || session_media->type != AST_MEDIA_TYPE_VIDEO) {
1643 return;
1644 }
1645
1646 ast_rtp_instance_extmap_clear(session_media->rtp);
1647
1648 for (index = 0; index < remote_stream->attr_count; ++index) {
1649 pjmedia_sdp_attr *attr = remote_stream->attr[index];
1650 char attr_value[pj_strlen(&attr->value) + 1];
1651 char *uri;
1652 int id;
1653 char direction_str[10] = "";
1654 char *attributes;
1656
1657 /* We only care about extmap attributes */
1658 if (pj_strcmp2(&attr->name, "extmap")) {
1659 continue;
1660 }
1661
1662 ast_copy_pj_str(attr_value, &attr->value, sizeof(attr_value));
1663
1664 /* Split the combined unique identifier and direction away from the URI and attributes for easier parsing */
1665 uri = strchr(attr_value, ' ');
1666 if (ast_strlen_zero(uri)) {
1667 continue;
1668 }
1669 *uri++ = '\0';
1670
1671 if ((sscanf(attr_value, "%30d%9s", &id, direction_str) < 1) || (id < 1)) {
1672 /* We require at a minimum the unique identifier */
1673 continue;
1674 }
1675
1676 /* Convert from the string to the internal representation */
1677 if (!strcasecmp(direction_str, "/sendonly")) {
1679 } else if (!strcasecmp(direction_str, "/recvonly")) {
1681 } else if (!strcasecmp(direction_str, "/inactive")) {
1683 }
1684
1685 attributes = strchr(uri, ' ');
1686 if (!ast_strlen_zero(attributes)) {
1687 *attributes++ = '\0';
1688 }
1689
1690 ast_rtp_instance_extmap_negotiate(session_media->rtp, id, direction, uri, attributes);
1691 }
1692}
enum queue_result id
Definition app_queue.c:1790
ast_rtp_extension_direction
Directions for RTP extensions.
Definition rtp_engine.h:827
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:869
void ast_rtp_instance_extmap_clear(struct ast_rtp_instance *instance)
Clear negotiated RTP extension information.
Definition rtp_engine.c:913

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(), id, ast_sip_session_media::rtp, session, and ast_sip_session_media::type.

Referenced by apply_negotiated_sdp_stream(), and negotiate_incoming_sdp_stream().

◆ 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 1047 of file res_pjsip_sdp_rtp.c.

1049{
1050 struct ast_rtp_engine_ice *ice;
1051 const pjmedia_sdp_attr *attr;
1052 char attr_value[256];
1053 unsigned int attr_i;
1054
1055 /* If ICE support is not enabled or available exit early */
1056 if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) {
1057 return;
1058 }
1059
1060 ast_debug_ice(2, "(%p) ICE process attributes\n", session_media->rtp);
1061
1062 attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-ufrag", NULL);
1063 if (!attr) {
1064 attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-ufrag", NULL);
1065 }
1066 if (attr) {
1067 ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
1069 } else {
1070 ast_debug_ice(2, "(%p) ICE no, or invalid ice-ufrag\n", session_media->rtp);
1071 return;
1072 }
1073
1075 if (!attr) {
1076 attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-pwd", NULL);
1077 }
1078 if (attr) {
1079 ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
1081 } else {
1082 ast_debug_ice(2, "(%p) ICE no, or invalid ice-pwd\n", session_media->rtp);
1083 return;
1084 }
1085
1087 ice->ice_lite(session_media->rtp);
1088 }
1089
1090 /* Find all of the candidates */
1091 for (attr_i = 0; attr_i < remote_stream->attr_count; ++attr_i) {
1092 char foundation[33], transport[32], address[PJ_INET6_ADDRSTRLEN + 1], cand_type[6], relay_address[PJ_INET6_ADDRSTRLEN + 1] = "";
1093 unsigned int port, relay_port = 0;
1094 struct ast_rtp_engine_ice_candidate candidate = { 0, };
1095
1096 attr = remote_stream->attr[attr_i];
1097
1098 /* If this is not a candidate line skip it */
1099 if (pj_strcmp2(&attr->name, "candidate")) {
1100 continue;
1101 }
1102
1103 ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
1104
1105 if (sscanf(attr_value, "%32s %30u %31s %30u %46s %30u typ %5s %*s %23s %*s %30u", foundation, &candidate.id, transport,
1106 (unsigned *)&candidate.priority, address, &port, cand_type, relay_address, &relay_port) < 7) {
1107 /* Candidate did not parse properly */
1108 continue;
1109 }
1110
1111 if (session->endpoint->media.rtcp_mux && session_media->remote_rtcp_mux && candidate.id > 1) {
1112 /* Remote side may have offered RTP and RTCP candidates. However, if we're using RTCP MUX,
1113 * then we should ignore RTCP candidates.
1114 */
1115 continue;
1116 }
1117
1118 candidate.foundation = foundation;
1119 candidate.transport = transport;
1120
1122 ast_sockaddr_set_port(&candidate.address, port);
1123
1124 if (!strcasecmp(cand_type, "host")) {
1126 } else if (!strcasecmp(cand_type, "srflx")) {
1128 } else if (!strcasecmp(cand_type, "relay")) {
1130 } else {
1131 continue;
1132 }
1133
1136 }
1137
1138 if (relay_port) {
1139 ast_sockaddr_set_port(&candidate.relay_address, relay_port);
1140 }
1141
1142 ice->add_remote_candidate(session_media->rtp, &candidate);
1143 }
1144
1145 ice->set_role(session_media->rtp, pjmedia_sdp_neg_was_answer_remote(session->inv_session->neg) == PJ_TRUE ?
1147 ice->start(session_media->rtp);
1148}
char * address
Definition f2c.h:59
@ AST_RTP_ICE_ROLE_CONTROLLING
Definition rtp_engine.h:521
@ AST_RTP_ICE_ROLE_CONTROLLED
Definition rtp_engine.h:520
#define ast_debug_ice(sublevel,...)
Log debug level ICE information.
void(* ice_lite)(struct ast_rtp_instance *instance)
Definition rtp_engine.h:552
void(* set_authentication)(struct ast_rtp_instance *instance, const char *ufrag, const char *password)
Definition rtp_engine.h:538
void(* add_remote_candidate)(struct ast_rtp_instance *instance, const struct ast_rtp_engine_ice_candidate *candidate)
Definition rtp_engine.h:540
void(* set_role)(struct ast_rtp_instance *instance, enum ast_rtp_ice_role role)
Definition rtp_engine.h:554

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_rtp_engine_ice_candidate::foundation, ast_rtp_engine_ice::ice_lite, ast_rtp_engine_ice_candidate::id, 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_session_media::rtp, session, 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().

◆ 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 1009 of file res_pjsip_sdp_rtp.c.

1011{
1012 struct ast_rtp_engine_ice *ice;
1014 char ufrag_attr_value[256];
1015 char passwd_attr_value[256];
1016
1017 /* If ICE support is not enabled or available exit early */
1018 if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) {
1019 return;
1020 }
1021
1023 if (!ufrag_attr) {
1024 ufrag_attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-ufrag", NULL);
1025 }
1026 if (ufrag_attr) {
1028 } else {
1029 return;
1030 }
1032 if (!passwd_attr) {
1033 passwd_attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-pwd", NULL);
1034 }
1035 if (passwd_attr) {
1037 } else {
1038 return;
1039 }
1040
1041 if (ufrag_attr && passwd_attr) {
1043 }
1044}

References ast_copy_pj_str(), ast_rtp_instance_get_ice(), NULL, session, ast_rtp_engine_ice::set_authentication, and ast_rtp_engine_ice::start.

Referenced by negotiate_incoming_sdp_stream().

◆ 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 1451 of file res_pjsip_sdp_rtp.c.

1453{
1454 int index;
1455
1456 if (!session->endpoint->media.bundle) {
1457 return;
1458 }
1459
1460 for (index = 0; index < remote_stream->attr_count; ++index) {
1461 pjmedia_sdp_attr *attr = remote_stream->attr[index];
1462 char attr_value[pj_strlen(&attr->value) + 1];
1463 char *ssrc_attribute_name, *ssrc_attribute_value = NULL;
1464 unsigned int ssrc;
1465
1466 /* We only care about ssrc attributes */
1467 if (pj_strcmp2(&attr->name, "ssrc")) {
1468 continue;
1469 }
1470
1471 ast_copy_pj_str(attr_value, &attr->value, sizeof(attr_value));
1472
1473 if ((ssrc_attribute_name = strchr(attr_value, ' '))) {
1474 /* This has an actual attribute */
1475 *ssrc_attribute_name++ = '\0';
1476 ssrc_attribute_value = strchr(ssrc_attribute_name, ':');
1477 if (ssrc_attribute_value) {
1478 /* Values are actually optional according to the spec */
1479 *ssrc_attribute_value++ = '\0';
1480 }
1481 }
1482
1483 if (sscanf(attr_value, "%30u", &ssrc) < 1) {
1484 continue;
1485 }
1486
1487 /* If we are currently negotiating as a result of the remote side renegotiating then
1488 * determine if the source for this stream has changed.
1489 */
1490 if (pjmedia_sdp_neg_get_state(session->inv_session->neg) == PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER &&
1491 session->active_media_state) {
1492 struct ast_rtp_instance_stats stats = { 0, };
1493
1495 stats.remote_ssrc != ssrc) {
1496 session_media->changed = 1;
1497 }
1498 }
1499
1500 ast_rtp_instance_set_remote_ssrc(session_media->rtp, ssrc);
1501 break;
1502 }
1503}
@ AST_RTP_INSTANCE_STAT_REMOTE_SSRC
Definition rtp_engine.h:251
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.
void ast_rtp_instance_set_remote_ssrc(struct ast_rtp_instance *rtp, unsigned int ssrc)
Set the remote SSRC for an RTP instance.
unsigned int remote_ssrc
Definition rtp_engine.h:454
unsigned int changed
The underlying session has been changed in some fashion.

References ast_copy_pj_str(), ast_rtp_instance_get_stats(), ast_rtp_instance_set_remote_ssrc(), AST_RTP_INSTANCE_STAT_REMOTE_SSRC, ast_sip_session_media::changed, NULL, ast_rtp_instance_stats::remote_ssrc, ast_sip_session_media::rtp, session, and ast_rtp_engine_ice::start.

Referenced by apply_negotiated_sdp_stream(), and negotiate_incoming_sdp_stream().

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

106{
107 struct ast_sip_session_media *session_media = (struct ast_sip_session_media *)data;
108 struct ast_rtp_instance *rtp = session_media->rtp;
109 struct ast_channel *chan;
110 int elapsed;
111 int now;
112 int timeout;
113
114 if (!rtp) {
115 return 0;
116 }
117
119 if (!chan) {
120 return 0;
121 }
122
123 /* Store these values locally to avoid multiple function calls */
124 now = time(NULL);
125 timeout = ast_rtp_instance_get_timeout(rtp);
126
127 /* If the channel is not in UP state or call is redirected
128 * outside Asterisk return for later check.
129 */
130 if (ast_channel_state(chan) != AST_STATE_UP || !ast_sockaddr_isnull(&session_media->direct_media_addr)) {
131 /* Avoiding immediately disconnect after channel up or direct media has been stopped */
133 ast_channel_unref(chan);
134 /* Recheck after half timeout for avoiding possible races
135 * and faster reacting to cases while there is no an RTP at all.
136 */
137 return timeout * 500;
138 }
139
140 elapsed = now - ast_rtp_instance_get_last_rx(rtp);
141 if (elapsed < timeout) {
142 ast_channel_unref(chan);
143 return (timeout - elapsed) * 1000;
144 }
145
146 ast_log(LOG_NOTICE, "Disconnecting channel '%s' for lack of %s RTP activity in %d seconds\n",
147 ast_channel_name(chan), ast_codec_media_type2str(session_media->type), elapsed);
148
149 ast_channel_lock(chan);
151 ast_channel_unlock(chan);
152
154 ast_channel_unref(chan);
155
156 return 0;
157}
#define AST_CAUSE_REQUESTED_CHAN_UNAVAIL
Definition causes.h:125
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_channel * ast_channel_get_by_name(const char *search)
Find a channel by name or uniqueid.
Definition channel.c:1417
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
Definition channel.c:2462
#define ast_channel_unref(c)
Decrease channel reference count.
Definition channel.h:3019
@ AST_SOFTHANGUP_DEV
Definition channel.h:1141
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
ast_channel_state
ast_channel states
@ AST_STATE_UP
#define LOG_NOTICE
time_t ast_rtp_instance_get_last_rx(const struct ast_rtp_instance *rtp)
Get the last RTP reception time.
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:599
Main Channel structure associated with a channel.

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_log, ast_rtp_instance_get_channel_id(), ast_rtp_instance_get_last_rx(), ast_rtp_instance_get_timeout(), ast_rtp_instance_set_last_rx(), ast_sockaddr_isnull(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_sip_session_media::direct_media_addr, LOG_NOTICE, NULL, ast_sip_session_media::rtp, and ast_sip_session_media::type.

Referenced by apply_negotiated_sdp_stream().

◆ send_keepalive()

static int send_keepalive ( const void *  data)
static

Definition at line 71 of file res_pjsip_sdp_rtp.c.

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;
78
79 if (!rtp) {
80 return 0;
81 }
82
84
85 if (!ast_sockaddr_isnull(&session_media->direct_media_addr)) {
86 ast_debug_rtp(3, "(%p) RTP not sending keepalive since direct media is in use\n", rtp);
87 return keepalive * 1000;
88 }
89
90 interval = time(NULL) - ast_rtp_instance_get_last_tx(rtp);
91 send_keepalive = interval >= keepalive;
92
93 ast_debug_rtp(3, "(%p) RTP it has been %d seconds since RTP was last sent. %sending keepalive\n",
94 rtp, (int) interval, send_keepalive ? "S" : "Not s");
95
96 if (send_keepalive) {
98 return keepalive * 1000;
99 }
100
101 return (keepalive - interval) * 1000;
102}
int ast_rtp_instance_get_keepalive(struct ast_rtp_instance *instance)
Get the RTP keepalive interval.
time_t ast_rtp_instance_get_last_tx(const struct ast_rtp_instance *rtp)
Get the last RTP transmission time.
int ast_rtp_instance_sendcng(struct ast_rtp_instance *instance, int level)
Send a comfort noise packet to the RTP instance.

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, ast_rtp_instance::keepalive, NULL, ast_sip_session_media::rtp, and send_keepalive().

Referenced by apply_negotiated_sdp_stream(), and send_keepalive().

◆ 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 673 of file res_pjsip_sdp_rtp.c.

678{
679 RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup);
680 RAII_VAR(struct ast_format_cap *, peer, NULL, ao2_cleanup);
681 RAII_VAR(struct ast_format_cap *, joint, NULL, ao2_cleanup);
682 enum ast_media_type media_type = session_media->type;
684 int direct_media_enabled = !ast_sockaddr_isnull(&session_media->direct_media_addr) &&
685 ast_format_cap_count(session->direct_media_cap);
686 int dsp_features = 0;
687 SCOPE_ENTER(1, "%s %s\n", ast_sip_session_get_name(session), is_offer ? "OFFER" : "ANSWER");
688
692 ast_log(LOG_ERROR, "Failed to allocate %s capabilities\n",
693 ast_codec_media_type2str(session_media->type));
694 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create %s capabilities\n",
695 ast_codec_media_type2str(session_media->type));
696 }
697
698 /* get the endpoint capabilities */
699 if (direct_media_enabled) {
700 ast_format_cap_get_compatible(session->endpoint->media.codecs, session->direct_media_cap, caps);
701 } else {
702 ast_format_cap_append_from_cap(caps, session->endpoint->media.codecs, media_type);
703 }
704
705 /* get the capabilities on the peer */
706 get_codecs(session, stream, &codecs, session_media, peer);
707
708 /* get the joint capabilities between peer and endpoint */
709 ast_format_cap_get_compatible(caps, peer, joint);
710 if (!ast_format_cap_count(joint)) {
713
715 ast_log(LOG_NOTICE, "No joint capabilities for '%s' media stream between our configuration(%s) and incoming SDP(%s)\n",
716 ast_codec_media_type2str(session_media->type),
717 ast_format_cap_get_names(caps, &usbuf),
718 ast_format_cap_get_names(peer, &thembuf));
719 SCOPE_EXIT_RTN_VALUE(-1, "No joint capabilities for '%s' media stream between our configuration(%s) and incoming SDP(%s)\n",
720 ast_codec_media_type2str(session_media->type),
721 ast_format_cap_get_names(caps, &usbuf),
722 ast_format_cap_get_names(peer, &thembuf));
723 } else {
724 struct ast_format *preferred_fmt = ast_format_cap_get_format(joint, 0);
725
727 ao2_ref(preferred_fmt, -1);
728 }
729
730 if (is_offer) {
731 /*
732 * Setup rx payload type mapping to prefer the mapping
733 * from the peer that the RFC says we SHOULD use.
734 */
736 }
737
738 if (session->channel) {
739 ast_channel_lock(session->channel);
740 }
741
743 session_media->rtp);
744
745 apply_cap_to_bundled(session_media, session_media_transport, asterisk_stream, joint);
746
747 if (session->channel && ast_sip_session_is_pending_stream_default(session, asterisk_stream)) {
751 ast_format_cap_remove_by_type(caps, media_type);
752
753 if (session->endpoint->preferred_codec_only) {
754 struct ast_format *preferred_fmt = ast_format_cap_get_format(joint, 0);
755 ast_format_cap_append(caps, preferred_fmt, 0);
756 ao2_ref(preferred_fmt, -1);
757 } else if (!session->endpoint->asymmetric_rtp_codec) {
758 struct ast_format *best;
759 /*
760 * If we don't allow the sending codec to be changed on our side
761 * then get the best codec from the joint capabilities of the media
762 * type and use only that. This ensures the core won't start sending
763 * out a format that we aren't currently sending.
764 */
765
766 best = ast_format_cap_get_best_by_type(joint, media_type);
767 if (best) {
769 ao2_ref(best, -1);
770 }
771 } else {
772 ast_format_cap_append_from_cap(caps, joint, media_type);
773 }
774
775 /*
776 * Apply the new formats to the channel, potentially changing
777 * raw read/write formats and translation path while doing so.
778 */
780 if (media_type == AST_MEDIA_TYPE_AUDIO) {
783 }
784
785 if ( ((session->dtmf == AST_SIP_DTMF_AUTO) || (session->dtmf == AST_SIP_DTMF_AUTO_INFO) )
787 && (session->dsp)) {
788 dsp_features = ast_dsp_get_features(session->dsp);
789 dsp_features &= ~DSP_FEATURE_DIGIT_DETECT;
790 if (dsp_features) {
791 ast_dsp_set_features(session->dsp, dsp_features);
792 } else {
793 ast_dsp_free(session->dsp);
794 session->dsp = NULL;
795 }
796 }
797
798 if (ast_channel_is_bridged(session->channel)) {
800 }
801 }
802
803 if (session->channel) {
804 ast_channel_unlock(session->channel);
805 }
806
809}
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.
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition channel.c:5785
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition channel.c:10725
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition channel.c:5826
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
void ast_dsp_free(struct ast_dsp *dsp)
Definition dsp.c:1968
int ast_dsp_get_features(struct ast_dsp *dsp)
Get features.
Definition dsp.c:1962
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition dsp.c:1953
#define AST_FORMAT_CAP_NAMES_LEN
Definition format_cap.h:324
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:425
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:742
static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp_media *stream, struct ast_rtp_codecs *codecs, struct ast_sip_session_media *session_media, struct ast_format_cap *astformats)
void ast_rtp_codecs_payloads_destroy(struct ast_rtp_codecs *codecs)
Destroy the contents of an RTP codecs structure (but not the structure 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.
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.
#define AST_RTP_CODECS_NULL_INIT
Definition rtp_engine.h:773
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.
int ast_rtp_codecs_set_preferred_format(struct ast_rtp_codecs *codecs, struct ast_format *format)
Set the preferred format.

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_payloads_copy(), ast_rtp_codecs_payloads_destroy(), ast_rtp_codecs_payloads_xover(), ast_rtp_codecs_set_preferred_format(), 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, codecs, ast_sip_session_media::direct_media_addr, get_codecs(), LOG_ERROR, LOG_NOTICE, NULL, RAII_VAR, ast_sip_session_media::rtp, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, session, and ast_sip_session_media::type.

Referenced by apply_negotiated_sdp_stream().

◆ set_ice_components()

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

Definition at line 1414 of file res_pjsip_sdp_rtp.c.

1415{
1416 struct ast_rtp_engine_ice *ice;
1417
1418 ast_assert(session_media->rtp != NULL);
1419
1421 if (!session->endpoint->media.rtp.ice_support || !ice) {
1422 return;
1423 }
1424
1425 if (session->endpoint->media.rtcp_mux && session_media->remote_rtcp_mux) {
1426 /* We both support RTCP mux. Only one ICE component necessary */
1427 ice->change_components(session_media->rtp, 1);
1428 } else {
1429 /* They either don't support RTCP mux or we don't know if they do yet. */
1430 ice->change_components(session_media->rtp, 2);
1431 }
1432}
void(* change_components)(struct ast_rtp_instance *instance, int num_components)
Definition rtp_engine.h:560
#define ast_assert(a)
Definition utils.h:779

References ast_assert, ast_rtp_instance_get_ice(), ast_rtp_engine_ice::change_components, NULL, session, and ast_rtp_engine_ice::start.

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

◆ 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 619 of file res_pjsip_sdp_rtp.c.

622{
623 struct ast_format_cap *incoming_call_offer_cap;
624 struct ast_format_cap *remote;
627
628
630 if (!remote) {
631 ast_log(LOG_ERROR, "Failed to allocate %s incoming remote capabilities\n",
632 ast_codec_media_type2str(session_media->type));
633 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't allocate caps\n");
634 }
635
636 /* Get the peer's capabilities*/
637 get_codecs(session, stream, &codecs, session_media, remote);
638
639 incoming_call_offer_cap = ast_sip_session_create_joint_call_cap(
640 session, session_media->type, remote);
641
642 ao2_ref(remote, -1);
643
644 if (!incoming_call_offer_cap || ast_format_cap_empty(incoming_call_offer_cap)) {
645 ao2_cleanup(incoming_call_offer_cap);
647 SCOPE_EXIT_RTN_VALUE(NULL, "No incoming call offer caps\n");
648 }
649
650 /*
651 * Setup rx payload type mapping to prefer the mapping
652 * from the peer that the RFC says we SHOULD use.
653 */
655
656 /*
657 * This only merges the newly offered payloads into the live RTP instance
658 * rather than doing a destructive replace, so any format the channel is
659 * still actively sending in (e.g. while a reINVITE is in flight) remains
660 * usable right up until set_caps() commits the channel to the new
661 * negotiated format. A destructive replace here, before the channel's
662 * own read/write format has caught up, is what let a concurrent bridge
663 * write briefly land on a payload mapping that no longer had its format.
664 */
666 ast_rtp_instance_get_codecs(session_media->rtp), session_media->rtp);
667
669
670 SCOPE_EXIT_RTN_VALUE(incoming_call_offer_cap);
671}
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:752
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.
void ast_rtp_codecs_payloads_merge(struct ast_rtp_codecs *src, struct ast_rtp_codecs *dest, struct ast_rtp_instance *instance)
Merge payload information from one RTP instance into another.

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_payloads_destroy(), ast_rtp_codecs_payloads_merge(), ast_rtp_codecs_payloads_xover(), ast_rtp_instance_get_codecs(), ast_sip_session_create_joint_call_cap(), ast_sip_session_get_name(), codecs, get_codecs(), LOG_ERROR, NULL, ast_sip_session_media::rtp, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, session, and ast_sip_session_media::type.

Referenced by negotiate_incoming_sdp_stream().

◆ set_session_media_remotely_held()

static void set_session_media_remotely_held ( struct ast_sip_session_media *  session_media,
const struct ast_sip_session *  session,
const pjmedia_sdp_media *  media,
const struct ast_stream *  stream,
const struct ast_sockaddr *  addrs 
)
static

Definition at line 1694 of file res_pjsip_sdp_rtp.c.

1699{
1701 (session_media->type == AST_MEDIA_TYPE_AUDIO)) {
1702 if (((addrs != NULL) && ast_sockaddr_isnull(addrs)) ||
1703 ((addrs != NULL) && ast_sockaddr_is_any(addrs)) ||
1704 pjmedia_sdp_media_find_attr2(media, "sendonly", NULL) ||
1705 pjmedia_sdp_media_find_attr2(media, "inactive", NULL)) {
1706 if (!session_media->remotely_held) {
1707 session_media->remotely_held = 1;
1708 session_media->remotely_held_changed = 1;
1709 }
1710 } else if (session_media->remotely_held) {
1711 session_media->remotely_held = 0;
1712 session_media->remotely_held_changed = 1;
1713 }
1714 }
1715}
int ast_sockaddr_is_any(const struct ast_sockaddr *addr)
Determine if the address type is unspecified, or "any" address.
Definition netsock2.c:534

References AST_MEDIA_TYPE_AUDIO, ast_sip_session_is_pending_stream_default(), ast_sockaddr_is_any(), ast_sockaddr_isnull(), NULL, ast_sip_session_media::remotely_held, ast_sip_session_media::remotely_held_changed, session, and ast_sip_session_media::type.

Referenced by apply_negotiated_sdp_stream(), and negotiate_incoming_sdp_stream().

◆ setup_dtls_srtp()

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

Definition at line 1256 of file res_pjsip_sdp_rtp.c.

1258{
1259 struct ast_rtp_engine_dtls *dtls;
1260
1261 if (!session->endpoint->media.rtp.dtls_cfg.enabled || !session_media->rtp) {
1262 return -1;
1263 }
1264
1265 dtls = ast_rtp_instance_get_dtls(session_media->rtp);
1266 if (!dtls) {
1267 return -1;
1268 }
1269
1270 session->endpoint->media.rtp.dtls_cfg.suite = ((session->endpoint->media.rtp.srtp_tag_32) ? AST_AES_CM_128_HMAC_SHA1_32 : AST_AES_CM_128_HMAC_SHA1_80);
1271 if (dtls->set_configuration(session_media->rtp, &session->endpoint->media.rtp.dtls_cfg)) {
1272 ast_log(LOG_ERROR, "Attempted to set an invalid DTLS-SRTP configuration on RTP instance '%p'\n",
1273 session_media->rtp);
1274 return -1;
1275 }
1276
1277 if (setup_srtp(session_media)) {
1278 return -1;
1279 }
1280 return 0;
1281}
static int setup_srtp(struct ast_sip_session_media *session_media)
@ AST_AES_CM_128_HMAC_SHA1_80
Definition res_srtp.h:58
@ AST_AES_CM_128_HMAC_SHA1_32
Definition res_srtp.h:59
int(* set_configuration)(struct ast_rtp_instance *instance, const struct ast_rtp_dtls_cfg *dtls_cfg)
Definition rtp_engine.h:623

References AST_AES_CM_128_HMAC_SHA1_32, AST_AES_CM_128_HMAC_SHA1_80, ast_log, ast_rtp_instance_get_dtls(), LOG_ERROR, ast_sip_session_media::rtp, session, ast_rtp_engine_dtls::set_configuration, and setup_srtp().

Referenced by add_crypto_to_stream(), and setup_media_encryption().

◆ 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 1387 of file res_pjsip_sdp_rtp.c.

1391{
1392 switch (session_media->encryption) {
1394 if (setup_sdes_srtp(session_media, stream)) {
1395 return -1;
1396 }
1397 break;
1399 if (setup_dtls_srtp(session, session_media)) {
1400 return -1;
1401 }
1402 if (parse_dtls_attrib(session_media, sdp, stream)) {
1403 return -1;
1404 }
1405 break;
1408 break;
1409 }
1410
1411 return 0;
1412}
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)

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(), session, setup_dtls_srtp(), and setup_sdes_srtp().

Referenced by apply_negotiated_sdp_stream(), and negotiate_incoming_sdp_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 1351 of file res_pjsip_sdp_rtp.c.

1353{
1354 int i;
1355
1356 for (i = 0; i < stream->attr_count; i++) {
1357 pjmedia_sdp_attr *attr;
1358 RAII_VAR(char *, crypto_str, NULL, ast_free);
1359
1360 /* check the stream for the required crypto attribute */
1361 attr = stream->attr[i];
1362 if (pj_strcmp2(&attr->name, "crypto")) {
1363 continue;
1364 }
1365
1366 crypto_str = ast_strndup(attr->value.ptr, attr->value.slen);
1367 if (!crypto_str) {
1368 return -1;
1369 }
1370
1371 if (setup_srtp(session_media)) {
1372 return -1;
1373 }
1374
1375 if (!ast_sdp_crypto_process(session_media->rtp, session_media->srtp, crypto_str)) {
1376 /* found a valid crypto attribute */
1377 return 0;
1378 }
1379
1380 ast_debug(1, "Ignoring crypto offer with unsupported parameters: %s\n", crypto_str);
1381 }
1382
1383 /* no usable crypto attributes found */
1384 return -1;
1385}
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

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

Referenced by setup_media_encryption().

◆ setup_srtp()

static int setup_srtp ( struct ast_sip_session_media *  session_media)
static

Definition at line 1237 of file res_pjsip_sdp_rtp.c.

1238{
1239 if (!session_media->srtp) {
1240 session_media->srtp = ast_sdp_srtp_alloc();
1241 if (!session_media->srtp) {
1242 return -1;
1243 }
1244 }
1245
1246 if (!session_media->srtp->crypto) {
1247 session_media->srtp->crypto = ast_sdp_crypto_alloc();
1248 if (!session_media->srtp->crypto) {
1249 return -1;
1250 }
1251 }
1252
1253 return 0;
1254}
struct ast_sdp_crypto * ast_sdp_crypto_alloc(void)
Initialize an return an ast_sdp_crypto struct.
Definition sdp_srtp.c:71
struct ast_sdp_crypto * crypto
Definition sdp_srtp.h:40

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().

◆ 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 2610 of file res_pjsip_sdp_rtp.c.

2611{
2612 if (session_media->rtp) {
2613 stream_stop(session_media);
2614 ast_rtp_instance_destroy(session_media->rtp);
2615 }
2616 session_media->rtp = NULL;
2617}
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:468

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

◆ stream_stop()

static void stream_stop ( struct ast_sip_session_media *  session_media)
static

Function which stops the RTP instance.

Definition at line 2598 of file res_pjsip_sdp_rtp.c.

2599{
2600 if (!session_media->rtp) {
2601 return;
2602 }
2603
2604 AST_SCHED_DEL(sched, session_media->keepalive_sched_id);
2605 AST_SCHED_DEL(sched, session_media->timeout_sched_id);
2606 ast_rtp_instance_stop(session_media->rtp);
2607}

References ast_rtp_instance_stop(), AST_SCHED_DEL, ast_sip_session_media::keepalive_sched_id, ast_sip_session_media::rtp, and ast_sip_session_media::timeout_sched_id.

Referenced by stream_destroy().

◆ unload_module()

static int unload_module ( void  )
static

Unloads the sdp RTP/AVP module from Asterisk.

Definition at line 2669 of file res_pjsip_sdp_rtp.c.

2670{
2674
2675 if (sched) {
2677 }
2678
2679 return 0;
2680}
void ast_sip_session_unregister_sdp_handler(struct ast_sip_session_sdp_handler *handler, const char *stream_type)
Unregister an SDP handler.
void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement)
Unregister a an supplement to SIP session processing.
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
Definition sched.c:271

References ast_sched_context_destroy(), ast_sip_session_unregister_sdp_handler(), ast_sip_session_unregister_supplement(), audio_sdp_handler, STR_AUDIO, STR_VIDEO, video_info_supplement, and video_sdp_handler.

Referenced by load_module().

◆ video_info_incoming_request()

static int video_info_incoming_request ( struct ast_sip_session *  session,
struct pjsip_rx_data *  rdata 
)
static

Definition at line 2641 of file res_pjsip_sdp_rtp.c.

2642{
2643 struct pjsip_transaction *tsx;
2644 pjsip_tx_data *tdata;
2645
2646 if (!session->channel
2647 || !ast_sip_are_media_types_equal(&rdata->msg_info.msg->body->content_type,
2649 return 0;
2650 }
2651
2652 tsx = pjsip_rdata_get_tsx(rdata);
2653
2655
2656 if (pjsip_dlg_create_response(session->inv_session->dlg, rdata, 200, NULL, &tdata) == PJ_SUCCESS) {
2657 pjsip_dlg_send_response(session->inv_session->dlg, tsx, tdata);
2658 }
2659
2660 return 0;
2661}
@ AST_CONTROL_VIDUPDATE
pjsip_media_type pjsip_media_type_application_media_control_xml
Definition res_pjsip.c:3950
int ast_sip_are_media_types_equal(pjsip_media_type *a, pjsip_media_type *b)
Compare pjsip media types.
Definition res_pjsip.c:2239

References AST_CONTROL_VIDUPDATE, ast_queue_control(), ast_sip_are_media_types_equal(), NULL, pjsip_media_type_application_media_control_xml, and session.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP SDP RTP/AVP stream handler" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .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

Definition at line 2735 of file res_pjsip_sdp_rtp.c.

◆ address_rtp

struct ast_sockaddr address_rtp
static

Address for RTP.

Definition at line 66 of file res_pjsip_sdp_rtp.c.

Referenced by create_rtp(), and load_module().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 2735 of file res_pjsip_sdp_rtp.c.

◆ audio_sdp_handler

struct ast_sip_session_sdp_handler audio_sdp_handler
static

SDP handler for 'audio' media stream.

Definition at line 2620 of file res_pjsip_sdp_rtp.c.

2620 {
2621 .id = STR_AUDIO,
2622 .negotiate_incoming_sdp_stream = negotiate_incoming_sdp_stream,
2623 .create_outgoing_sdp_stream = create_outgoing_sdp_stream,
2624 .apply_negotiated_sdp_stream = apply_negotiated_sdp_stream,
2625 .change_outgoing_sdp_stream_media_address = change_outgoing_sdp_stream_media_address,
2626 .stream_stop = stream_stop,
2627 .stream_destroy = stream_destroy,
2628};
static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const pjmedia_sdp_session *sdp, int index, struct ast_stream *asterisk_stream)
Function which negotiates an incoming media stream.
static int apply_negotiated_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_session *remote, int index, struct ast_stream *asterisk_stream)
static void stream_destroy(struct ast_sip_session_media *session_media)
Function which destroys the RTP instance when session ends.
static void change_outgoing_sdp_stream_media_address(pjsip_tx_data *tdata, struct pjmedia_sdp_media *stream, struct ast_sip_transport *transport)
Function which updates the media stream with external media address, if applicable.
static 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.

Referenced by load_module(), and unload_module().

◆ sched

struct ast_sched_context* sched
static

Scheduler for RTCP purposes.

Definition at line 63 of file res_pjsip_sdp_rtp.c.

◆ STR_AUDIO

const char STR_AUDIO[] = "audio"
static

Definition at line 68 of file res_pjsip_sdp_rtp.c.

Referenced by load_module(), and unload_module().

◆ STR_VIDEO

const char STR_VIDEO[] = "video"
static

Definition at line 69 of file res_pjsip_sdp_rtp.c.

Referenced by load_module(), and unload_module().

◆ video_info_supplement

struct ast_sip_session_supplement video_info_supplement
static
Initial value:
= {
.method = "INFO",
.incoming_request = video_info_incoming_request,
}
static int video_info_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)

Definition at line 2663 of file res_pjsip_sdp_rtp.c.

2663 {
2664 .method = "INFO",
2665 .incoming_request = video_info_incoming_request,
2666};

Referenced by load_module(), and unload_module().

◆ video_sdp_handler

struct ast_sip_session_sdp_handler video_sdp_handler
static

SDP handler for 'video' media stream.

Definition at line 2631 of file res_pjsip_sdp_rtp.c.

2631 {
2632 .id = STR_VIDEO,
2633 .negotiate_incoming_sdp_stream = negotiate_incoming_sdp_stream,
2634 .create_outgoing_sdp_stream = create_outgoing_sdp_stream,
2635 .apply_negotiated_sdp_stream = apply_negotiated_sdp_stream,
2636 .change_outgoing_sdp_stream_media_address = change_outgoing_sdp_stream_media_address,
2637 .stream_stop = stream_stop,
2638 .stream_destroy = stream_destroy,
2639};

Referenced by load_module(), and unload_module().