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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27