summaryrefslogtreecommitdiff
path: root/pjsip
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2009-06-03 10:19:44 +0000
committerBenny Prijono <bennylp@teluu.com>2009-06-03 10:19:44 +0000
commite624bbc74a4fe5f21f1f7175297056357cac8971 (patch)
tree37fa3521c2c7880023da290987e5a796f75626b9 /pjsip
parent4f1c10a2a7e221b2347c838e8ff9e9427648e326 (diff)
Ticket #822: Retransmit provisional response every 1 minute
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2739 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r--pjsip/src/pjsip/sip_transaction.c65
1 files 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.
*/