1 #include "AmBasicSipDialog.h"
2
3 #include "AmConfig.h"
4 #include "AmSipHeaders.h"
5 #include "SipCtrlInterface.h"
6 #include "AmSession.h"
7
8 #include "sip/parse_route.h"
9 #include "sip/parse_uri.h"
10 #include "sip/parse_next_hop.h"
11 #include "sip/msg_logger.h"
12 #include "sip/sip_parser.h"
13
14 const char* AmBasicSipDialog::status2str[AmBasicSipDialog::__max_Status] = {
15 "Disconnected",
16 "Trying",
17 "Proceeding",
18 "Cancelling",
19 "Early",
20 "Connected",
21 "Disconnecting"
22 };
23
test01()24 AmBasicSipDialog::AmBasicSipDialog(AmBasicSipEventHandler* h)
25 : status(Disconnected),
26 next_hop(AmConfig::NextHop),next_hop_1st_req(AmConfig::NextHop1stReq),patch_ruri_next_hop(false),
27 next_hop_fixed(false),
28 outbound_interface(-1),
29 usages(0),
30 hdl(h),
31 logger(0),
32 outbound_proxy(AmConfig::OutboundProxy),
33 force_outbound_proxy(AmConfig::ForceOutboundProxy),
34 nat_handling(AmConfig::SipNATHandling),
35 cseq(10),
36 r_cseq_i(false)
37 {
38 //assert(h);
39 }
40
41 AmBasicSipDialog::~AmBasicSipDialog()
42 {
43 termUasTrans();
44 termUacTrans();
45 if (logger) dec_ref(logger);
46 dump();
47 }
48
49 AmSipRequest* AmBasicSipDialog::getUACTrans(unsigned int t_cseq)
50 {
51 TransMap::iterator it = uac_trans.find(t_cseq);
52 if(it == uac_trans.end())
53 return NULL;
54
55 return &(it->second);
56 }
57
58 AmSipRequest* AmBasicSipDialog::getUASTrans(unsigned int t_cseq)
59 {
60 TransMap::iterator it = uas_trans.find(t_cseq);
61 if(it == uas_trans.end())
62 return NULL;
63
64 return &(it->second);
65 }
66
67 string AmBasicSipDialog::getUACTransMethod(unsigned int t_cseq)
68 {
69 AmSipRequest* req = getUACTrans(t_cseq);
70 if(req != NULL)
71 return req->method;
72
73 return string();
74 }
75
76 bool AmBasicSipDialog::getUACTransPending()
77 {
78 return !uac_trans.empty();
79 }
80
81 void AmBasicSipDialog::setStatus(Status new_status)
82 {
83 DBG("setting SIP dialog status: %s->%s\n",
84 getStatusStr(), getStatusStr(new_status));
85
86 status = new_status;
87 }
88
89 const char* AmBasicSipDialog::getStatusStr(AmBasicSipDialog::Status st)
90 {
91 if((st < 0) || (st >= __max_Status))
92 return "Invalid";
93 else
94 return status2str[st];
95 }
96
97 const char* AmBasicSipDialog::getStatusStr()
98 {
99 return getStatusStr(status);
100 }
101
102 string AmBasicSipDialog::getContactHdr() {
103 AmUriParser tmp_contact = contact;
104 if(tmp_contact.uri_host.empty()) {
105 int oif = getOutboundIf();
106 assert(oif >= 0);
107 assert(oif < (int)AmConfig::SIP_Ifs.size());
108 tmp_contact.uri_host = AmConfig::SIP_Ifs[oif].getIP();
109 tmp_contact.uri_port = int2str(AmConfig::SIP_Ifs[oif].LocalPort);
110 }
111
112 if(tmp_contact.uri_user.empty() && !ext_local_tag.empty()) {
113 tmp_contact.uri_user = local_tag;
114 }
115
116 string contact_str = tmp_contact.print();
117
118 DBG("[%s] resulting Contact header: %s",
119 local_tag.c_str(),
120 contact_str.c_str());
121
122 return SIP_HDR_COLSP(SIP_HDR_CONTACT) + contact_str += CRLF;
123 }
124
125
126 string AmBasicSipDialog::getContactUri()
127 {
128 string contact_uri = "sip:";
129
130 if(!ext_local_tag.empty()) {
131 contact_uri += local_tag + "@";
132 }
133
134 int oif = getOutboundIf();
135 assert(oif >= 0);
136 assert(oif < (int)AmConfig::SIP_Ifs.size());
137
138 contact_uri += AmConfig::SIP_Ifs[oif].getIP();
139 contact_uri += ":" + int2str(AmConfig::SIP_Ifs[oif].LocalPort);
140
141 if(!contact_params.empty()) {
142 contact_uri += ";" + contact_params;
143 }
144
145 return contact_uri;
146 }
147
148 string AmBasicSipDialog::getRoute()
149 {
150 string res;
151
152 if(!outbound_proxy.empty() && (force_outbound_proxy || remote_tag.empty())){
153 res += "<" + outbound_proxy + ";lr>";
154
155 if(!route.empty()) {
156 res += ",";
157 }
158 }
159
160 res += route;
161
162 if(!res.empty()) {
163 res = SIP_HDR_COLSP(SIP_HDR_ROUTE) + res + CRLF;
164 }
165
166 return res;
167 }
168
169 void AmBasicSipDialog::setOutboundInterface(int interface_id) {
170 DBG("setting outbound interface to %i\n", interface_id);
171 outbound_interface = interface_id;
172 }
173
174 /**
175 * Computes, set and return the outbound interface
176 * based on remote_uri, next_hop_ip, outbound_proxy, route.
177 */
178 int AmBasicSipDialog::getOutboundIf()
179 {
180 if (outbound_interface >= 0)
181 return outbound_interface;
182
183 if(AmConfig::SIP_Ifs.size() == 1){
184 return (outbound_interface = 0);
185 }
186
187 // Destination priority:
188 // 1. next_hop
189 // 2. outbound_proxy (if 1st req or force_outbound_proxy)
190 // 3. first route
191 // 4. remote URI
192
193 string dest_uri;
194 string dest_ip;
195 string local_ip;
196 multimap<string,unsigned short>::iterator if_it;
197
198 list<sip_destination> ip_list;
199 if(!next_hop.empty() &&
200 !parse_next_hop(stl2cstr(next_hop),ip_list) &&
201 !ip_list.empty()) {
202
203 dest_ip = c2stlstr(ip_list.front().host);
204 }
205 else if(!outbound_proxy.empty() &&
206 (remote_tag.empty() || force_outbound_proxy)) {
207 dest_uri = outbound_proxy;
208 }
209 else if(!route.empty()){
210 // parse first route
211 sip_header fr;
212 fr.value = stl2cstr(route);
213 sip_uri* route_uri = get_first_route_uri(&fr);
214 if(!route_uri){
215 ERROR("Could not parse route (local_tag='%s';route='%s')",
216 local_tag.c_str(),route.c_str());
217 goto error;
218 }
219
220 dest_ip = c2stlstr(route_uri->host);
221 }
222 else {
223 dest_uri = remote_uri;
224 }
225
226 if(dest_uri.empty() && dest_ip.empty()) {
227 ERROR("No destination found (local_tag='%s')",local_tag.c_str());
228 goto error;
229 }
230
231 if(!dest_uri.empty()){
232 sip_uri d_uri;
233 if(parse_uri(&d_uri,dest_uri.c_str(),dest_uri.length()) < 0){
234 ERROR("Could not parse destination URI (local_tag='%s';dest_uri='%s')",
235 local_tag.c_str(),dest_uri.c_str());
236 goto error;
237 }
238
239 dest_ip = c2stlstr(d_uri.host);
240 }
241
242 if(get_local_addr_for_dest(dest_ip,local_ip) < 0){
243 ERROR("No local address for dest '%s' (local_tag='%s')",dest_ip.c_str(),local_tag.c_str());
244 goto error;
245 }
246
247 if_it = AmConfig::LocalSIPIP2If.find(local_ip);
248 if(if_it == AmConfig::LocalSIPIP2If.end()){
249 ERROR("Could not find a local interface for resolved local IP (local_tag='%s';local_ip='%s')",
250 local_tag.c_str(), local_ip.c_str());
251 goto error;
252 }
253
254 setOutboundInterface(if_it->second);
255 return if_it->second;
256
257 error:
258 WARN("Error while computing outbound interface: default interface will be used instead.");
259 setOutboundInterface(0);
260 return 0;
261 }
262
263 void AmBasicSipDialog::resetOutboundIf()
264 {
265 setOutboundInterface(-1);
266 }
267
268 /**
269 * Update dialog status from UAC Request that we send.
270 */
271 void AmBasicSipDialog::initFromLocalRequest(const AmSipRequest& req)
272 {
273 setRemoteUri(req.r_uri);
274
275 user = req.user;
276 domain = req.domain;
277
278 setCallid( req.callid );
279 setLocalTag( req.from_tag );
280 setLocalUri( req.from_uri );
281 setRemoteParty( req.to );
282 setLocalParty( req.from );
283 }
284
285 bool AmBasicSipDialog::onRxReqSanity(const AmSipRequest& req)
286 {
287 // Sanity checks
288 if(!remote_tag.empty() && !req.from_tag.empty() &&
289 (req.from_tag != remote_tag)){
290 DBG("remote_tag = '%s'; req.from_tag = '%s'\n",
291 remote_tag.c_str(), req.from_tag.c_str());
292 reply_error(req, 481, SIP_REPLY_NOT_EXIST);
293 return false;
294 }
295
296 if (r_cseq_i && req.cseq <= r_cseq){
297
298 if (req.method == SIP_METH_NOTIFY) {
299 if (!AmConfig::IgnoreNotifyLowerCSeq) {
300 // clever trick to not break subscription dialog usage
301 // for implementations which follow 3265 instead of 5057
302 string hdrs = SIP_HDR_COLSP(SIP_HDR_RETRY_AFTER) "0" CRLF;
303
304 INFO("remote cseq lower than previous ones - refusing request\n");
305 // see 12.2.2
306 reply_error(req, 500, SIP_REPLY_SERVER_INTERNAL_ERROR, hdrs);
307 return false;
308 }
309 }
310 else {
311 INFO("remote cseq lower than previous ones - refusing request\n");
312 // see 12.2.2
313 reply_error(req, 500, SIP_REPLY_SERVER_INTERNAL_ERROR);
314 return false;
315 }
316 }
317
318 r_cseq = req.cseq;
319 r_cseq_i = true;
320
321 return true;
322 }
323
324 void AmBasicSipDialog::onRxRequest(const AmSipRequest& req)
325 {
326 DBG("AmBasicSipDialog::onRxRequest(req = %s)\n", req.method.c_str());
327
328 if(logger && (req.method != SIP_METH_ACK)) {
329 // log only non-initial received requests, the initial one is already logged
330 // or will be logged at application level (problem with SBCSimpleRelay)
331 if (!callid.empty()) req.log(logger);
332 }
333
334 if(!onRxReqSanity(req))
335 return;
336
337 uas_trans[req.cseq] = req;
338
339 // target refresh requests
340 if (req.from_uri.length() &&
341 (remote_uri.empty() ||
342 (req.method == SIP_METH_INVITE ||
343 req.method == SIP_METH_UPDATE ||
344 req.method == SIP_METH_SUBSCRIBE ||
345 req.method == SIP_METH_NOTIFY))) {
346
347 // refresh the target
348 if (remote_uri != req.from_uri) {
349 setRemoteUri(req.from_uri);
350 if(nat_handling && req.first_hop) {
351 string nh = req.remote_ip + ":"
352 + int2str(req.remote_port)
353 + "/" + req.trsp;
354 setNextHop(nh);
355 setNextHop1stReq(false);
356 }
357 }
358
359 string ua = getHeader(req.hdrs,"User-Agent");
360 setRemoteUA(ua);
361 }
362
363 // Dlg not yet initialized?
364 if(callid.empty()){
365
366 user = req.user;
367 domain = req.domain;
368
369 setCallid( req.callid );
370 setRemoteTag( req.from_tag );
371 setLocalUri( req.r_uri );
372 setRemoteParty( req.from );
373 setLocalParty( req.to );
374 setRouteSet( req.route );
375 set1stBranch( req.via_branch );
376 setOutboundInterface( req.local_if );
377 }
378
379 if(onRxReqStatus(req) && hdl)
380 hdl->onSipRequest(req);
381 }
382
383 bool AmBasicSipDialog::onRxReplyStatus(const AmSipReply& reply)
384 {
385 /**
386 * Error code list from RFC 5057:
387 * those error codes terminate the dialog
388 *
389 * Note: 408, 480 should only terminate
390 * the usage according to RFC 5057.
391 */
392 switch(reply.code){
393 case 404:
394 case 408:
395 case 410:
396 case 416:
397 case 480:
398 case 482:
399 case 483:
400 case 484:
401 case 485:
402 case 502:
403 case 604:
404 if(hdl) hdl->onRemoteDisappeared(reply);
405 break;
406 }
407
408 return true;
409 }
410
411 void AmBasicSipDialog::termUasTrans()
412 {
413 while(!uas_trans.empty()) {
414
415 TransMap::iterator it = uas_trans.begin();
416 int req_cseq = it->first;
417 const AmSipRequest& req = it->second;
418 DBG("terminating UAS transaction (%u %s)",req.cseq,req.cseq_method.c_str());
419
420 reply(req,481,SIP_REPLY_NOT_EXIST);
421
422 it = uas_trans.find(req_cseq);
423 if(it != uas_trans.end())
424 uas_trans.erase(it);
425 }
426 }
427
428 void AmBasicSipDialog::termUacTrans()
429 {
430 while(!uac_trans.empty()) {
431 TransMap::iterator it = uac_trans.begin();
432 trans_ticket& tt = it->second.tt;
433
434 tt.lock_bucket();
435 tt.remove_trans();
436 tt.unlock_bucket();
437
438 uac_trans.erase(it);
439 }
440 }
441
442 void AmBasicSipDialog::dropTransactions() {
443 termUacTrans();
444 uas_trans.clear();
445 }
446
447 bool AmBasicSipDialog::onRxReplySanity(const AmSipReply& reply)
448 {
449 if(ext_local_tag.empty()) {
450 if(reply.from_tag != local_tag) {
451 ERROR("received reply with wrong From-tag ('%s' vs. '%s')\n",
452 reply.from_tag.c_str(), local_tag.c_str());
453 throw string("reply has wrong from-tag");
454 //return;
455 }
456 }
457 else if(reply.from_tag != ext_local_tag) {
458 ERROR("received reply with wrong From-tag ('%s' vs. '%s')\n",
459 reply.from_tag.c_str(), ext_local_tag.c_str());
460 throw string("reply has wrong from-tag");
461 //return;
462 }
463
464 return true;
465 }
466
467 void AmBasicSipDialog::onRxReply(const AmSipReply& reply)
468 {
469 if(!onRxReplySanity(reply)) {
470 DBG("onRxReply (rep = %u %s): sanity check failed!\n",
471 reply.code, reply.reason.c_str());
472 return;
473 }
474
475 TransMap::iterator t_it = uac_trans.find(reply.cseq);
476 if(t_it == uac_trans.end()){
477 ERROR("could not find any transaction matching reply: %s\n",
478 ((AmSipReply)reply).print().c_str());
479 return;
480 }
481
482 DBG("onRxReply(rep = %u %s): transaction found!\n",
483 reply.code, reply.reason.c_str());
484
485 updateDialogTarget(reply);
486
487 Status saved_status = status;
488 AmSipRequest orig_req(t_it->second);
489
490 if(onRxReplyStatus(reply) && hdl) {
491 hdl->onSipReply(orig_req,reply,saved_status);
492 }
493
494 if((reply.code >= 200) && // final reply
495 // but not for 2xx INV reply (wait for 200 ACK)
496 ((reply.cseq_method != SIP_METH_INVITE) ||
497 (reply.code >= 300))) {
498
499 uac_trans.erase(reply.cseq);
500 if (hdl) hdl->onTransFinished();
501 }
502 }
503
504 void AmBasicSipDialog::updateDialogTarget(const AmSipReply& reply)
505 {
506 if( (reply.code > 100) && (reply.code < 300) &&
507 !reply.to_uri.empty() &&
508 !reply.to_tag.empty() &&
509 (remote_uri.empty() ||
510 (reply.cseq_method.length()==6 &&
511 ((reply.cseq_method == SIP_METH_INVITE) ||
512 (reply.cseq_method == SIP_METH_UPDATE) ||
513 (reply.cseq_method == SIP_METH_NOTIFY))) ||
514 (reply.cseq_method == SIP_METH_SUBSCRIBE)) ) {
515
516 setRemoteUri(reply.to_uri);
517 if(!getNextHop().empty()) {
518 string nh = reply.remote_ip
519 + ":" + int2str(reply.remote_port)
520 + "/" + reply.trsp;
521 setNextHop(nh);
522 }
523
524 string ua = getHeader(reply.hdrs,"Server");
525 setRemoteUA(ua);
526 }
527 }
528
529 void AmBasicSipDialog::setRemoteTag(const string& new_rt)
530 {
531 if(new_rt != remote_tag){
532 remote_tag = new_rt;
533 }
534 }
535
536 int AmBasicSipDialog::onTxRequest(AmSipRequest& req, int& flags)
537 {
538 if(hdl) hdl->onSendRequest(req,flags);
539
540 return 0;
541 }
542
543 int AmBasicSipDialog::onTxReply(const AmSipRequest& req,
544 AmSipReply& reply, int& flags)
545 {
546 if(hdl) hdl->onSendReply(req,reply,flags);
547
548 return 0;
549 }
550
551 void AmBasicSipDialog::onReplyTxed(const AmSipRequest& req,
552 const AmSipReply& reply)
553 {
554 if(hdl) hdl->onReplySent(req, reply);
555
556 /**
557 * Error code list from RFC 5057:
558 * those error codes terminate the dialog
559 *
560 * Note: 408, 480 should only terminate
561 * the usage according to RFC 5057.
562 */
563 switch(reply.code){
564 case 404:
565 case 408:
566 case 410:
567 case 416:
568 case 480:
569 case 482:
570 case 483:
571 case 484:
572 case 485:
573 case 502:
574 case 604:
575 if(hdl) hdl->onLocalTerminate(reply);
576 break;
577 }
578
579 if ((reply.code >= 200) &&
580 (reply.cseq_method != SIP_METH_CANCEL)) {
581
582 uas_trans.erase(reply.cseq);
583 if (hdl) hdl->onTransFinished();
584 }
585 }
586
587 void AmBasicSipDialog::onRequestTxed(const AmSipRequest& req)
588 {
589 if(hdl) hdl->onRequestSent(req);
590
591 if(req.method != SIP_METH_ACK) {
592 uac_trans[req.cseq] = req;
593 cseq++;
594 }
595 else {
596 uac_trans.erase(req.cseq);
597 if (hdl) hdl->onTransFinished();
598 }
599 }
600
601 int AmBasicSipDialog::reply(const AmSipRequest& req,
602 unsigned int code,
603 const string& reason,
604 const AmMimeBody* body,
605 const string& hdrs,
606 int flags)
607 {
608 TransMap::const_iterator t_it = uas_trans.find(req.cseq);
609 if(t_it == uas_trans.end()){
610 ERROR("could not find any transaction matching request cseq\n");
611 ERROR("request cseq=%i; reply code=%i; callid=%s; local_tag=%s; "
612 "remote_tag=%s\n",
613 req.cseq,code,callid.c_str(),
614 local_tag.c_str(),remote_tag.c_str());
615 log_stacktrace(L_ERR);
616 return -1;
617 }
618 DBG("reply: transaction found!\n");
619
620 AmSipReply reply;
621
622 reply.code = code;
623 reply.reason = reason;
624 reply.tt = req.tt;
625 if((code > 100) && !(flags & SIP_FLAGS_NOTAG))
626 reply.to_tag = ext_local_tag.empty() ? local_tag : ext_local_tag;
627 reply.hdrs = hdrs;
628 reply.cseq = req.cseq;
629 reply.cseq_method = req.method;
630
631 if(body != NULL)
632 reply.body = *body;
633
634 if(onTxReply(req,reply,flags)){
635 DBG("onTxReply failed\n");
636 return -1;
637 }
638
639 if (!(flags & SIP_FLAGS_VERBATIM)) {
640 // add Signature
641 if (AmConfig::Signature.length())
642 reply.hdrs += SIP_HDR_COLSP(SIP_HDR_SERVER) + AmConfig::Signature + CRLF;
643 }
644
645 if ((code > 100 && code < 300) && !(flags & SIP_FLAGS_NOCONTACT)) {
646 /* if 300<=code<400, explicit contact setting should be done */
647 reply.contact = getContactHdr();
648 }
649
650 int ret = SipCtrlInterface::send(reply,local_tag,logger);
651 if(ret){
652 ERROR("Could not send reply: code=%i; reason='%s'; method=%s;"
653 " call-id=%s; cseq=%i\n",
654 reply.code,reply.reason.c_str(),reply.cseq_method.c_str(),
655 callid.c_str(),reply.cseq);
656
657 return ret;
658 }
659 else {
660 onReplyTxed(req,reply);
661 }
662
663 return ret;
664 }
665
666
667 /* static */
668 int AmBasicSipDialog::reply_error(const AmSipRequest& req, unsigned int code,
669 const string& reason, const string& hdrs,
670 msg_logger* logger)
671 {
672 AmSipReply reply;
673
674 reply.code = code;
675 reply.reason = reason;
676 reply.tt = req.tt;
677 reply.hdrs = hdrs;
678 reply.to_tag = AmSession::getNewId();
679
680 if (AmConfig::Signature.length())
681 reply.hdrs += SIP_HDR_COLSP(SIP_HDR_SERVER) + AmConfig::Signature + CRLF;
682
683 // add transcoder statistics into reply headers
684 //addTranscoderStats(reply.hdrs);
685
686 int ret = SipCtrlInterface::send(reply,string(""),logger);
687 if(ret){
688 ERROR("Could not send reply: code=%i; reason='%s';"
689 " method=%s; call-id=%s; cseq=%i\n",
690 reply.code,reply.reason.c_str(),
691 req.method.c_str(),req.callid.c_str(),req.cseq);
692 }
693
694 return ret;
695 }
696
697 int AmBasicSipDialog::sendRequest(const string& method,
698 const AmMimeBody* body,
699 const string& hdrs,
700 int flags,
701 int max_forwards)
702 {
703 AmSipRequest req;
704
705 req.method = method;
706 req.r_uri = remote_uri;
707
708 req.from = SIP_HDR_COLSP(SIP_HDR_FROM) + local_party;
709 if(!ext_local_tag.empty())
710 req.from += ";tag=" + ext_local_tag;
711 else if(!local_tag.empty())
712 req.from += ";tag=" + local_tag;
713
714 req.to = SIP_HDR_COLSP(SIP_HDR_TO) + remote_party;
715 if(!remote_tag.empty())
716 req.to += ";tag=" + remote_tag;
717
718 req.cseq = cseq;
719 req.callid = callid;
720
721 req.hdrs = hdrs;
722
723 req.route = getRoute();
724
725 if(body != NULL) {
726 req.body = *body;
727 }
728
729 if(onTxRequest(req,flags) < 0)
730 return -1;
731
732 if (!(flags & SIP_FLAGS_NOCONTACT)) {
733 req.contact = getContactHdr();
734 }
735
736 if (!(flags & SIP_FLAGS_VERBATIM)) {
737 // add Signature
738 if (AmConfig::Signature.length())
739 req.hdrs += SIP_HDR_COLSP(SIP_HDR_USER_AGENT) + AmConfig::Signature + CRLF;
740 }
741
742 int send_flags = 0;
743 if(patch_ruri_next_hop && remote_tag.empty()) {
744 send_flags |= TR_FLAG_NEXT_HOP_RURI;
745 }
746
747 if((flags & SIP_FLAGS_NOBL) ||
748 !remote_tag.empty()) {
749 send_flags |= TR_FLAG_DISABLE_BL;
750 }
751
752 if (req.max_forwards > (int)AmConfig::MaxForwards) {
753 req.max_forwards = AmConfig::MaxForwards;
754 } else {
755 req.max_forwards = max_forwards;
756 };
757
758 int res = SipCtrlInterface::send(req, local_tag,
759 remote_tag.empty() || !next_hop_1st_req ?
760 next_hop : "",
761 outbound_interface,
762 send_flags,logger);
763 if(res) {
764 ERROR("Could not send request: method=%s; call-id=%s; cseq=%i\n",
765 req.method.c_str(),req.callid.c_str(),req.cseq);
766 return res;
767 }
768
769 onRequestTxed(req);
770 return 0;
771 }
772
773 void AmBasicSipDialog::dump()
774 {
775 DBG("callid = %s\n",callid.c_str());
776 DBG("local_tag = %s\n",local_tag.c_str());
777 DBG("uac_trans.size() = %zu\n",uac_trans.size());
778 if(uac_trans.size()){
779 for(TransMap::iterator it = uac_trans.begin();
780 it != uac_trans.end(); it++){
781
782 DBG(" cseq = %i; method = %s\n",it->first,it->second.method.c_str());
783 }
784 }
785 DBG("uas_trans.size() = %zu\n",uas_trans.size());
786 if(uas_trans.size()){
787 for(TransMap::iterator it = uas_trans.begin();
788 it != uas_trans.end(); it++){
789
790 DBG(" cseq = %i; method = %s\n",it->first,it->second.method.c_str());
791 }
792 }
793 }
794
795 void AmBasicSipDialog::setMsgLogger(msg_logger* logger)
796 {
797 if(this->logger) {
798 dec_ref(this->logger);
799 }
800
801 if(logger){
802 inc_ref(logger);
803 }
804
805 this->logger = logger;
806 }
807