Browse code

core: downgrade error msg to debug

Raphael Coeffic authored on 13/05/2014 15:01:33
Showing 1 changed files
... ...
@@ -555,7 +555,7 @@ int AmSipDialog::bye(const string& hdrs, int flags)
555 555
 
556 556
       // missing AmSipRequest to be able
557 557
       // to send the reply on behalf of the app.
558
-      ERROR("ignoring bye() in %s state: no UAS transaction to reply",getStatusStr());
558
+      DBG("ignoring bye() in %s state: no UAS transaction to reply",getStatusStr());
559 559
       setStatus(Disconnected);
560 560
       return 0;
561 561
 
Browse code

core: added info method to AmSipDialog

Juha Heinanen authored on 08/05/2014 18:29:55
Showing 1 changed files
... ...
@@ -641,6 +641,17 @@ int AmSipDialog::refer(const string& refer_to,
641 641
   }	
642 642
 }
643 643
 
644
+int AmSipDialog::info(const string& hdrs, const AmMimeBody* body)
645
+{
646
+  if(getStatus() == Connected) {
647
+    return sendRequest("INFO", body, hdrs);
648
+  } else {
649
+    DBG("info(): we are not Connected."
650
+	"(status=%s). do nothing!\n", getStatusStr());
651
+    return 0;
652
+  }
653
+}    
654
+
644 655
 // proprietary
645 656
 int AmSipDialog::transfer(const string& target)
646 657
 {
Browse code

core: fixed onRxReplyStatus method call

Raphael Coeffic authored on 02/04/2014 10:35:20 • Stefan Sayer committed on 08/04/2014 12:15:28
Showing 1 changed files
... ...
@@ -442,7 +442,7 @@ bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply)
442 442
     if(hdl) ((AmSipDialogEventHandler*)hdl)->onInvite2xx(reply);
443 443
 
444 444
   } else {
445
-    cont = AmBasicSipDialog::onRxReplyStatus(reply,t_uac_it);
445
+    cont = AmBasicSipDialog::onRxReplyStatus(reply);
446 446
   }
447 447
 
448 448
   return cont && rel100.onReplyIn(reply);
Browse code

core: b/f: do not re-use the uac transaction iterator after onRxReplyStatus()

The transaction could possibly have been deleted in between, whereby it is unclear where.

Raphael Coeffic authored on 02/04/2014 09:53:38 • Stefan Sayer committed on 08/04/2014 12:09:37
Showing 1 changed files
... ...
@@ -332,8 +332,7 @@ void AmSipDialog::onRequestTxed(const AmSipRequest& req)
332 332
   }
333 333
 }
334 334
 
335
-bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply, 
336
-				  TransMap::iterator t_uac_it)
335
+bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply)
337 336
 {
338 337
   // rfc3261 12.1
339 338
   // Dialog established only by 101-199 or 2xx 
Browse code

Merge remote-tracking branch 'frafos/tcp-trsp' into 1.6-dev-ccdsm

* frafos/tcp-trsp: (55 commits)
sip: b/f: fix segfault in try_next_ip()
sip: fns: solved some memory management issues
sip: b/f: fix case-sensitivity issue for transport parameter
sip: b/f: added Content-Length-HF to non-200 ACK
sip: b/f: return immediately from parse_headers() if the input string is empty
sbc: b/f: correct fix for nat_handling flag support
Revert "b/f:core:dlg: reevaluate nat_handling flag after onSipRequest/onInvite"
sip: initialise sip_destination correctly
sip: b/f: avoid checking header type more than once in parse_headers()
b/f:core:dlg: reevaluate nat_handling flag after onSipRequest/onInvite
sip: c/f: fixed copy-paste error
sip: insert into blacklist only if default_bl_ttl != 0
sip: try next target on TCP immediate errors
sip: moved resolve_targets() to resolver
sip: moved sip_target_set to resolver
sip: patch temporary Contact-HFs instead of the given ones
core: fixed small issue when sending BYE on 2xx w/o to-tag
sip: tcp: small fixes to avoid libevent errors
core: set transport when updating next-hop
sip: tcp: hash only the sin[6]_addr to compute the tcp worker thread
...

Conflicts:
core/sip/resolver.cpp
core/sip/resolver.h
core/sip/sip_parser.h
core/sip/trans_layer.cpp
core/sip/trans_layer.h

Stefan Sayer authored on 20/01/2014 10:01:13
Showing 0 changed files
Browse code

core: add Referred-By to AmSipDialog::refer()

Stefan Sayer authored on 03/01/2014 12:59:18
Showing 1 changed files
... ...
@@ -626,12 +626,16 @@ int AmSipDialog::update(const AmMimeBody* body,
626 626
 }
627 627
 
628 628
 int AmSipDialog::refer(const string& refer_to,
629
-		       int expires)
629
+		       int expires,
630
+		       const string& referred_by)
630 631
 {
631 632
   if(getStatus() == Connected) {
632 633
     string hdrs = SIP_HDR_COLSP(SIP_HDR_REFER_TO) + refer_to + CRLF;
633 634
     if (expires>=0) 
634 635
       hdrs+= SIP_HDR_COLSP(SIP_HDR_EXPIRES) + int2str(expires) + CRLF;
636
+    if (!referred_by.empty())
637
+      hdrs+= SIP_HDR_COLSP(SIP_HDR_REFERRED_BY) + referred_by + CRLF;
638
+
635 639
     return sendRequest("REFER", NULL, hdrs);
636 640
   }
637 641
   else {
Browse code

core: fixed small issue when sending BYE on 2xx w/o to-tag

It's better to ACK the INVITE transaction before sending BYE.

Raphael Coeffic authored on 18/11/2013 13:53:03
Showing 1 changed files
... ...
@@ -361,6 +361,7 @@ bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply,
361 361
 	  DBG("received 2xx reply without to-tag "
362 362
 	      "(callid=%s): sending BYE\n",reply.callid.c_str());
363 363
 
364
+	  send_200_ack(reply.cseq);
364 365
 	  sendRequest(SIP_METH_BYE);
365 366
 	}
366 367
 	else {
Browse code

sip: kill UAC transactions on cancel() even if no reply has been received yet.

In case no reply has been received yet, the stack would have only flagged the desire to cancel the transaction, but not stopped the UAC transaction, thus causing unneeded retransmissions.

Raphael Coeffic authored on 17/12/2013 15:27:46
Showing 1 changed files
... ...
@@ -64,7 +64,7 @@ AmSipDialog::AmSipDialog(AmSipDialogEventHandler* h)
64 64
   : AmBasicSipDialog(h),oa(this),rel100(this,h),
65 65
     offeranswer_enabled(true),
66 66
     early_session_started(false),session_started(false),
67
-    pending_invites(0),cancel_pending(false),
67
+    pending_invites(0),
68 68
     sdp_local(), sdp_remote()
69 69
 {
70 70
 }
... ...
@@ -372,10 +372,6 @@ bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply,
372 372
 	setStatus(Disconnected);
373 373
 	setRemoteTag(reply.to_tag);
374 374
       }
375
-      else if(cancel_pending){
376
-	cancel_pending = false;
377
-	bye();
378
-      }
379 375
       break;
380 376
 
381 377
     case Early:
... ...
@@ -712,12 +708,8 @@ int AmSipDialog::cancel()
712 708
 	t != uac_trans.rend(); t++) {
713 709
 	
714 710
 	if(t->second.method == SIP_METH_INVITE){
715
-	  
716
-	  if(getStatus() == Trying){
717
-	    cancel_pending=true;
718
-	    return 0;
719
-	  }
720
-	  else if(getStatus() != Cancelling){
711
+
712
+	  if(getStatus() != Cancelling){
721 713
 	    setStatus(Cancelling);
722 714
 	    return SipCtrlInterface::cancel(&t->second.tt, local_tag,
723 715
 					    t->first, t->second.hdrs);
Browse code

sip: b/f: find the correct transaction to cancel

In case the request has been sent to multiple destinations for failover purposes, new transactions might be created. To cancel such transactions, it necessary to find the last one by looking at the dialog-id and cseq, as only a reference to the original transaction has been saved in the dialog state.

Raphael Coeffic authored on 08/12/2013 13:55:05
Showing 1 changed files
... ...
@@ -719,7 +719,8 @@ int AmSipDialog::cancel()
719 719
 	  }
720 720
 	  else if(getStatus() != Cancelling){
721 721
 	    setStatus(Cancelling);
722
-	    return SipCtrlInterface::cancel(&t->second.tt,t->second.hdrs);
722
+	    return SipCtrlInterface::cancel(&t->second.tt, local_tag,
723
+					    t->first, t->second.hdrs);
723 724
 	  }
724 725
 	  else {
725 726
 	    ERROR("INVITE transaction has already been cancelled\n");
Browse code

core: fixed small issue when sending BYE on 2xx w/o to-tag

It's better to ACK the INVITE transaction before sending BYE.

Raphael Coeffic authored on 18/11/2013 13:53:03
Showing 1 changed files
... ...
@@ -361,6 +361,7 @@ bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply,
361 361
 	  DBG("received 2xx reply without to-tag "
362 362
 	      "(callid=%s): sending BYE\n",reply.callid.c_str());
363 363
 
364
+	  send_200_ack(reply.cseq);
364 365
 	  sendRequest(SIP_METH_BYE);
365 366
 	}
366 367
 	else {
Browse code

sip: destination blacklist

When a destination cannot be reached (timeout+grace period), the IP/port tuple is blacklisted for a certain period of time (default_bl_ttl). if all destinations for a message are blacklisted, a 500 error reply is generated internally.

In case a downstream proxy or UA returns 503, this proxy or UA also gets blacklisted.

Raphael Coeffic authored on 13/09/2013 10:01:03
Showing 1 changed files
... ...
@@ -416,6 +416,9 @@ bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply,
416 416
       }
417 417
       break;
418 418
 
419
+    //case Connected: // late 200...
420
+    //  TODO: if reply.to_tag != getRemoteTag()
421
+    //        -> ACK + BYE (+absorb answer)
419 422
     default:
420 423
       break;
421 424
     }
Browse code

core/sbc: added application support for Max-Forwards

- reply w/ 400 if Max-Forwards is not parseable or out of range.
- reply w/ 483 if Max-Forwards==0 and request should be forwarded.
- automatically add Max-Forwards HF if no value specified for sent requests.

Raphael Coeffic authored on 06/09/2013 08:58:54 • Václav Kubart committed on 16/10/2013 09:19:53
Showing 1 changed files
... ...
@@ -747,8 +747,10 @@ int AmSipDialog::send_200_ack(unsigned int inv_cseq,
747 747
   // acceptable, the UAC core MUST generate a valid answer in the ACK and
748 748
   // then send a BYE immediately."
749 749
 
750
-  if (uac_trans.find(inv_cseq) == uac_trans.end()) {
751
-    ERROR("trying to ACK a non-existing transaction (cseq=%i;local_tag=%s)\n",inv_cseq,local_tag.c_str());
750
+  TransMap::iterator inv_it = uac_trans.find(inv_cseq);
751
+  if (inv_it == uac_trans.end()) {
752
+    ERROR("trying to ACK a non-existing transaction (cseq=%i;local_tag=%s)\n",
753
+	  inv_cseq,local_tag.c_str());
752 754
     return -1;
753 755
   }
754 756
 
... ...
@@ -773,6 +775,8 @@ int AmSipDialog::send_200_ack(unsigned int inv_cseq,
773 775
     
774 776
   req.route = getRoute();
775 777
 
778
+  req.max_forwards = inv_it->second.max_forwards;
779
+
776 780
   if(body != NULL)
777 781
     req.body = *body;
778 782
 
... ...
@@ -783,9 +787,6 @@ int AmSipDialog::send_200_ack(unsigned int inv_cseq,
783 787
     // add Signature
784 788
     if (AmConfig::Signature.length())
785 789
       req.hdrs += SIP_HDR_COLSP(SIP_HDR_USER_AGENT) + AmConfig::Signature + CRLF;
786
-    
787
-    req.hdrs += SIP_HDR_COLSP(SIP_HDR_MAX_FORWARDS) 
788
-      + int2str(AmConfig::MaxForwards) + CRLF;
789 790
   }
790 791
 
791 792
   int res = SipCtrlInterface::send(req, local_tag,
Browse code

core: do not try to send a CANCEL request in Cancelling state.

Raphael Coeffic authored on 26/06/2013 13:37:03
Showing 1 changed files
... ...
@@ -524,7 +524,6 @@ int AmSipDialog::bye(const string& hdrs, int flags)
524 524
     case Trying:
525 525
     case Proceeding:
526 526
     case Early:
527
-    case Cancelling:
528 527
 	if(getUACInvTransPending())
529 528
 	    return cancel();
530 529
 	else {  
... ...
@@ -540,12 +539,27 @@ int AmSipDialog::bye(const string& hdrs, int flags)
540 539
 	    // missing AmSipRequest to be able
541 540
 	    // to send the reply on behalf of the app.
542 541
 	    ERROR("ignoring bye() in %s state: "
543
-		  "no UAC transaction to cancel.\n",
542
+		  "no UAC transaction to cancel or UAS transaction to reply.\n",
544 543
 		  getStatusStr());
545 544
 	    setStatus(Disconnected);
546 545
 	}
547 546
 	return 0;
548 547
 
548
+    case Cancelling:
549
+      for (TransMap::iterator it=uas_trans.begin();
550
+	   it != uas_trans.end(); it++) {
551
+	if (it->second.method == SIP_METH_INVITE){
552
+	  // let's quit this call by sending final reply
553
+	  return reply(it->second, 487,"Request terminated");
554
+	}
555
+      }
556
+
557
+      // missing AmSipRequest to be able
558
+      // to send the reply on behalf of the app.
559
+      ERROR("ignoring bye() in %s state: no UAS transaction to reply",getStatusStr());
560
+      setStatus(Disconnected);
561
+      return 0;
562
+
549 563
     default:
550 564
         DBG("bye(): we are not connected "
551 565
 	    "(status=%s). do nothing!\n",getStatusStr());
Browse code

sbc: added R-URI host patching with resolved fqdn.

Raphael Coeffic authored on 19/06/2013 10:54:57
Showing 1 changed files
... ...
@@ -777,7 +777,7 @@ int AmSipDialog::send_200_ack(unsigned int inv_cseq,
777 777
   int res = SipCtrlInterface::send(req, local_tag,
778 778
 				   remote_tag.empty() || !next_hop_1st_req ? 
779 779
 				   next_hop : "",
780
-				   outbound_interface, logger);
780
+				   outbound_interface, 0, logger);
781 781
   if (res)
782 782
     return res;
783 783
 
Browse code

sip: fixes CANCEL handling

do not overwrite INVITE transaction in uas_trans[] when a CANCEL is received.

Raphael Coeffic authored on 08/04/2013 13:41:53
Showing 1 changed files
... ...
@@ -88,7 +88,10 @@ bool AmSipDialog::onRxReqSanity(const AmSipRequest& req)
88 88
       return false;
89 89
     }
90 90
 
91
-    return true;
91
+    if(onRxReqStatus(req) && hdl)
92
+      hdl->onSipRequest(req);
93
+
94
+    return false;
92 95
   }
93 96
 
94 97
   if(!AmBasicSipDialog::onRxReqSanity(req))
Browse code

sip: fixed issues related to forking behind the SBC.

Raphael Coeffic authored on 08/04/2013 13:40:43
Showing 1 changed files
... ...
@@ -343,7 +343,7 @@ bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply,
343 343
     case Trying:
344 344
     case Proceeding:
345 345
       if(reply.code < 200){
346
-	if(reply.to_tag.empty())
346
+	if(reply.code == 100 || reply.to_tag.empty())
347 347
 	  setStatus(Proceeding);
348 348
 	else {
349 349
 	  setStatus(Early);
... ...
@@ -367,6 +367,7 @@ bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply,
367 367
 
368 368
       if(reply.code >= 300) {// error reply
369 369
 	setStatus(Disconnected);
370
+	setRemoteTag(reply.to_tag);
370 371
       }
371 372
       else if(cancel_pending){
372 373
 	cancel_pending = false;
... ...
@@ -392,6 +393,7 @@ bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply,
392 393
       }
393 394
       else { // error reply
394 395
 	setStatus(Disconnected);
396
+	setRemoteTag(reply.to_tag);
395 397
       }
396 398
       break;
397 399
 
... ...
@@ -404,6 +406,7 @@ bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply,
404 406
       else if(reply.code < 300){
405 407
 	// CANCEL rejected
406 408
 	DBG("CANCEL rejected/too late - bye()\n");
409
+	setRemoteTag(reply.to_tag);
407 410
 	bye();
408 411
 	// if BYE could not be sent,
409 412
 	// there is nothing we can do anymore...
Browse code

b/f: short-circuit ACK processing in AmSipDialog

before this fix, ACK requests would accumulate in uas_reqs for no reason.

Raphael Coeffic authored on 04/03/2013 10:40:07
Showing 1 changed files
... ...
@@ -76,7 +76,9 @@ AmSipDialog::~AmSipDialog()
76 76
 bool AmSipDialog::onRxReqSanity(const AmSipRequest& req)
77 77
 {
78 78
   if (req.method == SIP_METH_ACK) {
79
-    return true;
79
+    if(onRxReqStatus(req) && hdl)
80
+      hdl->onSipRequest(req);
81
+    return false;
80 82
   }
81 83
 
82 84
   if (req.method == SIP_METH_CANCEL) {
Browse code

moved most AmBasicSipDialog attributes to protected part to force use of setter/getter

Raphael Coeffic authored on 04/02/2013 15:11:06
Showing 1 changed files
... ...
@@ -345,13 +345,13 @@ bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply,
345 345
 	  setStatus(Proceeding);
346 346
 	else {
347 347
 	  setStatus(Early);
348
-	  updateRemoteTag(reply.to_tag);
349
-	  updateRouteSet(reply.route);
348
+	  setRemoteTag(reply.to_tag);
349
+	  setRouteSet(reply.route);
350 350
 	}
351 351
       }
352 352
       else if(reply.code < 300){
353 353
 	setStatus(Connected);
354
-	updateRouteSet(reply.route);
354
+	setRouteSet(reply.route);
355 355
 	if(reply.to_tag.empty()){
356 356
 	  DBG("received 2xx reply without to-tag "
357 357
 	      "(callid=%s): sending BYE\n",reply.callid.c_str());
... ...
@@ -359,7 +359,7 @@ bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply,
359 359
 	  sendRequest(SIP_METH_BYE);
360 360
 	}
361 361
 	else {
362
-	  updateRemoteTag(reply.to_tag);
362
+	  setRemoteTag(reply.to_tag);
363 363
 	}
364 364
       }
365 365
 
... ...
@@ -377,7 +377,7 @@ bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply,
377 377
       }
378 378
       else if(reply.code < 300){
379 379
 	setStatus(Connected);
380
-	updateRouteSet(reply.route);
380
+	setRouteSet(reply.route);
381 381
 	if(reply.to_tag.empty()){
382 382
 	  DBG("received 2xx reply without to-tag "
383 383
 	      "(callid=%s): sending BYE\n",reply.callid.c_str());
... ...
@@ -385,7 +385,7 @@ bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply,
385 385
 	  sendRequest(SIP_METH_BYE);
386 386
 	}
387 387
 	else {
388
-	  updateRemoteTag(reply.to_tag);
388
+	  setRemoteTag(reply.to_tag);
389 389
 	}
390 390
       }
391 391
       else { // error reply
Browse code

allow for custom AmSipDialog implementation in session classes

Raphael Coeffic authored on 02/02/2013 20:27:29
Showing 1 changed files
... ...
@@ -149,6 +149,8 @@ bool AmSipDialog::onRxReqStatus(const AmSipRequest& req)
149 149
 
150 150
 int AmSipDialog::onSdpCompleted()
151 151
 {
152
+  if(!hdl) return 0;
153
+
152 154
   int ret = ((AmSipDialogEventHandler*)hdl)->
153 155
     onSdpCompleted(oa.getLocalSdp(), oa.getRemoteSdp());
154 156
 
... ...
@@ -175,11 +177,13 @@ int AmSipDialog::onSdpCompleted()
175 177
 
176 178
 bool AmSipDialog::getSdpOffer(AmSdp& offer)
177 179
 {
180
+  if(!hdl) return false;
178 181
   return ((AmSipDialogEventHandler*)hdl)->getSdpOffer(offer);
179 182
 }
180 183
 
181 184
 bool AmSipDialog::getSdpAnswer(const AmSdp& offer, AmSdp& answer)
182 185
 {
186
+  if(!hdl) return false;
183 187
   return ((AmSipDialogEventHandler*)hdl)->getSdpAnswer(offer,answer);
184 188
 }
185 189
 
... ...
@@ -428,8 +432,7 @@ bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply,
428 432
   if( (reply.code >= 200) && (reply.code < 300) &&
429 433
       (reply.cseq_method == SIP_METH_INVITE) ) {
430 434
 
431
-    if(hdl)
432
-      ((AmSipDialogEventHandler*)hdl)->onInvite2xx(reply);
435
+    if(hdl) ((AmSipDialogEventHandler*)hdl)->onInvite2xx(reply);
433 436
 
434 437
   } else {
435 438
     cont = AmBasicSipDialog::onRxReplyStatus(reply,t_uac_it);
Browse code

sip: additional headers for CANCELs

Raphael Coeffic authored on 21/01/2013 01:07:22
Showing 1 changed files
... ...
@@ -691,7 +691,7 @@ int AmSipDialog::cancel()
691 691
 	  }
692 692
 	  else if(getStatus() != Cancelling){
693 693
 	    setStatus(Cancelling);
694
-	    return SipCtrlInterface::cancel(&t->second.tt);
694
+	    return SipCtrlInterface::cancel(&t->second.tt,t->second.hdrs);
695 695
 	  }
696 696
 	  else {
697 697
 	    ERROR("INVITE transaction has already been cancelled\n");
Browse code

sip: message logging draft.

Raphael Coeffic authored on 10/01/2013 14:14:12
Showing 1 changed files
... ...
@@ -766,7 +766,7 @@ int AmSipDialog::send_200_ack(unsigned int inv_cseq,
766 766
   int res = SipCtrlInterface::send(req, local_tag,
767 767
 				   remote_tag.empty() || !next_hop_1st_req ? 
768 768
 				   next_hop : "",
769
-				   outbound_interface);
769
+				   outbound_interface, logger);
770 770
   if (res)
771 771
     return res;
772 772
 
Browse code

use setter & getter to set dialog state elements

Raphael Coeffic authored on 14/01/2013 09:34:50
Showing 1 changed files
... ...
@@ -118,20 +118,20 @@ bool AmSipDialog::onRxReqStatus(const AmSipRequest& req)
118 118
   switch(status){
119 119
   case Disconnected:
120 120
     if(req.method == SIP_METH_INVITE)
121
-      status = Trying;
121
+      setStatus(Trying);
122 122
     break;
123 123
   case Connected:
124 124
     if(req.method == SIP_METH_BYE)
125
-      status = Disconnecting;
125
+      setStatus(Disconnecting);
126 126
     break;
127 127
 
128 128
   case Trying:
129 129
   case Proceeding:
130 130
   case Early:
131 131
     if(req.method == SIP_METH_BYE)
132
-      status = Disconnecting;
132
+      setStatus(Disconnecting);
133 133
     else if(req.method == SIP_METH_CANCEL){
134
-      status = Cancelling;
134
+      setStatus(Cancelling);
135 135
       reply(req,200,"OK");
136 136
     }
137 137
     break;
... ...
@@ -216,10 +216,10 @@ int AmSipDialog::onTxRequest(AmSipRequest& req, int& flags)
216 216
   addTranscoderStats(req.hdrs);
217 217
 
218 218
   if((req.method == SIP_METH_INVITE) && (status == Disconnected)){
219
-    status = Trying;
219
+    setStatus(Trying);
220 220
   }
221 221
   else if((req.method == SIP_METH_BYE) && (status != Disconnecting)){
222
-    status = Disconnecting;
222
+    setStatus(Disconnecting);
223 223
   }
224 224
 
225 225
   if ((req.method == SIP_METH_BYE) || (req.method == SIP_METH_CANCEL)) {
... ...
@@ -261,12 +261,12 @@ int AmSipDialog::onTxReply(const AmSipRequest& req, AmSipReply& reply, int& flag
261 261
   case Early:
262 262
     if(reply.cseq_method == SIP_METH_INVITE){
263 263
       if(reply.code < 200) {
264
-	status = Early;
264
+	setStatus(Early);
265 265
       }
266 266
       else if(reply.code < 300)
267
-	status = Connected;
267
+	setStatus(Connected);
268 268
       else
269
-	status = Disconnected;
269
+	setStatus(Disconnected);
270 270
     }
271 271
     break;
272 272
 
... ...
@@ -277,7 +277,7 @@ int AmSipDialog::onTxReply(const AmSipRequest& req, AmSipReply& reply, int& flag
277 277
       //  authentication (NYI at this place)
278 278
       // Also: we should not send provisionnal replies to a BYE
279 279
       if(reply.code >= 200)
280
-	status = Disconnected;
280
+	setStatus(Disconnected);
281 281
     }
282 282
     break;
283 283
 
... ...
@@ -338,15 +338,15 @@ bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply,
338 338
     case Proceeding:
339 339
       if(reply.code < 200){
340 340
 	if(reply.to_tag.empty())
341
-	  status = Proceeding;
341
+	  setStatus(Proceeding);
342 342
 	else {
343
-	  status = Early;
343
+	  setStatus(Early);
344 344
 	  updateRemoteTag(reply.to_tag);
345 345
 	  updateRouteSet(reply.route);
346 346
 	}
347 347
       }
348 348
       else if(reply.code < 300){
349
-	status = Connected;
349
+	setStatus(Connected);
350 350
 	updateRouteSet(reply.route);
351 351
 	if(reply.to_tag.empty()){
352 352
 	  DBG("received 2xx reply without to-tag "
... ...
@@ -360,7 +360,7 @@ bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply,
360 360
       }
361 361
 
362 362
       if(reply.code >= 300) {// error reply
363
-	status = Disconnected;
363
+	setStatus(Disconnected);
364 364
       }
365 365
       else if(cancel_pending){
366 366
 	cancel_pending = false;
... ...
@@ -372,7 +372,7 @@ bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply,
372 372
       if(reply.code < 200){
373 373
       }
374 374
       else if(reply.code < 300){
375
-	status = Connected;
375
+	setStatus(Connected);
376 376
 	updateRouteSet(reply.route);
377 377
 	if(reply.to_tag.empty()){
378 378
 	  DBG("received 2xx reply without to-tag "
... ...
@@ -385,7 +385,7 @@ bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply,
385 385
 	}
386 386
       }
387 387
       else { // error reply
388
-	status = Disconnected;
388
+	setStatus(Disconnected);
389 389
       }
390 390
       break;
391 391
 
... ...
@@ -393,7 +393,7 @@ bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply,
393 393
       if(reply.code >= 300){
394 394
 	// CANCEL accepted
395 395
 	DBG("CANCEL accepted, status -> Disconnected\n");
396
-	status = Disconnected;
396
+	setStatus(Disconnected);
397 397
       }
398 398
       else if(reply.code < 300){
399 399
 	// CANCEL rejected
... ...
@@ -416,7 +416,7 @@ bool AmSipDialog::onRxReplyStatus(const AmSipReply& reply,
416 416
 
417 417
     if((reply.cseq_method == SIP_METH_BYE) && (reply.code >= 200)){
418 418
       //TODO: support the auth case here (401/403)
419
-      status = Disconnected;
419
+      setStatus(Disconnected);
420 420
     }
421 421
   }
422 422
 
... ...
@@ -492,7 +492,7 @@ int AmSipDialog::bye(const string& hdrs, int flags)
492 492
       // collect INVITE UAC transactions
493 493
       vector<unsigned int> ack_trans;
494 494
       for (TransMap::iterator it=uac_trans.begin(); it != uac_trans.end(); it++) {
495
-	if (it->second.method == "INVITE"){
495
+	if (it->second.method == SIP_METH_INVITE){
496 496
 	  ack_trans.push_back(it->second.cseq);
497 497
 	}
498 498
       }
... ...
@@ -503,7 +503,7 @@ int AmSipDialog::bye(const string& hdrs, int flags)
503 503
       }
504 504
 
505 505
       if (status != Disconnecting) {
506
-	status = Disconnected;
506
+	setStatus(Disconnected);
507 507
 	return sendRequest(SIP_METH_BYE, NULL, hdrs, flags);
508 508
       } else {
509 509
 	return 0;
... ...
@@ -531,7 +531,7 @@ int AmSipDialog::bye(const string& hdrs, int flags)
531 531
 	    ERROR("ignoring bye() in %s state: "
532 532
 		  "no UAC transaction to cancel.\n",
533 533
 		  getStatusStr());
534
-	    status = Disconnected;
534
+	    setStatus(Disconnected);
535 535
 	}
536 536
 	return 0;
537 537
 
... ...
@@ -546,7 +546,7 @@ int AmSipDialog::reinvite(const string& hdrs,
546 546
 			  const AmMimeBody* body,
547 547
 			  int flags)
548 548
 {
549
-  if(status == Connected) {
549
+  if(getStatus() == Connected) {
550 550
     return sendRequest(SIP_METH_INVITE, body, hdrs, flags);
551 551
   }
552 552
   else {
... ...
@@ -560,7 +560,7 @@ int AmSipDialog::reinvite(const string& hdrs,
560 560
 int AmSipDialog::invite(const string& hdrs,  
561 561
 			const AmMimeBody* body)
562 562
 {
563
-  if(status == Disconnected) {
563
+  if(getStatus() == Disconnected) {
564 564
     int res = sendRequest(SIP_METH_INVITE, body, hdrs);
565 565
     DBG("TODO: is status already 'trying'? status=%s\n",getStatusStr());
566 566
     //status = Trying;
... ...
@@ -577,7 +577,7 @@ int AmSipDialog::invite(const string& hdrs,
577 577
 int AmSipDialog::update(const AmMimeBody* body, 
578 578
                         const string &hdrs)
579 579
 {
580
-  switch(status){
580
+  switch(getStatus()){
581 581
   case Connected://if Connected, we should send a re-INVITE instead...
582 582
     DBG("re-INVITE should be used instead (see RFC3311, section 5.1)\n");
583 583
   case Trying:
... ...
@@ -599,7 +599,7 @@ int AmSipDialog::update(const AmMimeBody* body,
599 599
 int AmSipDialog::refer(const string& refer_to,
600 600
 		       int expires)
601 601
 {
602
-  if(status == Connected) {
602
+  if(getStatus() == Connected) {
603 603
     string hdrs = SIP_HDR_COLSP(SIP_HDR_REFER_TO) + refer_to + CRLF;
604 604
     if (expires>=0) 
605 605
       hdrs+= SIP_HDR_COLSP(SIP_HDR_EXPIRES) + int2str(expires) + CRLF;
... ...
@@ -616,9 +616,9 @@ int AmSipDialog::refer(const string& refer_to,
616 616
 // proprietary
617 617
 int AmSipDialog::transfer(const string& target)
618 618
 {
619
-  if(status == Connected){
619
+  if(getStatus() == Connected){
620 620
 
621
-    status = Disconnecting;
621
+    setStatus(Disconnecting);
622 622
 		
623 623
     string      hdrs = "";
624 624
     AmSipDialog tmp_d(*this);
... ...
@@ -655,7 +655,7 @@ int AmSipDialog::prack(const AmSipReply &reply1xx,
655 655
                        const AmMimeBody* body, 
656 656
                        const string &hdrs)
657 657
 {
658
-  switch(status) {
658
+  switch(getStatus()) {
659 659
   case Trying:
660 660
   case Proceeding:
661 661
   case Cancelling:
... ...
@@ -685,12 +685,12 @@ int AmSipDialog::cancel()
685 685
 	
686 686
 	if(t->second.method == SIP_METH_INVITE){
687 687
 	  
688
-	  if(status == Trying){
688
+	  if(getStatus() == Trying){
689 689
 	    cancel_pending=true;
690 690
 	    return 0;
691 691
 	  }
692
-	  else if(status != Cancelling){
693
-	    status = Cancelling;
692
+	  else if(getStatus() != Cancelling){
693
+	    setStatus(Cancelling);
694 694
 	    return SipCtrlInterface::cancel(&t->second.tt);
695 695
 	  }
696 696
 	  else {
... ...
@@ -706,7 +706,7 @@ int AmSipDialog::cancel()
706 706
 
707 707
 int AmSipDialog::drop()
708 708
 {	
709
-  status = Disconnected;
709
+  setStatus(Disconnected);
710 710
   return 1;
711 711
 }
712 712
 
Browse code

SIP dialog b/f: quick fix to insert Contact into 2xx replies in INVITE

Václav Kubart authored on 02/01/2013 16:00:52
Showing 1 changed files
... ...
@@ -289,8 +289,10 @@ int AmSipDialog::onTxReply(const AmSipRequest& req, AmSipReply& reply, int& flag
289 289
   // add transcoder statistics into reply headers
290 290
   addTranscoderStats(reply.hdrs);
291 291
 
292
-  if(reply.cseq_method != SIP_METH_CANCEL && 
293
-     reply.cseq_method != SIP_METH_BYE) {
292
+  // target-refresh requests and their replies need to contain Contact (1xx
293
+  // replies only those establishing dialog, take care about them?)
294
+  if(reply.cseq_method != SIP_METH_INVITE && 
295
+     reply.cseq_method != SIP_METH_UPDATE) {
294 296
     
295 297
     flags |= SIP_FLAGS_NOCONTACT;
296 298
   }
Browse code

fixes for external dialog-id

Raphael Coeffic authored on 29/11/2012 14:34:06
Showing 1 changed files
... ...
@@ -761,7 +761,7 @@ int AmSipDialog::send_200_ack(unsigned int inv_cseq,
761 761
       + int2str(AmConfig::MaxForwards) + CRLF;
762 762
   }
763 763
 
764
-  int res = SipCtrlInterface::send(req, 
764
+  int res = SipCtrlInterface::send(req, local_tag,
765 765
 				   remote_tag.empty() || !next_hop_1st_req ? 
766 766
 				   next_hop : "",
767 767
 				   outbound_interface);
Browse code

sip: external local-tag support

This allows for an optional external local-tag which is used exclusively in SIP messages. The normal local-tag is still used as session identifier for passing events.

Raphael Coeffic authored on 16/10/2012 11:04:45
Showing 1 changed files
... ...
@@ -731,7 +731,9 @@ int AmSipDialog::send_200_ack(unsigned int inv_cseq,
731 731
   req.r_uri = remote_uri;
732 732
 
733 733
   req.from = SIP_HDR_COLSP(SIP_HDR_FROM) + local_party;
734
-  if(!local_tag.empty())
734
+  if(!ext_local_tag.empty())
735
+    req.from += ";tag=" + ext_local_tag;
736
+  else if(!local_tag.empty())
735 737
     req.from += ";tag=" + local_tag;
736 738
     
737 739
   req.to = SIP_HDR_COLSP(SIP_HDR_TO) + remote_party;
Browse code

fixes some errors made during splitting AmSipDialog.

Raphael Coeffic authored on 29/11/2012 13:56:26
Showing 1 changed files
... ...
@@ -742,37 +742,31 @@ int AmSipDialog::send_200_ack(unsigned int inv_cseq,
742 742
   req.callid = callid;
743 743
   req.contact = getContactHdr();
744 744
     
745
-  if (!(flags&SIP_FLAGS_VERBATIM)) {
746
-    // add Signature
747
-    if (AmConfig::Signature.length())
748
-      req.hdrs += SIP_HDR_COLSP(SIP_HDR_USER_AGENT) + AmConfig::Signature + CRLF;
749
-    
750
-    req.hdrs += SIP_HDR_COLSP(SIP_HDR_MAX_FORWARDS) + int2str(AmConfig::MaxForwards) + CRLF;
751
-  }
752
-
753 745
   req.route = getRoute();
754 746
 
755 747
   if(body != NULL)
756 748
     req.body = *body;
757 749
 
758
-  if (offeranswer_enabled && oa.onRequestOut(req))
750
+  if(onTxRequest(req,flags) < 0)
759 751
     return -1;
760 752
 
761
-  if(hdl)
762
-    hdl->onSendRequest(req,flags);
753
+  if (!(flags&SIP_FLAGS_VERBATIM)) {
754
+    // add Signature
755
+    if (AmConfig::Signature.length())
756
+      req.hdrs += SIP_HDR_COLSP(SIP_HDR_USER_AGENT) + AmConfig::Signature + CRLF;
757
+    
758
+    req.hdrs += SIP_HDR_COLSP(SIP_HDR_MAX_FORWARDS) 
759
+      + int2str(AmConfig::MaxForwards) + CRLF;
760
+  }
763 761
 
764
-  //onTxRequest(req); // not needed right now in the ACK case
765 762
   int res = SipCtrlInterface::send(req, 
766
-				   remote_tag.empty() ? next_hop : "",
763
+				   remote_tag.empty() || !next_hop_1st_req ? 
764
+				   next_hop : "",
767 765
 				   outbound_interface);
768 766
   if (res)
769 767
     return res;
770 768
 
771
-  uac_trans.erase(inv_cseq);
772
-  if (offeranswer_enabled) {
773
-    return oa.onRequestSent(req);
774
-  }
775
-
769
+  onRequestTxed(req);
776 770
   return 0;
777 771
 }
778 772
 
Browse code

split AmSipDialog and AmBasicSipDialog (WIP)

Raphael Coeffic authored on 28/11/2012 14:58:28
Showing 1 changed files
... ...
@@ -60,147 +60,61 @@ static void addTranscoderStats(string &hdrs)
60 60
   }
61 61
 }
62 62
 
63
-const char* __dlg_status2str[AmSipDialog::__max_Status]  = {
64
-  "Disconnected",
65
-  "Trying",
66
-  "Proceeding",
67
-  "Cancelling",
68
-  "Early",
69
-  "Connected",
70
-  "Disconnecting"
71
-};
72
-
73
-const char* dlgStatusStr(AmSipDialog::Status st)
74
-{
75
-  if((st < 0) || (st >= AmSipDialog::__max_Status))
76
-    return "Invalid";
77
-  else
78
-    return __dlg_status2str[st];
79
-}
80
-
81
-const char* AmSipDialog::getStatusStr()
82
-{
83
-  return dlgStatusStr(status);
84
-}
85
-
86 63
 AmSipDialog::AmSipDialog(AmSipDialogEventHandler* h)
87
-  : status(Disconnected),oa(this),rel100(this,h),
64
+  : AmBasicSipDialog(h),oa(this),rel100(this,h),
88 65
     offeranswer_enabled(true),
89 66
     early_session_started(false),session_started(false),
90
-    cseq(10),r_cseq_i(false),hdl(h),
91 67
     pending_invites(0),cancel_pending(false),
92
-    outbound_proxy(AmConfig::OutboundProxy),
93
-    force_outbound_proxy(AmConfig::ForceOutboundProxy),
94
-    next_hop(AmConfig::NextHop),
95
-    next_hop_1st_req(AmConfig::NextHop1stReq),
96
-    outbound_interface(-1),
97 68
     sdp_local(), sdp_remote()
98 69
 {
99
-  assert(h);
100 70
 }
101 71
 
102 72
 AmSipDialog::~AmSipDialog()
103 73
 {
104
-  DBG("callid = %s\n",callid.c_str());
105
-  DBG("local_tag = %s\n",local_tag.c_str());
106
-  DBG("uac_trans.size() = %u\n",(unsigned int)uac_trans.size());
107
-  if(uac_trans.size()){
108
-    for(TransMap::iterator it = uac_trans.begin();
109
-	it != uac_trans.end(); it++){
110
-	    
111
-      DBG("    cseq = %i; method = %s\n",it->first,it->second.method.c_str());
112
-    }
113
-  }
114
-  DBG("uas_trans.size() = %u\n",(unsigned int)uas_trans.size());
115
-  if(uas_trans.size()){
116
-    for(TransMap::iterator it = uas_trans.begin();
117
-	it != uas_trans.end(); it++){
118
-	    
119
-      DBG("    cseq = %i; method = %s\n",it->first,it->second.method.c_str());
120
-    }
121
-  }
122
-}
123
-
124
-void AmSipDialog::setStatus(Status new_status) {
125
-  DBG("setting SIP dialog status: %s->%s\n",
126
-      getStatusStr(), dlgStatusStr(new_status));
127
-
128
-  status = new_status;
129 74
 }
130 75
 
131
-void AmSipDialog::onRxRequest(const AmSipRequest& req)
76
+bool AmSipDialog::onRxReqSanity(const AmSipRequest& req)
132 77
 {
133
-  DBG("AmSipDialog::onRxRequest(req = %s)\n", req.method.c_str());
134
-
135
-  if ((req.method != SIP_METH_ACK) && (req.method != SIP_METH_CANCEL)) {
136
-
137
-    // Sanity checks
138
-    if (r_cseq_i && req.cseq <= r_cseq){
139
-      string hdrs; bool i = false;
140
-      if (req.method == SIP_METH_NOTIFY) {
141
-	if (AmConfig::IgnoreNotifyLowerCSeq)
142
-	  i = true;
143
-	else
144
-	  // clever trick to not break subscription dialog usage
145
-	  // for implementations which follow 3265 instead of 5057
146
-	  hdrs = SIP_HDR_COLSP(SIP_HDR_RETRY_AFTER)  "0"  CRLF;
147
-      }
78
+  if (req.method == SIP_METH_ACK) {
79
+    return true;
80
+  }
148 81
 
149
-      if (!i) {
150
-	INFO("remote cseq lower than previous ones - refusing request\n");
151
-	// see 12.2.2
152
-	reply_error(req, 500, SIP_REPLY_SERVER_INTERNAL_ERROR, hdrs);
153
-	return;
154
-      }
82
+  if (req.method == SIP_METH_CANCEL) {
83
+
84
+    if (uas_trans.find(req.cseq) == uas_trans.end()) {
85
+      reply_error(req,481,SIP_REPLY_NOT_EXIST);
86
+      return false;
155 87
     }
156 88
 
157
-    if (req.method == SIP_METH_INVITE) {
158
-      bool pending = pending_invites;
159
-      if (offeranswer_enabled) {
160
-	  // not sure this is needed here: could be in AmOfferAnswer as well
161
-	pending |= ((oa.getState() != AmOfferAnswer::OA_None) &&
162
-		    (oa.getState() != AmOfferAnswer::OA_Completed));
163
-      }
89
+    return true;
90
+  }
164 91
 
165
-      if (pending) {
166
-	reply_error(req, 491, SIP_REPLY_PENDING,
167
-		    SIP_HDR_COLSP(SIP_HDR_RETRY_AFTER) 
168
-		    + int2str(get_random() % 10) + CRLF);
169
-	return;
170
-      }
92
+  if(!AmBasicSipDialog::onRxReqSanity(req))
93
+    return false;
171 94
 
172
-      pending_invites++;
173
-    }
174
-    
175
-    r_cseq = req.cseq;
176
-    r_cseq_i = true;
177
-    uas_trans[req.cseq] = AmSipTransaction(req.method,req.cseq,req.tt);
178
-    
179
-    // target refresh requests
180
-    if (req.from_uri.length() && 
181
-	(req.method == SIP_METH_INVITE || 
182
-	 req.method == SIP_METH_UPDATE ||
183
-	 req.method == SIP_METH_SUBSCRIBE ||
184
-	 req.method == SIP_METH_NOTIFY)) {
185
-
186
-      // refresh the target
187
-      remote_uri = req.from_uri;
95
+  if (req.method == SIP_METH_INVITE) {
96
+    bool pending = pending_invites;
97
+    if (offeranswer_enabled) {
98
+      // not sure this is needed here: could be in AmOfferAnswer as well
99
+      pending |= ((oa.getState() != AmOfferAnswer::OA_None) &&
100
+		  (oa.getState() != AmOfferAnswer::OA_Completed));
188 101
     }
189 102
 
190
-    // Dlg not yet initialized?
191
-    if(callid.empty()){
192
-      callid       = req.callid;
193
-      remote_tag   = req.from_tag;
194
-      user         = req.user;
195
-      domain       = req.domain;
196
-      local_uri    = req.r_uri;
197
-      remote_party = req.from;
198
-      local_party  = req.to;
199
-      route        = req.route;
200
-      outbound_interface = req.local_if;
103
+    if (pending) {
104
+      reply_error(req, 491, SIP_REPLY_PENDING,
105
+		  SIP_HDR_COLSP(SIP_HDR_RETRY_AFTER) 
106
+		  + int2str(get_random() % 10) + CRLF);
107
+      return false;
201 108
     }
109
+
110
+    pending_invites++;
202 111
   }
203 112
 
113
+  return rel100.onRequestIn(req);
114
+}
115
+
116
+bool AmSipDialog::onRxReqStatus(const AmSipRequest& req)
117
+{
204 118
   switch(status){
205 119
   case Disconnected:
206 120
     if(req.method == SIP_METH_INVITE)
... ...
@@ -225,28 +139,30 @@ void AmSipDialog::onRxRequest(const AmSipRequest& req)
225 139
   default: break;
226 140
   }
227 141
 
142
+  bool cont = true;
228 143
   if (offeranswer_enabled) {
229
-    oa.onRequestIn(req);
144
+    cont = (oa.onRequestIn(req) == 0);
230 145
   }
231 146
 
232
-  if(rel100.onRequestIn(req) && hdl)
233
-    hdl->onSipRequest(req);
147
+  return cont;
234 148
 }
235 149
 
236 150
 int AmSipDialog::onSdpCompleted()
237 151
 {
238
-  int ret = hdl->onSdpCompleted(oa.getLocalSdp(), oa.getRemoteSdp());
152
+  int ret = ((AmSipDialogEventHandler*)hdl)->
153
+    onSdpCompleted(oa.getLocalSdp(), oa.getRemoteSdp());
154
+
239 155
   if(!ret) {
240 156
     sdp_local = oa.getLocalSdp();
241 157
     sdp_remote = oa.getRemoteSdp();
242 158
 
243 159
     if((getStatus() == Early) && !early_session_started) {
244
-      hdl->onEarlySessionStart();
160