Browse code

sbc b/f: call CCEnd only once upon hangup

Reported by Juha Heinanen

CCEnd & CCConnect is called only if CCStart was called before

Václav Kubart authored on 22/02/2013 20:55:53 • Raphael Coeffic committed on 28/02/2013 12:11:27
Showing 6 changed files
... ...
@@ -880,7 +880,6 @@ void CallLeg::onCancel(const AmSipRequest& req)
880 880
 void CallLeg::terminateLeg()
881 881
 {
882 882
   AmB2BSession::terminateLeg();
883
-  onCallStopped();
884 883
 }
885 884
 
886 885
 // was for caller only
... ...
@@ -244,10 +244,6 @@ class CallLeg: public AmB2BSession
244 244
      * use this method in SBCCallLeg only) */
245 245
     virtual void onCallConnected(const AmSipReply& reply) { }
246 246
 
247
-    /** handler called when call is stopped (FIXME: this is a hack, use this
248
-     * method in SBCCallLeg only)  */
249
-    virtual void onCallStopped() { }
250
-
251 247
     /** Method called if given B leg couldn't establish the call (refused with
252 248
      * failure response)
253 249
      *
... ...
@@ -148,7 +148,8 @@ SBCCallLeg::SBCCallLeg(const SBCCallProfile& call_profile, AmSipDialog* p_dlg)
148 148
     m_state(BB_Init),
149 149
     auth(NULL),
150 150
     call_profile(call_profile),
151
-    cc_timer_id(SBC_TIMER_ID_CALL_TIMERS_START)
151
+    cc_timer_id(SBC_TIMER_ID_CALL_TIMERS_START),
152
+    cc_started(false)
152 153
 {
153 154
   set_sip_relay_only(false);
154 155
   dlg->setRel100State(Am100rel::REL100_IGNORED);
... ...
@@ -165,7 +166,8 @@ SBCCallLeg::SBCCallLeg(const SBCCallProfile& call_profile, AmSipDialog* p_dlg)
165 166
 SBCCallLeg::SBCCallLeg(SBCCallLeg* caller, AmSipDialog* p_dlg)
166 167
   : auth(NULL),
167 168
     call_profile(caller->getCallProfile()),
168
-    CallLeg(caller,p_dlg)
169
+    CallLeg(caller,p_dlg),
170
+    cc_started(false)
169 171
 {
170 172
   // FIXME: do we want to inherit cc_vars from caller?
171 173
   // Can be pretty dangerous when caller stored pointer to object - we should
... ...
@@ -841,7 +843,7 @@ void SBCCallLeg::onCallConnected(const AmSipReply& reply) {
841 843
   }
842 844
 }
843 845
 
844
-void SBCCallLeg::onCallStopped() {
846
+void SBCCallLeg::onStop() {
845 847
   if (call_profile.cc_interfaces.size()) {
846 848
     gettimeofday(&call_end_ts, NULL);
847 849
   }
... ...
@@ -852,56 +854,10 @@ void SBCCallLeg::onCallStopped() {
852 854
 
853 855
   m_state = BB_Teardown;
854 856
 
855
-  CCEnd();
856
-}
857
-
858
-void SBCCallLeg::onOtherBye(const AmSipRequest& req)
859
-{
860
-  onCallStopped();
861
-
862
-  CallLeg::onOtherBye(req);
863
-}
864
-
865
-void SBCCallLeg::onSessionTimeout() {
866
-  onCallStopped();
867
-
868
-  CallLeg::onSessionTimeout();
869
-}
870
-
871
-void SBCCallLeg::onNoAck(unsigned int cseq) {
872
-  onCallStopped();
873
-
874
-  CallLeg::onNoAck(cseq);
875
-}
876
-
877
-void SBCCallLeg::onRemoteDisappeared(const AmSipReply& reply)  {
878
-  DBG("Remote unreachable - ending SBC call\n");
879
-  onCallStopped();
880
-
881
-  CallLeg::onRemoteDisappeared(reply);
882
-}
883
-
884
-void SBCCallLeg::onBye(const AmSipRequest& req)
885
-{
886
-  DBG("onBye()\n");
887
-
888
-  onCallStopped();
889
-
890
-  CallLeg::onBye(req);
891
-}
892
-
893
-void SBCCallLeg::onCancel(const AmSipRequest& cancel)
894
-{
895
-  dlg->bye();
896
-  stopCall();
897
-}
898
-
899
-void SBCCallLeg::onSystemEvent(AmSystemEvent* ev) {
900
-  if (ev->sys_event == AmSystemEvent::ServerShutdown) {
901
-    onCallStopped();
902
-  }
903
-
904
-  CallLeg::onSystemEvent(ev);
857
+  // call only if really started (on CCStart failure CCEnd will be called
858
+  // explicitly)
859
+  // Note that role may change, so testing for a_leg need not to be correct.
860
+  if (cc_started) CCEnd();
905 861
 }
906 862
 
907 863
 void SBCCallLeg::saveCallTimer(int timer, double timeout) {
... ...
@@ -1104,11 +1060,12 @@ bool SBCCallLeg::CCStart(const AmSipRequest& req) {
1104 1060
 
1105 1061
     cc_mod++;
1106 1062
   }
1063
+  cc_started = true;
1107 1064
   return true;
1108 1065
 }
1109 1066
 
1110 1067
 void SBCCallLeg::CCConnect(const AmSipReply& reply) {
1111
-  if (!a_leg) return; // preserve original behavior of the CC interface
1068
+  if (!cc_started) return; // preserve original behavior of the CC interface
1112 1069
 
1113 1070
   vector<AmDynInvoke*>::iterator cc_mod=cc_modules.begin();
1114 1071
 
... ...
@@ -1158,8 +1115,6 @@ void SBCCallLeg::CCEnd() {
1158 1115
 }
1159 1116
 
1160 1117
 void SBCCallLeg::CCEnd(const CCInterfaceListIteratorT& end_interface) {
1161
-  if (!a_leg) return; // preserve original behavior of the CC interface
1162
-
1163 1118
   vector<AmDynInvoke*>::iterator cc_mod=cc_modules.begin();
1164 1119
 
1165 1120
   for (CCInterfaceListIteratorT cc_it=call_profile.cc_interfaces.begin();
... ...
@@ -51,22 +51,17 @@ class SBCCallLeg : public CallLeg, public CredentialHolder
51 51
 
52 52
   SBCCallProfile call_profile;
53 53
 
54
+  /** set to true once CCStart passed to call CCEnd implicitly (from onStop)
55
+   * only when CCStart was called */
56
+  bool cc_started;
57
+
54 58
   void fixupCCInterface(const string& val, CCInterface& cc_if);
55 59
 
56 60
   /** handler called when the second leg is connected */
57 61
   virtual void onCallConnected(const AmSipReply& reply);
58 62
 
59
-  /** handler called when call is stopped */
60
-  virtual void onCallStopped();
61
-
62
-  /** handler called when SST timeout occured */
63
-  void onSessionTimeout();
64
-
65
-  /** handler called when no ACK received */
66
-  void onNoAck(unsigned int cseq);
67
-
68
-  /** handler called when we receive 408/481 */
69
-  void onRemoteDisappeared(const AmSipReply& reply);
63
+  /** handler called when call is stopped (see AmSession) */
64
+  virtual void onStop();
70 65
 
71 66
   /* set call timer (if enabled) */
72 67
   bool startCallTimers();
... ...
@@ -106,14 +101,10 @@ class SBCCallLeg : public CallLeg, public CredentialHolder
106 101
 
107 102
   void process(AmEvent* ev);
108 103
   void onB2BEvent(B2BEvent* ev);
109
-  void onBye(const AmSipRequest& req);
110 104
   void onInvite(const AmSipRequest& req);
111
-  void onCancel(const AmSipRequest& cancel);
112 105
 
113 106
   void onDtmf(int event, int duration);
114 107
 
115
-  void onSystemEvent(AmSystemEvent* ev);
116
-
117 108
   virtual void onStart();
118 109
   virtual void onBeforeDestroy();
119 110
 
... ...
@@ -165,8 +156,6 @@ class SBCCallLeg : public CallLeg, public CredentialHolder
165 156
   void onSipReply(const AmSipRequest& req, const AmSipReply& reply, AmSipDialog::Status old_dlg_status);
166 157
   void onSendRequest(AmSipRequest& req, int &flags);
167 158
 
168
-  void onOtherBye(const AmSipRequest& req);
169
-
170 159
   void onControlCmd(string& cmd, AmArg& params);
171 160
 
172 161
   void createCalleeSession();
... ...
@@ -480,6 +480,7 @@ void AmSession::finalize() {
480 480
 }
481 481
 
482 482
 void AmSession::setStopped(bool wakeup) {
483
+  if (!sess_stopped.get()) onStop();
483 484
   sess_stopped.set(true); 
484 485
   if (wakeup) 
485 486
     AmSessionContainer::instance()->postEvent(getLocalTag(), 
... ...
@@ -471,6 +471,12 @@ public:
471 471
    */
472 472
   virtual void onStart() {}
473 473
 
474
+  /**
475
+   * onStop will be called once session is marked to be stopped (called only
476
+   * once).
477
+   */
478
+  virtual void onStop() {}
479
+
474 480
   /**
475 481
    * onInvite will be called if an INVITE or re-INVITE
476 482
    * has been received for the session.