@ -5249,20 +5249,6 @@ static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
ast_copy_flags ( & dialog - > flags [ 2 ] , & peer - > flags [ 2 ] , SIP_PAGE3_FLAGS_TO_COPY ) ;
ast_format_cap_copy ( dialog - > caps , peer - > caps ) ;
dialog - > prefs = peer - > prefs ;
if ( ast_test_flag ( & dialog - > flags [ 1 ] , SIP_PAGE2_T38SUPPORT ) ) {
/* t38pt_udptl was enabled in the peer and not in [general] */
if ( dialog - > udptl | | ( ! dialog - > udptl & & ( dialog - > udptl = ast_udptl_new_with_bindaddr ( sched , io , 0 , & bindaddr ) ) ) ) {
dialog - > t38_maxdatagram = peer - > t38_maxdatagram ;
set_t38_capabilities ( dialog ) ;
} else {
/* It is impossible to support T38 without udptl */
ast_debug ( 1 , " UDPTL creation failed on dialog. \n " ) ;
ast_clear_flag ( & dialog - > flags [ 1 ] , SIP_PAGE2_T38SUPPORT ) ;
}
} else if ( dialog - > udptl ) {
ast_udptl_destroy ( dialog - > udptl ) ;
dialog - > udptl = NULL ;
}
ast_string_field_set ( dialog , engine , peer - > engine ) ;
@ -6782,6 +6768,53 @@ static int interpret_t38_parameters(struct sip_pvt *p, const struct ast_control_
return res ;
}
/*! \internal \brief Create and initialize UDPTL for the specified dialog
* \ param p SIP private structure to create UDPTL object for
* \ pre p is locked
* \ pre p - > owner is locked
*
* \ note In the case of failure , SIP_PAGE2_T38SUPPORT is cleared on p
*
* \ return 0 on success , any other value on failure
*/
static int initialize_udptl ( struct sip_pvt * p )
{
int natflags = ast_test_flag ( & p - > flags [ 1 ] , SIP_PAGE2_SYMMETRICRTP ) ;
if ( ! ast_test_flag ( & p - > flags [ 1 ] , SIP_PAGE2_T38SUPPORT ) ) {
return 1 ;
}
if ( ! p - > owner ) {
ast_log ( AST_LOG_WARNING , " Attempted to create UDPTL for dialog with no channel - disabling T38 for this dialog \n " ) ;
ast_clear_flag ( & p - > flags [ 1 ] , SIP_PAGE2_T38SUPPORT ) ;
return 1 ;
}
/* If we've already initialized T38, don't take any further action */
if ( p - > udptl ) {
return 0 ;
}
/* T38 can be supported by this dialog, create it and set the derived properties */
if ( ( p - > udptl = ast_udptl_new_with_bindaddr ( sched , io , 0 , & bindaddr ) ) ) {
ast_channel_set_fd ( p - > owner , 5 , ast_udptl_fd ( p - > udptl ) ) ;
ast_udptl_setqos ( p - > udptl , global_tos_audio , global_cos_audio ) ;
p - > t38_maxdatagram = p - > relatedpeer ? p - > relatedpeer - > t38_maxdatagram : global_t38_maxdatagram ;
set_t38_capabilities ( p ) ;
ast_debug ( 1 , " Setting NAT on UDPTL to %s \n " , natflags ? " On " : " Off " ) ;
ast_udptl_setnat ( p - > udptl , natflags ) ;
} else {
ast_log ( AST_LOG_WARNING , " UDPTL creation failed - disabling T38 for this dialog \n " ) ;
ast_clear_flag ( & p - > flags [ 1 ] , SIP_PAGE2_T38SUPPORT ) ;
return 1 ;
}
return 0 ;
}
/*! \brief Play indication to user
* With SIP a lot of indications is sent as messages , letting the device play
the indication - busy signal , congestion etc
@ -6889,12 +6922,14 @@ static int sip_indicate(struct ast_channel *ast, int condition, const void *data
res = - 1 ;
break ;
case AST_CONTROL_T38_PARAMETERS :
res = - 1 ;
if ( datalen ! = sizeof ( struct ast_control_t38_parameters ) ) {
ast_log ( LOG_ERROR , " Invalid datalen for AST_CONTROL_T38_PARAMETERS. Expected %d, got %d \n " , ( int ) sizeof ( struct ast_control_t38_parameters ) , ( int ) datalen ) ;
res = - 1 ;
} else {
const struct ast_control_t38_parameters * parameters = data ;
res = interpret_t38_parameters ( p , parameters ) ;
if ( ! initialize_udptl ( p ) ) {
res = interpret_t38_parameters ( p , parameters ) ;
}
}
break ;
case AST_CONTROL_SRCUPDATE :
@ -7069,7 +7104,9 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
}
}
/* Set file descriptors for audio, video, realtime text and UDPTL as needed */
/* Set file descriptors for audio, video, and realtime text. Since
* UDPTL is created as needed in the lifetime of a dialog , its file
* descriptor is set in initialize_udptl */
if ( i - > rtp ) {
ast_channel_set_fd ( tmp , 0 , ast_rtp_instance_fd ( i - > rtp , 0 ) ) ;
ast_channel_set_fd ( tmp , 1 , ast_rtp_instance_fd ( i - > rtp , 1 ) ) ;
@ -7081,9 +7118,6 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
if ( needtext & & i - > trtp ) {
ast_channel_set_fd ( tmp , 4 , ast_rtp_instance_fd ( i - > trtp , 0 ) ) ;
}
if ( i - > udptl ) {
ast_channel_set_fd ( tmp , 5 , ast_udptl_fd ( i - > udptl ) ) ;
}
if ( state = = AST_STATE_RING ) {
tmp - > rings = 1 ;
@ -7733,16 +7767,6 @@ struct sip_pvt *sip_alloc(ast_string_field callid, struct ast_sockaddr *addr,
p - > allowed_methods = UINT_MAX ;
if ( sip_methods [ intended_method ] . need_rtp ) {
if ( ast_test_flag ( & p - > flags [ 1 ] , SIP_PAGE2_T38SUPPORT ) ) {
if ( ( p - > udptl = ast_udptl_new_with_bindaddr ( sched , io , 0 , & bindaddr ) ) ) {
ast_udptl_setqos ( p - > udptl , global_tos_audio , global_cos_audio ) ;
p - > t38_maxdatagram = global_t38_maxdatagram ;
} else {
/* udptl creation failed, T38 can not be supported on this dialog */
ast_log ( LOG_ERROR , " UDPTL creation failed \n " ) ;
ast_clear_flag ( & p - > flags [ 1 ] , SIP_PAGE2_T38SUPPORT ) ;
}
}
p - > maxcallbitrate = default_maxcallbitrate ;
p - > autoframing = global_autoframing ;
}
@ -7770,11 +7794,8 @@ struct sip_pvt *sip_alloc(ast_string_field callid, struct ast_sockaddr *addr,
ast_format_cap_copy ( p - > caps , sip_cfg . caps ) ;
p - > allowtransfer = sip_cfg . allowtransfer ;
if ( ( ast_test_flag ( & p - > flags [ 0 ] , SIP_DTMF ) = = SIP_DTMF_RFC2833 ) | |
( ast_test_flag ( & p - > flags [ 0 ] , SIP_DTMF ) = = SIP_DTMF_AUTO ) )
( ast_test_flag ( & p - > flags [ 0 ] , SIP_DTMF ) = = SIP_DTMF_AUTO ) ) {
p - > noncodeccapability | = AST_RTP_DTMF ;
if ( p - > udptl ) {
p - > t38_maxdatagram = global_t38_maxdatagram ;
set_t38_capabilities ( p ) ;
}
ast_string_field_set ( p , context , sip_cfg . default_context ) ;
ast_string_field_set ( p , parkinglot , default_parkinglot ) ;
@ -9111,8 +9132,12 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
ast_rtp_codecs_payloads_set_m_type ( & newtextrtp , NULL , codec ) ;
}
/* Search for image media definition */
} else if ( p - > udptl & & ( ( sscanf ( m , " image %30u udptl t38%n " , & x , & len ) = = 1 & & len > 0 & & x ) | |
} else if ( ( ( sscanf ( m , " image %30u udptl t38%n " , & x , & len ) = = 1 & & len > 0 & & x ) | |
( sscanf ( m , " image %30u UDPTL t38%n " , & x , & len ) = = 1 & & len > 0 & & x ) ) ) {
if ( initialize_udptl ( p ) ) {
continue ;
}
if ( p - > offered_media [ SDP_IMAGE ] . order_offered ) {
ast_log ( LOG_WARNING , " Multiple T.38 streams are not supported \n " ) ;
res = - 3 ;
@ -9834,6 +9859,10 @@ static int process_sdp_a_image(const char *a, struct sip_pvt *p)
char s [ 256 ] ;
unsigned int x ;
if ( initialize_udptl ( p ) ) {
return found ;
}
if ( ( sscanf ( a , " T38FaxMaxBuffer:%30u " , & x ) = = 1 ) ) {
ast_debug ( 3 , " MaxBufferSize:%d \n " , x ) ;
found = TRUE ;
@ -23056,17 +23085,6 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
if ( authpeer ) {
p - > relatedpeer = sip_ref_peer ( authpeer , " setting dialog's relatedpeer pointer " ) ;
}
/* If T38 is needed but not present, then make it magically appear */
if ( ast_test_flag ( & p - > flags [ 1 ] , SIP_PAGE2_T38SUPPORT ) & & ! p - > udptl ) {
if ( ( p - > udptl = ast_udptl_new_with_bindaddr ( sched , io , 0 , & bindaddr ) ) ) {
p - > t38_maxdatagram = global_t38_maxdatagram ;
set_t38_capabilities ( p ) ;
} else {
/* udptl creation failed, T38 can not be supported on this dialog */
ast_debug ( 1 , " UDPTL creation failed on dialog. \n " ) ;
ast_clear_flag ( & p - > flags [ 1 ] , SIP_PAGE2_T38SUPPORT ) ;
}
}
req - > authenticated = 1 ;