⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dialog.cxx

📁 这是国外的resip协议栈
💻 CXX
📖 第 1 页 / 共 3 页
字号:
#include "resip/stack/Contents.hxx"#include "resip/stack/Helper.hxx"#include "resip/stack/SipMessage.hxx"#include "resip/dum/AppDialog.hxx"#include "resip/dum/BaseCreator.hxx"#include "resip/dum/ClientAuthManager.hxx"#include "resip/dum/ClientInviteSession.hxx"#include "resip/dum/ClientSubscription.hxx"#include "resip/dum/Dialog.hxx"#include "resip/dum/DialogUsageManager.hxx"#include "resip/dum/MasterProfile.hxx"#include "resip/dum/InviteSessionCreator.hxx"#include "resip/dum/InviteSessionHandler.hxx"#include "resip/dum/ServerInviteSession.hxx"#include "resip/dum/ServerSubscription.hxx"#include "resip/dum/SubscriptionHandler.hxx"#include "resip/dum/UsageUseException.hxx"#include "rutil/Logger.hxx"#include "rutil/Inserter.hxx"#include "rutil/WinLeakCheck.hxx"#define RESIPROCATE_SUBSYSTEM Subsystem::DUMusing namespace resip;using namespace std;Dialog::Dialog(DialogUsageManager& dum, const SipMessage& msg, DialogSet& ds)   : mDum(dum),     mDialogSet(ds),     mId("INVALID", "INVALID", "INVALID"),     mClientSubscriptions(),     mServerSubscriptions(),     mInviteSession(0),     mType(Fake),     mRouteSet(),     mLocalContact(),     mLocalCSeq(0),     mRemoteCSeq(0),     mRemoteTarget(),     mLocalNameAddr(),     mRemoteNameAddr(),     mCallId(msg.header(h_CallID)),     mDefaultSubExpiration(0),     mAppDialog(0),     mDestroying(false),     mReUseDialogSet(false){   assert(msg.isExternal());   assert(msg.header(h_CSeq).method() != MESSAGE);   assert(msg.header(h_CSeq).method() != REGISTER);   assert(msg.header(h_CSeq).method() != PUBLISH);   mNetworkAssociation.setDum(&dum);   if (msg.isRequest()) // UAS   {      const SipMessage& request = msg;      switch (request.header(h_CSeq).method())      {         case INVITE:            mType = Invitation;            break;         case SUBSCRIBE:         case REFER:         case NOTIFY:            //!dcm! -- event header check            mType = Subscription;            break;         default:            mType = Fake;      }      if (request.exists(h_RecordRoutes))      {         mRouteSet = request.header(h_RecordRoutes);       }      switch (request.header(h_CSeq).method())      {         case INVITE:         case SUBSCRIBE:         case REFER:         case NOTIFY:            DebugLog ( << "UAS dialog ID creation, DS: " << ds.getId());            mId = DialogId(ds.getId(),                            request.header(h_From).exists(p_tag) ? request.header(h_From).param(p_tag) : Data::Empty);                        mRemoteNameAddr = request.header(h_From);            mLocalNameAddr = request.header(h_To);            mLocalNameAddr.param(p_tag) = mId.getLocalTag();            if (request.exists(h_Contacts) && request.header(h_Contacts).size() == 1)            {               const NameAddr& contact = request.header(h_Contacts).front();               if (isEqualNoCase(contact.uri().scheme(), Symbols::Sips) ||                   isEqualNoCase(contact.uri().scheme(), Symbols::Sip))               {                  mLocalContact = NameAddr(request.header(h_RequestLine).uri()); // update later when send a request                  mRemoteTarget = contact;                  if (mDialogSet.getUserProfile()->hasOverrideHostAndPort())                  {                     mLocalContact.uri().host() = mDialogSet.getUserProfile()->getOverrideHostAndPort().host();                     mLocalContact.uri().port() = mDialogSet.getUserProfile()->getOverrideHostAndPort().port();                  }               }               else               {                  InfoLog(<< "Got an INVITE or SUBSCRIBE with invalid scheme");                  InfoLog(<< request);                  throw Exception("Invalid scheme in request", __FILE__, __LINE__);               }            }            else            {               InfoLog (<< "Got an INVITE or SUBSCRIBE that doesn't have exactly one contact");               InfoLog (<< request);               throw Exception("Too many (or no contact) contacts in request", __FILE__, __LINE__);            }            break;         default:            break;      }      mRemoteCSeq = request.header(h_CSeq).sequence();      mLocalCSeq = 1;      DebugLog ( << "************** Created Dialog as UAS **************" );      DebugLog ( << "mRemoteNameAddr: " << mRemoteNameAddr );      DebugLog ( << "mLocalNameAddr: " << mLocalNameAddr );      DebugLog ( << "mLocalContact: " << mLocalContact );      DebugLog ( << "mRemoteTarget: " << mRemoteTarget );   }   else if (msg.isResponse())   {      mId = DialogId(msg);      const SipMessage& response = msg;      mRemoteNameAddr = response.header(h_To);      mLocalNameAddr = response.header(h_From);      switch (msg.header(h_CSeq).method())      {         case INVITE:            mType = Invitation;            break;         case SUBSCRIBE:         case REFER:            mType = Subscription;            break;         default:            mType = Fake;      }      if (response.exists(h_RecordRoutes))      {         mRouteSet = response.header(h_RecordRoutes).reverse();      }      switch (response.header(h_CSeq).method())      {         case INVITE:         case SUBSCRIBE:         case REFER:            if (response.header(h_StatusLine).statusCode() > 100 &&                response.header(h_StatusLine).statusCode() < 300)            {               if  (response.exists(h_Contacts) && response.header(h_Contacts).size() == 1)               {                  const NameAddr& contact = response.header(h_Contacts).front();                  if (isEqualNoCase(contact.uri().scheme(), Symbols::Sips) ||                     isEqualNoCase(contact.uri().scheme(), Symbols::Sip))                  {                     BaseCreator* creator = mDialogSet.getCreator();					                      if( 0 == creator )                     {                        ErrLog(<< "BaseCreator is null for DialogSet");                        ErrLog(<< response);                        throw Exception("BaseCreator is null for DialogSet", __FILE__, __LINE__);                     }                     SharedPtr<SipMessage> lastRequest(creator->getLastRequest());                     if( 0 == lastRequest.get() ||                        !lastRequest->exists(h_Contacts) ||                        lastRequest->header(h_Contacts).empty())                     {                        InfoLog(<< "lastRequest does not contain a valid contact");						                        InfoLog(<< response);                        throw Exception("lastRequest does not contain a valid contact.", __FILE__, __LINE__);                     }                     mLocalContact = creator->getLastRequest()->header(h_Contacts).front();                     mRemoteTarget = contact;                  }                  else                  {                     InfoLog (<< "Got an INVITE or SUBSCRIBE with invalid scheme");                     DebugLog (<< response);                     throw Exception("Bad scheme in contact in response", __FILE__, __LINE__);                  }               }               else               {                  InfoLog (<< "Got an INVITE or SUBSCRIBE that doesn't have exactly one contact");                  DebugLog (<< response);                  throw Exception("Too many contacts (or no contact) in response", __FILE__, __LINE__);               }               break;               default:                  break;            }      }      mLocalCSeq = response.header(h_CSeq).sequence();      mRemoteCSeq = 0;      DebugLog ( << "************** Created Dialog as UAC **************" );      DebugLog ( << "mRemoteNameAddr: " << mRemoteNameAddr );      DebugLog ( << "mLocalNameAddr: " << mLocalNameAddr );      DebugLog ( << "mLocalContact: " << mLocalContact );      DebugLog ( << "mRemoteTarget: " << mRemoteTarget );   }   mDialogSet.addDialog(this);   DebugLog ( <<"Dialog::Dialog " << mId);}Dialog::~Dialog(){   DebugLog ( <<"Dialog::~Dialog() ");   mDestroying = true;   while (!mClientSubscriptions.empty())   {      delete *mClientSubscriptions.begin();   }   while (!mServerSubscriptions.empty())   {      delete *mServerSubscriptions.begin();   }   delete mInviteSession;   mDialogSet.mDialogs.erase(this->getId());   delete mAppDialog;   if(!mReUseDialogSet)   {      mDialogSet.possiblyDie();   }}const DialogId&Dialog::getId() const{   return mId;}voidDialog::cancel(){   assert(mType == Invitation);   ClientInviteSession* uac = dynamic_cast<ClientInviteSession*>(mInviteSession);   assert (uac);   uac->cancel();}voidDialog::end(){   if (mInviteSession)   {      mInviteSession->end();   }   // End Subscriptions   // !jrm! WARN ClientSubscription and ServerSubscription have access to this dialog and will remove themselves   // from the m<client|server>Subscriptions collections in the call to end().   for (list<ClientSubscription*>::iterator it(mClientSubscriptions.begin());        it != mClientSubscriptions.end();)   {	   ClientSubscription* c = *it;       it++;       	   c->end();   }   for (list<ServerSubscription*>::iterator it2(mServerSubscriptions.begin());        it2 != mServerSubscriptions.end();)   {	   ServerSubscription* s = *it2;       it2++;       	   s->end();   }}voidDialog::handleTargetRefresh(const SipMessage& msg){   switch(msg.header(h_CSeq).method())   {      case INVITE:      case UPDATE:         if (msg.isRequest() || (msg.isResponse() && msg.header(h_StatusLine).statusCode()/100 == 2))         {            //?dcm? modify local target; 12.2.2 of 3261 implies that the remote            //target is immediately modified.  Should we wait until a 2xx class            //reponse is sent to a re-invite(easy when all send requests go            //through Dialog)            if (msg.exists(h_Contacts))            {               //.dcm. replace or check then replace               mRemoteTarget = msg.header(h_Contacts).front();            }         }         break;      default:         return;   }}voidDialog::dispatch(const SipMessage& msg){   // !jf! Should be checking for messages with out of order CSeq and rejecting   DebugLog ( << "Dialog::dispatch: " << msg.brief());   if(msg.isExternal())   {      const Data& receivedTransport = msg.header(h_Vias).front().transport();      int keepAliveTime = 0;      if(receivedTransport == Symbols::TCP ||         receivedTransport == Symbols::TLS ||         receivedTransport == Symbols::SCTP)      {         keepAliveTime = mDialogSet.getUserProfile()->getKeepAliveTimeForStream();      }      else      {         keepAliveTime = mDialogSet.getUserProfile()->getKeepAliveTimeForDatagram();      }      if(keepAliveTime > 0)      {         mNetworkAssociation.update(msg, keepAliveTime);      }   }      handleTargetRefresh(msg);   if (msg.isRequest())   {      const SipMessage& request = msg;      switch (request.header(h_CSeq).method())      {         case INVITE:  // new INVITE            if (mInviteSession == 0)            {               DebugLog ( << "Dialog::dispatch  --  Created new server invite session" << msg.brief());               mInviteSession = makeServerInviteSession(request);            }            mInviteSession->dispatch(request);            break;            //refactor, send bad request for BYE, INFO, CANCEL?         case BYE:            if (mInviteSession == 0)            {               InfoLog ( << "Spurious BYE" );               return;            }            else            {               mInviteSession->dispatch(request);            }            break;         case UPDATE:            if (mInviteSession == 0)            {               InfoLog ( << "Spurious UPDATE" );               return;            }            else            {               mInviteSession->dispatch(request);            }            break;         case INFO:            if (mInviteSession == 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -