diff --git a/core/plug-in/sipctrl/sip_timers.h b/core/plug-in/sipctrl/sip_timers.h index b1ce5115..8d1692f9 100644 --- a/core/plug-in/sipctrl/sip_timers.h +++ b/core/plug-in/sipctrl/sip_timers.h @@ -59,6 +59,15 @@ //type 0x0a #define J_TIMER 64*T1_TIMER + +// This timer is not defined by +// RFC 3261. But it is needed +// to handle 200 ACKs automatically +// in UAC transactions. + +//type 0x0b +#define L_TIMER 64*T1_TIMER + #endif diff --git a/core/plug-in/sipctrl/sip_trans.h b/core/plug-in/sipctrl/sip_trans.h index a7b96f1f..be8dbd8e 100644 --- a/core/plug-in/sipctrl/sip_trans.h +++ b/core/plug-in/sipctrl/sip_trans.h @@ -80,8 +80,13 @@ enum sip_timer_type { STIMER_I, // Confirmed: -> Terminated // non-INVITE server transaction - STIMER_J // Completed: -> Terminated + STIMER_J, // Completed: -> Terminated + // This timer is not defined by + // RFC 3261. But it is needed + // to handle 200 ACKs automatically + // in UAC transactions. + STIMER_L // Terminated_200 -> Terminated }; diff --git a/core/plug-in/sipctrl/trans_layer.cpp b/core/plug-in/sipctrl/trans_layer.cpp index 585ce019..7dc3dd00 100644 --- a/core/plug-in/sipctrl/trans_layer.cpp +++ b/core/plug-in/sipctrl/trans_layer.cpp @@ -646,7 +646,6 @@ int trans_layer::cancel(trans_bucket* bucket, sip_trans* t) if(transport->get_local_port() != 5060) via += ":" + int2str(transport->get_local_port()); - //request_len += via_len(stl2cstr(via),branch); request_len += copy_hdr_len(req->via1); request_len += copy_hdr_len(req->to) @@ -937,6 +936,10 @@ int trans_layer::update_uac_trans(trans_bucket* bucket, sip_trans* t, sip_msg* m // - re-transmit ACK. t->state = TS_TERMINATED_200; + t->clear_timer(STIMER_A); + t->clear_timer(STIMER_B); + + t->reset_timer(STIMER_L, L_TIMER, bucket->get_id()); t->to_tag.s = new char[to_tag.len]; t->to_tag.len = to_tag.len; @@ -1276,7 +1279,6 @@ void trans_layer::timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr) switch(type){ - case STIMER_A: // Calling: (re-)send INV n++; @@ -1291,6 +1293,9 @@ void trans_layer::timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr) DBG("Transaction timeout!\n"); timeout(bucket,tr); } + else { + DBG("Transaction timeout timer hit while state=0x%x",tr->state); + } break; case STIMER_F: // Trying/Proceeding: terminate transaction @@ -1304,9 +1309,9 @@ void trans_layer::timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr) DBG("Transaction timeout!\n"); timeout(bucket,tr); break; - case TS_TERMINATED_200: - bucket->remove_trans(tr); - break; +// case TS_TERMINATED_200: +// bucket->remove_trans(tr); +// break; } break; @@ -1315,6 +1320,7 @@ void trans_layer::timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr) case STIMER_J: // Completed: -> Terminated case STIMER_H: // Completed: -> Terminated case STIMER_I: // Confirmed: -> Terminated + case STIMER_L: // Terminated_200 -> Terminated tr->clear_timer(type); tr->state = TS_TERMINATED;