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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27