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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3613 - (hide annotations) (download)
Wed Nov 24 01:03:05 2004 UTC (15 years ago) by jason
Original Path: main/sip/resiprocate/dum/Dialog.cxx
File size: 31178 byte(s)
reverting back to revision 3604 due to missing checkin. 

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

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27