📄 invitesession.cxx
字号:
switch (toEvent(msg, sdp.get())) { case OnAck: case OnAckAnswer: { mCurrentRetransmit200 = 0; // stop the 200 retransmit timer sendBye(); transition(Terminated); mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::Ended); break; } default: break; }}voidInviteSession::dispatchTerminated(const SipMessage& msg){ InfoLog (<< "InviteSession::dispatchTerminated " << msg.brief()); if (msg.isRequest()) { if (BYE == msg.header(h_CSeq).method()) { SharedPtr<SipMessage> response(new SipMessage); mDialog.makeResponse(*response, msg, 200); send(response); } else { SharedPtr<SipMessage> response(new SipMessage); mDialog.makeResponse(*response, msg, 481); send(response); } // !jf! means the peer sent BYE while we are waiting for response to BYE //mDum.destroy(this); } else { mDum.destroy(this); }}voidInviteSession::dispatchOthers(const SipMessage& msg){ // handle OnGeneralFailure // handle OnRedirect switch (msg.header(h_CSeq).method()) { case PRACK: dispatchPrack(msg); break; case CANCEL: dispatchCancel(msg); break; case BYE: dispatchBye(msg); break; case INFO: dispatchInfo(msg); break; case MESSAGE: dispatchMessage(msg); break; case ACK: // Ignore duplicate ACKs from 2xx reTransmissions break; default: // handled in Dialog WarningLog (<< "DUM delivered a " << msg.header(h_CSeq).unknownMethodName() << " to the InviteSession in state: " << toData(mState) << endl << msg); assert(0); break; }}voidInviteSession::dispatchUnhandledInvite(const SipMessage& msg){ assert(msg.isRequest()); assert(msg.header(h_CSeq).method() == INVITE); // If we get an INVITE request from the wire and we are not in // Connected state, reject the request and send a BYE SharedPtr<SipMessage> response(new SipMessage); mDialog.makeResponse(*response, msg, 400); // !jf! what code to use? InfoLog (<< "Sending " << response->brief()); send(response); sendBye(); transition(Terminated); mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::GeneralFailure, &msg); }voidInviteSession::dispatchPrack(const SipMessage& msg){ assert(msg.header(h_CSeq).method() == PRACK); if(msg.isRequest()) { SharedPtr<SipMessage> rsp(new SipMessage); mDialog.makeResponse(*rsp, msg, 481); send(rsp); sendBye(); // !jf! should we make some other callback here transition(Terminated); mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::GeneralFailure, &msg); } else { // ignore. could be PRACK/200 }}voidInviteSession::dispatchCancel(const SipMessage& msg){ InviteSessionHandler* handler = mDum.mInviteSessionHandler; assert(msg.header(h_CSeq).method() == CANCEL); if(msg.isRequest()) { SharedPtr<SipMessage> rsp(new SipMessage); mDialog.makeResponse(*rsp, msg, 200); send(rsp); sendBye(); // !jf! should we make some other callback here transition(Terminated); handler->onTerminated(getSessionHandle(), InviteSessionHandler::PeerEnded, &msg); } else { WarningLog (<< "DUM let me send a CANCEL at an incorrect state " << endl << msg); assert(0); }}voidInviteSession::dispatchBye(const SipMessage& msg){ InviteSessionHandler* handler = mDum.mInviteSessionHandler; if (msg.isRequest()) { SharedPtr<SipMessage> rsp(new SipMessage); InfoLog (<< "Received " << msg.brief()); mDialog.makeResponse(*rsp, msg, 200); send(rsp); // !jf! should we make some other callback here transition(Terminated); handler->onTerminated(getSessionHandle(), InviteSessionHandler::PeerEnded, &msg); mDum.destroy(this); } else { WarningLog (<< "DUM let me send a BYE at an incorrect state " << endl << msg); assert(0); }}voidInviteSession::dispatchInfo(const SipMessage& msg){ InviteSessionHandler* handler = mDum.mInviteSessionHandler; if (msg.isRequest()) { InfoLog (<< "Received " << msg.brief()); mDialog.makeResponse(*mLastNitResponse, msg, 200); handler->onInfo(getSessionHandle(), msg); } else { assert(mNitState == NitProceeding); //!dcm! -- toss away 1xx to an info? if (msg.header(h_StatusLine).statusCode() >= 300) { handler->onInfoFailure(getSessionHandle(), msg); } else if (msg.header(h_StatusLine).statusCode() >= 200) { handler->onInfoSuccess(getSessionHandle(), msg); } nitComplete(); }}voidInviteSession::acceptNIT(int statusCode, const Contents * contents){ if (statusCode / 100 != 2) { throw UsageUseException("Must accept with a 2xx", __FILE__, __LINE__); } mLastNitResponse->header(h_StatusLine).statusCode() = statusCode; mLastNitResponse->setContents(contents); Helper::getResponseCodeReason(statusCode, mLastNitResponse->header(h_StatusLine).reason()); send(mLastNitResponse); } class InviteSessionAcceptNITCommand : public DumCommandAdapter{public: InviteSessionAcceptNITCommand(InviteSession& inviteSession, int statusCode, const Contents* contents) : mInviteSession(inviteSession), mStatusCode(statusCode), mContents(contents?contents->clone():0) { } virtual void executeCommand() { mInviteSession.acceptNITCommand(mStatusCode, mContents.get()); } virtual std::ostream& encodeBrief(std::ostream& strm) const { return strm << "InviteSessionAcceptNITCommand"; }private: InviteSession& mInviteSession; int mStatusCode; std::auto_ptr<Contents> mContents;};voidInviteSession::acceptNITCommand(int statusCode, const Contents* contents){ mDum.post(new InviteSessionAcceptNITCommand(*this, statusCode, contents));} voidInviteSession::rejectNIT(int statusCode){ if (statusCode < 400) { throw UsageUseException("Must reject with a >= 4xx", __FILE__, __LINE__); } mLastNitResponse->header(h_StatusLine).statusCode() = statusCode; mLastNitResponse->releaseContents(); Helper::getResponseCodeReason(statusCode, mLastNitResponse->header(h_StatusLine).reason()); send(mLastNitResponse);}class InviteSessionRejectNITCommand : public DumCommandAdapter{public: InviteSessionRejectNITCommand(InviteSession& inviteSession, int statusCode) : mInviteSession(inviteSession), mStatusCode(statusCode) { } virtual void executeCommand() { mInviteSession.rejectNITCommand(mStatusCode); } virtual std::ostream& encodeBrief(std::ostream& strm) const { return strm << "InviteSessionRejectNITCommand"; }private: InviteSession& mInviteSession; int mStatusCode;};voidInviteSession::rejectNITCommand(int statusCode){ mDum.post(new InviteSessionRejectNITCommand(*this, statusCode));}voidInviteSession::dispatchMessage(const SipMessage& msg){ InviteSessionHandler* handler = mDum.mInviteSessionHandler; if (msg.isRequest()) { InfoLog (<< "Received " << msg.brief()); mDialog.makeResponse(*mLastNitResponse, msg, 200); mLastNitResponse->header(h_Contacts).clear(); handler->onMessage(getSessionHandle(), msg); } else { assert(mNitState == NitProceeding); //!dcm! -- toss away 1xx to an message? if (msg.header(h_StatusLine).statusCode() >= 300) { handler->onMessageFailure(getSessionHandle(), msg); } else if (msg.header(h_StatusLine).statusCode() >= 200) { handler->onMessageSuccess(getSessionHandle(), msg); } nitComplete(); }}voidInviteSession::startRetransmit200Timer(){ mCurrentRetransmit200 = Timer::T1; unsigned int seq = mLastRemoteSessionModification->header(h_CSeq).sequence(); mDum.addTimerMs(DumTimeout::Retransmit200, mCurrentRetransmit200, getBaseHandle(), seq); mDum.addTimerMs(DumTimeout::WaitForAck, Timer::TH, getBaseHandle(), seq);}// RFC3261 section 14.1// If a UAC receives a 491 response to a re-INVITE, it SHOULD start a timer with// a value T chosen as follows:// 1. If the UAC is the owner of the Call-ID of the dialog ID, T has a randomly// chosen value between 2.1 and 4 seconds in units of 10 ms.// 2. If the UAC is not the owner of the Call-ID of the dialog ID, T has a// randomly chosen value of between 0 and 2 seconds in units of 10 ms.voidInviteSession::start491Timer(){ unsigned int seq = mLastLocalSessionModification->header(h_CSeq).sequence(); if (dynamic_cast<ClientInviteSession*>(this)) { int timer = Random::getRandom() % (4000 - 2100); timer += 2100; timer -= timer % 10; DebugLog(<< "491 timer value: " << timer << "ms" << endl); mDum.addTimerMs(DumTimeout::Glare, timer, getBaseHandle(), seq); } else { int timer = Random::getRandom() % 2000; timer -= timer % 10; DebugLog(<< "491 timer value: " << timer << "ms" << endl); mDum.addTimerMs(DumTimeout::Glare, timer, getBaseHandle(), seq); }}void InviteSession::startStaleReInviteTimer(){ InfoLog (<< toData(mState) << ": startStaleReInviteTimer"); unsigned long when = mDialog.mDialogSet.getUserProfile()->getDefaultStaleReInviteTime(); mDum.addTimer(DumTimeout::StaleReInvite, when, getBaseHandle(), ++mStaleReInviteTimerSeq);}void InviteSession::setSessionTimerHeaders(SipMessage &msg){ if(mSessionInterval >= 90) // If mSessionInterval is 0 then SessionTimers are considered disabled { msg.header(h_SessionExpires).value() = mSessionInterval; if(msg.isRequest()) { msg.header(h_SessionExpires).param(p_refresher) = Data(mSessionRefresher ? "uac" : "uas"); } else { msg.header(h_SessionExpires).param(p_refresher) = Data(mSessionRefresher ? "uas" : "uac"); } msg.header(h_MinSE).value() = mMinSE; } else { msg.remove(h_SessionExpires); msg.remove(h_MinSE); }}voidInviteSession::sessionRefresh(){ if (updateMethodSupported()) { transition(SentUpdate); mDialog.makeRequest(*mLastLocalSessionModification, UPDATE); mLastLocalSessionModification->releaseContents(); // Don't send SDP } else { transition(SentReinvite); mDialog.makeRequest(*mLastLocalSessionModification, INVITE); startStaleReInviteTimer(); InviteSession::setSdp(*mLastLocalSessionModification, mCurrentLocalSdp.get()); mProposedLocalSdp = InviteSession::makeSdp(*mCurrentLocalSdp.get(), 0); mSessionRefreshReInvite = true; } setSessionTimerHeaders(*mLastLocalSessionModification); InfoLog (<< "sessionRefresh: Sending " << mLastLocalSessionModification->brief()); DumHelper::setOutgoingEncryptionLevel(*mLastLocalSessionModification, mCurrentEncryptionLevel); send(mLastLocalSessionModification);}voidInviteSession::setSessionTimerPreferences(){ mSessionInterval = mDialog.mDialogSet.getUserProfile()->getDefaultSessionTime(); // Used only if remote doesn't request a time if(mSessionInterval != 0) { // If session timers are no disabled then ensure interval is greater than or equal to MinSE mSessionInterval = resipMax(mMinSE, mSessionInterval); } switch(mDialog.mDialogSet.getUserProfile()->getDefaultSessionTimerMode()) { case Profile::PreferLocalRefreshes: mSessionRefresher = true; // Default refresher is Local break; case Profile::PreferRemoteRefreshes: mSessionRefresher = false; // Default refresher is Remote break; case Profile::PreferUASRefreshes: mSessionRefresher = dynamic_cast<ServerInviteSession*>(this) != NULL; // Default refresher is UAS (for the session) - callee break; case Profile::PreferUACRefreshes: mSessionRefresher = dynamic_cast<ClientInviteSession*>(this) != NULL; // Default refresher is UAC (for the session) - caller break; }}voidInviteSession::startSessionTimer(){ if(mSessionInterval >= 90) // 90 is the absolute minimum - RFC4028 { // Check if we are the refresher if(mSessionRefresher) { // Start Session-Refresh Timer to mSessionInterval / 2 (recommended by RFC4028) mDum.addTimer(DumTimeout::SessionRefresh, mSessionInterval / 2, getBaseHandle(), ++mSessionTimerSeq); } else { // Start Session-Expiration Timer to mSessionInterval - BYE should be sent a minimum of 32 and one third of the SessionInterval, seconds before the session expires (recommended by RFC4028) mDum.addTimer(DumTimeout::SessionExpiration, mSessionInterval - resipMin((UInt32)32,mSessionInterval/3), getBaseHandle(), ++mSessionTimerSeq); } } else // Session Interva
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -