Browse code

- make the AmSipDialog call the SIP event handler within AmSession, instead of the opposite. - WARNING: this code is not yet tested.

git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@1827 8eb893ce-cfd4-0310-b710-fb5ebe64c474

Raphael Coeffic authored on 26/04/2010 16:25:01
Showing 25 changed files
... ...
@@ -13,6 +13,7 @@ $(info exclude_app_modules: $(exclude_app_modules))
13 13
 app_modules = $(filter-out $(subst ;, ,$(exclude_app_modules))\
14 14
 		$(wildcard Makefile*) CVS CMakeLists.txt, \
15 15
 		$(wildcard *) examples/tutorial/cc_acc )
16
+$(info app_modules: $(app_modules))
16 17
 
17 18
 #modules = wav gsm ilbc bot echo announcement recorder voicemail dtmf_demo ivr
18 19
 
... ...
@@ -181,7 +181,7 @@ void AnnounceTransferDialog::onSipRequest(const AmSipRequest& req)
181 181
 
182 182
 }
183 183
 
184
-void AnnounceTransferDialog::onSipReply(const AmSipReply& rep) {
184
+void AnnounceTransferDialog::onSipReply(const AmSipReply& rep, int old_dlg_status) {
185 185
   if ((status==Transfering ||status==Hangup)  && 
186 186
       dlg.get_uac_trans_method(rep.cseq) == "REFER") {
187 187
     if (rep.code >= 300) {
... ...
@@ -191,7 +191,7 @@ void AnnounceTransferDialog::onSipReply(const AmSipReply& rep) {
191 191
     }
192 192
   }
193 193
 
194
-  AmSession::onSipReply(rep);
194
+  AmSession::onSipReply(rep, old_dlg_status);
195 195
 }
196 196
 
197 197
 void AnnounceTransferDialog::onBye(const AmSipRequest& req)
... ...
@@ -72,7 +72,7 @@ public:
72 72
   void startSession();
73 73
   void onBye(const AmSipRequest& req);
74 74
   void onSipRequest(const AmSipRequest& req);
75
-  void onSipReply(const AmSipReply& rep);
75
+    void onSipReply(const AmSipReply& rep, int old_dlg_status);
76 76
   void onDtmf(int event, int duration_msec) {}
77 77
 
78 78
   void process(AmEvent* event);
... ...
@@ -147,7 +147,7 @@ void AuthB2BDialog::onInvite(const AmSipRequest& req)
147 147
   removeHeader(invite_req.hdrs,PARAM_HDR);
148 148
   removeHeader(invite_req.hdrs,"P-App-Name");
149 149
 
150
-  dlg.updateStatus(req);
150
+  //dlg.updateStatus(req);
151 151
   recvd_req.insert(std::make_pair(req.cseq,req));
152 152
   
153 153
   set_sip_relay_only(true);
... ...
@@ -314,15 +314,15 @@ inline UACAuthCred* AuthB2BCalleeSession::getCredentials() {
314 314
   return &credentials;
315 315
 }
316 316
 
317
-void AuthB2BCalleeSession::onSipReply(const AmSipReply& reply) {
317
+void AuthB2BCalleeSession::onSipReply(const AmSipReply& reply, int old_dlg_status) {
318 318
   if (NULL == auth) {    
319
-    AmB2BCalleeSession::onSipReply(reply);
319
+      AmB2BCalleeSession::onSipReply(reply,old_dlg_status);
320 320
     return;
321 321
   }
322 322
   
323
-  int cseq_before = dlg.cseq;
323
+  unsigned int cseq_before = dlg.cseq;
324 324
   if (!auth->onSipReply(reply)) {
325
-    AmB2BCalleeSession::onSipReply(reply);
325
+      AmB2BCalleeSession::onSipReply(reply,old_dlg_status);
326 326
   } else {
327 327
     if (cseq_before != dlg.cseq) {
328 328
       DBG("uac_auth consumed reply with cseq %d and resent with cseq %d; "
... ...
@@ -95,7 +95,7 @@ class AuthB2BCalleeSession
95 95
   AmSessionEventHandler* auth;
96 96
 
97 97
  protected:
98
-  void onSipReply(const AmSipReply& reply);
98
+  void onSipReply(const AmSipReply& reply, int old_dlg_status);
99 99
   void onSendRequest(const string& method, const string& content_type,
100 100
 		     const string& body, string& hdrs, int flags, unsigned int cseq);
101 101
 
... ...
@@ -131,7 +131,6 @@ CallTimerDialog::~CallTimerDialog()
131 131
 
132 132
 void CallTimerDialog::onInvite(const AmSipRequest& req)
133 133
 {
134
-
135 134
   if (dlg.getStatus() == AmSipDialog::Connected) {
136 135
     DBG("not acting on re-Invite\n");
137 136
     return;
... ...
@@ -152,7 +151,7 @@ void CallTimerDialog::onInvite(const AmSipRequest& req)
152 151
   removeHeader(invite_req.hdrs, "P-App-Param");
153 152
   removeHeader(invite_req.hdrs, "P-App-Name");
154 153
 
155
-  dlg.updateStatus(invite_req);
154
+  //dlg.updateStatus(invite_req);
156 155
   recvd_req.insert(std::make_pair(invite_req.cseq,invite_req));
157 156
   
158 157
   set_sip_relay_only(true);
... ...
@@ -862,10 +862,10 @@ void ConferenceDialog::onSipRequest(const AmSipRequest& req)
862 862
   return;
863 863
 }
864 864
 
865
-void ConferenceDialog::onSipReply(const AmSipReply& reply)
865
+void ConferenceDialog::onSipReply(const AmSipReply& reply, int old_dlg_status)
866 866
 {
867 867
   int status = dlg.getStatus();
868
-  AmSession::onSipReply(reply);
868
+  AmSession::onSipReply(reply,old_dlg_status);
869 869
 
870 870
   DBG("ConferenceDialog::onSipReply: code = %i, reason = %s\n, status = %i\n",
871 871
       reply.code,reply.reason.c_str(),dlg.getStatus());
... ...
@@ -153,7 +153,7 @@ public:
153 153
   void onBye(const AmSipRequest& req);
154 154
 
155 155
   void onSipRequest(const AmSipRequest& req);
156
-  void onSipReply(const AmSipReply& reply);
156
+  void onSipReply(const AmSipReply& reply, int old_dlg_status);
157 157
 
158 158
 #ifdef WITH_SAS_TTS
159 159
   void onZRTPEvent(zrtp_event_t event, zrtp_stream_ctx_t *stream_ctx);
... ...
@@ -96,52 +96,54 @@ void SIPRegistration::setSessionEventHandler(AmSessionEventHandler* new_seh) {
96 96
   seh = new_seh;
97 97
 }
98 98
  
99
-void SIPRegistration::doRegistration() {
100
-  waiting_result = true;
101
-  req.to_tag     = "";
102
-  dlg.remote_tag = "";
103
-  req.r_uri    = "sip:"+info.domain;
104
-  dlg.remote_uri = req.r_uri;
105
-
106
-  // set outbound proxy as next hop 
107
-//   DBG("proxy is '%s' <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
108
-//       info.proxy.c_str());
109
-//   if (!info.proxy.empty()) {
110
-//     dlg.next_hop = info.proxy;
111
-//   } else if (!AmConfig::OutboundProxy.empty()) 
112
-//     dlg.next_hop = AmConfig::OutboundProxy;
113
-//   else 
114
-//     dlg.next_hop = "";
115
-  
116
-  dlg.sendRequest(req.method, "", "", "Expires: 1000\n");
117
-
118
-  // save TS
119
-  struct timeval now;
120
-  gettimeofday(&now, NULL);
121
-  reg_send_begin  = now.tv_sec;
99
+void SIPRegistration::doRegistration() 
100
+{
101
+    waiting_result = true;
102
+    req.to_tag     = "";
103
+    dlg.remote_tag = "";
104
+    req.r_uri    = "sip:"+info.domain;
105
+    dlg.remote_uri = req.r_uri;
106
+    
107
+    // set outbound proxy as next hop 
108
+    DBG("proxy is '%s' <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
109
+	info.proxy.c_str());
110
+    if (!info.proxy.empty()) {
111
+	dlg.outbound_proxy = info.proxy;
112
+    } else if (!AmConfig::OutboundProxy.empty()) 
113
+	dlg.outbound_proxy = AmConfig::OutboundProxy;
114
+    //else 
115
+    //    dlg.outbound_proxy = "";
116
+    
117
+    dlg.sendRequest(req.method, "", "", "Expires: 1000\n");
118
+    
119
+    // save TS
120
+    struct timeval now;
121
+    gettimeofday(&now, NULL);
122
+    reg_send_begin  = now.tv_sec;
122 123
 }
123 124
 
124
-void SIPRegistration::doUnregister() {
125
-  waiting_result = true;
126
-  req.to_tag     = "";
127
-  dlg.remote_tag = "";
128
-  req.r_uri    = "sip:"+info.domain;
129
-  dlg.remote_uri = req.r_uri;
130
-
131
-  // set outbound proxy as next hop 
132
-//   if (!info.proxy.empty()) {
133
-//     dlg.next_hop = info.proxy;
134
-//   } else if (!AmConfig::OutboundProxy.empty()) 
135
-//     dlg.next_hop = AmConfig::OutboundProxy;
136
-//   else 
137
-//     dlg.next_hop = "";
138
-
139
-  dlg.sendRequest(req.method, "", "", "Expires: 0\n");
125
+void SIPRegistration::doUnregister() 
126
+{
127
+    waiting_result = true;
128
+    req.to_tag     = "";
129
+    dlg.remote_tag = "";
130
+    req.r_uri      = "sip:"+info.domain;
131
+    dlg.remote_uri = req.r_uri;
132
+    
133
+    // set outbound proxy as next hop 
134
+    if (!info.proxy.empty()) {
135
+	dlg.outbound_proxy = info.proxy;
136
+    } else if (!AmConfig::OutboundProxy.empty()) 
137
+	dlg.outbound_proxy = AmConfig::OutboundProxy;
138
+    //else 
139
+    //    dlg.outbound_proxy = "";
140
+    
141
+    dlg.sendRequest(req.method, "", "", "Expires: 0\n");
140 142
 
141
-  // save TS
142
-  struct timeval now;
143
-  gettimeofday(&now, NULL);
144
-  reg_send_begin  = now.tv_sec;
143
+    // save TS
144
+    struct timeval now;
145
+    gettimeofday(&now, NULL);
146
+    reg_send_begin  = now.tv_sec;
145 147
 }
146 148
 
147 149
 void SIPRegistration::onSendRequest(const string& method,
... ...
@@ -315,7 +317,8 @@ void SIPRegistrarClient::onServerShutdown() {
315 317
 //   return;
316 318
 }
317 319
 
318
-void SIPRegistrarClient::process(AmEvent* ev) {
320
+void SIPRegistrarClient::process(AmEvent* ev) 
321
+{
319 322
   if (ev->event_id == E_SYSTEM) {
320 323
     AmSystemEvent* sys_ev = dynamic_cast<AmSystemEvent*>(ev);
321 324
     if(sys_ev){	
... ...
@@ -329,7 +332,7 @@ void SIPRegistrarClient::process(AmEvent* ev) {
329 332
 
330 333
   AmSipReplyEvent* sip_rep = dynamic_cast<AmSipReplyEvent*>(ev);
331 334
   if (sip_rep) {
332
-    onSipReplyEvent(sip_rep);
335
+      onSipReplyEvent(sip_rep);
333 336
     return;
334 337
   }
335 338
 
... ...
@@ -351,7 +354,7 @@ void SIPRegistrarClient::process(AmEvent* ev) {
351 354
 void SIPRegistrarClient::onSipReplyEvent(AmSipReplyEvent* ev) {
352 355
   SIPRegistration* reg = get_reg(ev->reply.local_tag);
353 356
   if (reg != NULL) {
354
-    reg->onSipReply(ev->reply);
357
+      reg->getDlg()->updateStatus(ev->reply);//onSipReply(ev->reply);
355 358
   }
356 359
 }
357 360
 
... ...
@@ -369,14 +372,13 @@ bool SIPRegistration::registerExpired(time_t now_sec) {
369 372
   return ((reg_begin+reg_expires) < (unsigned int)now_sec);	
370 373
 }
371 374
 
372
-void SIPRegistration::onSipReply(AmSipReply& reply) {
375
+void SIPRegistration::onSipReply(const AmSipReply& reply, int old_dlg_status)
376
+{
373 377
   if ((seh!=NULL) && seh->onSipReply(reply)) 
374 378
     return;
375 379
 
376 380
   waiting_result = false;
377 381
 
378
-  dlg.updateStatus(reply);
379
-
380 382
   if ((reply.code>=200)&&(reply.code<300)) {
381 383
     DBG("positive reply to REGISTER!\n");
382 384
     size_t end  = 0;
... ...
@@ -408,7 +410,7 @@ void SIPRegistration::onSipReply(AmSipReply& reply) {
408 410
 	if (server_contact.isEqual(local_contact)) {
409 411
 	  DBG("contact found\n");
410 412
 	  found = active = true;
411
-	  bool str2i(const string& str, unsigned int& result);
413
+	  //bool str2i(const string& str, unsigned int& result);
412 414
 					
413 415
 	  if (str2i(server_contact.params["expires"], reg_expires)) {
414 416
 	    ERROR("could not extract expires value.\n");
... ...
@@ -118,11 +118,15 @@ class SIPRegistration : public AmSipDialogEventHandler,
118 118
 		   const string& body,
119 119
 		   string& hdrs,
120 120
 		   int flags);
121
+
121 122
   // DialogControl if
122 123
   AmSipDialog* getDlg() { return &dlg; }
123 124
   // CredentialHolder	
124 125
   UACAuthCred* getCredentials() { return &cred; }
125
-  void onSipReply(AmSipReply& reply);
126
+
127
+  void onSipReply(const AmSipReply& reply, int old_dlg_status);
128
+  void onSipRequest(const AmSipRequest& req) {}
129
+  void onInvite2xx(const AmSipReply&) {}
126 130
 
127 131
   /** is this registration registered? */
128 132
   bool active; 
... ...
@@ -121,7 +121,7 @@ void SSTB2BDialog::onInvite(const AmSipRequest& req)
121 121
   removeHeader(invite_req.hdrs,PARAM_HDR);
122 122
   removeHeader(invite_req.hdrs,"P-App-Name");
123 123
 
124
-  dlg.updateStatus(req);
124
+  //dlg.updateStatus(req);
125 125
   recvd_req.insert(std::make_pair(req.cseq,req));
126 126
   
127 127
   set_sip_relay_only(true);
... ...
@@ -163,7 +163,8 @@ void SSTB2BDialog::onSipRequest(const AmSipRequest& req) {
163 163
   AmB2BCallerSession::onSipRequest(req);
164 164
 }
165 165
 
166
-void SSTB2BDialog::onSipReply(const AmSipReply& reply) {
166
+void SSTB2BDialog::onSipReply(const AmSipReply& reply, int old_dlg_status) 
167
+{
167 168
   TransMap::iterator t = relayed_req.find(reply.cseq);
168 169
   bool fwd = t != relayed_req.end();
169 170
 
... ...
@@ -173,7 +174,7 @@ void SSTB2BDialog::onSipReply(const AmSipReply& reply) {
173 174
       CALL_EVENT_H(onSipReply,reply);    
174 175
   }
175 176
 
176
-  AmB2BCallerSession::onSipReply(reply);
177
+  AmB2BCallerSession::onSipReply(reply,old_dlg_status);
177 178
 }
178 179
 
179 180
 bool SSTB2BDialog::onOtherReply(const AmSipReply& reply)
... ...
@@ -335,7 +336,8 @@ void SSTB2BCalleeSession::onSipRequest(const AmSipRequest& req) {
335 336
   AmB2BCalleeSession::onSipRequest(req);
336 337
 }
337 338
 
338
-void SSTB2BCalleeSession::onSipReply(const AmSipReply& reply) {
339
+void SSTB2BCalleeSession::onSipReply(const AmSipReply& reply, int old_dlg_status) 
340
+{
339 341
   // call event handlers where it is not done 
340 342
   TransMap::iterator t = relayed_req.find(reply.cseq);
341 343
   bool fwd = t != relayed_req.end();
... ...
@@ -346,13 +348,13 @@ void SSTB2BCalleeSession::onSipReply(const AmSipReply& reply) {
346 348
   }
347 349
 
348 350
   if (NULL == auth) {    
349
-    AmB2BCalleeSession::onSipReply(reply);
351
+      AmB2BCalleeSession::onSipReply(reply,old_dlg_status);
350 352
     return;
351 353
   }
352 354
   
353
-  int cseq_before = dlg.cseq;
355
+  unsigned int cseq_before = dlg.cseq;
354 356
   if (!auth->onSipReply(reply)) {
355
-    AmB2BCalleeSession::onSipReply(reply);
357
+      AmB2BCalleeSession::onSipReply(reply,old_dlg_status);
356 358
   } else {
357 359
     if (cseq_before != dlg.cseq) {
358 360
       DBG("uac_auth consumed reply with cseq %d and resent with cseq %d; "
... ...
@@ -93,7 +93,7 @@ class SSTB2BDialog : public AmB2BCallerSession
93 93
   void sendReinvite(bool updateSDP, const string& headers);
94 94
 
95 95
  protected:
96
-  void onSipReply(const AmSipReply& reply);
96
+    void onSipReply(const AmSipReply& reply, int old_dlg_status);
97 97
   void onSipRequest(const AmSipRequest& req);  
98 98
 
99 99
  protected:
... ...
@@ -115,7 +115,7 @@ class SSTB2BCalleeSession
115 115
 
116 116
  protected:
117 117
   void onSipRequest(const AmSipRequest& req);
118
-  void onSipReply(const AmSipReply& reply);
118
+    void onSipReply(const AmSipReply& reply, int old_dlg_status);
119 119
   void onSendRequest(const string& method, const string& content_type,
120 120
 		     const string& body, string& hdrs, int flags, unsigned int cseq);
121 121
 
... ...
@@ -183,7 +183,7 @@ void SWPrepaidSIPDialog::onInvite(const AmSipRequest& req)
183 183
     }
184 184
 
185 185
     invite_req = req;
186
-    dlg.updateStatus(req);
186
+    //dlg.updateStatus(req);
187 187
     recvd_req.insert(std::make_pair(req.cseq,req));
188 188
 
189 189
     connectCallee("<" + m_ruri + ">", m_proxy + ";sw_prepaid", true);
... ...
@@ -173,12 +173,13 @@ void WebConferenceDialog::onSessionStart(const AmSipReply& rep) {
173 173
   connectConference(dlg.user);
174 174
 }
175 175
 
176
-void WebConferenceDialog::onSipReply(const AmSipReply& reply) {
177
-  int status = dlg.getStatus();
176
+void WebConferenceDialog::onSipReply(const AmSipReply& reply, int old_dlg_status) 
177
+{
178
+  //int status = dlg.getStatus();
178 179
 
179
-  AmSession::onSipReply(reply);
180
+  AmSession::onSipReply(reply,old_dlg_status);
180 181
 
181
-  if ((status < AmSipDialog::Connected) && 
182
+  if ((old_dlg_status < AmSipDialog::Connected) && 
182 183
       (dlg.getStatus() == AmSipDialog::Disconnected)) {
183 184
     DBG("Call failed.\n");
184 185
     setStopped();
... ...
@@ -94,7 +94,7 @@ public:
94 94
   ~WebConferenceDialog();
95 95
 
96 96
   void process(AmEvent* ev);
97
-  void onSipReply(const AmSipReply& reply);
97
+  void onSipReply(const AmSipReply& reply, int old_dlg_status);
98 98
   void onSessionStart(const AmSipRequest& req);
99 99
   void onSessionStart(const AmSipReply& rep);
100 100
   void onEarlySessionStart(const AmSipReply& rep);
... ...
@@ -353,9 +353,10 @@ void AmB2ABCalleeSession::onSessionStart(const AmSipReply& rep) {
353 353
   relayEvent(new B2ABConnectAudioEvent());
354 354
 }
355 355
 
356
-void AmB2ABCalleeSession::onSipReply(const AmSipReply& rep) {
357
-  int status_before = dlg.getStatus();
358
-  AmB2ABSession::onSipReply(rep);
356
+void AmB2ABCalleeSession::onSipReply(const AmSipReply& rep, int old_dlg_status) {
357
+
358
+    int status_before = old_dlg_status;//dlg.getStatus();
359
+    AmB2ABSession::onSipReply(rep, old_dlg_status);
359 360
   int status = dlg.getStatus();
360 361
  
361 362
   if ((status_before == AmSipDialog::Pending)&&
... ...
@@ -247,7 +247,7 @@ class AmB2ABCalleeSession: public AmB2ABSession
247 247
 
248 248
   void onEarlySessionStart(const AmSipReply& rep);
249 249
   void onSessionStart(const AmSipReply& rep);
250
-  void onSipReply(const AmSipReply& rep);	
250
+  void onSipReply(const AmSipReply& rep, int old_dlg_status);	
251 251
 
252 252
  protected:
253 253
   void onB2ABEvent(B2ABEvent* ev);
... ...
@@ -188,14 +188,14 @@ void AmB2BSession::onSipRequest(const AmSipRequest& req)
188 188
   if(!fwd)
189 189
     AmSession::onSipRequest(req);
190 190
   else {
191
-    dlg.updateStatus(req);
191
+      //dlg.updateStatus(req);
192 192
     recvd_req.insert(std::make_pair(req.cseq,req));
193 193
   }
194 194
 
195 195
   relayEvent(new B2BSipRequestEvent(req,fwd));
196 196
 }
197 197
 
198
-void AmB2BSession::onSipReply(const AmSipReply& reply)
198
+void AmB2BSession::onSipReply(const AmSipReply& reply, int old_dlg_status)
199 199
 {
200 200
   TransMap::iterator t = relayed_req.find(reply.cseq);
201 201
   bool fwd = t != relayed_req.end();
... ...
@@ -206,7 +206,7 @@ void AmB2BSession::onSipReply(const AmSipReply& reply)
206 206
     AmSipReply n_reply = reply;
207 207
     n_reply.cseq = t->second.cseq;
208 208
     
209
-    dlg.updateStatus(reply, false);
209
+    //dlg.updateStatus(reply, false);
210 210
     relayEvent(new B2BSipReplyEvent(n_reply,true));
211 211
 
212 212
     if(reply.code >= 200) {
... ...
@@ -238,28 +238,33 @@ void AmB2BSession::onSipReply(const AmSipReply& reply)
238 238
 	// todo (?): add do_200_ack flag to AmSession::onSipReply and call AmSession::onSipReply
239 239
 	CALL_EVENT_H(onSipReply,reply);
240 240
 	
241
-	int status = dlg.getStatus();
242
-	dlg.updateStatus(reply, false);
241
+	//int status = dlg.getStatus();
242
+	//dlg.updateStatus(reply, false);
243 243
 	
244
-	if (status != dlg.getStatus())
244
+	if (old_dlg_status != dlg.getStatus())
245 245
 	  DBG("Dialog status changed %s -> %s (stopped=%s) \n", 
246
-	      AmSipDialog::status2str[status], 
246
+	      AmSipDialog::status2str[old_dlg_status], 
247 247
 	      AmSipDialog::status2str[dlg.getStatus()],
248 248
 	      getStopped() ? "true" : "false");
249 249
 	else 
250
-	  DBG("Dialog status stays %s (stopped=%s)\n", AmSipDialog::status2str[status], 
250
+	  DBG("Dialog status stays %s (stopped=%s)\n", AmSipDialog::status2str[old_dlg_status], 
251 251
 	      getStopped() ? "true" : "false");
252 252
       } else {
253 253
 	relayed_body_req.erase(rel_body_it);
254
-	AmSession::onSipReply(reply);
254
+	AmSession::onSipReply(reply, old_dlg_status);
255 255
       }      
256 256
     } else {
257
-      AmSession::onSipReply(reply);
257
+	AmSession::onSipReply(reply, old_dlg_status);
258 258
     }
259 259
     relayEvent(new B2BSipReplyEvent(reply,false));
260 260
   }
261 261
 }
262 262
 
263
+void AmB2BSession::onInvite2xx(const AmSipReply& reply)
264
+{
265
+    // do not send the 200 ACK yet...
266
+}
267
+
263 268
 void AmB2BSession::relayEvent(AmEvent* ev)
264 269
 {
265 270
   DBG("AmB2BSession::relayEvent: id=%s\n",
... ...
@@ -170,7 +170,8 @@ class AmB2BSession: public AmSession
170 170
 
171 171
   /** @see AmSession */
172 172
   void onSipRequest(const AmSipRequest& req);
173
-  void onSipReply(const AmSipReply& reply);
173
+  void onSipReply(const AmSipReply& reply, int old_dlg_status);
174
+  void onInvite2xx(const AmSipReply& reply);
174 175
 
175 176
   /** @see AmEventQueue */
176 177
   void process(AmEvent* event);
... ...
@@ -42,9 +42,7 @@ class AmPluginFactory;
42 42
 class AmSessionFactory;
43 43
 class AmSessionEventHandlerFactory;
44 44
 class AmDynInvokeFactory;
45
-//class AmSIPEventHandler;
46 45
 class AmLoggingFacility;
47
-//class AmCtrlInterfaceFactory;
48 46
 class AmSipRequest;
49 47
 
50 48
 struct amci_exports_t;
... ...
@@ -120,7 +118,6 @@ class AmPlugIn : public AmPayloadProviderInterface
120 118
   int loadBasePlugIn(AmPluginFactory* cb);
121 119
   int loadDiPlugIn(AmPluginFactory* cb);
122 120
   int loadLogFacPlugIn(AmPluginFactory* f);
123
-  //int loadCtrlFacPlugIn(AmPluginFactory* f);
124 121
 
125 122
  public:
126 123
 
... ...
@@ -636,9 +636,9 @@ void AmSession::process(AmEvent* ev)
636 636
   }
637 637
 
638 638
   AmAudioEvent* audio_ev = dynamic_cast<AmAudioEvent*>(ev);
639
-  if(audio_ev && (audio_ev->event_id == AmAudioEvent::cleared)){
640
-    setStopped();
641
-    return;
639
+  if(audio_ev){
640
+      onAudioEvent(audio_ev);
641
+      return;
642 642
   }
643 643
 
644 644
   AmDtmfEvent* dtmf_ev = dynamic_cast<AmDtmfEvent*>(ev);
... ...
@@ -671,14 +671,16 @@ void AmSession::onSipEvent(AmSipEvent* sip_ev)
671 671
 
672 672
   AmSipRequestEvent* req_ev = dynamic_cast<AmSipRequestEvent*>(sip_ev);
673 673
   if(req_ev) {
674
-    onSipRequest(req_ev->req);
674
+      //onSipRequest(req_ev->req);
675
+    dlg.updateStatus(req_ev->req);
675 676
     return;
676 677
   }
677 678
     
678 679
 
679 680
   AmSipReplyEvent* reply_ev = dynamic_cast<AmSipReplyEvent*>(sip_ev);
680 681
   if(reply_ev) {
681
-    onSipReply(reply_ev->reply);
682
+      //onSipReply(reply_ev->reply);
683
+    dlg.updateStatus(reply_ev->reply);
682 684
     return;
683 685
   }
684 686
 
... ...
@@ -689,7 +691,7 @@ void AmSession::onSipRequest(const AmSipRequest& req)
689 691
 {
690 692
   CALL_EVENT_H(onSipRequest,req);
691 693
 
692
-  dlg.updateStatus(req);
694
+  //dlg.updateStatus(req);
693 695
     
694 696
   DBG("onSipRequest: method = %s\n",req.method.c_str());
695 697
   if(req.method == "INVITE"){
... ...
@@ -730,25 +732,25 @@ void AmSession::onSipRequest(const AmSipRequest& req)
730 732
 }
731 733
 
732 734
 
733
-void AmSession::onSipReply(const AmSipReply& reply)
735
+void AmSession::onSipReply(const AmSipReply& reply, int old_dlg_status)
734 736
 {
735 737
   CALL_EVENT_H(onSipReply,reply);
736 738
 
737
-  int status = dlg.getStatus();
738
-  dlg.updateStatus(reply);
739
+//   int status = dlg.getStatus();
740
+//   dlg.updateStatus(reply);
739 741
 
740
-  if (status != dlg.getStatus())
742
+  if (old_dlg_status != dlg.getStatus())
741 743
     DBG("Dialog status changed %s -> %s (stopped=%s) \n", 
742
-	AmSipDialog::status2str[status], 
744
+	AmSipDialog::status2str[old_dlg_status], 
743 745
 	AmSipDialog::status2str[dlg.getStatus()],
744 746
 	sess_stopped.get() ? "true" : "false");
745 747
   else 
746
-    DBG("Dialog status stays %s (stopped=%s)\n", AmSipDialog::status2str[status], 
748
+    DBG("Dialog status stays %s (stopped=%s)\n", AmSipDialog::status2str[old_dlg_status], 
747 749
 	sess_stopped.get() ? "true" : "false");
748 750
 
749 751
 
750 752
   if (negotiate_onreply) {    
751
-    if(status < AmSipDialog::Connected){
753
+    if(old_dlg_status < AmSipDialog::Connected){
752 754
       
753 755
       switch(dlg.getStatus()){
754 756
 	
... ...
@@ -764,8 +766,8 @@ void AmSession::onSipReply(const AmSipReply& reply)
764 766
 	    onSessionStart(reply);
765 767
 		  
766 768
 	    if(input || output || local_input || local_output)
767
-	      AmMediaProcessor::instance()->addSession(this,
768
-						       callgroup); 
769
+		AmMediaProcessor::instance()->addSession(this,
770
+							 callgroup); 
769 771
 	    else { 
770 772
 	      DBG("no audio input and output set. "
771 773
 		  "Session will not be attached to MediaProcessor.\n");
... ...
@@ -824,6 +826,18 @@ void AmSession::onSipReply(const AmSipReply& reply)
824 826
   }
825 827
 }
826 828
 
829
+void AmSession::onInvite2xx(const AmSipReply& reply)
830
+{
831
+    AmSipTransaction* t = dlg.get_uac_trans(reply.cseq);
832
+    if(t) dlg.send_200_ack(*t);
833
+}
834
+
835
+void AmSession::onAudioEvent(AmAudioEvent* audio_ev)
836
+{
837
+    if (audio_ev->event_id == AmAudioEvent::cleared)
838
+	setStopped();
839
+}
840
+
827 841
 void AmSession::onInvite(const AmSipRequest& req)
828 842
 {
829 843
   try {
... ...
@@ -467,8 +467,15 @@ public:
467 467
   /** Entry point for SIP Requests   */
468 468
   virtual void onSipRequest(const AmSipRequest& req);
469 469
   /** Entry point for SIP Replies   */
470
-  virtual void onSipReply(const AmSipReply& reply);
470
+    virtual void onSipReply(const AmSipReply& reply, int old_dlg_status);
471 471
 
472
+    /** 2xx reply has been received for an INVITE transaction */
473
+    virtual void onInvite2xx(const AmSipReply& reply);
474
+
475
+    /**
476
+     * Entry point for Audio events
477
+     */
478
+    virtual void onAudioEvent(AmAudioEvent* audio_ev);
472 479
 
473 480
   /**
474 481
    * entry point for system events
... ...
@@ -64,6 +64,7 @@ public:
64 64
    * shall be stopped after them.
65 65
    */
66 66
   virtual bool process(AmEvent*);
67
+
67 68
   virtual bool onSipEvent(AmSipEvent*);
68 69
   virtual bool onSipRequest(const AmSipRequest&);
69 70
   virtual bool onSipReply(const AmSipReply&);
... ...
@@ -75,6 +75,11 @@ void AmSipDialog::updateStatus(const AmSipRequest& req)
75 75
     return;
76 76
   }
77 77
 
78
+  if (req.cseq <= r_cseq){
79
+      reply_error(req,500,"Server Internal Error");
80
+      return;
81
+  }
82
+
78 83
   if(uas_trans.find(req.cseq) == uas_trans.end()){
79 84
       DBG("req.tt = {%p,%p}\n",req.tt._bucket, req.tt._t);
80 85
       uas_trans[req.cseq] = AmSipTransaction(req.method,req.cseq,req.tt);
... ...
@@ -105,6 +110,9 @@ void AmSipDialog::updateStatus(const AmSipRequest& req)
105 110
     local_party  = req.to;
106 111
     route        = req.route;
107 112
   }
113
+  
114
+  if(hdl)
115
+      hdl->onSipRequest(req);
108 116
 }
109 117
 
110 118
 /**
... ...
@@ -186,7 +194,7 @@ int AmSipDialog::updateStatusReply(const AmSipRequest& req, unsigned int code)
186 194
   return 0;
187 195
 }
188 196
 
189
-void AmSipDialog::updateStatus(const AmSipReply& reply, bool do_200_ack)
197
+void AmSipDialog::updateStatus(const AmSipReply& reply/*, bool do_200_ack*/)
190 198
 {
191 199
   TransMap::iterator t_it = uac_trans.find(reply.cseq);
192 200
   if(t_it == uac_trans.end()){
... ...
@@ -197,6 +205,7 @@ void AmSipDialog::updateStatus(const AmSipReply& reply, bool do_200_ack)
197 205
   DBG("updateStatus(reply): transaction found!\n");
198 206
 
199 207
   AmSipTransaction& t = t_it->second;
208
+  int old_dlg_status = status;
200 209
 
201 210
   // rfc3261 12.1
202 211
   // Dialog established only by 101-199 or 2xx 
... ...
@@ -262,12 +271,22 @@ void AmSipDialog::updateStatus(const AmSipReply& reply, bool do_200_ack)
262 271
     // TODO: 
263 272
     // - place this somewhere else.
264 273
     //   (probably in AmSession...)
265
-    if((reply.code < 300) && (t.method == "INVITE") && do_200_ack) {
266
-      send_200_ack(t);
267
-    }
274
+    if((reply.code < 300) && (t.method == "INVITE")) {
268 275
 
269
-    uac_trans.erase(t_it);
276
+	if(hdl) {
277
+	    hdl->onInvite2xx(reply);
278
+	}
279
+	else {
280
+	    send_200_ack(t);
281
+	}
282
+    }
283
+    else {
284
+	uac_trans.erase(t_it);
285
+    }
270 286
   }
287
+
288
+  if(hdl)
289
+      hdl->onSipReply(reply, old_dlg_status);
271 290
 }
272 291
 
273 292
 string AmSipDialog::getContactHdr()
... ...
@@ -608,6 +627,16 @@ string AmSipDialog::get_uac_trans_method(unsigned int cseq)
608 627
   return "";
609 628
 }
610 629
 
630
+AmSipTransaction* AmSipDialog::get_uac_trans(unsigned int cseq)
631
+{
632
+    TransMap::iterator t = uac_trans.find(cseq);
633
+    
634
+    if (t != uac_trans.end())
635
+	return &(t->second);
636
+    
637
+    return NULL;
638
+}
639
+
611 640
 int AmSipDialog::drop()
612 641
 {	
613 642
   status = Disconnected;
... ...
@@ -636,7 +665,6 @@ int AmSipDialog::send_200_ack(const AmSipTransaction& t,
636 665
 
637 666
   req.method = "ACK";
638 667
   req.r_uri = remote_uri;
639
-  //req.next_hop = next_hop;
640 668
 
641 669
   req.from = SIP_HDR_COLSP(SIP_HDR_FROM) + local_party;
642 670
   if(!local_tag.empty())
... ...
@@ -70,23 +70,35 @@ typedef std::map<int,AmSipTransaction> TransMap;
70 70
  */
71 71
 class AmSipDialogEventHandler 
72 72
 {
73
- public:
74
-  virtual void onSendRequest(const string& method,
73
+public:
74
+    
75
+    /** Hook called when a request has been received */
76
+    virtual void onSipRequest(const AmSipRequest& req)=0;
77
+
78
+    /** Hook called when a reply has been received */
79
+    virtual void onSipReply(const AmSipReply& reply, int old_dlg_status)=0;
80
+
81
+    /** Hook called before a request is sent */
82
+    virtual void onSendRequest(const string& method,
83
+			       const string& content_type,
84
+			       const string& body,
85
+			       string& hdrs,
86
+			       int flags,
87
+			       unsigned int cseq)=0;
88
+    
89
+    /** Hook called before a reply is sent */
90
+    virtual void onSendReply(const AmSipRequest& req,
91
+			     unsigned int  code,
92
+			     const string& reason,
75 93
 			     const string& content_type,
76 94
 			     const string& body,
77 95
 			     string& hdrs,
78
-			     int flags,
79
-			     unsigned int cseq)=0;
80
-
81
-  virtual void onSendReply(const AmSipRequest& req,
82
-			   unsigned int  code,
83
-			   const string& reason,
84
-			   const string& content_type,
85
-			   const string& body,
86
-			   string& hdrs,
87
-			   int flags)=0;
88
-
89
-  virtual ~AmSipDialogEventHandler() {};
96
+			     int flags)=0;
97
+    
98
+    /** Hook called when a local INVITE request has been replied with 2xx */
99
+    virtual void onInvite2xx(const AmSipReply& reply)=0;
100
+
101
+    virtual ~AmSipDialogEventHandler() {};
90 102
 };
91 103
 
92 104
 /**
... ...
@@ -136,7 +148,8 @@ class AmSipDialog
136 148
   string outbound_proxy;
137 149
   bool   force_outbound_proxy;
138 150
 
139
-  int    cseq; // Local CSeq for next request
151
+  unsigned int cseq; // Local CSeq for next request
152
+  unsigned int r_cseq; // last remote CSeq  
140 153
 
141 154
   AmSipDialog(AmSipDialogEventHandler* h=0);
142 155
   ~AmSipDialog();
... ...
@@ -145,12 +158,12 @@ class AmSipDialog
145 158
   int    getStatus() { return status; }
146 159
   string getContactHdr();
147 160
 
148
-  void updateStatus(const AmSipRequest& req);
149
-  void updateStatus(const AmSipReply& reply, bool do_200_ack=true);
150
-
151 161
   /** update Status from locally originated request (e.g. INVITE) */
152 162
   void updateStatusFromLocalRequest(const AmSipRequest& req);
153 163
 
164
+  void updateStatus(const AmSipRequest& req);
165
+  void updateStatus(const AmSipReply& reply);
166
+    
154 167
   int reply(const AmSipRequest& req,
155 168
 	    unsigned int  code, 
156 169
 	    const string& reason,
... ...
@@ -190,6 +203,8 @@ class AmSipDialog
190 203
    */
191 204
   string get_uac_trans_method(unsigned int cseq);
192 205
 
206
+  AmSipTransaction* get_uac_trans(unsigned int cseq);
207
+
193 208
   static int reply_error(const AmSipRequest& req,
194 209
 			 unsigned int  code, 
195 210
 			 const string& reason,