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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27