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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3383 - (show annotations) (download)
Fri Oct 8 17:45:53 2004 UTC (15 years, 2 months ago) by sgodin
Original Path: main/sip/resiprocate/dum/Dialog.cxx
File size: 29978 byte(s)
remove headers from ACK and CANCEL that shouldn't be present
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 DebugLog (<< "Making subscription (from creator) request: " << 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 DebugLog (<< "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; currently, spurious failure messages may cause callbacks
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 ClientSubscription* sub = makeClientSubscription(creator->getLastRequest());
559 mClientSubscriptions.push_back(sub);
560 sub->dispatch(response);
561 }
562 }
563 }
564 }
565 }
566 break;
567 case NOTIFY:
568 {
569 //2xx responses are treated as retransmission quenchers(handled by
570 //the stack). Failures are dispatched to all ServerSubsscriptions,
571 //which may not be correct.
572
573 int code = msg.header(h_StatusLine).statusCode();
574 if (code >= 300)
575 {
576 //!dcm! -- ick, write guard
577 mDestroying = true;
578 for (list<ServerSubscription*>::iterator it = mServerSubscriptions.begin();
579 it != mServerSubscriptions.end(); )
580 {
581 ServerSubscription* s = *it;
582 it++;
583 s->dispatch(msg);
584 }
585 mDestroying = false;
586 possiblyDie();
587 }
588 // ServerSubscription* server = findMatchingServerSub(response);
589 // if (server)
590 // {
591 // server->dispatch(response);
592 // }
593 }
594 break;
595 default:
596 assert(0);
597 return;
598 }
599 }
600 }
601
602 ServerSubscription*
603 Dialog::findMatchingServerSub(const SipMessage& msg)
604 {
605 for (std::list<ServerSubscription*>::iterator i=mServerSubscriptions.begin();
606 i != mServerSubscriptions.end(); ++i)
607 {
608 if ((*i)->matches(msg))
609 {
610 return *i;
611 }
612 }
613 return 0;
614 }
615
616 ClientSubscription*
617 Dialog::findMatchingClientSub(const SipMessage& msg)
618 {
619 for (std::list<ClientSubscription*>::iterator i=mClientSubscriptions.begin();
620 i != mClientSubscriptions.end(); ++i)
621 {
622 if ((*i)->matches(msg))
623 {
624 return *i;
625 }
626 }
627 return 0;
628 }
629
630 InviteSessionHandle
631 Dialog::getInviteSession()
632 {
633 if (mInviteSession)
634 {
635 return mInviteSession->getSessionHandle();
636 }
637 else
638 {
639 return InviteSessionHandle::NotValid();
640 }
641 }
642
643 std::vector<ClientSubscriptionHandle>
644 Dialog::findClientSubscriptions(const Data& event)
645 {
646 std::vector<ClientSubscriptionHandle> handles;
647
648 for (std::list<ClientSubscription*>::const_iterator i = mClientSubscriptions.begin();
649 i != mClientSubscriptions.end(); ++i)
650 {
651 if ( (*i)->getEventType() == event)
652 {
653 handles.push_back((*i)->getHandle());
654 }
655 }
656 return handles;
657 }
658
659 std::vector<ServerSubscriptionHandle>
660 Dialog::findServerSubscriptions(const Data& event)
661 {
662 std::vector<ServerSubscriptionHandle> handles;
663
664 for (std::list<ServerSubscription*>::const_iterator i = mServerSubscriptions.begin();
665 i != mServerSubscriptions.end(); ++i)
666 {
667 if ( (*i)->getEventType() == event)
668 {
669 handles.push_back((*i)->getHandle());
670 }
671 }
672 return handles;
673 }
674
675
676 std::vector<ClientSubscriptionHandle>
677 Dialog::getClientSubscriptions()
678 {
679 std::vector<ClientSubscriptionHandle> handles;
680
681 for (std::list<ClientSubscription*>::const_iterator i = mClientSubscriptions.begin();
682 i != mClientSubscriptions.end(); ++i)
683 {
684 handles.push_back((*i)->getHandle());
685 }
686
687 return handles;
688 }
689
690 std::vector<ServerSubscriptionHandle>
691 Dialog::getServerSubscriptions()
692 {
693 std::vector<ServerSubscriptionHandle> handles;
694
695 for (std::list<ServerSubscription*>::const_iterator i = mServerSubscriptions.begin();
696 i != mServerSubscriptions.end(); ++i)
697 {
698 handles.push_back((*i)->getHandle());
699 }
700
701 return handles;
702 }
703
704 void
705 Dialog::redirected(const SipMessage& msg)
706 {
707 //Established dialogs are not destroyed by a redirect
708 if (!mClientSubscriptions.empty() || !mServerSubscriptions.empty())
709 {
710 return;
711 }
712 if (mInviteSession)
713 {
714 ClientInviteSession* cInv = dynamic_cast<ClientInviteSession*>(mInviteSession);
715 if (cInv)
716 {
717 cInv->redirected(msg);
718 }
719 }
720 }
721
722
723 #if 0
724 void
725 Dialog::processNotify(const SipMessage& notify)
726 {
727 if (notify.isRequest())
728 {
729 if (findSubscriptions().empty())
730 {
731 SubscriptionCreator* creator = dynamic_cast<SubscriptionCreator*>(DialogSetId(notify).getCreator());
732 if (creator)
733 {
734 creator->makeNewSubscription(notify);
735 }
736 }
737 else
738 {
739 for (std::list<BaseUsage*>::iterator i=mUsages.begin(); i!=mUsages.end(); i++)
740 {
741 ClientSubscription* sub = dynamic_cast<ClientSubscription*>(*i);
742 if (sub && sub->matches(notify))
743 {
744 sub->process(notify);
745 break;
746 }
747 }
748 }
749 }
750 }
751 #endif
752
753
754 void
755 Dialog::makeRequest(SipMessage& request, MethodTypes method)
756 {
757 RequestLine rLine(method);
758
759 rLine.uri() = mRemoteTarget.uri();
760
761 request.header(h_RequestLine) = rLine;
762 request.header(h_To) = mRemoteNameAddr;
763 // request.header(h_To).param(p_tag) = mId.getRemoteTag();
764 request.header(h_From) = mLocalNameAddr;
765 // request.header(h_From).param(p_tag) = mId.getLocalTag();
766
767 request.header(h_CallId) = mCallId;
768
769 request.remove(h_RecordRoutes); //!dcm! -- all of this is rather messy
770
771 request.remove(h_Contacts);
772 request.header(h_Contacts).push_front(mLocalContact);
773 request.header(h_CSeq).method() = method;
774 request.header(h_MaxForwards).value() = 70;
775
776 //must keep old via for cancel
777 if (method != CANCEL)
778 {
779 request.header(h_Routes) = mRouteSet;
780 request.remove(h_Vias);
781 Via via;
782 via.param(p_branch); // will create the branch
783 request.header(h_Vias).push_front(via);
784 }
785 else
786 {
787 assert(request.exists(h_Vias));
788 }
789 //don't increment CSeq for ACK or CANCEL
790 if (method != ACK && method != CANCEL)
791 {
792 request.header(h_CSeq).sequence() = ++mLocalCSeq;
793 }
794 else
795 {
796 // ACK and cancel have a minimal header set
797 request.remove(h_Accepts);
798 request.remove(h_AcceptEncodings);
799 request.remove(h_AcceptLanguages);
800 request.remove(h_Allows);
801 request.remove(h_Requires);
802 request.remove(h_ProxyRequires);
803 request.remove(h_Supporteds);
804 }
805 DebugLog ( << "Dialog::makeRequest: " << request );
806 }
807
808 void
809 Dialog::makeCancel(SipMessage& request)
810 {
811 //minimal for cancel
812 request.header(h_RequestLine).method() = CANCEL;
813 request.header(h_CSeq).method() = CANCEL;
814 request.remove(h_Accepts);
815 request.remove(h_AcceptEncodings);
816 request.remove(h_AcceptLanguages);
817 request.remove(h_Allows);
818 request.remove(h_Requires);
819 request.remove(h_ProxyRequires);
820 request.remove(h_Supporteds);
821 assert(request.exists(h_Vias));
822
823 //not sure of these
824 request.header(h_To).remove(p_tag);
825 request.remove(h_RecordRoutes);
826 request.remove(h_Contacts);
827 request.header(h_Contacts).push_front(mLocalContact);
828 request.header(h_MaxForwards).value() = 70;
829 }
830
831 void
832 Dialog::makeResponse(SipMessage& response, const SipMessage& request, int code)
833 {
834 assert( code >= 100 );
835 response.remove(h_Contacts);
836 if (code < 300 && code > 100)
837 {
838 assert(request.isRequest());
839 assert(request.header(h_RequestLine).getMethod() == INVITE ||
840 request.header(h_RequestLine).getMethod() == SUBSCRIBE ||
841 request.header(h_RequestLine).getMethod() == BYE ||
842 request.header(h_RequestLine).getMethod() == CANCEL ||
843 request.header(h_RequestLine).getMethod() == REFER ||
844 request.header(h_RequestLine).getMethod() == MESSAGE ||
845 request.header(h_RequestLine).getMethod() == NOTIFY ||
846 request.header(h_RequestLine).getMethod() == INFO ||
847 request.header(h_RequestLine).getMethod() == OPTIONS
848 );
849
850 // assert (request.header(h_RequestLine).getMethod() == CANCEL || // Contact header is not required for Requests that do not form a dialog
851 // request.header(h_RequestLine).getMethod() == BYE ||
852 // request.header(h_Contacts).size() == 1);
853 Helper::makeResponse(response, request, code, mLocalContact);
854 response.header(h_To).param(p_tag) = mId.getLocalTag();
855 }
856 else
857 {
858 Helper::makeResponse(response, request, code);
859 response.header(h_To).param(p_tag) = mId.getLocalTag();
860
861 }
862 DebugLog ( << "Dialog::makeResponse: " << response);
863 }
864
865
866 ClientInviteSession*
867 Dialog::makeClientInviteSession(const SipMessage& response)
868 {
869 InviteSessionCreator* creator = dynamic_cast<InviteSessionCreator*>(mDialogSet.getCreator());
870 assert(creator); // !jf! this maybe can assert by evil UAS
871 //return mDum.createAppClientInviteSession(*this, *creator);
872 return new ClientInviteSession(mDum, *this, creator->getLastRequest(),
873 creator->getInitialOffer(), creator->getServerSubscription());
874 }
875
876
877
878 ClientSubscription*
879 Dialog::makeClientSubscription(const SipMessage& request)
880 {
881 return new ClientSubscription(mDum, *this, request);
882 }
883
884
885 ServerInviteSession*
886 Dialog::makeServerInviteSession(const SipMessage& request)
887 {
888 return new ServerInviteSession(mDum, *this, request);
889 }
890
891 ServerSubscription*
892 Dialog::makeServerSubscription(const SipMessage& request)
893 {
894 return new ServerSubscription(mDum, *this, request);
895 }
896
897 Dialog::Exception::Exception(const Data& msg, const Data& file, int line)
898 : BaseException(msg, file, line)
899 {
900 }
901
902 void
903 Dialog::update(const SipMessage& msg)
904 {
905 }
906
907 #if 0
908 void
909 Dialog::setLocalContact(const NameAddr& localContact)
910 {
911 mLocalContact = localContact;
912 }
913
914 void
915 Dialog::setRemoteTarget(const NameAddr& remoteTarget)
916 {
917 mRemoteTarget = remoteTarget;
918 }
919 #endif
920
921 void Dialog::possiblyDie()
922 {
923 if (!mDestroying)
924 {
925 if (mClientSubscriptions.empty() &&
926 mServerSubscriptions.empty() &&
927 !mInviteSession)
928 {
929 delete this;
930 }
931 }
932 }
933
934 bool
935 Dialog::matches(const SipMessage& msg)
936 {
937 //currently only responses are passed to this method
938 if (msg.isRequest())
939 {
940 return false;
941 }
942
943 switch (msg.header(h_CSeq).method())
944 {
945 case INVITE:
946 case CANCEL:
947 case REFER:
948 case BYE:
949 if (mInviteSession == 0)
950 {
951 return false;
952 }
953 else
954 {
955 return msg.getTransactionId() == mInviteSession->mLastRequest.getTransactionId();
956 }
957 break;
958 case INFO:
959 if (mInviteSession == 0)
960 {
961 return false;
962 }
963 else
964 {
965 return msg.getTransactionId() == mInviteSession->mLastNit.getTransactionId();
966 }
967 break;
968 case SUBSCRIBE:
969 if (mClientSubscriptions.empty())
970 {
971 return false;
972 }
973 else
974 {
975 for (std::list<ClientSubscription*>::iterator it = mClientSubscriptions.begin();
976 it != mClientSubscriptions.end(); it++)
977 {
978 return msg.getTransactionId() == (*it)->mLastRequest.getTransactionId();
979 }
980 }
981 break;
982 case NOTIFY:
983 if (mServerSubscriptions.empty())
984 {
985 return false;
986 }
987 else
988 {
989 for (std::list<ServerSubscription*>::iterator it = mServerSubscriptions.begin();
990 it != mServerSubscriptions.end(); it++)
991 {
992 return msg.getTransactionId() == (*it)->mLastNotify.getTransactionId();
993 }
994 }
995 break;
996 default:
997 return false;
998 }
999 return false;
1000 }
1001
1002 ostream&
1003 resip::operator<<(ostream& strm, const Dialog& dialog)
1004 {
1005
1006 return strm;
1007 }
1008

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27