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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27