@ -620,6 +620,8 @@ struct ast_sip_session_delayed_request {
ast_sip_session_sdp_creation_cb on_sdp_creation ;
/*! Callback to call when the delayed request receives a response */
ast_sip_session_response_cb on_response ;
/*! Whether to generate new SDP */
int generate_new_sdp ;
/*! Request to send */
pjsip_tx_data * tdata ;
AST_LIST_ENTRY ( ast_sip_session_delayed_request ) next ;
@ -629,6 +631,7 @@ static struct ast_sip_session_delayed_request *delayed_request_alloc(const char
ast_sip_session_request_creation_cb on_request_creation ,
ast_sip_session_sdp_creation_cb on_sdp_creation ,
ast_sip_session_response_cb on_response ,
int generate_new_sdp ,
pjsip_tx_data * tdata )
{
struct ast_sip_session_delayed_request * delay = ast_calloc ( 1 , sizeof ( * delay ) ) ;
@ -639,6 +642,7 @@ static struct ast_sip_session_delayed_request *delayed_request_alloc(const char
delay - > on_request_creation = on_request_creation ;
delay - > on_sdp_creation = on_sdp_creation ;
delay - > on_response = on_response ;
delay - > generate_new_sdp = generate_new_sdp ;
delay - > tdata = tdata ;
return delay ;
}
@ -654,10 +658,10 @@ static int send_delayed_request(struct ast_sip_session *session, struct ast_sip_
if ( ! strcmp ( delay - > method , " INVITE " ) ) {
ast_sip_session_refresh ( session , delay - > on_request_creation ,
delay - > on_sdp_creation , delay - > on_response , AST_SIP_SESSION_REFRESH_METHOD_INVITE , 1 ) ;
delay - > on_sdp_creation , delay - > on_response , AST_SIP_SESSION_REFRESH_METHOD_INVITE , delay - > generate_new_sdp ) ;
} else if ( ! strcmp ( delay - > method , " UPDATE " ) ) {
ast_sip_session_refresh ( session , delay - > on_request_creation ,
delay - > on_sdp_creation , delay - > on_response , AST_SIP_SESSION_REFRESH_METHOD_UPDATE , 1 ) ;
delay - > on_sdp_creation , delay - > on_response , AST_SIP_SESSION_REFRESH_METHOD_UPDATE , delay - > generate_new_sdp ) ;
} else {
ast_log ( LOG_WARNING , " Unexpected delayed %s request with no existing request structure \n " , delay - > method ) ;
return - 1 ;
@ -694,10 +698,10 @@ static void queue_delayed_request(struct ast_sip_session *session)
static int delay_request ( struct ast_sip_session * session , ast_sip_session_request_creation_cb on_request ,
ast_sip_session_sdp_creation_cb on_sdp_creation , ast_sip_session_response_cb on_response ,
const char * method , pjsip_tx_data * tdata )
int generate_new_sdp , const char * method , pjsip_tx_data * tdata )
{
struct ast_sip_session_delayed_request * delay = delayed_request_alloc ( method ,
on_request , on_sdp_creation , on_response , tdata) ;
on_request , on_sdp_creation , on_response , generate_new_sdp, tdata) ;
if ( ! delay ) {
return - 1 ;
@ -737,12 +741,21 @@ int ast_sip_session_refresh(struct ast_sip_session *session,
return 0 ;
}
/* If the dialog has not yet been established we have to defer until it has */
if ( inv_session - > dlg - > state ! = PJSIP_DIALOG_STATE_ESTABLISHED ) {
ast_debug ( 3 , " Delaying sending request to %s because dialog has not been established... \n " ,
ast_sorcery_object_get_id ( session - > endpoint ) ) ;
return delay_request ( session , on_request_creation , on_sdp_creation , on_response , generate_new_sdp ,
method = = AST_SIP_SESSION_REFRESH_METHOD_INVITE ? " INVITE " : " UPDATE " , NULL ) ;
}
if ( method = = AST_SIP_SESSION_REFRESH_METHOD_INVITE ) {
if ( inv_session - > invite_tsx ) {
/* We can't send a reinvite yet, so delay it */
ast_debug ( 3 , " Delaying sending reinvite to %s because of outstanding transaction... \n " ,
ast_sorcery_object_get_id ( session - > endpoint ) ) ;
return delay_request ( session , on_request_creation , on_sdp_creation , on_response , " INVITE " , NULL ) ;
return delay_request ( session , on_request_creation , on_sdp_creation , on_response ,
generate_new_sdp , " INVITE " , NULL ) ;
} else if ( inv_session - > state ! = PJSIP_INV_STATE_CONFIRMED ) {
/* Initial INVITE transaction failed to progress us to a confirmed state
* which means re - invites are not possible
@ -754,6 +767,14 @@ int ast_sip_session_refresh(struct ast_sip_session *session,
}
if ( generate_new_sdp ) {
/* SDP can only be generated if current negotiation has already completed */
if ( pjmedia_sdp_neg_get_state ( inv_session - > neg ) ! = PJMEDIA_SDP_NEG_STATE_DONE ) {
ast_debug ( 3 , " Delaying session refresh with new SDP to %s because SDP negotiation is not yet done... \n " ,
ast_sorcery_object_get_id ( session - > endpoint ) ) ;
return delay_request ( session , on_request_creation , on_sdp_creation , on_response , generate_new_sdp ,
method = = AST_SIP_SESSION_REFRESH_METHOD_INVITE ? " INVITE " : " UPDATE " , NULL ) ;
}
new_sdp = generate_session_refresh_sdp ( session ) ;
if ( ! new_sdp ) {
ast_log ( LOG_ERROR , " Failed to generate session refresh SDP. Not sending session refresh \n " ) ;
@ -1732,7 +1753,7 @@ static void resend_reinvite(pj_timer_heap_t *timer, pj_timer_entry *entry)
static void reschedule_reinvite ( struct ast_sip_session * session , ast_sip_session_response_cb on_response , pjsip_tx_data * tdata )
{
struct ast_sip_session_delayed_request * delay = delayed_request_alloc ( " INVITE " ,
NULL , NULL , on_response , tdata ) ;
NULL , NULL , on_response , 1 , tdata ) ;
pjsip_inv_session * inv = session - > inv_session ;
struct reschedule_reinvite_data * rrd = reschedule_reinvite_data_alloc ( session , delay ) ;
pj_time_val tv ;
@ -2032,7 +2053,9 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans
/* Terminated INVITE transactions always should result in queuing delayed requests,
* no matter what event caused the transaction to terminate
*/
if ( tsx - > method . id = = PJSIP_INVITE_METHOD & & tsx - > state = = PJSIP_TSX_STATE_TERMINATED ) {
if ( tsx - > method . id = = PJSIP_INVITE_METHOD & &
( ( tsx - > state = = PJSIP_TSX_STATE_TERMINATED ) | |
( tsx - > state = = PJSIP_TSX_STATE_PROCEEDING ) ) ) {
queue_delayed_request ( session ) ;
}
}