/[resiprocate]/main/resip/dum/Dialog.cxx
ViewVC logotype

Contents of /main/resip/dum/Dialog.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3146 - (show annotations) (download)
Sat Jul 24 00:26:47 2004 UTC (15 years, 4 months ago) by derek
Original Path: main/sip/resiprocate/dum/Dialog.cxx
File size: 24719 byte(s)
minor refer related fixes
1 #include "resiprocate/Contents.hxx"
2 #include "resiprocate/Helper.hxx"
3 #include "resiprocate/SipMessage.hxx"
4 #include "resiprocate/dum/AppDialog.hxx"
5 #include "resiprocate/dum/BaseCreator.hxx"
6 #include "resiprocate/dum/ClientAuthManager.hxx"
7 #include "resiprocate/dum/ClientInviteSession.hxx"
8 #include "resiprocate/dum/ClientSubscription.hxx"
9 #include "resiprocate/dum/Dialog.hxx"
10 #include "resiprocate/dum/DialogUsageManager.hxx"
11 #include "resiprocate/dum/InviteSessionCreator.hxx"
12 #include "resiprocate/dum/InviteSessionHandler.hxx"
13 #include "resiprocate/dum/ServerInviteSession.hxx"
14 #include "resiprocate/dum/ServerSubscription.hxx"
15 #include "resiprocate/dum/SubscriptionHandler.hxx"
16 #include "resiprocate/dum/UsageUseException.hxx"
17 #include "resiprocate/os/Logger.hxx"
18
19 #if defined(WIN32) && defined(_DEBUG) && defined(LEAK_CHECK)// Used for tracking down memory leaks in Visual Studio
20 #define _CRTDBG_MAP_ALLOC
21 #include <stdlib.h>
22 #include <crtdbg.h>
23 #define new new( _NORMAL_BLOCK, __FILE__, __LINE__)
24 #endif // defined(WIN32) && defined(_DEBUG)
25
26 #define RESIPROCATE_SUBSYSTEM Subsystem::DUM
27
28 using namespace resip;
29 using namespace std;
30
31 Dialog::Dialog(DialogUsageManager& dum, const SipMessage& msg, DialogSet& ds)
32 : mDum(dum),
33 mDialogSet(ds),
34 mId("INVALID", "INVALID", "INVALID"),
35 mClientSubscriptions(),
36 mServerSubscriptions(),
37 mInviteSession(0),
38 mType(Fake),
39 mRouteSet(),
40 mLocalContact(),
41 mLocalCSeq(0),
42 mRemoteCSeq(0),
43 mRemoteTarget(),
44 mLocalNameAddr(),
45 mRemoteNameAddr(),
46 mCallId(msg.header(h_CallID)),
47 mDestroying(false)
48 {
49 assert(msg.isExternal());
50
51
52 if (msg.isRequest()) // UAS
53 {
54 const SipMessage& request = msg;
55
56 switch (request.header(h_CSeq).method())
57 {
58 case INVITE:
59 mType = Invitation;
60 break;
61
62 case SUBSCRIBE:
63 case REFER:
64 case NOTIFY:
65 //!dcm! -- event header check
66 mType = Subscription;
67 break;
68
69 default:
70 mType = Fake;
71 }
72 if (request.exists(h_RecordRoutes))
73 {
74 mRouteSet = request.header(h_RecordRoutes); // !jf! is this right order
75 }
76
77 switch (request.header(h_CSeq).method())
78 {
79 case INVITE:
80 case SUBSCRIBE:
81 case REFER:
82 InfoLog ( << "UAS dialog ID creation, DS: " << ds.getId());
83 mId = DialogId(ds.getId(), request.header(h_From).param(p_tag));
84 mRemoteNameAddr = request.header(h_From);
85 mLocalNameAddr = request.header(h_To);
86 mLocalNameAddr.param(p_tag) = mId.getLocalTag();
87 if (request.exists(h_Contacts) && request.header(h_Contacts).size() == 1)
88 {
89 const NameAddr& contact = request.header(h_Contacts).front();
90 if (isEqualNoCase(contact.uri().scheme(), Symbols::Sips) ||
91 isEqualNoCase(contact.uri().scheme(), Symbols::Sip))
92 {
93 mLocalContact = NameAddr(request.header(h_RequestLine).uri()); // update later when send a request
94 mRemoteTarget = contact;
95 }
96 else
97 {
98 InfoLog(<< "Got an INVITE or SUBSCRIBE with invalid scheme");
99 DebugLog(<< request);
100 throw Exception("Invalid scheme in request", __FILE__, __LINE__);
101 }
102 }
103 else
104 {
105 InfoLog (<< "Got an INVITE or SUBSCRIBE that doesn't have exactly one contact");
106 DebugLog (<< request);
107 throw Exception("Too many (or no contact) contacts in request", __FILE__, __LINE__);
108 }
109 break;
110 default:
111 break;
112 }
113
114 mRemoteCSeq = request.header(h_CSeq).sequence();
115 mLocalCSeq = 1;
116
117 InfoLog ( << "************** Created Dialog as UAS **************" );
118 InfoLog ( << "mRemoteNameAddr: " << mRemoteNameAddr );
119 InfoLog ( << "mLocalNameAddr: " << mLocalNameAddr );
120 InfoLog ( << "mLocalContact: " << mLocalContact );
121 InfoLog ( << "mRemoteTarget: " << mRemoteTarget );
122 }
123 else if (msg.isResponse())
124 {
125 mId = DialogId(msg);
126 const SipMessage& response = msg;
127 mRemoteNameAddr = response.header(h_To);
128 mLocalNameAddr = response.header(h_From);
129
130 switch (msg.header(h_CSeq).method())
131 {
132 case INVITE:
133 mType = Invitation;
134 break;
135
136 case SUBSCRIBE:
137 case REFER:
138 mType = Subscription;
139 break;
140
141 default:
142 mType = Fake;
143 }
144
145 if (response.exists(h_RecordRoutes))
146 {
147 mRouteSet = response.header(h_RecordRoutes).reverse();
148 }
149
150 switch (response.header(h_CSeq).method())
151 {
152 case INVITE:
153 case SUBSCRIBE:
154 case REFER:
155 if (response.header(h_StatusLine).statusCode() > 100 &&
156 response.header(h_StatusLine).statusCode() < 300)
157 {
158
159 if (response.exists(h_Contacts) && response.header(h_Contacts).size() == 1)
160 {
161 const NameAddr& contact = response.header(h_Contacts).front();
162 if (isEqualNoCase(contact.uri().scheme(), Symbols::Sips) ||
163 isEqualNoCase(contact.uri().scheme(), Symbols::Sip))
164 {
165 BaseCreator* creator = mDum.findCreator(mId);
166 assert(creator);// !jf! throw or something here
167
168 mLocalContact = creator->getLastRequest().header(h_Contacts).front();
169 mRemoteTarget = contact;
170 }
171 else
172 {
173 InfoLog (<< "Got an INVITE or SUBSCRIBE with invalid scheme");
174 DebugLog (<< response);
175 throw Exception("Bad scheme in contact in response", __FILE__, __LINE__);
176 }
177 }
178 else
179 {
180 InfoLog (<< "Got an INVITE or SUBSCRIBE that doesn't have exactly one contact");
181 DebugLog (<< response);
182 throw Exception("Too many contacts (or no contact) in response", __FILE__, __LINE__);
183 }
184 break;
185 default:
186 break;
187 }
188 }
189
190 mLocalCSeq = response.header(h_CSeq).sequence();
191 mRemoteCSeq = 0;
192 InfoLog ( << "************** Created Dialog as UAC **************" );
193 InfoLog ( << "mRemoteNameAddr: " << mRemoteNameAddr );
194 InfoLog ( << "mLocalNameAddr: " << mLocalNameAddr );
195 InfoLog ( << "mLocalContact: " << mLocalContact );
196 InfoLog ( << "mRemoteTarget: " << mRemoteTarget );
197
198
199 }
200 mDialogSet.addDialog(this);
201 DebugLog ( <<"Dialog::Dialog " << mId);
202 }
203
204 Dialog::~Dialog()
205 {
206 DebugLog ( <<"Dialog::~Dialog() ");
207
208 mDestroying = true;
209
210 while (!mClientSubscriptions.empty())
211 {
212 delete *mClientSubscriptions.begin();
213 }
214
215 while (!mServerSubscriptions.empty())
216 {
217 delete *mServerSubscriptions.begin();
218 }
219
220 delete mInviteSession;
221
222 mDialogSet.mDialogs.erase(this->getId());
223 delete mAppDialog;
224 mDialogSet.possiblyDie();
225 }
226
227 DialogId
228 Dialog::getId() const
229 {
230 return mId;
231 }
232
233 void
234 Dialog::cancel()
235 {
236 if (mInviteSession)
237 {
238 mInviteSession->send(mInviteSession->end());
239 }
240 else
241 {
242 if (mDialogSet.getCreator())
243 {
244 SipMessage& request = mDialogSet.getCreator()->getLastRequest();
245 if (request.header(h_RequestLine).method() == INVITE)
246 {
247 makeCancel(request);
248 mDum.send(request);
249 delete this;
250 }
251 else
252 {
253 throw new UsageUseException("Can only CANCEL an INVITE", __FILE__, __LINE__);
254 }
255 }
256 else
257 {
258 throw new UsageUseException("Attempting to cancel UAS dialogSet", __FILE__, __LINE__);
259 }
260 }
261 }
262
263 void
264 Dialog::dispatch(const SipMessage& msg)
265 {
266 InfoLog ( << "Dialog::dispatch: " << msg.brief());
267 if (msg.isRequest())
268 {
269 const SipMessage& request = msg;
270 switch (request.header(h_CSeq).method())
271 {
272 case INVITE: // new INVITE
273 if (mInviteSession == 0)
274 {
275 InfoLog ( << "Dialog::dispatch -- Created new server invite session" << msg.brief());
276 mInviteSession = makeServerInviteSession(request);
277 }
278 mInviteSession->dispatch(request);
279 break;
280 case BYE:
281 if (mInviteSession == 0)
282 {
283 InfoLog ( << "Spurious BYE" );
284 return;
285 }
286 else
287 {
288 mInviteSession->dispatch(request);
289 }
290 break;
291 case ACK:
292 case CANCEL:
293 if (mInviteSession == 0)
294 {
295 InfoLog (<< "Drop stray ACK or CANCEL in dialog on the floor");
296 DebugLog (<< request);
297 }
298 else
299 {
300 mInviteSession->dispatch(request);
301 }
302 break;
303 case SUBSCRIBE:
304 {
305 ServerSubscription* server = findMatchingServerSub(request);
306 if (server)
307 {
308 server->dispatch(request);
309 }
310 else
311 {
312 if (request.header(h_Event).value() == "refer")
313 {
314 InfoLog (<< "Received a subscribe to a non-existent refer subscription: " << request.brief());
315 SipMessage failure;
316 makeResponse(failure, request, 403);
317 mDum.sendResponse(failure);
318 return;
319 }
320 else
321 {
322 server = makeServerSubscription(request);
323 mServerSubscriptions.push_back(server);
324 server->dispatch(request);
325 }
326 }
327 mDum.mInviteSessionHandler->onRefer(mInviteSession->getSessionHandle(), server->getHandle(), msg);
328 }
329 break;
330 case REFER:
331 {
332 if (mInviteSession == 0)
333 {
334 InfoLog (<< "Received an in dialog refer in a non-invite dialog: " << request.brief());
335 SipMessage failure;
336 makeResponse(failure, request, 405);
337 mDum.sendResponse(failure);
338 return;
339 }
340 else if (!request.exists(h_ReferTo))
341 {
342 InfoLog (<< "Received refer w/out a Refer-To: " << request.brief());
343 SipMessage failure;
344 makeResponse(failure, request, 400);
345 mDum.sendResponse(failure);
346 return;
347 }
348 else
349 {
350 ServerSubscription* server = findMatchingServerSub(request);
351 if (server)
352 {
353 server->dispatch(request);
354 }
355 else
356 {
357 server = makeServerSubscription(request);
358 mServerSubscriptions.push_back(server);
359 server->dispatch(request);
360 }
361 mDum.mInviteSessionHandler->onRefer(mInviteSession->getSessionHandle(), server->getHandle(), msg);
362 }
363 }
364 break;
365 case NOTIFY:
366 {
367 ClientSubscription* client = findMatchingClientSub(request);
368 if (client)
369 {
370 client->dispatch(request);
371 }
372 else
373 {
374 BaseCreator* creator = mDum.findCreator(mId);
375 if (creator)
376 {
377 ClientSubscription* sub = makeClientSubscription(request);
378 mClientSubscriptions.push_back(sub);
379 sub->dispatch(request);
380 }
381 else
382 {
383 SipMessage failure;
384 makeResponse(failure, request, 481);
385 mDum.sendResponse(failure);
386 return;
387 }
388 }
389 }
390 break;
391 default:
392 assert(0);
393 return;
394 }
395 }
396 else if (msg.isResponse())
397 {
398 if (!mDialogSet.getCreator() ||
399 !(msg.header(h_CSeq).method() == mDialogSet.getCreator()->getLastRequest().header(h_RequestLine).method()))
400 {
401 SipMessage* lastRequest = 0;
402 switch (msg.header(h_CSeq).method())
403 {
404 case INVITE:
405 case CANCEL:
406 case REFER:
407 case BYE:
408 if (mInviteSession == 0)
409 {
410 //spurious
411 return;
412 }
413 else
414 {
415 lastRequest = &mInviteSession->mLastRequest;
416 }
417 break;
418 default:
419 break;
420 }
421 if ( lastRequest && mDum.mClientAuthManager->handle( *lastRequest, msg ) )
422 {
423 InfoLog( << "about to retransmit request with digest credentials" );
424 InfoLog( << *lastRequest );
425
426 mDum.send(*lastRequest);
427 return;
428 }
429 }
430
431 const SipMessage& response = msg;
432 int code = response.header(h_StatusLine).statusCode();
433 if (code >=200 && code < 300)
434 {
435 if (response.exists(h_RecordRoutes))
436 {
437 mRouteSet = response.header(h_RecordRoutes).reverse();
438 }
439 }
440
441 // !jf! should this only be for 2xx responses? !jf! Propose no as an
442 // answer !dcm! what is he on?
443 switch (response.header(h_CSeq).method())
444 {
445 case INVITE:
446 if (mInviteSession == 0)
447 {
448 // #if!jf! don't think creator needs a dispatch
449 //BaseCreator* creator = mDum.findCreator(mId);
450 //assert (creator); // stray responses have been rejected already
451 //creator->dispatch(response);
452 // #endif!jf!
453 InfoLog ( << "Dialog::dispatch -- Created new client invite session" << msg.brief());
454
455 mInviteSession = makeClientInviteSession(response);
456 mInviteSession->dispatch(response);
457 }
458 else
459 {
460 mInviteSession->dispatch(response);
461 }
462 break;
463 case BYE:
464 case ACK:
465 case CANCEL:
466 if (mInviteSession != 0)
467 {
468 mInviteSession->dispatch(response);
469 }
470 // else drop on the floor
471 break;
472 case REFER:
473 {
474 int code = response.header(h_StatusLine).statusCode();
475 if (code < 300)
476 {
477 // throw it away
478 return;
479 }
480 else
481 {
482 if (mInviteSession && mDum.mInviteSessionHandler)
483 {
484 mDum.mInviteSessionHandler->onReferRejected(mInviteSession->getSessionHandle(), response);
485 }
486 }
487 }
488 break;
489 case SUBSCRIBE:
490 {
491 int code = response.header(h_StatusLine).statusCode();
492 if (code < 300)
493 {
494 // throw it away
495 return;
496 }
497 else
498 {
499 ClientSubscription* client = findMatchingClientSub(response);
500 if (client)
501 {
502 client->dispatch(response);
503 }
504 else
505 {
506 //!dcm! -- can't subscribe in an existing Dialog, this is all
507 //a bit of a hack.
508 BaseCreator* creator = mDialogSet.getCreator();
509 assert(creator);
510 assert(creator->getLastRequest().exists(h_Event));
511 ClientSubscriptionHandler* handler =
512 mDum.getClientSubscriptionHandler(creator->getLastRequest().header(h_Event).value());
513 assert(handler);
514 handler->onTerminated(ClientSubscriptionHandle::NotValid(), response);
515 possiblyDie();
516 }
517 }
518 }
519 break;
520 case NOTIFY:
521 {
522 //only dispatch if there is a matching server subscription. DUM does
523 //not handle responses to out-of-dialog NOTIFY messages
524 ServerSubscription* server = findMatchingServerSub(response);
525 if (server)
526 {
527 server->dispatch(response);
528 }
529 }
530 default:
531 assert(0);
532 return;
533 }
534 }
535 }
536
537 ServerSubscription*
538 Dialog::findMatchingServerSub(const SipMessage& msg)
539 {
540 for (std::list<ServerSubscription*>::iterator i=mServerSubscriptions.begin();
541 i != mServerSubscriptions.end(); ++i)
542 {
543 if ((*i)->matches(msg))
544 {
545 return *i;
546 }
547 }
548 return 0;
549 }
550
551 ClientSubscription*
552 Dialog::findMatchingClientSub(const SipMessage& msg)
553 {
554 for (std::list<ClientSubscription*>::iterator i=mClientSubscriptions.begin();
555 i != mClientSubscriptions.end(); ++i)
556 {
557 if ((*i)->matches(msg))
558 {
559 return *i;
560 }
561 }
562 return 0;
563 }
564
565 InviteSessionHandle
566 Dialog::getInviteSession()
567 {
568 if (mInviteSession)
569 {
570 return mInviteSession->getSessionHandle();
571 }
572 else
573 {
574 return InviteSessionHandle::NotValid();
575 }
576 }
577
578 std::vector<ClientSubscriptionHandle>
579 Dialog::findClientSubscriptions(const Data& event)
580 {
581 std::vector<ClientSubscriptionHandle> handles;
582
583 for (std::list<ClientSubscription*>::const_iterator i = mClientSubscriptions.begin();
584 i != mClientSubscriptions.end(); ++i)
585 {
586 if ( (*i)->getEventType() == event)
587 {
588 handles.push_back((*i)->getHandle());
589 }
590 }
591 return handles;
592 }
593
594 std::vector<ServerSubscriptionHandle>
595 Dialog::findServerSubscriptions(const Data& event)
596 {
597 std::vector<ServerSubscriptionHandle> handles;
598
599 for (std::list<ServerSubscription*>::const_iterator i = mServerSubscriptions.begin();
600 i != mServerSubscriptions.end(); ++i)
601 {
602 if ( (*i)->getEventType() == event)
603 {
604 handles.push_back((*i)->getHandle());
605 }
606 }
607 return handles;
608 }
609
610
611 std::vector<ClientSubscriptionHandle>
612 Dialog::getClientSubscriptions()
613 {
614 std::vector<ClientSubscriptionHandle> handles;
615
616 for (std::list<ClientSubscription*>::const_iterator i = mClientSubscriptions.begin();
617 i != mClientSubscriptions.end(); ++i)
618 {
619 handles.push_back((*i)->getHandle());
620 }
621
622 return handles;
623 }
624
625 std::vector<ServerSubscriptionHandle>
626 Dialog::getServerSubscriptions()
627 {
628 std::vector<ServerSubscriptionHandle> handles;
629
630 for (std::list<ServerSubscription*>::const_iterator i = mServerSubscriptions.begin();
631 i != mServerSubscriptions.end(); ++i)
632 {
633 handles.push_back((*i)->getHandle());
634 }
635
636 return handles;
637 }
638
639
640 #if 0
641 void
642 Dialog::processNotify(const SipMessage& notify)
643 {
644 if (notify.isRequest())
645 {
646 if (findSubscriptions().empty())
647 {
648 SubscriptionCreator* creator = dynamic_cast<SubscriptionCreator*>(DialogSetId(notify).getCreator());
649 if (creator)
650 {
651 creator->makeNewSubscription(notify);
652 }
653 }
654 else
655 {
656 for (std::list<BaseUsage*>::iterator i=mUsages.begin(); i!=mUsages.end(); i++)
657 {
658 ClientSubscription* sub = dynamic_cast<ClientSubscription*>(*i);
659 if (sub && sub->matches(notify))
660 {
661 sub->process(notify);
662 break;
663 }
664 }
665 }
666 }
667 }
668 #endif
669
670
671 void
672 Dialog::makeRequest(SipMessage& request, MethodTypes method)
673 {
674 RequestLine rLine(method);
675
676 rLine.uri() = mRemoteTarget.uri();
677
678 request.header(h_RequestLine) = rLine;
679 request.header(h_To) = mRemoteNameAddr;
680 // request.header(h_To).param(p_tag) = mId.getRemoteTag();
681 request.header(h_From) = mLocalNameAddr;
682 // request.header(h_From).param(p_tag) = mId.getLocalTag();
683
684 request.header(h_CallId) = mCallId;
685
686 request.remove(h_RecordRoutes); //!dcm! -- all of this is rather messy
687
688 request.remove(h_Contacts);
689 request.header(h_Contacts).push_front(mLocalContact);
690 request.header(h_CSeq).method() = method;
691 request.header(h_MaxForwards).value() = 70;
692
693 //must keep old via for cancel
694 if (method != CANCEL)
695 {
696 request.header(h_Routes) = mRouteSet;
697 request.remove(h_Vias);
698 Via via;
699 via.param(p_branch); // will create the branch
700 request.header(h_Vias).push_front(via);
701 }
702 else
703 {
704 assert(request.exists(h_Vias));
705 }
706 //don't increment CSeq for ACK or CANCEL
707 if (method != ACK && method != CANCEL)
708 {
709 request.header(h_CSeq).sequence() = ++mLocalCSeq;
710 }
711 InfoLog ( << "Dialog::makeRequest: " << request );
712 }
713
714 void
715 Dialog::makeCancel(SipMessage& request)
716 {
717 //minimal for cancel
718 request.header(h_RequestLine).method() = CANCEL;
719 request.header(h_CSeq).method() = CANCEL;
720 request.remove(h_Requires);
721 request.remove(h_ProxyRequires);
722 assert(request.exists(h_Vias));
723
724 //not sure of these
725 request.header(h_To).remove(p_tag);
726 request.remove(h_RecordRoutes);
727 request.remove(h_Contacts);
728 request.header(h_Contacts).push_front(mLocalContact);
729 request.header(h_MaxForwards).value() = 70;
730 }
731
732 void
733 Dialog::makeResponse(SipMessage& response, const SipMessage& request, int code)
734 {
735 assert( code >= 100 );
736 response.remove(h_Contacts);
737 if (code < 300 && code > 100)
738 {
739 assert(request.isRequest());
740 assert(request.header(h_RequestLine).getMethod() == INVITE ||
741 request.header(h_RequestLine).getMethod() == SUBSCRIBE ||
742 request.header(h_RequestLine).getMethod() == BYE ||
743 request.header(h_RequestLine).getMethod() == CANCEL ||
744 request.header(h_RequestLine).getMethod() == REFER ||
745 request.header(h_RequestLine).getMethod() == MESSAGE ||
746 request.header(h_RequestLine).getMethod() == NOTIFY ||
747 request.header(h_RequestLine).getMethod() == OPTIONS
748 );
749
750 assert (request.header(h_RequestLine).getMethod() == CANCEL || // Contact header is not required for Requests that do not form a dialog
751 request.header(h_RequestLine).getMethod() == BYE ||
752 request.header(h_Contacts).size() == 1);
753 Helper::makeResponse(response, request, code, mLocalContact);
754 response.header(h_To).param(p_tag) = mId.getLocalTag();
755 }
756 else
757 {
758 Helper::makeResponse(response, request, code, mLocalContact);
759 response.header(h_To).param(p_tag) = mId.getLocalTag();
760
761 }
762 InfoLog ( << "Dialog::makeResponse: " << response);
763 }
764
765
766 ClientInviteSession*
767 Dialog::makeClientInviteSession(const SipMessage& response)
768 {
769 InviteSessionCreator* creator = dynamic_cast<InviteSessionCreator*>(mDialogSet.getCreator());
770 assert(creator); // !jf! this maybe can assert by evil UAS
771 //return mDum.createAppClientInviteSession(*this, *creator);
772 return new ClientInviteSession(mDum, *this, creator->getLastRequest(),
773 creator->getInitialOffer(), creator->getServerSubscription());
774 }
775
776
777
778 ClientSubscription*
779 Dialog::makeClientSubscription(const SipMessage& request)
780 {
781 return new ClientSubscription(mDum, *this, request);
782 }
783
784
785 ServerInviteSession*
786 Dialog::makeServerInviteSession(const SipMessage& request)
787 {
788 return new ServerInviteSession(mDum, *this, request);
789 }
790
791 ServerSubscription*
792 Dialog::makeServerSubscription(const SipMessage& request)
793 {
794 return new ServerSubscription(mDum, *this, request);
795 }
796
797 Dialog::Exception::Exception(const Data& msg, const Data& file, int line)
798 : BaseException(msg, file, line)
799 {
800 }
801
802 void
803 Dialog::update(const SipMessage& msg)
804 {
805 }
806
807 #if 0
808 void
809 Dialog::setLocalContact(const NameAddr& localContact)
810 {
811 mLocalContact = localContact;
812 }
813
814 void
815 Dialog::setRemoteTarget(const NameAddr& remoteTarget)
816 {
817 mRemoteTarget = remoteTarget;
818 }
819 #endif
820
821 void Dialog::possiblyDie()
822 {
823 if (!mDestroying)
824 {
825 if (mClientSubscriptions.empty() &&
826 mServerSubscriptions.empty() &&
827 !mInviteSession)
828 {
829 delete this;
830 }
831 }
832 }
833
834 ostream&
835 resip::operator<<(ostream& strm, const Dialog& dialog)
836 {
837
838 return strm;
839 }
840

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27