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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3308 - (hide annotations) (download)
Fri Sep 10 17:07:28 2004 UTC (15 years, 3 months ago) by derek
Original Path: main/sip/resiprocate/dum/Dialog.cxx
File size: 29004 byte(s)
added setOverrideHostAndPort for NAT traversal
if there is no to tag in a response, tid is used to dispatch to the correct dialog if one exists
temproary fix on onIllegalNegotiation; re-invite state machine needs tweaking

1 davidb 2603 #include "resiprocate/Contents.hxx"
2 jason 2614 #include "resiprocate/Helper.hxx"
3 jason 2885 #include "resiprocate/SipMessage.hxx"
4 derek 2943 #include "resiprocate/dum/AppDialog.hxx"
5 jason 2885 #include "resiprocate/dum/BaseCreator.hxx"
6 derek 2991 #include "resiprocate/dum/ClientAuthManager.hxx"
7 jason 2941 #include "resiprocate/dum/ClientInviteSession.hxx"
8     #include "resiprocate/dum/ClientSubscription.hxx"
9 jason 2885 #include "resiprocate/dum/Dialog.hxx"
10     #include "resiprocate/dum/DialogUsageManager.hxx"
11     #include "resiprocate/dum/InviteSessionCreator.hxx"
12 derek 3058 #include "resiprocate/dum/InviteSessionHandler.hxx"
13 jason 2941 #include "resiprocate/dum/ServerInviteSession.hxx"
14     #include "resiprocate/dum/ServerSubscription.hxx"
15 derek 3082 #include "resiprocate/dum/SubscriptionHandler.hxx"
16 derek 3101 #include "resiprocate/dum/UsageUseException.hxx"
17 davidb 2603 #include "resiprocate/os/Logger.hxx"
18    
19 sgodin 3103 #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 sgodin 3102
26 davidb 2603 #define RESIPROCATE_SUBSYSTEM Subsystem::DUM
27    
28 ken 2520 using namespace resip;
29     using namespace std;
30    
31 derek 2867 Dialog::Dialog(DialogUsageManager& dum, const SipMessage& msg, DialogSet& ds)
32 derek 2995 : mDum(dum),
33 derek 2867 mDialogSet(ds),
34 derek 3089 mId("INVALID", "INVALID", "INVALID"),
35 jason 2588 mClientSubscriptions(),
36 derek 3041 mServerSubscriptions(),
37 jason 2588 mInviteSession(0),
38     mType(Fake),
39     mRouteSet(),
40 jason 2611 mLocalContact(),
41 jason 2577 mLocalCSeq(0),
42     mRemoteCSeq(0),
43 derek 2981 mRemoteTarget(),
44 derek 2995 mLocalNameAddr(),
45     mRemoteNameAddr(),
46     mCallId(msg.header(h_CallID)),
47 derek 3308 mAppDialog(0),
48     mDestroying(false)
49 jason 2577 {
50 davidb 2603 assert(msg.isExternal());
51 jason 2577
52 derek 2936
53 jason 2577 if (msg.isRequest()) // UAS
54     {
55     const SipMessage& request = msg;
56    
57     switch (request.header(h_CSeq).method())
58     {
59     case INVITE:
60 jason 2611 mType = Invitation;
61     break;
62    
63 davidb 2603 case SUBSCRIBE:
64 jason 2611 case REFER:
65     case NOTIFY:
66 derek 3041 //!dcm! -- event header check
67 jason 2611 mType = Subscription;
68     break;
69    
70     default:
71     mType = Fake;
72     }
73 derek 3024 if (request.exists(h_RecordRoutes))
74     {
75     mRouteSet = request.header(h_RecordRoutes); // !jf! is this right order
76     }
77 jason 2611
78     switch (request.header(h_CSeq).method())
79     {
80     case INVITE:
81     case SUBSCRIBE:
82     case REFER:
83 jason 3182 case NOTIFY:
84 jason 3156 DebugLog ( << "UAS dialog ID creation, DS: " << ds.getId());
85 derek 2995 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 jason 2577 if (request.exists(h_Contacts) && request.header(h_Contacts).size() == 1)
90     {
91 davidb 2603 const NameAddr& contact = request.header(h_Contacts).front();
92 jason 2577 if (isEqualNoCase(contact.uri().scheme(), Symbols::Sips) ||
93     isEqualNoCase(contact.uri().scheme(), Symbols::Sip))
94     {
95 jason 2611 mLocalContact = NameAddr(request.header(h_RequestLine).uri()); // update later when send a request
96 jason 2577 mRemoteTarget = contact;
97     }
98     else
99     {
100 davidb 2603 InfoLog(<< "Got an INVITE or SUBSCRIBE with invalid scheme");
101     DebugLog(<< request);
102 jason 2611 throw Exception("Invalid scheme in request", __FILE__, __LINE__);
103 jason 2577 }
104     }
105     else
106     {
107     InfoLog (<< "Got an INVITE or SUBSCRIBE that doesn't have exactly one contact");
108     DebugLog (<< request);
109 jason 2611 throw Exception("Too many (or no contact) contacts in request", __FILE__, __LINE__);
110 jason 2577 }
111     break;
112 davidb 2603 default:
113     break;
114 jason 2577 }
115    
116     mRemoteCSeq = request.header(h_CSeq).sequence();
117 jason 2611 mLocalCSeq = 1;
118 derek 2995
119 jason 3156 DebugLog ( << "************** Created Dialog as UAS **************" );
120     DebugLog ( << "mRemoteNameAddr: " << mRemoteNameAddr );
121     DebugLog ( << "mLocalNameAddr: " << mLocalNameAddr );
122     DebugLog ( << "mLocalContact: " << mLocalContact );
123     DebugLog ( << "mRemoteTarget: " << mRemoteTarget );
124 jason 2577 }
125     else if (msg.isResponse())
126     {
127 derek 2995 mId = DialogId(msg);
128 jason 2577 const SipMessage& response = msg;
129 derek 2995 mRemoteNameAddr = response.header(h_To);
130     mLocalNameAddr = response.header(h_From);
131 jason 2611
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 jason 2577 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 davidb 2603 case SUBSCRIBE:
156 jason 2611 case REFER:
157 derek 2983 if (response.header(h_StatusLine).statusCode() > 100 &&
158     response.header(h_StatusLine).statusCode() < 300)
159 jason 2577 {
160 derek 2983
161     if (response.exists(h_Contacts) && response.header(h_Contacts).size() == 1)
162 jason 2577 {
163 derek 2983 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 jason 3182 BaseCreator* creator = mDialogSet.getCreator();
168 derek 2983 assert(creator);// !jf! throw or something here
169 jason 2612
170 derek 2983 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 jason 2577 }
180     else
181     {
182 derek 2983 InfoLog (<< "Got an INVITE or SUBSCRIBE that doesn't have exactly one contact");
183 jason 2577 DebugLog (<< response);
184 derek 2983 throw Exception("Too many contacts (or no contact) in response", __FILE__, __LINE__);
185 jason 2577 }
186 derek 2983 break;
187     default:
188     break;
189 jason 2577 }
190     }
191 derek 2983
192 jason 2577 mLocalCSeq = response.header(h_CSeq).sequence();
193 jason 2611 mRemoteCSeq = 0;
194 jason 3156 DebugLog ( << "************** Created Dialog as UAC **************" );
195     DebugLog ( << "mRemoteNameAddr: " << mRemoteNameAddr );
196     DebugLog ( << "mLocalNameAddr: " << mLocalNameAddr );
197     DebugLog ( << "mLocalContact: " << mLocalContact );
198     DebugLog ( << "mRemoteTarget: " << mRemoteTarget );
199 derek 2995
200 jason 2611
201 jason 2577 }
202 derek 2867 mDialogSet.addDialog(this);
203 derek 3081 DebugLog ( <<"Dialog::Dialog " << mId);
204 jason 2577 }
205    
206 jason 2868 Dialog::~Dialog()
207     {
208 derek 3081 DebugLog ( <<"Dialog::~Dialog() ");
209    
210 derek 2981 mDestroying = true;
211 derek 3089
212     while (!mClientSubscriptions.empty())
213 derek 2981 {
214 derek 3089 delete *mClientSubscriptions.begin();
215 derek 2981 }
216 derek 3089
217     while (!mServerSubscriptions.empty())
218 derek 3041 {
219 derek 3089 delete *mServerSubscriptions.begin();
220 derek 3041 }
221 derek 3089
222 derek 2981 delete mInviteSession;
223    
224 jason 2884 mDialogSet.mDialogs.erase(this->getId());
225 derek 2976 delete mAppDialog;
226     mDialogSet.possiblyDie();
227 jason 2868 }
228    
229 jason 2588 DialogId
230     Dialog::getId() const
231     {
232     return mId;
233     }
234    
235 davidb 2604 void
236 jason 2891 Dialog::cancel()
237     {
238 derek 3006 if (mInviteSession)
239     {
240 sgodin 3102 mInviteSession->send(mInviteSession->end());
241 derek 3006 }
242     else
243     {
244 derek 3101 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 derek 3006 }
263 jason 2891 }
264    
265     void
266 davidb 2604 Dialog::dispatch(const SipMessage& msg)
267     {
268 jason 3156 DebugLog ( << "Dialog::dispatch: " << msg.brief());
269 jason 2614 if (msg.isRequest())
270 jason 2583 {
271 jason 2614 const SipMessage& request = msg;
272     switch (request.header(h_CSeq).method())
273 derek 3089 {
274 jason 2614 case INVITE: // new INVITE
275     if (mInviteSession == 0)
276     {
277 jason 3156 DebugLog ( << "Dialog::dispatch -- Created new server invite session" << msg.brief());
278 jason 2885 mInviteSession = makeServerInviteSession(request);
279 jason 2614 }
280     mInviteSession->dispatch(request);
281     break;
282 derek 3255 //refactor, send bad request for BYE, INFO, CANCEL?
283 derek 2997 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 derek 3255 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 jason 2614 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 derek 3041 {
319     ServerSubscription* server = findMatchingServerSub(request);
320     if (server)
321 jason 2614 {
322 derek 3041 server->dispatch(request);
323 jason 2614 }
324 derek 3041 else
325     {
326 derek 3101 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 derek 3041 }
341 derek 3101 mDum.mInviteSessionHandler->onRefer(mInviteSession->getSessionHandle(), server->getHandle(), msg);
342 derek 3041 }
343     break;
344 derek 3101 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 jason 2614 case NOTIFY:
380 derek 3089 {
381     ClientSubscription* client = findMatchingClientSub(request);
382     if (client)
383 jason 2614 {
384 derek 3089 client->dispatch(request);
385     }
386     else
387     {
388 jason 3182 BaseCreator* creator = mDialogSet.getCreator();
389 derek 3274 if (creator && (creator->getLastRequest().header(h_RequestLine).method() == SUBSCRIBE ||
390     creator->getLastRequest().header(h_RequestLine).method() == REFER))
391 jason 2612 {
392 derek 3274 InfoLog (<< "Making subscription from creator: " << creator->getLastRequest());
393     ClientSubscription* sub = makeClientSubscription(creator->getLastRequest());
394 derek 3089 mClientSubscriptions.push_back(sub);
395     sub->dispatch(request);
396 jason 2612 }
397 derek 3274 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 jason 2612 else
405     {
406 derek 3179 SipMessage failure;
407     makeResponse(failure, request, 481);
408 jason 3182 failure.header(h_To).remove(p_tag); // otherwise it will be INVALID
409     InfoLog (<< "Sending 481 - no dialog created " << endl << failure);
410 derek 3179 mDum.sendResponse(failure);
411     return;
412 jason 2612 }
413 jason 2614 }
414 derek 3089 }
415     break;
416     default:
417     assert(0);
418     return;
419 jason 2583 }
420 jason 2614 }
421     else if (msg.isResponse())
422     {
423 derek 3089 if (!mDialogSet.getCreator() ||
424 derek 3308 !(msg.header(h_CSeq) == mDialogSet.getCreator()->getLastRequest().header(h_CSeq)))
425 derek 3089 {
426     SipMessage* lastRequest = 0;
427     switch (msg.header(h_CSeq).method())
428     {
429     case INVITE:
430     case CANCEL:
431     case REFER:
432 derek 3146 case BYE:
433 derek 3255 case INFO:
434 derek 3096 if (mInviteSession == 0)
435 derek 3089 {
436     //spurious
437     return;
438     }
439     else
440     {
441     lastRequest = &mInviteSession->mLastRequest;
442     }
443     break;
444     default:
445     break;
446     }
447     if ( lastRequest && mDum.mClientAuthManager->handle( *lastRequest, msg ) )
448     {
449 jason 3156 InfoLog( << "about to re-send request with digest credentials" );
450 derek 3089 InfoLog( << *lastRequest );
451 derek 3308 mLocalCSeq++;
452 derek 3089 mDum.send(*lastRequest);
453     return;
454     }
455     }
456    
457 jason 2614 const SipMessage& response = msg;
458 derek 3112 int code = response.header(h_StatusLine).statusCode();
459     if (code >=200 && code < 300)
460     {
461     if (response.exists(h_RecordRoutes))
462     {
463     mRouteSet = response.header(h_RecordRoutes).reverse();
464     }
465     }
466    
467 jason 2885 // !jf! should this only be for 2xx responses? !jf! Propose no as an
468     // answer !dcm! what is he on?
469 jason 2614 switch (response.header(h_CSeq).method())
470 jason 2583 {
471 jason 2614 case INVITE:
472     if (mInviteSession == 0)
473     {
474 jason 2885 // #if!jf! don't think creator needs a dispatch
475     //BaseCreator* creator = mDum.findCreator(mId);
476     //assert (creator); // stray responses have been rejected already
477     //creator->dispatch(response);
478     // #endif!jf!
479 jason 3156 DebugLog ( << "Dialog::dispatch -- Created new client invite session" << msg.brief());
480 derek 2992
481 jason 2885 mInviteSession = makeClientInviteSession(response);
482     mInviteSession->dispatch(response);
483 jason 2614 }
484     else
485     {
486     mInviteSession->dispatch(response);
487     }
488     break;
489 derek 2997 case BYE:
490 jason 2614 case ACK:
491     case CANCEL:
492 derek 3261 case INFO:
493 jason 2614 if (mInviteSession != 0)
494     {
495     mInviteSession->dispatch(response);
496     }
497     // else drop on the floor
498 derek 3058 break;
499 jason 2614 case REFER:
500     {
501 derek 3058 int code = response.header(h_StatusLine).statusCode();
502     if (code < 300)
503 jason 2612 {
504 derek 3058 // throw it away
505     return;
506     }
507 jason 2614 else
508     {
509 derek 3058 if (mInviteSession && mDum.mInviteSessionHandler)
510     {
511     mDum.mInviteSessionHandler->onReferRejected(mInviteSession->getSessionHandle(), response);
512     }
513     }
514     }
515     break;
516     case SUBSCRIBE:
517     {
518     int code = response.header(h_StatusLine).statusCode();
519     if (code < 300)
520     {
521     // throw it away
522     return;
523     }
524     else
525     {
526     ClientSubscription* client = findMatchingClientSub(response);
527     if (client)
528     {
529     client->dispatch(response);
530     }
531 derek 3082 else
532     {
533     //!dcm! -- can't subscribe in an existing Dialog, this is all
534     //a bit of a hack.
535     BaseCreator* creator = mDialogSet.getCreator();
536 derek 3274 if (!creator || !creator->getLastRequest().exists(h_Event))
537     {
538     return;
539     }
540     else
541     {
542     ClientSubscriptionHandler* handler =
543     mDum.getClientSubscriptionHandler(creator->getLastRequest().header(h_Event).value());
544     if (handler)
545     {
546     handler->onTerminated(ClientSubscriptionHandle::NotValid(), response);
547     possiblyDie();
548     }
549     }
550 derek 3082 }
551 jason 2614 }
552     }
553 derek 3058 break;
554 derek 3101 case NOTIFY:
555     {
556 derek 3274 //2xx responses are treated as retransmission quenchers(handled by
557     //the stack). Failures are dispatched to all ServerSubsscriptions,
558     //which may not be correct.
559    
560     int code = msg.header(h_StatusLine).statusCode();
561     if (code >= 300)
562 derek 3101 {
563 derek 3274 //!dcm! -- ick, write guard
564     mDestroying = true;
565     for (list<ServerSubscription*>::iterator it = mServerSubscriptions.begin();
566     it != mServerSubscriptions.end(); )
567     {
568     ServerSubscription* s = *it;
569     it++;
570     s->dispatch(msg);
571     }
572     mDestroying = false;
573     possiblyDie();
574 derek 3101 }
575 derek 3274 // ServerSubscription* server = findMatchingServerSub(response);
576     // if (server)
577     // {
578     // server->dispatch(response);
579     // }
580 derek 3101 }
581 derek 3155 break;
582 derek 3101 default:
583     assert(0);
584     return;
585 jason 2583 }
586     }
587 jason 2578 }
588    
589 derek 3041 ServerSubscription*
590     Dialog::findMatchingServerSub(const SipMessage& msg)
591     {
592     for (std::list<ServerSubscription*>::iterator i=mServerSubscriptions.begin();
593     i != mServerSubscriptions.end(); ++i)
594     {
595     if ((*i)->matches(msg))
596     {
597     return *i;
598     }
599     }
600     return 0;
601     }
602 jason 2612
603     ClientSubscription*
604     Dialog::findMatchingClientSub(const SipMessage& msg)
605 jason 2583 {
606 derek 2858 for (std::list<ClientSubscription*>::iterator i=mClientSubscriptions.begin();
607 jason 2612 i != mClientSubscriptions.end(); ++i)
608 jason 2583 {
609 jason 2614 if ((*i)->matches(msg))
610 jason 2612 {
611 jason 2614 return *i;
612 jason 2612 }
613     }
614 jason 2614 return 0;
615 jason 2612 }
616 jason 2585
617 jason 2941 InviteSessionHandle
618 derek 3041 Dialog::getInviteSession()
619 ken 2520 {
620 davidb 2603 if (mInviteSession)
621     {
622     return mInviteSession->getSessionHandle();
623     }
624     else
625     {
626 derek 3041 return InviteSessionHandle::NotValid();
627 davidb 2603 }
628 ken 2520 }
629    
630 jason 2941 std::vector<ClientSubscriptionHandle>
631 derek 3041 Dialog::findClientSubscriptions(const Data& event)
632 ken 2520 {
633 jason 2941 std::vector<ClientSubscriptionHandle> handles;
634 davidb 2603
635 derek 2858 for (std::list<ClientSubscription*>::const_iterator i = mClientSubscriptions.begin();
636 davidb 2603 i != mClientSubscriptions.end(); ++i)
637     {
638 derek 3041 if ( (*i)->getEventType() == event)
639     {
640     handles.push_back((*i)->getHandle());
641     }
642     }
643     return handles;
644     }
645    
646     std::vector<ServerSubscriptionHandle>
647     Dialog::findServerSubscriptions(const Data& event)
648     {
649     std::vector<ServerSubscriptionHandle> handles;
650    
651     for (std::list<ServerSubscription*>::const_iterator i = mServerSubscriptions.begin();
652     i != mServerSubscriptions.end(); ++i)
653     {
654     if ( (*i)->getEventType() == event)
655     {
656     handles.push_back((*i)->getHandle());
657     }
658     }
659     return handles;
660     }
661    
662    
663     std::vector<ClientSubscriptionHandle>
664     Dialog::getClientSubscriptions()
665     {
666     std::vector<ClientSubscriptionHandle> handles;
667    
668     for (std::list<ClientSubscription*>::const_iterator i = mClientSubscriptions.begin();
669     i != mClientSubscriptions.end(); ++i)
670     {
671 davidb 2603 handles.push_back((*i)->getHandle());
672     }
673    
674     return handles;
675 ken 2520 }
676    
677 derek 3041 std::vector<ServerSubscriptionHandle>
678     Dialog::getServerSubscriptions()
679     {
680     std::vector<ServerSubscriptionHandle> handles;
681    
682     for (std::list<ServerSubscription*>::const_iterator i = mServerSubscriptions.begin();
683     i != mServerSubscriptions.end(); ++i)
684     {
685     handles.push_back((*i)->getHandle());
686     }
687    
688     return handles;
689     }
690    
691 derek 3179 void
692     Dialog::redirected(const SipMessage& msg)
693     {
694     //Established dialogs are not destroyed by a redirect
695     if (!mClientSubscriptions.empty() || !mServerSubscriptions.empty())
696     {
697     return;
698     }
699     if (mInviteSession)
700     {
701     ClientInviteSession* cInv = dynamic_cast<ClientInviteSession*>(mInviteSession);
702     if (cInv)
703     {
704     cInv->redirected(msg);
705     }
706     }
707     }
708 ken 2520
709 derek 3179
710 jason 2614 #if 0
711 jason 2539 void
712 jason 2535 Dialog::processNotify(const SipMessage& notify)
713     {
714     if (notify.isRequest())
715     {
716     if (findSubscriptions().empty())
717     {
718     SubscriptionCreator* creator = dynamic_cast<SubscriptionCreator*>(DialogSetId(notify).getCreator());
719     if (creator)
720     {
721     creator->makeNewSubscription(notify);
722     }
723     }
724     else
725     {
726     for (std::list<BaseUsage*>::iterator i=mUsages.begin(); i!=mUsages.end(); i++)
727     {
728     ClientSubscription* sub = dynamic_cast<ClientSubscription*>(*i);
729     if (sub && sub->matches(notify))
730     {
731     sub->process(notify);
732     break;
733     }
734     }
735     }
736     }
737     }
738 jason 2612 #endif
739 jason 2539
740    
741 derek 2813 void
742     Dialog::makeRequest(SipMessage& request, MethodTypes method)
743     {
744     RequestLine rLine(method);
745    
746 derek 2817 rLine.uri() = mRemoteTarget.uri();
747 derek 2813
748     request.header(h_RequestLine) = rLine;
749 derek 2995 request.header(h_To) = mRemoteNameAddr;
750     // request.header(h_To).param(p_tag) = mId.getRemoteTag();
751     request.header(h_From) = mLocalNameAddr;
752     // request.header(h_From).param(p_tag) = mId.getLocalTag();
753 derek 2813
754     request.header(h_CallId) = mCallId;
755 derek 2997
756     request.remove(h_RecordRoutes); //!dcm! -- all of this is rather messy
757    
758 derek 2995 request.remove(h_Contacts);
759     request.header(h_Contacts).push_front(mLocalContact);
760 derek 2813 request.header(h_CSeq).method() = method;
761     request.header(h_MaxForwards).value() = 70;
762    
763 derek 2961 //must keep old via for cancel
764     if (method != CANCEL)
765     {
766 derek 3024 request.header(h_Routes) = mRouteSet;
767 derek 2992 request.remove(h_Vias);
768 derek 2961 Via via;
769     via.param(p_branch); // will create the branch
770     request.header(h_Vias).push_front(via);
771     }
772     else
773     {
774     assert(request.exists(h_Vias));
775     }
776 derek 3024 //don't increment CSeq for ACK or CANCEL
777     if (method != ACK && method != CANCEL)
778 derek 2965 {
779     request.header(h_CSeq).sequence() = ++mLocalCSeq;
780     }
781 jason 3156 DebugLog ( << "Dialog::makeRequest: " << request );
782 derek 2813 }
783    
784 derek 2961 void
785     Dialog::makeCancel(SipMessage& request)
786     {
787 derek 3138 //minimal for cancel
788     request.header(h_RequestLine).method() = CANCEL;
789     request.header(h_CSeq).method() = CANCEL;
790 derek 2961 request.remove(h_Requires);
791     request.remove(h_ProxyRequires);
792 derek 3138 assert(request.exists(h_Vias));
793    
794     //not sure of these
795 derek 3058 request.header(h_To).remove(p_tag);
796 derek 3138 request.remove(h_RecordRoutes);
797     request.remove(h_Contacts);
798     request.header(h_Contacts).push_front(mLocalContact);
799     request.header(h_MaxForwards).value() = 70;
800 derek 2961 }
801    
802 derek 2813 void
803 jason 2887 Dialog::makeResponse(SipMessage& response, const SipMessage& request, int code)
804 derek 2813 {
805     assert( code >= 100 );
806 derek 3146 response.remove(h_Contacts);
807 derek 2992 if (code < 300 && code > 100)
808 derek 2813 {
809     assert(request.isRequest());
810     assert(request.header(h_RequestLine).getMethod() == INVITE ||
811 derek 2997 request.header(h_RequestLine).getMethod() == SUBSCRIBE ||
812 derek 3024 request.header(h_RequestLine).getMethod() == BYE ||
813 derek 3082 request.header(h_RequestLine).getMethod() == CANCEL ||
814 derek 3146 request.header(h_RequestLine).getMethod() == REFER ||
815     request.header(h_RequestLine).getMethod() == MESSAGE ||
816     request.header(h_RequestLine).getMethod() == NOTIFY ||
817 derek 3261 request.header(h_RequestLine).getMethod() == INFO ||
818 derek 3146 request.header(h_RequestLine).getMethod() == OPTIONS
819 derek 3082 );
820 derek 2813
821 derek 3289 // assert (request.header(h_RequestLine).getMethod() == CANCEL || // Contact header is not required for Requests that do not form a dialog
822     // request.header(h_RequestLine).getMethod() == BYE ||
823     // request.header(h_Contacts).size() == 1);
824 derek 2992 Helper::makeResponse(response, request, code, mLocalContact);
825 derek 2936 response.header(h_To).param(p_tag) = mId.getLocalTag();
826 derek 2813 }
827     else
828     {
829 derek 3274 Helper::makeResponse(response, request, code);
830 derek 3006 response.header(h_To).param(p_tag) = mId.getLocalTag();
831    
832 derek 2813 }
833 jason 3156 DebugLog ( << "Dialog::makeResponse: " << response);
834 derek 2813 }
835    
836 jason 2885
837     ClientInviteSession*
838     Dialog::makeClientInviteSession(const SipMessage& response)
839     {
840     InviteSessionCreator* creator = dynamic_cast<InviteSessionCreator*>(mDialogSet.getCreator());
841     assert(creator); // !jf! this maybe can assert by evil UAS
842 jason 2941 //return mDum.createAppClientInviteSession(*this, *creator);
843 derek 3101 return new ClientInviteSession(mDum, *this, creator->getLastRequest(),
844     creator->getInitialOffer(), creator->getServerSubscription());
845 jason 2885 }
846    
847    
848    
849     ClientSubscription*
850 derek 3058 Dialog::makeClientSubscription(const SipMessage& request)
851 jason 2885 {
852 derek 3058 return new ClientSubscription(mDum, *this, request);
853 jason 2885 }
854    
855    
856     ServerInviteSession*
857     Dialog::makeServerInviteSession(const SipMessage& request)
858     {
859 jason 2941 return new ServerInviteSession(mDum, *this, request);
860 jason 2885 }
861    
862     ServerSubscription*
863     Dialog::makeServerSubscription(const SipMessage& request)
864     {
865 jason 2941 return new ServerSubscription(mDum, *this, request);
866 jason 2885 }
867    
868 davidb 2603 Dialog::Exception::Exception(const Data& msg, const Data& file, int line)
869     : BaseException(msg, file, line)
870 jason 2885 {
871     }
872 davidb 2603
873 jason 2853 void
874     Dialog::update(const SipMessage& msg)
875     {
876     }
877    
878     #if 0
879 derek 2839 void
880     Dialog::setLocalContact(const NameAddr& localContact)
881     {
882     mLocalContact = localContact;
883     }
884    
885     void
886     Dialog::setRemoteTarget(const NameAddr& remoteTarget)
887     {
888     mRemoteTarget = remoteTarget;
889     }
890 jason 2853 #endif
891 derek 2839
892 derek 2858 void Dialog::possiblyDie()
893     {
894 derek 2981 if (!mDestroying)
895 derek 2858 {
896 derek 2981 if (mClientSubscriptions.empty() &&
897 derek 3041 mServerSubscriptions.empty() &&
898 derek 3089 !mInviteSession)
899 derek 2981 {
900     delete this;
901     }
902     }
903 derek 2858 }
904 derek 2862
905 derek 3308 bool
906     Dialog::matches(const SipMessage& msg)
907     {
908     //currently only responses are passed to this method
909     if (msg.isRequest())
910     {
911     return false;
912     }
913    
914     switch (msg.header(h_CSeq).method())
915     {
916     case INVITE:
917     case CANCEL:
918     case REFER:
919     case BYE:
920     if (mInviteSession == 0)
921     {
922     return false;
923     }
924     else
925     {
926     return msg.getTransactionId() == mInviteSession->mLastRequest.getTransactionId();
927     }
928     break;
929     case INFO:
930     if (mInviteSession == 0)
931     {
932     return false;
933     }
934     else
935     {
936     return msg.getTransactionId() == mInviteSession->mLastNit.getTransactionId();
937     }
938     break;
939     case SUBSCRIBE:
940     if (mClientSubscriptions.empty())
941     {
942     return false;
943     }
944     else
945     {
946     for (std::list<ClientSubscription*>::iterator it = mClientSubscriptions.begin();
947     it != mClientSubscriptions.end(); it++)
948     {
949     return msg.getTransactionId() == (*it)->mLastRequest.getTransactionId();
950     }
951     }
952     break;
953     case NOTIFY:
954     if (mServerSubscriptions.empty())
955     {
956     return false;
957     }
958     else
959     {
960     for (std::list<ServerSubscription*>::iterator it = mServerSubscriptions.begin();
961     it != mServerSubscriptions.end(); it++)
962     {
963     return msg.getTransactionId() == (*it)->mLastNotify.getTransactionId();
964     }
965     }
966     break;
967     default:
968     return false;
969     }
970     return false;
971     }
972    
973 jason 2884 ostream&
974     resip::operator<<(ostream& strm, const Dialog& dialog)
975     {
976    
977     return strm;
978     }
979    

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27