Module: sems
Branch: sayer/1.4-spce2.5
Commit: 841be6b7a7beedc19725bf11d22e531500221a4a
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=841be6b7a7beedc19725bf11d22e531500221a4a

Author: Raphael Coeffic <[email protected]>
Committer: Stefan Sayer <[email protected]>
Date:   Sat Feb  4 18:10:56 2012 +0100

sip: timer C support.

---

 core/sip/sip_timers.h    |    9 ++++++++-
 core/sip/sip_trans.cpp   |    5 +++--
 core/sip/trans_layer.cpp |   40 ++++++++++++++++++++++++++++++++++++++--
 3 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/core/sip/sip_timers.h b/core/sip/sip_timers.h
index de2eed2..a59eaf7 100644
--- a/core/sip/sip_timers.h
+++ b/core/sip/sip_timers.h
@@ -64,7 +64,10 @@ enum sip_timer_type {
     // Transport address failover timer:
     // - used to cycle throught multiple addresses
     //   in case the R-URI resolves to multiple addresses
-    STIMER_M
+    STIMER_M,
+
+    // INVITE client transaction
+    STIMER_C   // Proceeding -> Terminated
 };
 
 
@@ -81,6 +84,9 @@ enum sip_timer_type {
 //type 0x02
 #define B_TIMER  64*T1_TIMER
 
+//type 0x0d
+#define C_TIMER  (3*60*1000)
+
 //type 0x03
 #define D_TIMER  64*T1_TIMER
 
@@ -116,6 +122,7 @@ enum sip_timer_type {
 // Transport address failover timer:
 // - used to cycle throught multiple addresses
 //   in case the R-URI resolves to multiple addresses
+//type 0x0c
 #define M_TIMER  (B_TIMER/4)
 
 #endif
diff --git a/core/sip/sip_trans.cpp b/core/sip/sip_trans.cpp
index 375b531..ef94946 100644
--- a/core/sip/sip_trans.cpp
+++ b/core/sip/sip_trans.cpp
@@ -45,7 +45,8 @@ int _timer_type_lookup[] = {
     0,1,2, // STIMER_G, STIMER_H, STIMER_I
     0,     // STIMER_J
     2,     // STIMER_L; shares the same slot as STIMER_D
-    2      // STIMER_M; shares the same slot as STIMER_D/STIMER_K
+    2,     // STIMER_M; shares the same slot as STIMER_D/STIMER_K
+    1,     // STIMER_C; shares the same slot at STIMER_B (INV trans only)
 };
 
 inline timer** fetch_timer(unsigned int timer_type, timer** base)
@@ -120,7 +121,7 @@ timer* sip_trans::get_timer(unsigned int timer_type)
 }
 
 
-char _timer_name_lookup[] = 
{'0','A','B','D','E','F','K','G','H','I','J','L','M'};
+char _timer_name_lookup[] = 
{'0','A','B','D','E','F','K','G','H','I','J','L','M','C'};
 #define timer_name(type) \
     (_timer_name_lookup[(type) & 0xFFFF])
 
diff --git a/core/sip/trans_layer.cpp b/core/sip/trans_layer.cpp
index 930c294..6589586 100644
--- a/core/sip/trans_layer.cpp
+++ b/core/sip/trans_layer.cpp
@@ -1262,8 +1262,12 @@ int _trans_layer::update_uac_reply(trans_bucket* bucket, 
sip_trans* t, sip_msg*
            // fall through trap
 
        case TS_PROCEEDING:
-           if(t->msg->u.request->method != sip_request::CANCEL)
+           if(t->msg->u.request->method != sip_request::CANCEL) {
+               if(t->msg->u.request->method == sip_request::INVITE) {
+                   t->reset_timer(STIMER_C, C_TIMER, bucket->get_id());
+               }
                goto pass_reply;
+           }
            else
                goto end;
 
@@ -1297,7 +1301,9 @@ int _trans_layer::update_uac_reply(trans_bucket* bucket, 
sip_trans* t, sip_msg*
                t->clear_timer(STIMER_B);
 
            case TS_PROCEEDING:
-               
+       
+               t->clear_timer(STIMER_C);
+
                t->state = TS_COMPLETED;
                send_non_200_ack(msg,t);
                t->reset_timer(STIMER_D, D_TIMER, bucket->get_id());
@@ -1337,6 +1343,11 @@ int _trans_layer::update_uac_reply(trans_bucket* bucket, 
sip_trans* t, sip_msg*
                t->clear_timer(STIMER_M);
                t->clear_timer(STIMER_B);
 
+               // Timer B & C share the same slot,
+               // so it would pretty useless to clear
+               // the same timer slote another time ;-)
+               //t->clear_timer(STIMER_C);
+
                t->reset_timer(STIMER_L, L_TIMER, bucket->get_id());
 
                if (t->to_tag.len==0) {
@@ -1652,6 +1663,31 @@ void _trans_layer::timer_expired(timer* t, trans_bucket* 
bucket, sip_trans* tr)
        }
        break;
 
+    case STIMER_C: // Proceeding -> Terminated
+       
+       // Note: remember well, we first set timer C
+       //       after the first provisional reply.
+       tr->clear_timer(STIMER_C);
+       if(tr->state != TS_PROCEEDING)
+           break; // shouldn't happen
+
+       bucket->unlock();
+
+       {
+           // send CANCEL
+           trans_ticket tt(tr,bucket);
+           cancel(&tt);
+           
+           // Now remove the transaction
+           bucket->lock();
+           if(bucket->exist(tr)) {
+               // unlocks the bucket
+               timeout(bucket,tr);
+               return;
+           }
+       }
+       break;
+
     case STIMER_F:  // Trying/Proceeding: terminate transaction
        
        tr->clear_timer(STIMER_F);

_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev

Reply via email to