@ -317,6 +317,7 @@ static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp
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 )
{
@ -376,6 +377,24 @@ static int set_caps(struct ast_sip_session *session,
ast_stream_set_formats ( asterisk_stream , joint ) ;
/* If this is a bundled stream then apply the payloads to RTP instance acting as transport to prevent conflicts */
if ( session_media_transport ! = session_media & & session_media - > bundled ) {
int index ;
for ( index = 0 ; index < ast_format_cap_count ( joint ) ; + + index ) {
struct ast_format * format = ast_format_cap_get_format ( joint , index ) ;
int rtp_code ;
/* Ensure this payload is in the bundle group transport codecs, this purposely doesn't check the return value for
* things as the format is guaranteed to have a payload already .
*/
rtp_code = ast_rtp_codecs_payload_code ( ast_rtp_instance_get_codecs ( session_media - > rtp ) , 1 , format , 0 ) ;
ast_rtp_codecs_payload_set_rx ( ast_rtp_instance_get_codecs ( session_media_transport - > rtp ) , rtp_code , format ) ;
ao2_ref ( format , - 1 ) ;
}
}
if ( session - > channel & & ast_sip_session_is_pending_stream_default ( session , asterisk_stream ) ) {
ast_channel_lock ( session - > channel ) ;
ast_format_cap_remove_by_type ( caps , AST_MEDIA_TYPE_UNKNOWN ) ;
@ -496,7 +515,8 @@ static pjmedia_sdp_attr* generate_fmtp_attr(pj_pool_t *pool, struct ast_format *
}
/*! \brief Function which adds ICE attributes to a media 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 )
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 )
{
struct ast_rtp_engine_ice * ice ;
struct ao2_container * candidates ;
@ -506,8 +526,7 @@ static void add_ice_to_stream(struct ast_sip_session *session, struct ast_sip_se
struct ao2_iterator it_candidates ;
struct ast_rtp_engine_ice_candidate * candidate ;
if ( ! session - > endpoint - > media . rtp . ice_support | | ! ( ice = ast_rtp_instance_get_ice ( session_media - > rtp ) ) | |
! ( candidates = ice - > get_local_candidates ( session_media - > rtp ) ) ) {
if ( ! session - > endpoint - > media . rtp . ice_support | | ! ( ice = ast_rtp_instance_get_ice ( session_media - > rtp ) ) ) {
return ;
}
@ -521,6 +540,15 @@ static void add_ice_to_stream(struct ast_sip_session *session, struct ast_sip_se
media - > attr [ media - > attr_count + + ] = attr ;
}
if ( ! include_candidates ) {
return ;
}
candidates = ice - > get_local_candidates ( session_media - > rtp ) ;
if ( ! candidates ) {
return ;
}
it_candidates = ao2_iterator_init ( candidates , 0 ) ;
for ( ; ( candidate = ao2_iterator_next ( & it_candidates ) ) ; ao2_ref ( candidate , - 1 ) ) {
struct ast_str * attr_candidate = ast_str_create ( 128 ) ;
@ -940,6 +968,63 @@ static void set_ice_components(struct ast_sip_session *session, struct ast_sip_s
}
}
/*! \brief Function which adds ssrc attributes to a media 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 )
{
pj_str_t stmp ;
pjmedia_sdp_attr * attr ;
char tmp [ 128 ] ;
if ( ! session - > endpoint - > media . bundle | | session_media - > bundle_group = = - 1 ) {
return ;
}
snprintf ( tmp , sizeof ( tmp ) , " %u cname:%s " , ast_rtp_instance_get_ssrc ( session_media - > rtp ) , ast_rtp_instance_get_cname ( session_media - > rtp ) ) ;
attr = pjmedia_sdp_attr_create ( pool , " ssrc " , pj_cstr ( & stmp , tmp ) ) ;
media - > attr [ media - > attr_count + + ] = attr ;
}
/*! \brief Function which processes ssrc attributes in a 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 )
{
int index ;
if ( ! session - > endpoint - > media . bundle ) {
return ;
}
for ( index = 0 ; index < remote_stream - > attr_count ; + + index ) {
pjmedia_sdp_attr * attr = remote_stream - > attr [ index ] ;
char attr_value [ pj_strlen ( & attr - > value ) + 1 ] ;
char * ssrc_attribute_name , * ssrc_attribute_value = NULL ;
unsigned int ssrc ;
/* We only care about ssrc attributes */
if ( pj_strcmp2 ( & attr - > name , " ssrc " ) ) {
continue ;
}
ast_copy_pj_str ( attr_value , & attr - > value , sizeof ( attr_value ) ) ;
if ( ( ssrc_attribute_name = strchr ( attr_value , ' ' ) ) ) {
/* This has an actual attribute */
* ssrc_attribute_name + + = ' \0 ' ;
ssrc_attribute_value = strchr ( ssrc_attribute_name , ' : ' ) ;
if ( ssrc_attribute_value ) {
/* Values are actually optional according to the spec */
* ssrc_attribute_value + + = ' \0 ' ;
}
}
if ( sscanf ( attr_value , " %30u " , & ssrc ) < 1 ) {
continue ;
}
ast_rtp_instance_set_remote_ssrc ( session_media - > rtp , ssrc ) ;
}
}
/*! \brief Function which negotiates an incoming media stream */
static int negotiate_incoming_sdp_stream ( struct ast_sip_session * session ,
struct ast_sip_session_media * session_media , const pjmedia_sdp_session * sdp ,
@ -948,6 +1033,7 @@ static int negotiate_incoming_sdp_stream(struct ast_sip_session *session,
char host [ NI_MAXHOST ] ;
RAII_VAR ( struct ast_sockaddr * , addrs , NULL , ast_free ) ;
pjmedia_sdp_media * stream = sdp - > media [ index ] ;
struct ast_sip_session_media * session_media_transport ;
enum ast_media_type media_type = session_media - > type ;
enum ast_sip_session_media_encryption encryption = AST_SIP_MEDIA_ENCRYPT_NONE ;
int res ;
@ -981,38 +1067,51 @@ static int negotiate_incoming_sdp_stream(struct ast_sip_session *session,
return - 1 ;
}
session_media - > remote_rtcp_mux = ( pjmedia_sdp_media_find_attr2 ( stream , " rtcp-mux " , NULL ) ! = NULL ) ;
set_ice_components ( session , session_media ) ;
process_ssrc_attributes ( session , session_media , stream ) ;
enable_rtcp ( session , session_media , stream ) ;
session_media_transport = ast_sip_session_media_get_transport ( session , session_media ) ;
res = setup_media_encryption ( session , session_media , sdp , stream ) ;
if ( res ) {
if ( ! session - > endpoint - > media . rtp . encryption_optimistic | |
! pj_strncmp2 ( & stream - > desc . transport , " RTP/SAVP " , 8 ) ) {
/* If optimistic encryption is disabled and crypto should have been enabled
* but was not this session must fail . This must also fail if crypto was
* required in the offer but could not be set up .
*/
return - 1 ;
if ( session_media_transport = = session_media | | ! session_media - > bundled ) {
/* If this media session is carrying actual traffic then set up those aspects */
session_media - > remote_rtcp_mux = ( pjmedia_sdp_media_find_attr2 ( stream , " rtcp-mux " , NULL ) ! = NULL ) ;
set_ice_components ( session , session_media ) ;
enable_rtcp ( session , session_media , stream ) ;
res = setup_media_encryption ( session , session_media , sdp , stream ) ;
if ( res ) {
if ( ! session - > endpoint - > media . rtp . encryption_optimistic | |
! pj_strncmp2 ( & stream - > desc . transport , " RTP/SAVP " , 8 ) ) {
/* If optimistic encryption is disabled and crypto should have been enabled
* but was not this session must fail . This must also fail if crypto was
* required in the offer but could not be set up .
*/
return - 1 ;
}
/* There is no encryption, sad. */
session_media - > encryption = AST_SIP_MEDIA_ENCRYPT_NONE ;
}
/* There is no encryption, sad. */
session_media - > encryption = AST_SIP_MEDIA_ENCRYPT_NONE ;
}
/* If we've been explicitly configured to use the received transport OR if
* encryption is on and crypto is present use the received transport .
* This is done in case of optimistic because it may come in as RTP / AVP or RTP / SAVP depending
* on the configuration of the remote endpoint ( optimistic themselves or mandatory ) .
*/
if ( ( session - > endpoint - > media . rtp . use_received_transport ) | |
( ( encryption = = AST_SIP_MEDIA_ENCRYPT_SDES ) & & ! res ) ) {
pj_strdup ( session - > inv_session - > pool , & session_media - > transport , & stream - > desc . transport ) ;
}
/* If we've been explicitly configured to use the received transport OR if
* encryption is on and crypto is present use the received transport .
* This is done in case of optimistic because it may come in as RTP / AVP or RTP / SAVP depending
* on the configuration of the remote endpoint ( optimistic themselves or mandatory ) .
*/
if ( ( session - > endpoint - > media . rtp . use_received_transport ) | |
( ( encryption = = AST_SIP_MEDIA_ENCRYPT_SDES ) & & ! res ) ) {
pj_strdup ( session - > inv_session - > pool , & session_media - > transport , & stream - > desc . transport ) ;
}
} else {
/* This is bundled with another session, so mark it as such */
ast_rtp_instance_bundle ( session_media - > rtp , session_media_transport - > rtp ) ;
if ( set_caps ( session , session_media , stream , 1 , asterisk_stream ) ) {
enable_rtcp ( session , session_media , stream ) ;
}
if ( set_caps ( session , session_media , session_media_transport , stream , 1 , asterisk_stream ) ) {
return 0 ;
}
return 1 ;
}
@ -1032,6 +1131,7 @@ static int add_crypto_to_stream(struct ast_sip_session *session,
static const pj_str_t STR_PASSIVE = { " passive " , 7 } ;
static const pj_str_t STR_ACTPASS = { " actpass " , 7 } ;
static const pj_str_t STR_HOLDCONN = { " holdconn " , 8 } ;
enum ast_rtp_dtls_setup setup ;
switch ( session_media - > encryption ) {
case AST_SIP_MEDIA_ENCRYPT_NONE :
@ -1085,7 +1185,16 @@ static int add_crypto_to_stream(struct ast_sip_session *session,
break ;
}
switch ( dtls - > get_setup ( session_media - > rtp ) ) {
/* If this is an answer we need to use our current state, if it's an offer we need to use
* the configured value .
*/
if ( pjmedia_sdp_neg_get_state ( session - > inv_session - > neg ) ! = PJMEDIA_SDP_NEG_STATE_DONE ) {
setup = dtls - > get_setup ( session_media - > rtp ) ;
} else {
setup = session - > endpoint - > media . rtp . dtls_cfg . default_setup ;
}
switch ( setup ) {
case AST_RTP_DTLS_SETUP_ACTIVE :
attr = pjmedia_sdp_attr_create ( pool , " setup " , & STR_ACTIVE ) ;
media - > attr [ media - > attr_count + + ] = attr ;
@ -1100,7 +1209,6 @@ static int add_crypto_to_stream(struct ast_sip_session *session,
break ;
case AST_RTP_DTLS_SETUP_HOLDCONN :
attr = pjmedia_sdp_attr_create ( pool , " setup " , & STR_HOLDCONN ) ;
media - > attr [ media - > attr_count + + ] = attr ;
break ;
default :
break ;
@ -1152,6 +1260,7 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as
int rtp_code ;
RAII_VAR ( struct ast_format_cap * , caps , NULL , ao2_cleanup ) ;
enum ast_media_type media_type = session_media - > type ;
struct ast_sip_session_media * session_media_transport ;
int direct_media_enabled = ! ast_sockaddr_isnull ( & session_media - > direct_media_addr ) & &
ast_format_cap_count ( session - > direct_media_cap ) ;
@ -1195,68 +1304,106 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as
return - 1 ;
}
set_ice_components ( session , session_media ) ;
enable_rtcp ( session , session_media , NULL ) ;
/* If this stream has not been bundled already it is new and we need to ensure there is no SSRC conflict */
if ( session_media - > bundle_group ! = - 1 & & ! session_media - > bundled ) {
for ( index = 0 ; index < sdp - > media_count ; + + index ) {
struct ast_sip_session_media * other_session_media ;
/* Crypto has to be added before setting the media transport so that SRTP is properly
* set up according to the configuration . This ends up changing the media transport .
*/
if ( add_crypto_to_stream ( session , session_media , pool , media ) ) {
return - 1 ;
}
other_session_media = AST_VECTOR_GET ( & session - > pending_media_state - > sessions , index ) ;
if ( ! other_session_media - > rtp | | other_session_media - > bundle_group ! = session_media - > bundle_group ) {
continue ;
}
if ( pj_strlen ( & session_media - > transport ) ) {
/* If a transport has already been specified use it */
media - > desc . transport = session_media - > transport ;
} else {
media - > desc . transport = pj_str ( ast_sdp_get_rtp_profile (
/* Optimistic encryption places crypto in the normal RTP/AVP profile */
! session - > endpoint - > media . rtp . encryption_optimistic & &
( session_media - > encryption = = AST_SIP_MEDIA_ENCRYPT_SDES ) ,
session_media - > rtp , session - > endpoint - > media . rtp . use_avpf ,
session - > endpoint - > media . rtp . force_avp ) ) ;
if ( ast_rtp_instance_get_ssrc ( session_media - > rtp ) = = ast_rtp_instance_get_ssrc ( other_session_media - > rtp ) ) {
ast_rtp_instance_change_source ( session_media - > rtp ) ;
/* Start the conflict check over again */
index = - 1 ;
continue ;
}
}
}
media - > conn = pj_pool_zalloc ( pool , sizeof ( struct pjmedia_sdp_conn ) ) ;
if ( ! media - > conn ) {
return - 1 ;
}
session_media_transport = ast_sip_session_media_get_transport ( session , session_media ) ;
/* Add connection level details */
if ( direct_media_enabled ) {
hostip = ast_sockaddr_stringify_fmt ( & session_media - > direct_media_addr , AST_SOCKADDR_STR_ADDR ) ;
} else if ( ast_strlen_zero ( session - > endpoint - > media . address ) ) {
hostip = ast_sip_get_host_ip_string ( session - > endpoint - > media . rtp . ipv6 ? pj_AF_INET6 ( ) : pj_AF_INET ( ) ) ;
} else {
hostip = session - > endpoint - > media . address ;
}
if ( session_media_transport = = session_media | | ! session_media - > bundled ) {
set_ice_components ( session , session_media ) ;
enable_rtcp ( session , session_media , NULL ) ;
if ( ast_strlen_zero ( hostip ) ) {
ast_log ( LOG_ERROR , " No local host IP available for stream %s \n " ,
ast_codec_media_type2str ( session_media - > type ) ) ;
return - 1 ;
}
/* Crypto has to be added before setting the media transport so that SRTP is properly
* set up according to the configuration . This ends up changing the media transport .
*/
if ( add_crypto_to_stream ( session , session_media , pool , media ) ) {
return - 1 ;
}
media - > conn - > net_type = STR_IN ;
/* Assume that the connection will use IPv4 until proven otherwise */
media - > conn - > addr_type = STR_IP4 ;
pj_strdup2 ( pool , & media - > conn - > addr , hostip ) ;
if ( pj_strlen ( & session_media - > transport ) ) {
/* If a transport has already been specified use it */
media - > desc . transport = session_media - > transport ;
} else {
media - > desc . transport = pj_str ( ast_sdp_get_rtp_profile (
/* Optimistic encryption places crypto in the normal RTP/AVP profile */
! session - > endpoint - > media . rtp . encryption_optimistic & &
( session_media - > encryption = = AST_SIP_MEDIA_ENCRYPT_SDES ) ,
session_media - > rtp , session - > endpoint - > media . rtp . use_avpf ,
session - > endpoint - > media . rtp . force_avp ) ) ;
}
if ( ! ast_strlen_zero ( session - > endpoint - > media . address ) ) {
pj_sockaddr ip ;
media - > conn = pj_pool_zalloc ( pool , sizeof ( struct pjmedia_sdp_conn ) ) ;
if ( ! media - > conn ) {
return - 1 ;
}
if ( ( pj_sockaddr_parse ( pj_AF_UNSPEC ( ) , 0 , & media - > conn - > addr , & ip ) = = PJ_SUCCESS ) & &
( ip . addr . sa_family = = pj_AF_INET6 ( ) ) ) {
media - > conn - > addr_type = STR_IP6 ;
/* Add connection level details */
if ( direct_media_enabled ) {
hostip = ast_sockaddr_stringify_fmt ( & session_media - > direct_media_addr , AST_SOCKADDR_STR_ADDR ) ;
} else if ( ast_strlen_zero ( session - > endpoint - > media . address ) ) {
hostip = ast_sip_get_host_ip_string ( session - > endpoint - > media . rtp . ipv6 ? pj_AF_INET6 ( ) : pj_AF_INET ( ) ) ;
} else {
hostip = session - > endpoint - > media . address ;
}
}
/* Add ICE attributes and candidates */
add_ice_to_stream ( session , session_media , pool , media ) ;
if ( ast_strlen_zero ( hostip ) ) {
ast_log ( LOG_ERROR , " No local host IP available for stream %s \n " ,
ast_codec_media_type2str ( session_media - > type ) ) ;
return - 1 ;
}
media - > conn - > net_type = STR_IN ;
/* Assume that the connection will use IPv4 until proven otherwise */
media - > conn - > addr_type = STR_IP4 ;
pj_strdup2 ( pool , & media - > conn - > addr , hostip ) ;
if ( ! ast_strlen_zero ( session - > endpoint - > media . address ) ) {
pj_sockaddr ip ;
if ( ( pj_sockaddr_parse ( pj_AF_UNSPEC ( ) , 0 , & media - > conn - > addr , & ip ) = = PJ_SUCCESS ) & &
( ip . addr . sa_family = = pj_AF_INET6 ( ) ) ) {
media - > conn - > addr_type = STR_IP6 ;
}
}
/* Add ICE attributes and candidates */
add_ice_to_stream ( session , session_media , pool , media , 1 ) ;
ast_rtp_instance_get_local_address ( session_media - > rtp , & addr ) ;
media - > desc . port = direct_media_enabled ? ast_sockaddr_port ( & session_media - > direct_media_addr ) : ( pj_uint16_t ) ast_sockaddr_port ( & addr ) ;
media - > desc . port_count = 1 ;
} else {
pjmedia_sdp_media * bundle_group_stream = sdp - > media [ session_media_transport - > stream_num ] ;
/* As this is in a bundle group it shares the same details as the group instance */
media - > desc . transport = bundle_group_stream - > desc . transport ;
media - > conn = bundle_group_stream - > conn ;
media - > desc . port = bundle_group_stream - > desc . port ;
if ( add_crypto_to_stream ( session , session_media_transport , pool , media ) ) {
return - 1 ;
}
ast_rtp_instance_get_local_address ( session_media - > rtp , & addr ) ;
media - > desc . port = direct_media_enabled ? ast_sockaddr_port ( & session_media - > direct_media_addr ) : ( pj_uint16_t ) ast_sockaddr_port ( & addr ) ;
media - > desc . port_count = 1 ;
add_ice_to_stream ( session , session_media_transport , pool , media , 0 ) ;
enable_rtcp ( session , session_media , NULL ) ;
}
if ( ! ( caps = ast_format_cap_alloc ( AST_FORMAT_CAP_FLAG_DEFAULT ) ) ) {
ast_log ( LOG_ERROR , " Failed to allocate %s capabilities \n " ,
@ -1278,10 +1425,23 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as
continue ;
}
if ( ( rtp_code = ast_rtp_codecs_payload_code ( ast_rtp_instance_get_codecs ( session_media - > rtp ) , 1 , format , 0 ) ) = = - 1 ) {
ast_log ( LOG_WARNING , " Unable to get rtp codec payload code for %s \n " , ast_format_get_name ( format ) ) ;
ao2_ref ( format , - 1 ) ;
continue ;
/* If this stream is not a transport we need to use the transport codecs structure for payload management to prevent
* conflicts .
*/
if ( session_media_transport ! = session_media ) {
if ( ( rtp_code = ast_rtp_codecs_payload_code ( ast_rtp_instance_get_codecs ( session_media_transport - > rtp ) , 1 , format , 0 ) ) = = - 1 ) {
ast_log ( LOG_WARNING , " Unable to get rtp codec payload code for %s \n " , ast_format_get_name ( format ) ) ;
ao2_ref ( format , - 1 ) ;
continue ;
}
/* Our instance has to match the payload number though */
ast_rtp_codecs_payload_set_rx ( ast_rtp_instance_get_codecs ( session_media - > rtp ) , rtp_code , format ) ;
} else {
if ( ( rtp_code = ast_rtp_codecs_payload_code ( ast_rtp_instance_get_codecs ( session_media - > rtp ) , 1 , format , 0 ) ) = = - 1 ) {
ast_log ( LOG_WARNING , " Unable to get rtp codec payload code for %s \n " , ast_format_get_name ( format ) ) ;
ao2_ref ( format , - 1 ) ;
continue ;
}
}
if ( ( attr = generate_rtpmap_attr ( session , media , pool , rtp_code , 1 , format , 0 ) ) ) {
@ -1332,6 +1492,7 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as
}
}
/* If no formats were actually added to the media stream don't add it to the SDP */
if ( ! media - > desc . fmt_count ) {
return 1 ;
@ -1365,6 +1526,8 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as
pjmedia_sdp_attr_add ( & media - > attr_count , media - > attr , attr ) ;
}
add_ssrc_to_stream ( session , session_media , pool , media ) ;
/* Add the media stream to the SDP */
sdp - > media [ sdp - > media_count + + ] = media ;
@ -1425,6 +1588,7 @@ static int apply_negotiated_sdp_stream(struct ast_sip_session *session,
enum ast_media_type media_type = session_media - > type ;
char host [ NI_MAXHOST ] ;
int res ;
struct ast_sip_session_media * session_media_transport ;
if ( ! session - > channel ) {
return 1 ;
@ -1441,48 +1605,60 @@ static int apply_negotiated_sdp_stream(struct ast_sip_session *session,
return - 1 ;
}
session_media - > remote_rtcp_mux = ( pjmedia_sdp_media_find_attr2 ( remote_stream , " rtcp-mux " , NULL ) ! = NULL ) ;
set_ice_components ( session , session_media ) ;
process_ssrc_attributes ( session , session_media , remote_stream ) ;
enable_rtcp ( session , session_media , remote_stream ) ;
session_media_transport = ast_sip_session_media_get_transport ( session , session_media ) ;
res = setup_media_encryption ( session , session_media , remote , remote_stream ) ;
if ( ! session - > endpoint - > media . rtp . encryption_optimistic & & res ) {
/* If optimistic encryption is disabled and crypto should have been enabled but was not
* this session must fail .
*/
return - 1 ;
}
if ( session_media_transport = = session_media | | ! session_media - > bundled ) {
session_media - > remote_rtcp_mux = ( pjmedia_sdp_media_find_attr2 ( remote_stream , " rtcp-mux " , NULL ) ! = NULL ) ;
set_ice_components ( session , session_media ) ;
if ( ! remote_stream - > conn & & ! remote - > conn ) {
return 1 ;
}
enable_rtcp ( session , session_media , remote_stream ) ;
ast_copy_pj_str ( host , remote_stream - > conn ? & remote_stream - > conn - > addr : & remote - > conn - > addr , sizeof ( host ) ) ;
res = setup_media_encryption ( session , session_media , remote , remote_stream ) ;
if ( ! session - > endpoint - > media . rtp . encryption_optimistic & & res ) {
/* If optimistic encryption is disabled and crypto should have been enabled but was not
* this session must fail .
*/
return - 1 ;
}
/* Ensure that the address provided is valid */
if ( ast_sockaddr_resolve ( & addrs , host , PARSE_PORT_FORBID , AST_AF_UNSPEC ) < = 0 ) {
/* The provided host was actually invalid so we error out this negotiation */
return - 1 ;
}
if ( ! remote_stream - > conn & & ! remote - > conn ) {
return 1 ;
}
/* Apply connection information to the RTP instance */
ast_sockaddr_set_port ( addrs , remote_stream - > desc . port ) ;
ast_rtp_instance_set_remote_address ( session_media - > rtp , addrs ) ;
if ( set_caps ( session , session_media , remote_stream , 0 , asterisk_stream ) ) {
return 1 ;
}
ast_copy_pj_str ( host , remote_stream - > conn ? & remote_stream - > conn - > addr : & remote - > conn - > addr , sizeof ( host ) ) ;
ast_sip_session_media_set_write_callback ( session , session_media , media_session_rtp_write_callback ) ;
ast_sip_session_media_add_read_callback ( session , session_media , ast_rtp_instance_fd ( session_media - > rtp , 0 ) ,
media_session_rtp_read_callback ) ;
if ( ! session - > endpoint - > media . rtcp_mux | | ! session_media - > remote_rtcp_mux ) {
ast_sip_session_media_add_read_callback ( session , session_media , ast_rtp_instance_fd ( session_media - > rtp , 1 ) ,
media_session_rtcp_read_callback ) ;
/* Ensure that the address provided is valid */
if ( ast_sockaddr_resolve ( & addrs , host , PARSE_PORT_FORBID , AST_AF_UNSPEC ) < = 0 ) {
/* The provided host was actually invalid so we error out this negotiation */
return - 1 ;
}
/* Apply connection information to the RTP instance */
ast_sockaddr_set_port ( addrs , remote_stream - > desc . port ) ;
ast_rtp_instance_set_remote_address ( session_media - > rtp , addrs ) ;
ast_sip_session_media_set_write_callback ( session , session_media , media_session_rtp_write_callback ) ;
ast_sip_session_media_add_read_callback ( session , session_media , ast_rtp_instance_fd ( session_media - > rtp , 0 ) ,
media_session_rtp_read_callback ) ;
if ( ! session - > endpoint - > media . rtcp_mux | | ! session_media - > remote_rtcp_mux ) {
ast_sip_session_media_add_read_callback ( session , session_media , ast_rtp_instance_fd ( session_media - > rtp , 1 ) ,
media_session_rtcp_read_callback ) ;
}
/* If ICE support is enabled find all the needed attributes */
process_ice_attributes ( session , session_media , remote , remote_stream ) ;
} else {
/* This is bundled with another session, so mark it as such */
ast_rtp_instance_bundle ( session_media - > rtp , session_media_transport - > rtp ) ;
ast_sip_session_media_set_write_callback ( session , session_media , media_session_rtp_write_callback ) ;
enable_rtcp ( session , session_media , remote_stream ) ;
}
/* If ICE support is enabled find all the needed attributes */
process_ice_attributes ( session , session_media , remote , remote_stream ) ;
if ( set_caps ( session , session_media , session_media_transport , remote_stream , 0 , asterisk_stream ) ) {
return 1 ;
}
/* Set the channel uniqueid on the RTP instance now that it is becoming active */
ast_channel_lock ( session - > channel ) ;
@ -1490,6 +1666,7 @@ static int apply_negotiated_sdp_stream(struct ast_sip_session *session,
ast_channel_unlock ( session - > channel ) ;
/* Ensure the RTP instance is active */
ast_rtp_instance_set_stream_num ( session_media - > rtp , ast_stream_get_position ( asterisk_stream ) ) ;
ast_rtp_instance_activate ( session_media - > rtp ) ;
/* audio stream handles music on hold */