📄 clientinvitesession.cxx
字号:
} else { InviteSession::dispatch(timer); }}voidClientInviteSession::handleRedirect (const SipMessage& msg){ InviteSessionHandler* handler = mDum.mInviteSessionHandler; transition(Terminated); handler->onRedirected(getHandle(), msg); mDum.destroy(this);}voidClientInviteSession::handleProvisional(const SipMessage& msg){ assert(msg.isResponse()); assert(msg.header(h_StatusLine).statusCode() < 200); assert(msg.header(h_StatusLine).statusCode() > 100); InviteSessionHandler* handler = mDum.mInviteSessionHandler; //.dcm. Kept the following checks here rather than discardMessage as the // state machine can be affected(termination). // !dcm! should we really end the InviteSession or should be discard the 1xx instead? if (msg.header(h_CSeq).sequence() != mLastLocalSessionModification->header(h_CSeq).sequence()) { InfoLog (<< "Failure: CSeq doesn't match invite: " << msg.brief()); handler->onFailure(getHandle(), msg); end(NotSpecified); } //!dcm! this should never happen, the invite will have 100rel in the //required header. Keep for interop? else if (mDum.getMasterProfile()->getUacReliableProvisionalMode() == MasterProfile::Required) { if (!msg.exists(h_RSeq)) { InfoLog (<< "Failure: No RSeq in 1xx: " << msg.brief()); handler->onFailure(getHandle(), msg); end(NotSpecified); return; } } startStaleCallTimer(); handler->onProvisional(getHandle(), msg);}voidClientInviteSession::handleFinalResponse(const SipMessage& msg){ assert(msg.isResponse()); assert(msg.header(h_StatusLine).statusCode() >= 200); assert(msg.header(h_StatusLine).statusCode() < 300); handleSessionTimerResponse(msg); storePeerCapabilities(msg); ++mStaleCallTimerSeq; // disable stale call timer}voidClientInviteSession::handleOffer (const SipMessage& msg, const SdpContents& sdp){ InviteSessionHandler* handler = mDum.mInviteSessionHandler; handleProvisional(msg); mProposedRemoteSdp = InviteSession::makeSdp(sdp); mCurrentEncryptionLevel = getEncryptionLevel(msg); handler->onOffer(getSessionHandle(), msg, sdp);}voidClientInviteSession::handleAnswer(const SipMessage& msg, const SdpContents& sdp){ //mCurrentLocalSdp = mProposedLocalSdp; setCurrentLocalSdp(msg); mCurrentEncryptionLevel = getEncryptionLevel(msg); mCurrentRemoteSdp = InviteSession::makeSdp(sdp); InviteSessionHandler* handler = mDum.mInviteSessionHandler; handleProvisional(msg); handler->onAnswer(getSessionHandle(), msg, sdp); sendPrackIfNeeded(msg);}// will not include SDP (this is a subsequent 1xx)voidClientInviteSession::sendPrackIfNeeded(const SipMessage& msg){ assert(msg.isResponse()); assert(msg.header(h_StatusLine).statusCode() < 200); assert(msg.header(h_StatusLine).statusCode() > 100); if (isReliable(msg)) { SharedPtr<SipMessage> prack(new SipMessage); mDialog.makeRequest(*prack, PRACK); prack->header(h_RAck) = mRelRespInfo; send(prack); }}// This version is used to send an answer to the UAS in PRACK// from EarlyWithOffer state. Assumes that it is the first PRACK. Subsequent// PRACK will not have SDPvoidClientInviteSession::sendPrack(const SdpContents& sdp){ SharedPtr<SipMessage> prack(new SipMessage); mDialog.makeRequest(*prack, PRACK); prack->header(h_RAck)= mRelRespInfo; InviteSession::setSdp(*prack, sdp); // Remember last session modification. // mLastSessionModification = prack; // ?slg? is this needed? DumHelper::setOutgoingEncryptionLevel(*prack, mCurrentEncryptionLevel); send(prack);}/*boolClientInviteSession::isNextProvisional(const SipMessage& msg){}boolClientInviteSession::isRetransmission(const SipMessage& msg){ if ( mLastReceivedRSeq == 0 || msg.header(h_RSeq).value() <= mLastReceivedRSeq) { return false; } else { return true; }}*/voidClientInviteSession::dispatchStart (const SipMessage& msg){ assert(msg.isResponse()); assert(msg.header(h_StatusLine).statusCode() > 100); assert(msg.header(h_CSeq).method() == INVITE); InviteSessionHandler* handler = mDum.mInviteSessionHandler; std::auto_ptr<SdpContents> sdp = InviteSession::getSdp(msg); InviteSession::Event event = toEvent(msg, sdp.get()); switch (event) { case On1xx: transition(UAC_Early); handler->onNewSession(getHandle(), None, msg); if(!isTerminated()) { handleProvisional(msg); sendPrackIfNeeded(msg); //may wish to move emprty PRACK handling //outside the state machine } break; case On1xxEarly: //!dcm! according to draft-ietf-sipping-offeranswer there can be a non // reliable 1xx followed by a reliable 1xx. Also, the intial 1xx // doesn't have to have an offer. However, DUM will only generate // reliabled 1xx responses when 100rel is available. transition(UAC_Early); mEarlyMedia = InviteSession::makeSdp(*sdp); handler->onNewSession(getHandle(), None, msg); if(!isTerminated()) { handleProvisional(msg); if(!isTerminated()) { handler->onEarlyMedia(getHandle(), msg, *sdp); } } break; case On1xxOffer: transition(UAC_EarlyWithOffer); handler->onNewSession(getHandle(), Offer, msg); if(!isTerminated()) { handleOffer(msg, *sdp); } break; case On1xxAnswer: transition(UAC_EarlyWithAnswer); handler->onNewSession(getHandle(), Answer, msg); if(!isTerminated()) { handleAnswer(msg, *sdp); } break; case On2xxOffer: transition(UAC_Answered); handleFinalResponse(msg); mProposedRemoteSdp = InviteSession::makeSdp(*sdp); handler->onNewSession(getHandle(), Offer, msg); assert(mProposedLocalSdp.get() == 0); mCurrentEncryptionLevel = getEncryptionLevel(msg); if(!isTerminated()) { handler->onOffer(getSessionHandle(), msg, *sdp); if(!isTerminated()) //?jf? can this be terminated here but not above? .slg. yes application can call end() { handler->onConnected(getHandle(), msg); } } break; case On2xxAnswer: transition(Connected); sendAck(); handleFinalResponse(msg); //mCurrentLocalSdp = mProposedLocalSdp; setCurrentLocalSdp(msg); mCurrentEncryptionLevel = getEncryptionLevel(msg); mCurrentRemoteSdp = InviteSession::makeSdp(*sdp); handler->onNewSession(getHandle(), Answer, msg); if(!isTerminated()) // onNewSession callback may call end() or reject() { handler->onAnswer(getSessionHandle(), msg, *sdp); if(!isTerminated()) // onAnswer callback may call end() or reject() { handler->onConnected(getHandle(), msg); } } break; case On2xx: { sendAck(); sendBye(); InfoLog (<< "Failure: 2xx with no answer: " << msg.brief()); transition(Terminated); handler->onFailure(getHandle(), msg); handler->onTerminated(getSessionHandle(), InviteSessionHandler::GeneralFailure, &msg); break; } case OnRedirect: // Redirects are handled by the DialogSet - if a 3xx gets here then it's because the redirect was intentionaly not handled and should be treated as an INVITE failure case OnInviteFailure: case OnGeneralFailure: case On422Invite: case On487Invite: case On491Invite: InfoLog (<< "Failure: error response: " << msg.brief()); transition(Terminated); handler->onFailure(getHandle(), msg); handler->onTerminated(getSessionHandle(), InviteSessionHandler::GeneralFailure, &msg); mDum.destroy(this); break; case OnBye: dispatchBye(msg); break; default: // !kh! // should not assert here for peer sent us garbage. WarningLog (<< "Don't know what this is : " << msg); break; }}voidClientInviteSession::dispatchEarly (const SipMessage& msg){ InviteSessionHandler* handler = mDum.mInviteSessionHandler; std::auto_ptr<SdpContents> sdp = InviteSession::getSdp(msg); switch (toEvent(msg, sdp.get())) { case On1xx: transition(UAC_Early); handleProvisional(msg); break; case On1xxEarly: // only unreliable transition(UAC_Early); handleProvisional(msg); if(!isTerminated()) { mEarlyMedia = InviteSession::makeSdp(*sdp); handler->onEarlyMedia(getHandle(), msg, *sdp); } break; case On1xxOffer: transition(UAC_EarlyWithOffer); handleOffer(msg, *sdp); break; case On1xxAnswer: transition(UAC_EarlyWithAnswer); handleAnswer(msg, *sdp); break; case On2xxOffer: transition(UAC_Answered); handleFinalResponse(msg); assert(mProposedLocalSdp.get() == 0); mCurrentEncryptionLevel = getEncryptionLevel(msg); mProposedRemoteSdp = InviteSession::makeSdp(*sdp); handler->onOffer(getSessionHandle(), msg, *sdp); if(!isTerminated()) { handler->onConnected(getHandle(), msg); } break; case On2xxAnswer: transition(Connected); sendAck(); handleFinalResponse(msg); //mCurrentLocalSdp = mProposedLocalSdp; setCurrentLocalSdp(msg); mCurrentEncryptionLevel = getEncryptionLevel(msg); mCurrentRemoteSdp = InviteSession::makeSdp(*sdp); handler->onAnswer(getSessionHandle(), msg, *sdp); if(!isTerminated()) // onNewSession callback may call end() or reject() { handler->onConnected(getHandle(), msg); } break; case On2xx: { sendAck(); sendBye(); InfoLog (<< "Failure: 2xx with no answer: " << msg.brief()); transition(Terminated); handler->onFailure(getHandle(), msg); handler->onTerminated(getSessionHandle(), InviteSessionHandler::GeneralFailure, &msg); break; } case OnRedirect: // Redirects are handled by the DialogSet - if a 3xx gets here then it's because the redirect was intentionaly not handled and should be treated as an INVITE failure case OnInviteFailure: case OnGeneralFailure: case On422Invite: case On487Invite: InfoLog (<< "Failure: error response: " << msg.brief()); transition(Terminated); handler->onFailure(getHandle(), msg); handler->onTerminated(getSessionHandle(), InviteSessionHandler::GeneralFailure, &msg); mDum.destroy(this); break; case OnBye: dispatchBye(msg); break; default: // !kh! // should not assert here for peer sent us garbage. WarningLog (<< "Don't know what this is : " << msg); break; }}voidClientInviteSession::dispatchAnswered (const SipMessage& msg){ //InviteSessionHandler* handler = mDum.mInviteSessionHandler; std::auto_ptr<SdpContents> sdp = InviteSession::getSdp(msg); switch (toEvent(msg, sdp.get())) { case On1xx: case On1xxEarly: case On1xxOffer: // late, so ignore break; case On2xxOffer: case On2xx: case On2xxAnswer: // retransmission break; case OnRedirect: // too late break; // .slg. This doesn't really make sense (after a 2xx) case OnGeneralFailure: case On422Invite: break;#if 0 // !jf! don't think this is right { sendBye(); InfoLog (<< "Failure: error response: " << msg.brief()); transition(Terminated); handler->onFailure(getHandle(), msg); handler->onTerminated(getSessionHandle(), InviteSessionHandler::GeneralFailure, &msg); mDum.destroy(this); break; }#endif case OnBye: dispatchBye(msg); break; default: // !kh! // should not assert here for peer sent us garbage. WarningLog (<< "Don't know what this is : " << msg); break; }}voidClientInviteSession::dispatchEarlyWithOffer (const SipMessage& msg){ InviteSessionHandler* handler = mDum.mInviteSessionHandler; std::auto_ptr<SdpContents> sdp = InviteSession::getSdp(msg); switch (toEvent(msg, sdp.get())) { case On1xx: // must be reliable handleProvisional(msg); sendPrackIfNeeded(msg); break; case On2xx: case On2xxAnswer: sendAck(); sendBye(); InfoLog (<< "Failure: no answer sent: " << msg.brief()); transition(Terminated); handler->onFailure(getHandle(), msg); handler->onTerminated(getSessionHandle(), InviteSessionHandler::GeneralFailure, &msg); break; case OnRedirect: // Redirects are handled by the DialogSet - if a 3xx gets here then it's because the redirect was intentionaly not handled and should be treated as an INVITE failure case OnInviteFailure: case OnGeneralFailure: case On422Invite: case On487Invite: case On491Invite: InfoLog (<< "Failure: error response: " << msg.brief()); transition(Terminated); handler->onFailure(getHandle(), msg);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -