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

📄 invitesession.cxx

📁 这是国外的resip协议栈
💻 CXX
📖 第 1 页 / 共 5 页
字号:
      if (mNitState == NitComplete)      {         mNitState = NitProceeding;         send(info);         return;      }      mNITQueue.push(new QueuedNIT(info));      DebugLog(<< "refer - queuing NIT:" << info->brief()<<endl);      return;   }   else   {      WarningLog (<< "Can't send INFO before Connected");      assert(0);      throw UsageUseException("Can't send INFO before Connected", __FILE__, __LINE__);   }}class InviteSessionInfoCommand : public DumCommandAdapter{public:   InviteSessionInfoCommand(InviteSession& inviteSession, const Contents& contents)      : mInviteSession(inviteSession),        mContents(contents.clone())   {   }   virtual void executeCommand()   {      mInviteSession.info(*mContents);   }   virtual std::ostream& encodeBrief(std::ostream& strm) const   {      return strm << "InviteSessionInfoCommand";   }private:   InviteSession& mInviteSession;   std::auto_ptr<Contents> mContents;};voidInviteSession::infoCommand(const Contents& contents){   mDum.post(new InviteSessionInfoCommand(*this, contents));}voidInviteSession::message(const Contents& contents){   if (isConnected())  // ?slg? likely not safe in any state except Connected - what should behaviour be if state is ReceivedReinvite?   {      SharedPtr<SipMessage> message(new SipMessage());      mDialog.makeRequest(*message, MESSAGE);      // !jf! handle multipart here      message->setContents(&contents);      DumHelper::setOutgoingEncryptionLevel(*message, mCurrentEncryptionLevel);      InfoLog (<< "Trying to send MESSAGE: " << message);      if (mNitState == NitComplete)      {         mNitState = NitProceeding;         send(message);         return;      }      mNITQueue.push(new QueuedNIT(message));      DebugLog(<< "refer - queuing NIT:" << message->brief()<<endl);      return;   }   else   {      WarningLog (<< "Can't send MESSAGE before Connected");      assert(0);      throw UsageUseException("Can't send MESSAGE before Connected", __FILE__, __LINE__);   }}class InviteSessionMessageCommand : public DumCommandAdapter{public:   InviteSessionMessageCommand(InviteSession& inviteSession, const Contents& contents)      : mInviteSession(inviteSession),        mContents(contents.clone())   {   }   virtual void executeCommand()   {      mInviteSession.message(*mContents);   }   virtual std::ostream& encodeBrief(std::ostream& strm) const   {      return strm << "InviteSessionMessageCommand";   }private:   InviteSession& mInviteSession;   std::auto_ptr<Contents> mContents;};voidInviteSession::messageCommand(const Contents& contents){   mDum.post(new InviteSessionMessageCommand(*this, contents));}voidInviteSession::dispatch(const SipMessage& msg){   // Look for 2xx retransmissions - resend ACK and filter out of state machine   if(msg.header(h_CSeq).method() == INVITE && msg.isResponse() && msg.header(h_StatusLine).statusCode() / 100 == 2)   {      AckMap::iterator i = mAcks.find(msg.getTransactionId());      if (i != mAcks.end())      {         send(i->second);  // resend ACK         return;      }   }   // !jf! do we need to handle 3xx here or is it handled elsewhere?   switch (mState)   {      case Connected:         dispatchConnected(msg);         break;      case SentUpdate:         dispatchSentUpdate(msg);         break;       case SentReinvite:         dispatchSentReinvite(msg);         break;      case SentReinviteNoOffer:         dispatchSentReinviteNoOffer(msg);         break;      case SentReinviteAnswered:         dispatchSentReinviteAnswered(msg);         break;      case SentUpdateGlare:      case SentReinviteGlare:         // The behavior is the same except for timer which is handled in dispatch(Timer)         dispatchGlare(msg);         break;      case SentReinviteNoOfferGlare:         dispatchReinviteNoOfferGlare(msg);         break;      case ReceivedUpdate:      case ReceivedReinvite:      case ReceivedReinviteNoOffer:         dispatchReceivedUpdateOrReinvite(msg);         break;      case ReceivedReinviteSentOffer:         dispatchReceivedReinviteSentOffer(msg);         break;      case Answered:         dispatchAnswered(msg);         break;      case WaitingToOffer:         dispatchWaitingToOffer(msg);         break;      case WaitingToRequestOffer:         dispatchWaitingToRequestOffer(msg);         break;      case WaitingToTerminate:         dispatchWaitingToTerminate(msg);         break;      case WaitingToHangup:         dispatchWaitingToHangup(msg);         break;      case Terminated:         dispatchTerminated(msg);         break;      case Undefined:      default:         assert(0);         break;   }}voidInviteSession::dispatch(const DumTimeout& timeout){   if (timeout.type() == DumTimeout::Retransmit200)   {      if (mCurrentRetransmit200)      {         InfoLog (<< "Retransmitting: " << endl << mInvite200->brief());         //DumHelper::setOutgoingEncryptionLevel(*mInvite200, mCurrentEncryptionLevel);         send(mInvite200);         mCurrentRetransmit200 *= 2;         mDum.addTimerMs(DumTimeout::Retransmit200, resipMin(Timer::T2, mCurrentRetransmit200), getBaseHandle(),  timeout.seq());      }   }   else if (timeout.type() == DumTimeout::WaitForAck)   {      if(mCurrentRetransmit200)  // If retransmit200 timer is active then ACK is not received yet      {         if (timeout.seq() == mLastRemoteSessionModification->header(h_CSeq).sequence())         {            mCurrentRetransmit200 = 0; // stop the 200 retransmit timer            // If we are waiting for an Ack and it times out, then end with a BYE            if(mState == UAS_WaitingToHangup ||                mState == WaitingToHangup)            {               sendBye();               transition(Terminated);               mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::Ended);             }            else if(mState == ReceivedReinviteSentOffer)            {               transition(Connected);               mProposedLocalSdp.reset();               mProposedEncryptionLevel = DialogUsageManager::None;               //!dcm! -- should this be onIllegalNegotiation?               mDum.mInviteSessionHandler->onOfferRejected(getSessionHandle(), 0);            }            else if(mState == WaitingToOffer ||                     mState == UAS_WaitingToOffer)            {               assert(mProposedLocalSdp.get());               mDum.mInviteSessionHandler->onAckNotReceived(getSessionHandle());               if(!isTerminated())                 {                  provideProposedOffer();                }            }            else if(mState == WaitingToRequestOffer ||                    mState == UAS_WaitingToRequestOffer)            {               mDum.mInviteSessionHandler->onAckNotReceived(getSessionHandle());               if(!isTerminated())                 {                  requestOffer();                }            }            else            {               // this is so the app can decided to ignore this. default implementation               // will call end next               mDum.mInviteSessionHandler->onAckNotReceived(getSessionHandle());            }         }      }   }   else if (timeout.type() == DumTimeout::CanDiscardAck)   {      AckMap::iterator i = mAcks.find(timeout.transactionId());      if (i != mAcks.end())      {         mAcks.erase(i);      }   }   else if (timeout.type() == DumTimeout::Glare)   {      if (mState == SentUpdateGlare)      {         transition(SentUpdate);         InfoLog (<< "Retransmitting the UPDATE (glare condition timer)");         mDialog.makeRequest(*mLastLocalSessionModification, UPDATE);  // increments CSeq         send(mLastLocalSessionModification);      }      else if (mState == SentReinviteGlare)      {         transition(SentReinvite);         InfoLog (<< "Retransmitting the reINVITE (glare condition timer)");         mDialog.makeRequest(*mLastLocalSessionModification, INVITE); // increments CSeq         startStaleReInviteTimer();         send(mLastLocalSessionModification);      }      else if (mState == SentReinviteNoOfferGlare)      {         transition(SentReinviteNoOffer);         InfoLog (<< "Retransmitting the reINVITE-nooffer (glare condition timer)");         mDialog.makeRequest(*mLastLocalSessionModification, INVITE);  // increments CSeq         startStaleReInviteTimer();         send(mLastLocalSessionModification);      }   }   else if (timeout.type() == DumTimeout::StaleReInvite)   {      if(timeout.seq() == mStaleReInviteTimerSeq)      {         if(mState == WaitingToTerminate)         {            sendBye();            transition(Terminated);            mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::Ended);          }         else if(mState == SentReinvite ||                 mState == SentReinviteNoOffer)         {            transition(Connected);            mProposedLocalSdp.reset();            mProposedEncryptionLevel = DialogUsageManager::None;            // this is so the app can decide to ignore this. default implementation            // will call end next - which will send a BYE            mDum.mInviteSessionHandler->onStaleReInviteTimeout(getSessionHandle());         }      }   }   else if (timeout.type() == DumTimeout::SessionExpiration)   {      if(timeout.seq() == mSessionTimerSeq)      {         // this is so the app can decide to ignore this. default implementation         // will call end next - which will send a BYE         mDum.mInviteSessionHandler->onSessionExpired(getSessionHandle());      }   }   else if (timeout.type() == DumTimeout::SessionRefresh)   {     if(timeout.seq() == mSessionTimerSeq)     {        // Note: If not connected then we must be issueing a reinvite/update or        // receiving one - in either case the session timer stuff will get        // reset/renegotiated - thus just ignore this referesh        if(mState == Connected)          {           sessionRefresh();        }     }   }}voidInviteSession::dispatchConnected(const SipMessage& msg){   InviteSessionHandler* handler = mDum.mInviteSessionHandler;   std::auto_ptr<SdpContents> sdp = InviteSession::getSdp(msg);   switch (toEvent(msg, sdp.get()))   {      case OnInvite:      case OnInviteReliable:         *mLastRemoteSessionModification = msg;         transition(ReceivedReinviteNoOffer);         //handler->onDialogModified(getSessionHandle(), None, msg);         handler->onOfferRequired(getSessionHandle(), msg);         break;      case OnInviteOffer:      case OnInviteReliableOffer:         *mLastRemoteSessionModification = msg;         transition(ReceivedReinvite);         mCurrentEncryptionLevel = getEncryptionLevel(msg);         mProposedRemoteSdp = sdp;          //handler->onDialogModified(getSessionHandle(), Offer, msg);         handler->onOffer(getSessionHandle(), msg, *mProposedRemoteSdp);         break;      case On2xx:      case On2xxOffer:      case On2xxAnswer:         // retransmission of 200I         // !jf! Need to include the answer here.         sendAck();          break;      case OnUpdateOffer:         transition(ReceivedUpdate);         //  !kh!         //  Find out if it's an UPDATE requiring state change.         //  See rfc3311 5.2, 4th paragraph.         *mLastRemoteSessionModification = msg;         mCurrentEncryptionLevel = getEncryptionLevel(msg);         mProposedRemoteSdp = sdp;          handler->onOffer(getSessionHandle(), msg, *mProposedRemoteSdp);         break;      case OnUpdate:      {         // ?slg? no sdp in update - just respond immediately (likely session timer) - do we need a callback?         SharedPtr<SipMessage> response(new SipMessage);         *mLastRemoteSessionModification = msg;         mDialog.makeResponse(*response, *mLastRemoteSessionModification, 200);         handleSessionTimerRequest(*response, *mLastRemoteSessionModification);         send(response);         break;      }      case OnUpdateRejected:      case On200Update:         WarningLog (<< "DUM delivered an UPDATE response in an incorrect state " << endl << msg);         assert(0);         break;      case OnAck:      case OnAckAnswer: // .bwc. Don't drop ACK with SDP!         mCurrentRetransmit200 = 0; // stop the 200 retransmit timer         handler->onAckReceived(getSessionHandle(), msg);         break;      default:         dispatchOthers(msg);         break;   }}voidInviteSession::dispatchSentUpdate(const SipMessage& msg){   InviteSessionHandler* handler = mDum.mInviteSessionHandler;   std::auto_ptr<SdpContents> sdp = InviteSession::getSdp(msg);   switch (toEvent(msg, sdp.get()))   {      case OnInvite:      case OnInviteReliable:      case OnInviteOffer:      case OnInviteReliableOffer:      case OnUpdate:      case OnUpdateOffer:      {         // glare         SharedPtr<SipMessage> response(new SipMessage);         mDialog.makeResponse(*response, msg, 491);         send(response);         break;      }      case On200Update:         transition(Connected);         handleSessionTimerResponse(msg);         if (sdp.get() && mProposedLocalSdp.get())         {            mCurrentEncryptionLevel = getEncryptionLevel(msg);            setCurrentLocalSdp(msg);            mCurrentRemoteSdp = sdp;             handler->onAnswer(getSessionHandle(), msg, *mCurrentRemoteSdp);         }         else if(mProposedLocalSdp.get())          {            // If we sent an offer in the Update Request and no answer is received            handler->onIllegalNegotiation(getSessionHandle(), msg);            mProposedLocalSdp.reset();            mProposedEncryptionLevel = DialogUsageManager::None;         }         break;      case On491Update:         transition(SentUpdateGlare);         start491Timer();         break;      case On422Update: // session timer         if(msg.exists(h_MinSE))         {            // Change interval to min from 422 response            mSessionInterval = msg.header(h_MinSE).value();

⌨️ 快捷键说明

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