From e624bbc74a4fe5f21f1f7175297056357cac8971 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Wed, 3 Jun 2009 10:19:44 +0000 Subject: Ticket #822: Retransmit provisional response every 1 minute git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2739 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip/src/pjsip/sip_transaction.c | 65 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 5 deletions(-) diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c index f205ff5d..4ab94632 100644 --- a/pjsip/src/pjsip/sip_transaction.c +++ b/pjsip/src/pjsip/sip_transaction.c @@ -146,6 +146,13 @@ static pj_time_val timeout_timer_val = { (64*PJSIP_T1_TIMEOUT)/1000, #define TIMER_INACTIVE 0 #define TIMER_ACTIVE 1 +/* Delay for 1xx retransmission (should be 60 seconds). + * Specify 0 to disable this feature + */ +#ifndef PJSIP_TSX_1XX_RETRANS_DELAY +# define PJSIP_TSX_1XX_RETRANS_DELAY 60 +#endif + /* Prototypes. */ static void lock_tsx(pjsip_transaction *tsx, struct tsx_lock_data *lck); @@ -1949,7 +1956,7 @@ PJ_DEF(pj_status_t) pjsip_tsx_retransmit_no_state(pjsip_transaction *tsx, static void tsx_resched_retransmission( pjsip_transaction *tsx ) { pj_time_val timeout; - unsigned msec_time; + pj_uint32_t msec_time; pj_assert((tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) == 0); @@ -1967,10 +1974,18 @@ static void tsx_resched_retransmission( pjsip_transaction *tsx ) msec_time = pjsip_cfg()->tsx.t2; } } else { - /* Retransmission of INVITE final response also caps-off at T2 */ - pj_assert(tsx->status_code >= 200); - if (msec_time > pjsip_cfg()->tsx.t2) - msec_time = pjsip_cfg()->tsx.t2; + /* For UAS, this can be retransmission of 2xx response for INVITE + * or non-100 1xx response. + */ + if (tsx->status_code < 200) { + /* non-100 1xx retransmission is at 60 seconds */ + msec_time = PJSIP_TSX_1XX_RETRANS_DELAY * 1000; + } else { + /* Retransmission of INVITE final response also caps-off at T2 */ + pj_assert(tsx->status_code >= 200); + if (msec_time > pjsip_cfg()->tsx.t2) + msec_time = pjsip_cfg()->tsx.t2; + } } timeout.sec = msec_time / 1000; @@ -2338,8 +2353,42 @@ static pj_status_t tsx_on_state_proceeding_uas( pjsip_transaction *tsx, tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING, PJSIP_EVENT_TX_MSG, tdata ); + /* Retransmit provisional response every 1 minute if this is + * an INVITE provisional response greater than 100. + */ + if (PJSIP_TSX_1XX_RETRANS_DELAY > 0 && + tsx->method.id==PJSIP_INVITE_METHOD && tsx->status_code>100) + { + + /* Stop 1xx retransmission timer, if any */ + if (tsx->retransmit_timer.id) { + pjsip_endpt_cancel_timer(tsx->endpt, + &tsx->retransmit_timer); + tsx->retransmit_timer.id = 0; + } + + /* Schedule retransmission */ + tsx->retransmit_count = 0; + if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) { + tsx->transport_flag |= TSX_HAS_PENDING_RESCHED; + } else { + pj_time_val delay = {PJSIP_TSX_1XX_RETRANS_DELAY, 0}; + + tsx->retransmit_timer.id = TIMER_ACTIVE; + pjsip_endpt_schedule_timer( tsx->endpt, + &tsx->retransmit_timer, + &delay); + } + } + } else if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 200)) { + /* Stop 1xx retransmission timer, if any */ + if (tsx->retransmit_timer.id) { + pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer); + tsx->retransmit_timer.id = 0; + } + if (tsx->method.id == PJSIP_INVITE_METHOD && tsx->handle_200resp==0) { /* 2xx class message is not saved, because retransmission @@ -2409,6 +2458,12 @@ static pj_status_t tsx_on_state_proceeding_uas( pjsip_transaction *tsx, } else if (tsx->status_code >= 300) { + /* Stop 1xx retransmission timer, if any */ + if (tsx->retransmit_timer.id) { + pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer); + tsx->retransmit_timer.id = 0; + } + /* 3xx-6xx class message causes transaction to move to * "Completed" state. */ -- cgit v1.2.3