22#define RESIPROCATE_SUBSYSTEM Subsystem::DUM
26 mFirstRequest(request),
28 mCurrentRetransmit1xxSeq(0),
30 mAnswerSentReliably(false)
73 auto response = std::make_shared<SipMessage>();
75 response->header(h_Contacts) = contacts;
78 if (
mDum.mDialogEventStateManager)
108 : mServerInviteSessionHandle(serverInviteSessionHandle),
117 if(mServerInviteSessionHandle.isValid())
119 mServerInviteSessionHandle->redirect(mContacts, mCode);
125 return strm <<
"ServerInviteSessionRedirectCommand";
148 sendProvisional(code, earlyFlag);
154 sendProvisional(code, earlyFlag);
160 sendProvisional(code, earlyFlag);
165 sendProvisional(code, earlyFlag);
171 sendProvisional(code, earlyFlag);
179 if(mUnacknowledgedReliableProvisional.get())
181 InfoLog (<<
"Waiting for PRACK. queued provisional, code=" << code <<
", early=" << (earlyFlag ?
"YES" :
"NO") );
182 queueResponse(code, earlyFlag);
186 sendProvisional(code, earlyFlag);
192 if(sendProvisional(code, earlyFlag))
200 if(sendProvisional(code, earlyFlag))
208 if(mUnacknowledgedReliableProvisional.get())
210 InfoLog (<<
"Waiting for PRACK. queued provisional, code=" << code <<
", early=" << (earlyFlag ?
"YES" :
"NO") );
211 queueResponse(code, earlyFlag);
213 else if(sendProvisional(code, earlyFlag) && earlyFlag)
239 : mServerInviteSessionHandle(serverInviteSessionHandle),
240 mStatusCode(statusCode),
241 mEarlyFlag(earlyFlag)
247 if(mServerInviteSessionHandle.isValid())
249 mServerInviteSessionHandle->provisional(mStatusCode, mEarlyFlag);
255 return strm <<
"ServerInviteSessionProvisionalCommand";
273 bool sendOfferAtAccept)
299 if (sendOfferAtAccept)
363 bool sendOfferAtAccept)
399 mAnswerSentReliably =
false;
431 auto response = std::make_shared<SipMessage>();
436 InfoLog (<<
"Sending " << response->brief());
444 auto response = std::make_shared<SipMessage>();
449 InfoLog (<<
"Sending " << response->brief());
471 auto p200 = std::make_shared<SipMessage>();
474 mAnswerSentReliably =
true;
475 mPrackWithOffer.reset();
603 reject(code,
nullptr, warning);
642 auto response = std::make_shared<SipMessage>();
647 response->setContents(contents);
651 response->header(h_Warnings).push_back(*warning);
655 if (
mDum.mDialogEventStateManager)
722 InfoLog (<<
"Waiting for PRACK. queued 200 OK" );
723 queueResponse(code,
false);
727 if (mUnacknowledgedReliableProvisional)
729 InfoLog (<<
"Waiting for PRACK. queued provisional" );
730 queueResponse(code,
false);
748 queueResponse(code,
false);
753 queueResponse(code,
false);
773 : mServerInviteSessionHandle(serverInviteSessionHandle),
774 mStatusCode(statusCode)
780 if(mServerInviteSessionHandle.isValid())
782 mServerInviteSessionHandle->accept(mStatusCode);
788 return strm <<
"ServerInviteSessionAcceptCommand";
802ServerInviteSession::dispatch(
const SipMessage& msg)
836 dispatchOfferOrEarly(msg);
839 dispatchOfferReliableProvidedAnswer(msg);
842 dispatchAccepted(msg);
845 dispatchWaitingToOffer(msg);
848 dispatchWaitingToRequestOffer(msg);
851 dispatchAcceptedWaitingAnswer(msg);
854 dispatchFirstSentAnswerReliable(msg);
857 dispatchNoAnswerReliableWaitingPrack(msg);
860 dispatchFirstSentOfferReliable(msg);
863 dispatchReceivedUpdate(msg);
866 dispatchReceivedUpdateWaitingAnswer(msg);
869 dispatchSentUpdate(msg);
872 dispatchSentUpdateGlare(msg);
875 dispatchWaitingToHangup(msg);
878 dispatchSentUpdateAccepted(msg);
881 dispatchNegotiatedReliable(msg);
890ServerInviteSession::dispatch(
const DumTimeout& timeout)
894 if (timeout.
seq() == mCurrentRetransmit1xxSeq)
897 startRetransmit1xxTimer();
902 if (timeout.
seq() == mCurrentRetransmit1xxSeq)
905 if(m1xx->exists(h_RSeq))
908 m1xx->header(h_RSeq).value()++;
911 m1xx->setContents(0);
913 mUnacknowledgedReliableProvisional = m1xx;
915 startResubmit1xxRelTimer();
921 if (mUnacknowledgedReliableProvisional.get() &&
922 mUnacknowledgedReliableProvisional->header(h_RSeq).value() == timeout.
seq())
927 InfoLog (<<
"Reliable provisional timeout, duration=" << duration );
928 auto i504 = std::make_shared<SipMessage>();
934 if (
mDum.mDialogEventStateManager)
946 InfoLog (<<
"Reliable provisional retransmit, duration=" << duration );
947 send(mUnacknowledgedReliableProvisional);
957 InfoLog (<<
"Retransmitting the UPDATE (glare condition timer)");
973ServerInviteSession::dispatchStart(
const SipMessage& msg)
982 if (
mDum.mDialogEventStateManager)
984 mDum.mDialogEventStateManager->onTryingUas(
mDialog, msg);
987 switch (
toEvent(msg, offerAnswer.get()))
1039ServerInviteSession::dispatchOfferOrEarly(
const SipMessage& msg)
1042 switch (
toEvent(msg, offerAnswer.get()))
1045 dispatchCancel(msg);
1054 auto response = std::make_shared<SipMessage>();
1062 dispatchUnknown(msg);
1069ServerInviteSession::dispatchAccepted(
const SipMessage& msg)
1075 switch (
toEvent(msg, offerAnswer.get()))
1084 auto response = std::make_shared<SipMessage>();
1100 auto c200 = std::make_shared<SipMessage>();
1108 auto b200 = std::make_shared<SipMessage>();
1122 auto p481 = std::make_shared<SipMessage>();
1131 dispatchUnknown(msg);
1138ServerInviteSession::dispatchWaitingToOffer(
const SipMessage& msg)
1142 InfoLog (<<
"dispatchWaitingToOffer: " << msg.
brief());
1144 switch (
toEvent(msg, offerAnswer.get()))
1153 auto response = std::make_shared<SipMessage>();
1175 auto c200 = std::make_shared<SipMessage>();
1183 auto b200 = std::make_shared<SipMessage>();
1196 dispatchUnknown(msg);
1203ServerInviteSession::dispatchWaitingToRequestOffer(
const SipMessage& msg)
1207 InfoLog (<<
"dispatchWaitingToRequestOffer: " << msg.
brief());
1209 switch (
toEvent(msg, offerAnswer.get()))
1218 auto response = std::make_shared<SipMessage>();
1239 auto c200 = std::make_shared<SipMessage>();
1247 auto b200 = std::make_shared<SipMessage>();
1260 dispatchUnknown(msg);
1267ServerInviteSession::dispatchAcceptedWaitingAnswer(
const SipMessage& msg)
1272 switch (
toEvent(msg, offerAnswer.get()))
1281 auto response = std::make_shared<SipMessage>();
1311 auto c200 = std::make_shared<SipMessage>();
1321 auto p481 = std::make_shared<SipMessage>();
1330 dispatchUnknown(msg);
1337ServerInviteSession::dispatchFirstSentOfferReliable(
const SipMessage& msg)
1342 switch (
toEvent(msg, offerAnswer.get()))
1345 dispatchCancel(msg);
1356 auto response = std::make_shared<SipMessage>();
1363 if(handlePrack(msg))
1368 auto p200 = std::make_shared<SipMessage>();
1385 auto p406 = std::make_shared<SipMessage>();
1390 auto i406 = std::make_shared<SipMessage>();
1402 dispatchUnknown(msg);
1409ServerInviteSession::handlePrack(
const SipMessage& msg)
1413 if(mUnacknowledgedReliableProvisional.get() &&
1414 mUnacknowledgedReliableProvisional->header(h_RSeq).value() == msg.
header(h_RAck).rSequence() &&
1415 mUnacknowledgedReliableProvisional->header(h_CSeq).sequence() == msg.
header(h_RAck).cSequence() &&
1416 mUnacknowledgedReliableProvisional->header(h_CSeq).method() == msg.
header(h_RAck).
method())
1418 mUnacknowledgedReliableProvisional.reset();
1420 InfoLog (<<
"Found matching provisional for PRACK.");
1425 auto p481 = std::make_shared<SipMessage>();
1432ServerInviteSession::prackCheckQueue()
1434 InfoLog (<<
"prackCheckQueue: " << mQueuedResponses.size() );
1435 if (!mQueuedResponses.empty() && mQueuedResponses.front().first < 200)
1437 InfoLog (<<
"Sending queued provisional" );
1438 sendProvisional(mQueuedResponses.front().first, mQueuedResponses.front().second);
1439 mQueuedResponses.pop_front();
1441 else if (!mQueuedResponses.empty() && mQueuedResponses.front().first < 300)
1443 InfoLog (<<
"Sending queued 200 OK" );
1451 sendAccept(mQueuedResponses.front().first, sdp);
1453 mQueuedResponses.clear();
1458ServerInviteSession::updateCheckQueue()
1461 InfoLog (<<
"updateCheckQueue: " << mQueuedResponses.size() );
1462 if (!mQueuedResponses.empty() &&
1463 mQueuedResponses.front().first >= 200 &&
1464 mQueuedResponses.front().first < 300)
1466 InfoLog (<<
"Sending queued 200 OK" );
1469 sendAccept(mQueuedResponses.front().first, 0);
1471 mQueuedResponses.pop_front();
1476ServerInviteSession::dispatchOfferReliableProvidedAnswer(
const SipMessage& msg)
1481 switch (
toEvent(msg, offerAnswer.get()))
1484 dispatchCancel(msg);
1495 auto response = std::make_shared<SipMessage>();
1502 if(handlePrack(msg))
1514 auto p406 = std::make_shared<SipMessage>();
1519 auto i406 = std::make_shared<SipMessage>();
1528 auto p200 = std::make_shared<SipMessage>();
1533 if (!mQueuedResponses.empty() &&
1534 mQueuedResponses.front().first < 200 &&
1535 mQueuedResponses.front().second)
1548 dispatchUnknown(msg);
1555ServerInviteSession::dispatchFirstSentAnswerReliable(
const SipMessage& msg)
1560 switch (
toEvent(msg, offerAnswer.get()))
1563 dispatchCancel(msg);
1574 auto response = std::make_shared<SipMessage>();
1581 if(handlePrack(msg))
1594 mPrackWithOffer = std::make_shared<SipMessage>(msg);
1605 auto p200 = std::make_shared<SipMessage>();
1628 dispatchUnknown(msg);
1635ServerInviteSession::dispatchNoAnswerReliableWaitingPrack(
const SipMessage& msg)
1640 switch (
toEvent(msg, offerAnswer.get()))
1643 dispatchCancel(msg);
1654 auto response = std::make_shared<SipMessage>();
1661 if(handlePrack(msg))
1673 auto p406 = std::make_shared<SipMessage>();
1678 auto i406 = std::make_shared<SipMessage>();
1687 auto p200 = std::make_shared<SipMessage>();
1696 if (!mQueuedResponses.empty() && mQueuedResponses.front().first < 200)
1698 if (mQueuedResponses.front().second)
1715 dispatchUnknown(msg);
1722ServerInviteSession::dispatchSentUpdate(
const SipMessage& msg)
1727 switch (
toEvent(msg, offerAnswer.get()))
1730 dispatchCancel(msg);
1741 auto response = std::make_shared<SipMessage>();
1775 dispatchUnknown(msg);
1782ServerInviteSession::dispatchSentUpdateGlare(
const SipMessage& msg)
1787 switch (
toEvent(msg, offerAnswer.get()))
1790 dispatchCancel(msg);
1801 dispatchNegotiatedReliable(msg);
1807 dispatchUnknown(msg);
1814ServerInviteSession::dispatchSentUpdateAccepted(
const SipMessage& msg)
1819 switch (
toEvent(msg, offerAnswer.get()))
1822 dispatchCancel(msg);
1833 auto response = std::make_shared<SipMessage>();
1870 dispatchUnknown(msg);
1877ServerInviteSession::dispatchReceivedUpdate(
const SipMessage& msg)
1881 switch (
toEvent(msg, offerAnswer.get()))
1884 dispatchCancel(msg);
1896 auto u500 = std::make_shared<SipMessage>();
1906 dispatchUnknown(msg);
1913ServerInviteSession::dispatchReceivedUpdateWaitingAnswer(
const SipMessage& msg)
1917 switch (
toEvent(msg, offerAnswer.get()))
1920 dispatchCancel(msg);
1932 auto u500 = std::make_shared<SipMessage>();
1941 dispatchUnknown(msg);
1948ServerInviteSession::dispatchNegotiatedReliable(
const SipMessage& msg)
1953 switch (
toEvent(msg, offerAnswer.get()))
1956 dispatchCancel(msg);
1964 if(handlePrack(msg))
1969 mPrackWithOffer = std::make_shared<SipMessage>(msg);
1980 auto p200 = std::make_shared<SipMessage>();
2004 auto response = std::make_shared<SipMessage>();
2013 dispatchUnknown(msg);
2020ServerInviteSession::dispatchWaitingToHangup(
const SipMessage& msg)
2024 switch (
toEvent(msg, offerAnswer.get()))
2043ServerInviteSession::dispatchCancel(
const SipMessage& msg)
2045 auto c200 = std::make_shared<SipMessage>();
2049 auto i487 = std::make_shared<SipMessage>();
2055 if (
mDum.mDialogEventStateManager)
2065ServerInviteSession::dispatchBye(
const SipMessage& msg)
2067 auto b200 = std::make_shared<SipMessage>();
2071 auto i487 = std::make_shared<SipMessage>();
2082ServerInviteSession::dispatchUnknown(
const SipMessage& msg)
2084 InfoLog (<<
"Unknown request (" << msg.
brief() <<
") received in state=" <<
toData(
mState) <<
", rejecting request and terminating call.");
2086 auto r500 = std::make_shared<SipMessage>();
2090 auto i400 = std::make_shared<SipMessage>();
2100ServerInviteSession::startRetransmit1xxTimer()
2111ServerInviteSession::startResubmit1xxRelTimer()
2122ServerInviteSession::startRetransmit1xxRelTimer()
2124 unsigned int seq = m1xx->header(h_RSeq).value();
2129ServerInviteSession::sendProvisional(
int code,
bool earlyFlag)
2131 m1xx->setContents(0);
2134 bool sendReliably = code > 100 &&
2155 mAnswerSentReliably =
true;
2156 sendReliably =
true;
2166 DebugLog( <<
"Sending a reliable provisional after receiving an INVITE with no offer, requires provideOffer to be called first (RFC3262-Section 5).");
2177 sendReliably =
true;
2196 DebugLog ( <<
"Sending provisional reliably" );
2197 if (!m1xx->exists(h_Requires) ||
2202 m1xx->header(h_RSeq).value() = ++mLocalRSeq;
2208 resip_assert(!mUnacknowledgedReliableProvisional.get());
2209 mUnacknowledgedReliableProvisional = m1xx;
2210 startRetransmit1xxRelTimer();
2211 startResubmit1xxRelTimer();
2216 if(m1xx->exists(h_RSeq))
2218 m1xx->remove(h_RSeq);
2220 if(m1xx->exists(h_Requires))
2223 for(; it != m1xx->header(h_Requires).
end(); it++)
2227 m1xx->header(h_Requires).erase(it);
2232 startRetransmit1xxTimer();
2235 if (
mDum.mDialogEventStateManager)
2241 return sendReliably;
2245ServerInviteSession::queueResponse(
int code,
bool earlyFlag)
2247 InfoLog (<<
"Response " << code <<
" queued." );
2248 mQueuedResponses.emplace_back(std::make_pair(code, earlyFlag));
2252ServerInviteSession::sendAccept(
int code,
Contents* offerAnswer)
2256 if (offerAnswer && !mAnswerSentReliably )
2259 mAnswerSentReliably =
true;
2261 mCurrentRetransmit1xxSeq++;
2265 if (
mDum.mDialogEventStateManager)
2274ServerInviteSession::sendUpdate(
const Contents& offerAnswer)
#define WarningLog(args_)
#define resip_assert(x)
This file needs to work for both C and C++ code.
EncodeStream & encodeBrief(EncodeStream &strm) const override
output a brief description to stream
ServerInviteSessionAcceptCommand(const ServerInviteSessionHandle &serverInviteSessionHandle, int statusCode)
void executeCommand() override
ServerInviteSessionProvisionalCommand(const ServerInviteSessionHandle &serverInviteSessionHandle, int statusCode, bool earlyFlag)
EncodeStream & encodeBrief(EncodeStream &strm) const override
output a brief description to stream
void executeCommand() override
void executeCommand() override
EncodeStream & encodeBrief(EncodeStream &strm) const override
output a brief description to stream
ServerInviteSessionRedirectCommand(const ServerInviteSessionHandle &serverInviteSessionHandle, const NameAddrs &contacts, int code)
BaseUsageHandle getBaseHandle() const
DialogUsageManager & mDum
Base class for all SIP body types.
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
std::shared_ptr< UserProfile > getUserProfile() const
std::shared_ptr< MasterProfile > & getMasterProfile()
void setAdvertisedCapabilities(SipMessage &msg, const std::shared_ptr< UserProfile > &userProfile)
virtual void send(std::shared_ptr< SipMessage > msg)
dcm! – kill typedef std::list<DialogId> DialogIdSet;
void makeRequest(SipMessage &request, MethodTypes method, bool incrementCSeq=true)
void makeResponse(SipMessage &response, const SipMessage &request, int responseCode)
static void setOutgoingEncryptionLevel(SipMessage &message, DialogUsageManager::EncryptionLevel level)
unsigned int secondarySeq() const
virtual void onOfferRejected(InviteSessionHandle, const SipMessage *msg)=0
called if an offer in a UPDATE or re-INVITE was rejected - not real useful.
virtual void onAnswer(InviteSessionHandle, const SipMessage &msg, const SdpContents &)=0
called when an answer is received - has nothing to do with user answering the call
virtual void onOfferRequired(InviteSessionHandle, const SipMessage &msg)=0
called when an Invite w/out offer is sent, or any other context which requires an offer from the user
virtual void onConnectedConfirmed(InviteSessionHandle, const SipMessage &msg)
called when ACK (with out an answer) is received for initial invite (UAS)
virtual void onPrack(ServerInviteSessionHandle, const SipMessage &msg)
called when PRACK is received for a reliable provisional answer (UAS)
virtual void onTerminated(InviteSessionHandle, InviteSessionHandler::TerminatedReason reason, const SipMessage *related=0)=0
virtual void onOffer(InviteSessionHandle, const SipMessage &msg, const SdpContents &)=0
called when an offer is received - must send an answer soon after this
virtual void onNewSession(ClientInviteSessionHandle, InviteSession::OfferAnswerType oat, const SipMessage &msg)=0
called when an initial INVITE or the intial response to an outoing invite
@ Referred
slg! - This is really Redirected - not sure why it is called Referred. Only gets used when we send a ...
virtual void onConnected(ClientInviteSessionHandle, const SipMessage &msg)=0
called when a dialog initiated as a UAC enters the connected state
Base class for class ClientInviteSession and class ServerInviteSession.
std::unique_ptr< Contents > getOfferAnswer(const SipMessage &msg)
void transition(State target)
void setCurrentLocalOfferAnswer(const SipMessage &msg)
std::shared_ptr< SipMessage > sendBye()
virtual void reject(int statusCode, WarningCategory *warning=0)
Rejects an offer at the SIP level.
std::shared_ptr< SipMessage > mInvite200
std::unique_ptr< Contents > mProposedRemoteOfferAnswer
std::unique_ptr< Contents > mProposedLocalOfferAnswer
std::unique_ptr< Contents > mCurrentLocalOfferAnswer
std::shared_ptr< SipMessage > mLastRemoteSessionModification
std::shared_ptr< SipMessage > mLastLocalSessionModification
virtual void requestOffer()
Called to request that the far end provide an offer.
virtual void end() override
static std::unique_ptr< Contents > makeOfferAnswer(const Contents &offerAnswer)
DialogUsageManager::EncryptionLevel mProposedEncryptionLevel
unsigned long mCurrentRetransmit200
void startRetransmit200Timer()
void storePeerCapabilities(const SipMessage &msg)
InviteSessionHandle getSessionHandle()
virtual void provideAnswer(const Contents &answer)
Similar to provideOffer - called to set the answer to be signaled to the peer.
void dispatchMessage(const SipMessage &msg)
@ UAS_ReceivedUpdateWaitingAnswer
@ UAS_WaitingToRequestOffer
@ UAS_FirstSentOfferReliable
@ UAS_NoAnswerReliableWaitingPrack
@ UAS_FirstSentAnswerReliable
@ UAS_ProvidedOfferReliable
@ UAS_OfferProvidedAnswer
@ UAS_OfferReliableProvidedAnswer
@ UAS_AcceptedWaitingAnswer
@ UAS_EarlyProvidedAnswer
bool updateMethodSupported() const
static void setOfferAnswer(SipMessage &msg, const Contents &offerAnswer, const Contents *alternative=0)
std::unique_ptr< Contents > mCurrentRemoteOfferAnswer
void dispatchInfo(const SipMessage &msg)
void dispatch(const SipMessage &msg) override
Event toEvent(const SipMessage &msg, const Contents *offeranswer)
void handleSessionTimerRequest(SipMessage &response, const SipMessage &request)
bool isTerminated() const
DialogUsageManager::EncryptionLevel getEncryptionLevel(const SipMessage &msg)
void provideProposedOffer()
virtual void provideOffer(const Contents &offer)
Called to set the offer that will be used in the next message that sends an offer.
static Data toData(State state)
ParserContainer< Token > mUserEndReasons
DialogUsageManager::EncryptionLevel mCurrentEncryptionLevel
virtual Brief brief() const
return a facet for brief encoding of message
An iterator class (bidirectional)
static int getRandom()
Returns a postive integer (31 bits) of randomness.
void redirect(const NameAddrs &contacts, int code=302)
send a 3xx
void redirectCommand(const NameAddrs &contacts, int code=302)
Provide asynchronous method access by using command.
virtual void reject(int statusCode, WarningCategory *warning=0)
Rejects an offer at the SIP level.
void accept(int statusCode=200)
accept an initial invite (2xx) - this is only applicable to the UAS
virtual void provideAnswer(const Contents &answer)
Similar to provideOffer - called to set the answer to be signaled to the peer.
ServerInviteSession(const ServerInviteSession &)=delete
void acceptCommand(int statusCode=200)
virtual void provideOffer(const Contents &offer)
Called to set the offer that will be used in the next message that sends an offer.
virtual void requestOffer()
Called to request that the far end provide an offer.
void provisionalCommand(int code=180, bool earlyFlag=true)
void provisional(int code=180, bool earlyFlag=true)
send a 1xx - provisional response.
Handle< ServerInviteSession > ServerInviteSessionHandle
ServerInviteSessionHandle getHandle()
Represents a SIP message.
bool isRequest() const
Returns true if message is a request, false otherwise.
const RequestLine & header(const RequestLineType &l) const
Returns the RequestLine. This is only valid for request messages.
bool exists(const HeaderBase &headerType) const
Returns true if the given header field is present, false otherwise.
static const char * C100rel
Represents the "token" element in the RFC 3261 grammar.
void post(Message *msg)
Posts a Message to this TransactionUser's fifo.
Represents the "warning-value" element in the RFC 3261 grammar.
This file is used to handle compatibility fixes/tweaks so reSIProcate can function on multiple platfo...
dcm! – add UnusedChecking(_enum) below;
StatusLineType h_StatusLine
RequestLineType h_RequestLine