📄 invitesession.cxx
字号:
#include "resip/stack/MultipartMixedContents.hxx"#include "resip/stack/MultipartAlternativeContents.hxx"#include "resip/stack/SdpContents.hxx"#include "resip/stack/SipMessage.hxx"#include "resip/stack/Helper.hxx"#include "resip/dum/BaseCreator.hxx"#include "resip/dum/Dialog.hxx"#include "resip/dum/DialogUsageManager.hxx"#include "resip/dum/InviteSession.hxx"#include "resip/dum/ServerInviteSession.hxx"#include "resip/dum/ClientSubscription.hxx"#include "resip/dum/ServerSubscription.hxx"#include "resip/dum/ClientInviteSession.hxx"#include "resip/dum/InviteSessionHandler.hxx"#include "resip/dum/MasterProfile.hxx"#include "resip/dum/UsageUseException.hxx"#include "resip/dum/DumHelper.hxx"#include "rutil/Inserter.hxx"#include "rutil/Logger.hxx"#include "rutil/MD5Stream.hxx"#include "rutil/Timer.hxx"#include "rutil/Random.hxx"#include "rutil/compat.hxx"#include "rutil/WinLeakCheck.hxx"// Remove warning about 'this' use in initiator list - pointer is only stored#if defined(WIN32) && !defined(__GNUC__)#pragma warning( disable : 4355 ) // using this in base member initializer list#pragma warning( disable : 4800 ) // forcing value to bool (performance warning)#endif#define RESIPROCATE_SUBSYSTEM Subsystem::DUM#define THROW(msg) throw DialogUsage::Exception(msg, __FILE__,__LINE__);using namespace resip;using namespace std;Data EndReasons[] ={ "Not Specified", "User Hung Up", "Application Rejected Sdp(usually no common codec)", "Illegal Sdp Negotiation", "ACK not received", "Session Timer Expired"};const Data& getEndReasonString(InviteSession::EndReason reason){ assert(reason >= InviteSession::NotSpecified && reason < InviteSession::ENDREASON_MAX); //!dcm! -- necessary? return EndReasons[reason];}InviteSession::InviteSession(DialogUsageManager& dum, Dialog& dialog) : DialogUsage(dum, dialog), mState(Undefined), mNitState(NitComplete), mLastLocalSessionModification(new SipMessage), mLastRemoteSessionModification(new SipMessage), mInvite200(new SipMessage), mLastNitResponse(new SipMessage), mCurrentRetransmit200(0), mStaleReInviteTimerSeq(1), mSessionInterval(0), mMinSE(90), mSessionRefresher(false), mSessionTimerSeq(0), mSessionRefreshReInvite(false), mReferSub(true), mCurrentEncryptionLevel(DialogUsageManager::None), mProposedEncryptionLevel(DialogUsageManager::None), mEndReason(NotSpecified){ DebugLog ( << "^^^ InviteSession::InviteSession " << this); assert(mDum.mInviteSessionHandler);}InviteSession::~InviteSession(){ DebugLog ( << "^^^ InviteSession::~InviteSession " << this); mDialog.mInviteSession = 0; while(!mNITQueue.empty()) { delete mNITQueue.front(); mNITQueue.pop(); }}void InviteSession::dialogDestroyed(const SipMessage& msg){ assert(0); // !jf! Is this correct? Merged from main... // !jf! what reason - guessed for now? //mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::PeerEnded, msg); //delete this; }const SdpContents&InviteSession::getLocalSdp() const{ if(mCurrentLocalSdp.get()) { return *mCurrentLocalSdp; } else { return SdpContents::Empty; }}const SdpContents&InviteSession::getRemoteSdp() const{ if(mCurrentRemoteSdp.get()) { return *mCurrentRemoteSdp; } else { return SdpContents::Empty; }}const SdpContents&InviteSession::getProposedRemoteSdp() const{ if(mProposedRemoteSdp.get()) { return *mProposedRemoteSdp; } else { return SdpContents::Empty; }}const Data& InviteSession::getDialogId() const{ return mDialog.getId().getCallId();}InviteSessionHandleInviteSession::getSessionHandle(){ return InviteSessionHandle(mDum, getBaseHandle().getId());}void InviteSession::storePeerCapabilities(const SipMessage& msg){ if (msg.exists(h_Allows)) { mPeerSupportedMethods = msg.header(h_Allows); } if (msg.exists(h_Supporteds)) { mPeerSupportedOptionTags = msg.header(h_Supporteds); } if (msg.exists(h_AcceptEncodings)) { mPeerSupportedEncodings = msg.header(h_AcceptEncodings); } if (msg.exists(h_AcceptLanguages)) { mPeerSupportedLanguages = msg.header(h_AcceptLanguages); } if (msg.exists(h_AllowEvents)) { mPeerAllowedEvents = msg.header(h_AllowEvents); } if (msg.exists(h_Accepts)) { mPeerSupportedMimeTypes = msg.header(h_Accepts); } if (msg.exists(h_UserAgent)) { mPeerUserAgent = msg.header(h_UserAgent).value(); }}boolInviteSession::updateMethodSupported() const{ // Check if Update is supported locally if(mDum.getMasterProfile()->isMethodSupported(UPDATE)) { // Check if peer supports UPDATE return mPeerSupportedMethods.find(Token("UPDATE")); } return false;}const NameAddr&InviteSession::myAddr() const{ return mDialog.mLocalNameAddr;}const NameAddr&InviteSession::peerAddr() const{ return mDialog.mRemoteNameAddr;}boolInviteSession::isConnected() const{ switch (mState) { case Connected: case SentUpdate: case SentUpdateGlare: case SentReinvite: case SentReinviteGlare: case SentReinviteNoOffer: case SentReinviteAnswered: case SentReinviteNoOfferGlare: case ReceivedUpdate: case ReceivedReinvite: case ReceivedReinviteNoOffer: case ReceivedReinviteSentOffer: case Answered: case WaitingToOffer: case WaitingToRequestOffer: return true; default: return false; }}boolInviteSession::isEarly() const{ switch (mState) { case UAC_Early: case UAC_EarlyWithOffer: case UAC_EarlyWithAnswer: case UAC_SentUpdateEarly: case UAC_ReceivedUpdateEarly: case UAC_SentAnswer: case UAC_QueuedUpdate: return true; default: return false; }}bool InviteSession::isAccepted() const{ switch (mState) { case UAS_Start: case UAS_Offer: case UAS_NoOffer: case UAS_NoOfferReliable: case UAS_ProvidedOffer: case UAS_OfferProvidedAnswer: case UAS_EarlyOffer: case UAS_EarlyProvidedOffer: case UAS_EarlyProvidedAnswer: case UAS_EarlyNoOffer: case UAS_FirstSentAnswerReliable: case UAS_FirstSentOfferReliable: case UAS_NegotiatedReliable: return false; default: return true; }}boolInviteSession::isTerminated() const{ switch (mState) { case Terminated: case WaitingToTerminate: case WaitingToHangup: case UAC_Cancelled: case UAS_WaitingToTerminate: case UAS_WaitingToHangup: return true; default: return false; }}std::ostream&InviteSession::dump(std::ostream& strm) const{ strm << "INVITE: " << mId << " " << toData(mState) << " ADDR=" << myAddr() << " PEER=" << peerAddr(); return strm;}voidInviteSession::requestOffer(){ switch (mState) { case Connected: case WaitingToRequestOffer: case UAS_WaitingToRequestOffer: transition(SentReinviteNoOffer); mDialog.makeRequest(*mLastLocalSessionModification, INVITE); startStaleReInviteTimer(); mLastLocalSessionModification->setContents(0); // Clear the SDP contents from the INVITE setSessionTimerHeaders(*mLastLocalSessionModification); InfoLog (<< "Sending " << mLastLocalSessionModification->brief()); // call send to give app an chance to adorn the message. send(mLastLocalSessionModification); break; case Answered: // queue the offer to be sent after the ACK is received transition(WaitingToRequestOffer); break; // ?slg? Can we handle all of the states listed in isConnected() ??? default: WarningLog (<< "Can't requestOffer when not in Connected state"); throw DialogUsage::Exception("Can't request an offer", __FILE__,__LINE__); }}voidInviteSession::provideOffer(const SdpContents& offer, DialogUsageManager::EncryptionLevel level, const SdpContents* alternative){ switch (mState) { case Connected: case WaitingToOffer: case UAS_WaitingToOffer: if (updateMethodSupported()) { transition(SentUpdate); mDialog.makeRequest(*mLastLocalSessionModification, UPDATE); } else { transition(SentReinvite); mDialog.makeRequest(*mLastLocalSessionModification, INVITE); startStaleReInviteTimer(); } setSessionTimerHeaders(*mLastLocalSessionModification); InfoLog (<< "Sending " << mLastLocalSessionModification->brief()); InviteSession::setSdp(*mLastLocalSessionModification, offer, alternative); mProposedLocalSdp = InviteSession::makeSdp(offer, alternative); mProposedEncryptionLevel = level; DumHelper::setOutgoingEncryptionLevel(*mLastLocalSessionModification, mProposedEncryptionLevel); // call send to give app an chance to adorn the message. send(mLastLocalSessionModification); break; case Answered: // queue the offer to be sent after the ACK is received transition(WaitingToOffer); mProposedEncryptionLevel = level; mProposedLocalSdp = InviteSession::makeSdp(offer, alternative); break; case ReceivedReinviteNoOffer: assert(!mProposedRemoteSdp.get()); transition(ReceivedReinviteSentOffer); mDialog.makeResponse(*mInvite200, *mLastRemoteSessionModification, 200); handleSessionTimerRequest(*mInvite200, *mLastRemoteSessionModification); InviteSession::setSdp(*mInvite200, offer, 0); mProposedLocalSdp = InviteSession::makeSdp(offer); InfoLog (<< "Sending " << mInvite200->brief()); DumHelper::setOutgoingEncryptionLevel(*mInvite200, mCurrentEncryptionLevel); send(mInvite200); startRetransmit200Timer(); break; default: WarningLog (<< "Incorrect state to provideOffer: " << toData(mState)); throw DialogUsage::Exception("Can't provide an offer", __FILE__,__LINE__); }}class InviteSessionProvideOfferExCommand : public DumCommandAdapter{public: InviteSessionProvideOfferExCommand(InviteSession& inviteSession, const SdpContents& offer, DialogUsageManager::EncryptionLevel level, const SdpContents* alternative) : mInviteSession(inviteSession), mOffer(offer) { } virtual void executeCommand() { mInviteSession.provideOffer(mOffer, mLevel, mAlternative.get()); } virtual std::ostream& encodeBrief(std::ostream& strm) const { return strm << "InviteSessionProvideOfferExCommand"; }private: InviteSession& mInviteSession; SdpContents mOffer; DialogUsageManager::EncryptionLevel mLevel; std::auto_ptr<const SdpContents> mAlternative;};voidInviteSession::provideOfferCommand(const SdpContents& offer, DialogUsageManager::EncryptionLevel level, const SdpContents* alternative){ mDum.post(new InviteSessionProvideOfferExCommand(*this, offer, level, alternative));}voidInviteSession::provideOffer(const SdpContents& offer){ return provideOffer(offer, mCurrentEncryptionLevel, 0);}class InviteSessionProvideOfferCommand : public DumCommandAdapter{public: InviteSessionProvideOfferCommand(InviteSession& inviteSession, const SdpContents& offer) : mInviteSession(inviteSession), mOffer(offer) { } virtual void executeCommand() { mInviteSession.provideOffer(mOffer); } virtual std::ostream& encodeBrief(std::ostream& strm) const { return strm << "InviteSessionProvideOfferCommand"; }private: InviteSession& mInviteSession; SdpContents mOffer;};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -