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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 5767 by daniel, Thu Dec 22 23:55:37 2005 UTC revision 8782 by sgodin, Sun Jul 4 18:06:19 2010 UTC
# Line 40  Line 40 
40       mLocalNameAddr(),       mLocalNameAddr(),
41       mRemoteNameAddr(),       mRemoteNameAddr(),
42       mCallId(msg.header(h_CallID)),       mCallId(msg.header(h_CallID)),
43         mDefaultSubExpiration(0),
44       mAppDialog(0),       mAppDialog(0),
45       mDestroying(false),       mDestroying(false),
46       mReUseDialogSet(false)       mReUseDialogSet(false)
# Line 74  Line 75 
75        }        }
76        if (request.exists(h_RecordRoutes))        if (request.exists(h_RecordRoutes))
77        {        {
78           mRouteSet = request.header(h_RecordRoutes); // !jf! is this right order           mRouteSet = request.header(h_RecordRoutes);
79        }        }
80    
81        switch (request.header(h_CSeq).method())        switch (request.header(h_CSeq).method())
# Line 84  Line 85 
85           case REFER:           case REFER:
86           case NOTIFY:           case NOTIFY:
87              DebugLog ( << "UAS dialog ID creation, DS: " << ds.getId());              DebugLog ( << "UAS dialog ID creation, DS: " << ds.getId());
88              mId = DialogId(ds.getId(), request.header(h_From).param(p_tag));              mId = DialogId(ds.getId(),
89                               request.header(h_From).exists(p_tag) ? request.header(h_From).param(p_tag) : Data::Empty);            
90    
91              mRemoteNameAddr = request.header(h_From);              mRemoteNameAddr = request.header(h_From);
92              mLocalNameAddr = request.header(h_To);              mLocalNameAddr = request.header(h_To);
93              mLocalNameAddr.param(p_tag) = mId.getLocalTag();              mLocalNameAddr.param(p_tag) = mId.getLocalTag();
# Line 94  Line 97 
97                 if (isEqualNoCase(contact.uri().scheme(), Symbols::Sips) ||                 if (isEqualNoCase(contact.uri().scheme(), Symbols::Sips) ||
98                     isEqualNoCase(contact.uri().scheme(), Symbols::Sip))                     isEqualNoCase(contact.uri().scheme(), Symbols::Sip))
99                 {                 {
                   mLocalContact = NameAddr(request.header(h_RequestLine).uri()); // update later when send a request  
100                    mRemoteTarget = contact;                    mRemoteTarget = contact;
101                      
102                      if (!mDialogSet.getUserProfile()->isAnonymous() && mDialogSet.getUserProfile()->hasPublicGruu())
103                      {
104                         mLocalContact.uri() = mDialogSet.getUserProfile()->getPublicGruu();
105                      }
106                      else if(mDialogSet.getUserProfile()->isAnonymous() && mDialogSet.getUserProfile()->hasTempGruu())
107                      {
108                         mLocalContact.uri() = mDialogSet.getUserProfile()->getTempGruu();
109                      }
110                      else
111                      {
112                         if (mDialogSet.getUserProfile()->hasOverrideHostAndPort())
113                         {
114                            mLocalContact.uri() = mDialogSet.getUserProfile()->getOverrideHostAndPort();
115                         }
116                         if(request.header(h_RequestLine).uri().user().empty())
117                         {
118                            mLocalContact.uri().user() = request.header(h_To).uri().user();
119                         }
120                         else
121                         {
122                            mLocalContact.uri().user() = request.header(h_RequestLine).uri().user();
123                         }
124                      }
125                 }                 }
126                 else                 else
127                 {                 {
# Line 167  Line 193 
193                        isEqualNoCase(contact.uri().scheme(), Symbols::Sip))                        isEqualNoCase(contact.uri().scheme(), Symbols::Sip))
194                    {                    {
195                       BaseCreator* creator = mDialogSet.getCreator();                       BaseCreator* creator = mDialogSet.getCreator();
196                       assert(creator);// !jf! throw or something here  
197                       assert(creator->getLastRequest()->exists(h_Contacts));                       if( 0 == creator )
198                       assert(!creator->getLastRequest()->header(h_Contacts).empty());                       {
199                            ErrLog(<< "BaseCreator is null for DialogSet");
200                            ErrLog(<< response);
201                            throw Exception("BaseCreator is null for DialogSet", __FILE__, __LINE__);
202                         }
203    
204                         SharedPtr<SipMessage> lastRequest(creator->getLastRequest());
205    
206                         if( 0 == lastRequest.get() ||
207                            !lastRequest->exists(h_Contacts) ||
208                            lastRequest->header(h_Contacts).empty())
209                         {
210                            InfoLog(<< "lastRequest does not contain a valid contact");                                            
211                            InfoLog(<< response);
212                            throw Exception("lastRequest does not contain a valid contact.", __FILE__, __LINE__);
213                         }
214                       mLocalContact = creator->getLastRequest()->header(h_Contacts).front();                       mLocalContact = creator->getLastRequest()->header(h_Contacts).front();
215                       mRemoteTarget = contact;                       mRemoteTarget = contact;
216                    }                    }
# Line 199  Line 240 
240        DebugLog ( << "mLocalNameAddr: " << mLocalNameAddr );        DebugLog ( << "mLocalNameAddr: " << mLocalNameAddr );
241        DebugLog ( << "mLocalContact: " << mLocalContact );        DebugLog ( << "mLocalContact: " << mLocalContact );
242        DebugLog ( << "mRemoteTarget: " << mRemoteTarget );        DebugLog ( << "mRemoteTarget: " << mRemoteTarget );
   
   
243     }     }
244     mDialogSet.addDialog(this);     mDialogSet.addDialog(this);
245     DebugLog ( <<"Dialog::Dialog " << mId);     DebugLog ( <<"Dialog::Dialog " << mId);
# Line 237  Line 276 
276     return mId;     return mId;
277  }  }
278    
279    const NameAddr&
280    Dialog::getLocalNameAddr() const
281    {
282       return mLocalNameAddr;
283    }
284    
285    const NameAddr&
286    Dialog::getLocalContact() const
287    {
288       return mLocalContact;
289    }
290    
291    const NameAddr&
292    Dialog::getRemoteNameAddr() const
293    {
294       return mRemoteNameAddr;
295    }
296    
297    const NameAddr&
298    Dialog::getRemoteTarget() const
299    {
300       return mRemoteTarget;
301    }
302    
303    const NameAddrs&
304    Dialog::getRouteSet() const
305    {
306       return mRouteSet;
307    }
308    
309  void  void
310  Dialog::cancel()  Dialog::cancel()
311  {  {
# Line 253  Line 322 
322     {     {
323        mInviteSession->end();        mInviteSession->end();
324     }     }
325     else  
326       // End Subscriptions
327       // !jrm! WARN ClientSubscription and ServerSubscription have access to this dialog and will remove themselves
328       // from the m<client|server>Subscriptions collections in the call to end().
329       for (list<ClientSubscription*>::iterator it(mClientSubscriptions.begin());
330            it != mClientSubscriptions.end();)
331     {     {
332        //!dcm! -- end subscriptions             ClientSubscription* c = *it;
333           it++;      
334               c->end();
335       }
336    
337       for (list<ServerSubscription*>::iterator it2(mServerSubscriptions.begin());
338            it2 != mServerSubscriptions.end();)
339       {
340               ServerSubscription* s = *it2;
341           it2++;      
342               s->end();
343     }     }
344  }  }
345    
# Line 291  Line 375 
375    
376     DebugLog ( << "Dialog::dispatch: " << msg.brief());     DebugLog ( << "Dialog::dispatch: " << msg.brief());
377    
378     if (msg.getReceivedTransport())     if(msg.isExternal())
379     {     {
380        TransportType type = msg.getReceivedTransport()->getTuple().getType();        const Data& receivedTransport = msg.header(h_Vias).front().transport();
381        int keepAliveTime = 0;        int keepAliveTime = 0;
382          if(receivedTransport == Symbols::TCP ||
383        if (type == TCP || type == TLS || type == SCTP)           receivedTransport == Symbols::TLS ||
384             receivedTransport == Symbols::SCTP)
385        {        {
386           keepAliveTime = mDialogSet.getUserProfile()->getKeepAliveTimeForStream();           keepAliveTime = mDialogSet.getUserProfile()->getKeepAliveTimeForStream();
387        }        }
# Line 413  Line 498 
498           break;           break;
499           case REFER:           case REFER:
500           {           {
501              if (mInviteSession == 0)  //             if (mInviteSession == 0)
502              {  //             {
503                 InfoLog (<< "Received an in dialog refer in a non-invite dialog: " << request.brief());  //                InfoLog (<< "Received an in dialog refer in a non-invite dialog: " << request.brief());
504                 SipMessage failure;  //                SipMessage failure;
505                 makeResponse(failure, request, 603);  //                makeResponse(failure, request, 603);
506                 mDum.sendResponse(failure);  //                mDum.sendResponse(failure);
507                 return;  //                return;
508              }  //             }
509              else if  (!request.exists(h_ReferTo))  //             else
510    
511                if  (!request.exists(h_ReferTo))
512              {              {
513                 InfoLog (<< "Received refer w/out a Refer-To: " << request.brief());                 InfoLog (<< "Received refer w/out a Refer-To: " << request.brief());
514                 SipMessage failure;                 SipMessage failure;
# Line 431  Line 518 
518              }              }
519              else              else
520              {              {
521                   if (request.exists(h_ReferSub) && request.header(h_ReferSub).value()=="false")
522                   {
523                      assert(mInviteSession);
524                      mInviteSession->referNoSub(msg);
525                   }
526                   else
527                   {
528                 ServerSubscription* server = findMatchingServerSub(request);                 ServerSubscription* server = findMatchingServerSub(request);
529                 ServerSubscriptionHandle serverHandle;                 ServerSubscriptionHandle serverHandle;
530                 if (server)                 if (server)
# Line 445  Line 539 
539                    serverHandle = server->getHandle();                    serverHandle = server->getHandle();
540                    server->dispatch(request);                    server->dispatch(request);
541                 }                 }
542    
543                      if (mInviteSession)
544                      {
545                 mDum.mInviteSessionHandler->onRefer(mInviteSession->getSessionHandle(), serverHandle, msg);                 mDum.mInviteSessionHandler->onRefer(mInviteSession->getSessionHandle(), serverHandle, msg);
546              }              }
547                      
548                   }
549                }
550           }           }
551           break;           break;
552           case NOTIFY:           case NOTIFY:
# Line 460  Line 560 
560              {              {
561                 BaseCreator* creator = mDialogSet.getCreator();                 BaseCreator* creator = mDialogSet.getCreator();
562                 if (creator && (creator->getLastRequest()->header(h_RequestLine).method() == SUBSCRIBE ||                 if (creator && (creator->getLastRequest()->header(h_RequestLine).method() == SUBSCRIBE ||
563                                 creator->getLastRequest()->header(h_RequestLine).method() == REFER))  // ?slg? OOD Refer?  Click-to-Call?                       creator->getLastRequest()->header(h_RequestLine).method() == REFER))  
564                 {                 {
565                    DebugLog (<< "Making subscription (from creator) request: " << *creator->getLastRequest());                    DebugLog (<< "Making subscription (from creator) request: " << *creator->getLastRequest());
566                    ClientSubscription* sub = makeClientSubscription(*creator->getLastRequest());                    ClientSubscription* sub = makeClientSubscription(*creator->getLastRequest());
# Line 469  Line 569 
569                 }                 }
570                 else                 else
571                 {                 {
572                             if (mInviteSession != 0 && (!msg.exists(h_Event) || msg.header(h_Event).value() == "refer"))                       if (mInviteSession != 0 && (!msg.exists(h_Event) || msg.header(h_Event).value() == "refer") &&
573                             mDum.getClientSubscriptionHandler("refer")!=0)
574                     {                     {
575                            DebugLog (<< "Making subscription from NOTIFY: " << msg);                            DebugLog (<< "Making subscription from NOTIFY: " << msg);
576                        ClientSubscription* sub = makeClientSubscription(msg);                        ClientSubscription* sub = makeClientSubscription(msg);
577                        mClientSubscriptions.push_back(sub);                        mClientSubscriptions.push_back(sub);
578                                    ClientSubscriptionHandle client = sub->getHandle();                                                                    ClientSubscriptionHandle client = sub->getHandle();                                
                       sub->dispatch(request);  
                       mInviteSession->mSentRefer = false;  
                       if (client.isValid())  
                       {  
579                           mDum.mInviteSessionHandler->onReferAccepted(mInviteSession->getSessionHandle(), client, msg);                           mDum.mInviteSessionHandler->onReferAccepted(mInviteSession->getSessionHandle(), client, msg);
580                        }                          sub->dispatch(request);
                       else  
                       {  
                          mDum.mInviteSessionHandler->onReferRejected(mInviteSession->getSessionHandle(), msg);  
                       }  
581                                     }                                     }
582                                     else                                     else
583                                     {                                     {
# Line 507  Line 600 
600        // from how it worked in main branch pre merge.        // from how it worked in main branch pre merge.
601        // If the response doesn't match a cseq for a request I've sent, ignore        // If the response doesn't match a cseq for a request I've sent, ignore
602        // the response        // the response
603          {//scope 'r' as it is invalidated below
604        RequestMap::iterator r = mRequests.find(msg.header(h_CSeq).sequence());        RequestMap::iterator r = mRequests.find(msg.header(h_CSeq).sequence());
605        if (r != mRequests.end())        if (r != mRequests.end())
606        {        {
# Line 525  Line 619 
619           mRequests.erase(r);           mRequests.erase(r);
620                   if (handledByAuth) return;                   if (handledByAuth) return;
621        }        }
       else  
       {  
          InfoLog( << "Dialog::dispatch, ignoring stray response: " << msg.brief() );  
622        }        }
623                
624        const SipMessage& response = msg;        const SipMessage& response = msg;
625        int code = response.header(h_StatusLine).statusCode();        int code = response.header(h_StatusLine).statusCode();
626        if (code >=200 && code < 300)        // If this is a 200 response to the initial request, then store the routeset (if present)
627          BaseCreator* creator = mDialogSet.getCreator();
628          if (creator && (creator->getLastRequest()->header(h_CSeq) == response.header(h_CSeq)) && code >=200 && code < 300)
629        {        {
630           if (response.exists(h_RecordRoutes))           if (response.exists(h_RecordRoutes))
631           {           {
632              mRouteSet = response.header(h_RecordRoutes).reverse();              mRouteSet = response.header(h_RecordRoutes).reverse();
633           }           }
634             else
635             {
636                // Ensure that if the route-set in the 200 is empty, then we overwrite any existing route-sets
637                mRouteSet.clear();
638             }
639        }        }
640    
641        // !jf! should this only be for 2xx responses? !jf! Propose no as an        // !jf! should this only be for 2xx responses? !jf! Propose no as an
# Line 550  Line 648 
648                 DebugLog ( << "Dialog::dispatch  --  Created new client invite session" << msg.brief());                 DebugLog ( << "Dialog::dispatch  --  Created new client invite session" << msg.brief());
649    
650                 mInviteSession = makeClientInviteSession(response);                 mInviteSession = makeClientInviteSession(response);
651                   if (mInviteSession)
652                   {
653                 mInviteSession->dispatch(response);                 mInviteSession->dispatch(response);
654              }              }
655              else              else
656              {              {
657                      ErrLog( << "Dialog::dispatch  --  Unable to create invite session from response" << msg.brief());
658                   }
659                }
660                else
661                {
662                 mInviteSession->dispatch(response);                 mInviteSession->dispatch(response);
663              }              }
664              break;              break;
# Line 573  Line 678 
678                   case REFER:                   case REFER:
679              if(mInviteSession)              if(mInviteSession)
680              {              {
                mInviteSession->mSentRefer = false;  
   
681                 if (code >= 300)                 if (code >= 300)
682                 {                 {
683                    mDum.mInviteSessionHandler->onReferRejected(mInviteSession->getSessionHandle(), msg);                    mDum.mInviteSessionHandler->onReferRejected(mInviteSession->getSessionHandle(), msg);
684                 }                 }
685                   else
686                   {
687                      //!dys! the OR condition below is not draft compliant.
688                      if (!mInviteSession->mReferSub &&
689                          ((msg.exists(h_ReferSub) && msg.header(h_ReferSub).value()=="false") ||
690                           !msg.exists(h_ReferSub)))
691                      {
692                         DebugLog(<< "refer accepted with norefersub");
693                         mDum.mInviteSessionHandler->onReferAccepted(mInviteSession->getSessionHandle(), ClientSubscriptionHandle::NotValid(), msg);
694                      }
695                 // else no need for action - first Notify will cause onReferAccepted to be called                 // else no need for action - first Notify will cause onReferAccepted to be called
696              }              }
697                   mInviteSession->nitComplete();
698              break;              break;
699                }
700                // fall through, out of dialog refer was sent.
701    
702           case SUBSCRIBE:           case SUBSCRIBE:
703           {           {
# Line 593  Line 709 
709              }              }
710              else if (code < 300)              else if (code < 300)
711              {              {
712                   /*
713                      we're capturing the  value from the expires header off
714                      the 2xx because the ClientSubscription is only created
715                      after receiving the NOTIFY that comes (usually) after
716                      this 2xx.  We really should be creating the
717                      ClientSubscription at either the 2xx or the NOTIFY
718                      whichever arrives first. .mjf.
719                      Note: we're capturing a duration here (not the
720                      absolute time because all the inputs to
721                      ClientSubscription desling with the expiration are expecting
722                      duration type values from the headers. .mjf.
723                    */
724                   if(response.exists(h_Expires))
725                   {
726                      mDefaultSubExpiration = response.header(h_Expires).value();
727                   }
728                   else
729                   {
730                      //?dcm? defaults to 3600 in ClientSubscription if no expires value
731                      //is provided anywhere...should we assume the value from the
732                      //sub in the basecreator if it exists?
733                      mDefaultSubExpiration = 0;
734                   }              
735                 return;                 return;
736              }              }
737              else              else
# Line 822  Line 961 
961     request.header(h_CallId) = mCallId;     request.header(h_CallId) = mCallId;
962    
963     request.remove(h_RecordRoutes);  //!dcm! -- all of this is rather messy     request.remove(h_RecordRoutes);  //!dcm! -- all of this is rather messy
964       request.remove(h_Replaces);
965    
966     request.remove(h_Contacts);     request.remove(h_Contacts);
967     request.header(h_Contacts).push_front(mLocalContact);     request.header(h_Contacts).push_front(mLocalContact);
# Line 871  Line 1011 
1011        if(mDialogSet.getUserProfile()->isAdvertisedCapability(Headers::Supported)) request.header(h_Supporteds) = mDum.getMasterProfile()->getSupportedOptionTags();        if(mDialogSet.getUserProfile()->isAdvertisedCapability(Headers::Supported)) request.header(h_Supporteds) = mDum.getMasterProfile()->getSupportedOptionTags();
1012     }     }
1013    
1014     DebugLog ( << "Dialog::makeRequest: " << request );     if (mDialogSet.mUserProfile->isAnonymous())
1015       {
1016          request.header(h_Privacys).push_back(PrivacyCategory(Symbols::id));
1017       }
1018    
1019       DebugLog ( << "Dialog::makeRequest: " << std::endl << std::endl << request );
1020  }  }
1021    
1022    
# Line 906  Line 1051 
1051           && code >= 200 && code < 300)           && code >= 200 && code < 300)
1052        {        {
1053           // Check if we should add our capabilites to the invite success response           // Check if we should add our capabilites to the invite success response
1054           if(mDialogSet.getUserProfile()->isAdvertisedCapability(Headers::Allow)) response.header(h_Allows) = mDum.getMasterProfile()->getAllowedMethods();           if(mDialogSet.getUserProfile()->isAdvertisedCapability(Headers::Allow))
1055           if(mDialogSet.getUserProfile()->isAdvertisedCapability(Headers::AcceptEncoding)) response.header(h_AcceptEncodings) = mDum.getMasterProfile()->getSupportedEncodings();           {
1056           if(mDialogSet.getUserProfile()->isAdvertisedCapability(Headers::AcceptLanguage)) response.header(h_AcceptLanguages) = mDum.getMasterProfile()->getSupportedLanguages();              response.header(h_Allows) = mDum.getMasterProfile()->getAllowedMethods();
1057           if(mDialogSet.getUserProfile()->isAdvertisedCapability(Headers::AllowEvents)) response.header(h_AllowEvents) = mDum.getMasterProfile()->getAllowedEvents();           }
1058           if(mDialogSet.getUserProfile()->isAdvertisedCapability(Headers::Supported)) response.header(h_Supporteds) = mDum.getMasterProfile()->getSupportedOptionTags();           if(mDialogSet.getUserProfile()->isAdvertisedCapability(Headers::AcceptEncoding))
1059             {
1060                response.header(h_AcceptEncodings) = mDum.getMasterProfile()->getSupportedEncodings();
1061             }
1062             if(mDialogSet.getUserProfile()->isAdvertisedCapability(Headers::AcceptLanguage))
1063             {
1064                response.header(h_AcceptLanguages) = mDum.getMasterProfile()->getSupportedLanguages();
1065             }
1066             if(mDialogSet.getUserProfile()->isAdvertisedCapability(Headers::AllowEvents))
1067             {
1068                response.header(h_AllowEvents) = mDum.getMasterProfile()->getAllowedEvents();
1069             }
1070             if(mDialogSet.getUserProfile()->isAdvertisedCapability(Headers::Supported))
1071             {
1072                response.header(h_Supporteds) = mDum.getMasterProfile()->getSupportedOptionTags();
1073             }
1074        }        }
1075     }     }
1076     else     else
# Line 918  Line 1078 
1078        Helper::makeResponse(response, request, code);        Helper::makeResponse(response, request, code);
1079        response.header(h_To).param(p_tag) = mId.getLocalTag();        response.header(h_To).param(p_tag) = mId.getLocalTag();
1080     }     }
1081     DebugLog ( << "Dialog::makeResponse: " << response);  
1082       DebugLog ( << "Dialog::makeResponse: " << std::endl << std::endl << response);
1083  }  }
1084    
1085    
# Line 926  Line 1087 
1087  Dialog::makeClientInviteSession(const SipMessage& response)  Dialog::makeClientInviteSession(const SipMessage& response)
1088  {  {
1089     InviteSessionCreator* creator = dynamic_cast<InviteSessionCreator*>(mDialogSet.getCreator());     InviteSessionCreator* creator = dynamic_cast<InviteSessionCreator*>(mDialogSet.getCreator());
1090     assert(creator); // !jf! this maybe can assert by evil UAS     if (!creator)
1091       {
1092          assert(0); // !jf! this maybe can assert by evil UAS
1093          return 0;
1094       }
1095     //return mDum.createAppClientInviteSession(*this, *creator);     //return mDum.createAppClientInviteSession(*this, *creator);
1096     return new ClientInviteSession(mDum, *this, creator->getLastRequest(),     return new ClientInviteSession(mDum, *this, creator->getLastRequest(),
1097                                    creator->getInitialOffer(), creator->getEncryptionLevel(), creator->getServerSubscription());                                    creator->getInitialOffer(), creator->getEncryptionLevel(), creator->getServerSubscription());
# Line 937  Line 1102 
1102  ClientSubscription*  ClientSubscription*
1103  Dialog::makeClientSubscription(const SipMessage& request)  Dialog::makeClientSubscription(const SipMessage& request)
1104  {  {
1105     return new ClientSubscription(mDum, *this, request);     return new ClientSubscription(mDum, *this, request, mDefaultSubExpiration);
1106  }  }
1107    
1108    
# Line 981  Line 1146 
1146    
1147  void Dialog::possiblyDie()  void Dialog::possiblyDie()
1148  {  {
    // !slg! Note:  dialogs should really stick around for 32s, in order to ensure that all 2xx retransmissions get 481 correctly  
1149     if (!mDestroying)     if (!mDestroying)
1150     {     {
1151        if (mClientSubscriptions.empty() &&        if (mClientSubscriptions.empty() &&
# Line 994  Line 1158 
1158     }     }
1159  }  }
1160    
1161  ostream&  EncodeStream&
1162  resip::operator<<(ostream& strm, const Dialog& dialog)  resip::operator<<(EncodeStream& strm, const Dialog& dialog)
1163  {  {
1164     strm     strm
1165        << "mClientSubscriptions("        << "mClientSubscriptions("
# Line 1059  Line 1223 
1223   */   */
1224    
1225    
1226    

Legend:
Removed from v.5767  
changed lines
  Added in v.8782

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27