reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
InviteSession.hxx
Go to the documentation of this file.
1#if !defined(RESIP_INVITESESSION_HXX)
2#define RESIP_INVITESESSION_HXX
3
8
9#include <map>
10#include <memory>
11#include <queue>
12#include <utility>
13
14namespace resip
15{
16
17class Contents;
18class SdpContents;
19
25{
26 public:
27 InviteSession(const InviteSession&) = delete;
29
32
37 virtual void provideOffer(const Contents& offer);
38 virtual void provideOffer(const Contents& offer, DialogUsageManager::EncryptionLevel level, const Contents* alternative);
39
43 virtual void provideAnswer(const Contents& answer);
44
47 virtual void requestOffer();
48
49 typedef enum
50 {
51 None, // means no Offer or Answer (may have body)
53 Answer
55
56 // WARNING: Do not change this list without appropriately adjusting the
57 // EndReasons array in InviteSession.cxx
59 {
67 ENDREASON_MAX, // Maximum used by the global array in InviteSession.cxx
68 UserSpecified // User-specified reason - doesn't use the array in InviteSession.cxx
69 };
70
72 virtual void end(const Data& userReason);
73 virtual void end(const ParserContainer<Token>& endReasons);
74 virtual void end(EndReason reason);
75 virtual void end() override; // reason == NotSpecified ; same as above - required for BaseUsage pure virtual
76
79 virtual void reject(int statusCode, WarningCategory *warning = 0);
80 virtual void reject(int statusCode, const Contents* contents, WarningCategory *warning = 0);
81
84 virtual void targetRefresh(const NameAddr& localUri);
85
86 // Following methods are for sending requests within a dialog
87
89 virtual void refer(const NameAddr& referTo, bool referSub = true);
90 virtual void refer(const NameAddr& referTo, const NameAddr& referredBy, bool referSub = true);
91 virtual void refer(const NameAddr& referTo, std::unique_ptr<resip::Contents> contents, bool referSub = true);
92 virtual void refer(const NameAddr& referTo, const NameAddr& referredBy, std::unique_ptr<resip::Contents> contents, bool referSub = true);
93
95 virtual void refer(const NameAddr& referTo, InviteSessionHandle sessionToReplace, bool referSub = true);
96 virtual void refer(const NameAddr& referTo, InviteSessionHandle sessionToReplace, std::unique_ptr<resip::Contents> contents, bool referSub = true);
97 virtual void refer(const NameAddr& referTo, const CallId& replaces, bool referSub = true);
98 virtual void refer(const NameAddr& referTo, const CallId& replaces, std::unique_ptr<resip::Contents> contents, bool referSub = true);
99
101 virtual void info(const Contents& contents);
102
113 virtual void message(const Contents& contents);
114
116 virtual void acceptNIT(int statusCode = 200, const Contents * contents = 0);
117
119 virtual void rejectNIT(int statusCode = 488);
120
125 std::shared_ptr<SipMessage> getLastSentNITRequest() const;
126
130 virtual void provideOfferCommand(const Contents& offer);
131 virtual void provideOfferCommand(const Contents& offer, DialogUsageManager::EncryptionLevel level, const Contents* alternative);
132 virtual void provideAnswerCommand(const Contents& answer);
134 virtual void endCommand(EndReason reason = NotSpecified);
135 virtual void endCommand(const Data& userReason);
136 virtual void endCommand(const resip::ParserContainer<resip::Token>& endReasons);
139 virtual void rejectCommand(int statusCode, WarningCategory *warning = 0);
140 virtual void rejectCommand(int statusCode, const Contents* contents, WarningCategory *warning = 0);
141 virtual void referCommand(const NameAddr& referTo, bool referSub = true);
142 virtual void referCommand(const NameAddr& referTo, InviteSessionHandle sessionToReplace, bool referSub = true);
143 virtual void infoCommand(const Contents& contents);
144 virtual void messageCommand(const Contents& contents);
146 virtual void acceptNITCommand(int statusCode = 200, const Contents * contents = 0);
148 virtual void rejectNITCommand(int statusCode = 488);
149
150 virtual void acceptReferNoSub(int statusCode = 200);
151 virtual void rejectReferNoSub(int responseCode);
152
153 bool hasLocalOfferAnswer() const;
154 const Contents& getLocalOfferAnswer() const;
155 bool hasRemoteOfferAnswer() const;
156 const Contents& getRemoteOfferAnswer() const;
157 bool hasProposedRemoteOfferAnswer() const;
159
160 // Note: The following fn's are for backwards compatibility and are only valid to call
161 // if the InviteSessionHandler is not in Generic mode (ie.
162 // InviteSessionHandler::isGenericOfferAnswer is false)
163 bool hasLocalSdp() const;
164 const SdpContents& getLocalSdp() const;
165 bool hasRemoteSdp() const;
166 const SdpContents& getRemoteSdp() const;
167 bool hasProposedRemoteSdp() const;
168 const SdpContents& getProposedRemoteSdp() const;
169
170 bool isConnected() const;
171 bool isSessionModificationInFlight() const; // we have sent an UPDATE/OPTIONS/reINVITE that hasn't been answered yet
172 bool isTerminated() const;
173 bool isEarly() const; // UAC Early states
174 bool isAccepted() const; // UAS States after accept is called
175
185
186 EncodeStream& dump(EncodeStream& strm) const override;
188
189 protected:
190
191 typedef enum
192 {
193 Undefined, // Not used
195 SentUpdate, // Sent an UPDATE
196 SentUpdateGlare, // got a 491
197 SentReinvite, // Sent a reINVITE
198 SentReinviteGlare, // Got a 491
199 SentReinviteNoOffer, // Sent a reINVITE with no offer (requestOffer)
200 SentReinviteAnswered, // Sent a reINVITE no offer and received a 200-offer
202 SentOptions, // Sent an OPTIONS
203 SentOptionsGlare, // Got a 491
204 ReceivedUpdate, // Received an UPDATE
205 ReceivedReinvite, // Received a reINVITE
206 ReceivedReinviteNoOffer, // Received a reINVITE with no offer
207 ReceivedReinviteSentOffer, // Sent a 200 to a reINVITE with no offer
211 WaitingToTerminate, // Waiting for 2xx response before sending BYE
212 WaitingToHangup, // Waiting for ACK before sending BYE
213 Terminated, // Ended. waiting to delete
214
226
232
240
257 // !!!!WARNING!!!! when adding new UAS state - make sure you check if they
258 // need to be added to the isAccepted method
260
300
301 typedef enum
302 {
306
308 virtual ~InviteSession();
309 virtual void onReadyToSend(SipMessage& msg) override;
310 virtual void flowTerminated();
311
312 void dispatch(const SipMessage& msg) override;
313 void dispatch(const DumTimeout& timer) override;
314
315 // Utility methods (one for each State)
316 void dispatchConnected(const SipMessage& msg);
317 void dispatchSentUpdate(const SipMessage& msg);
318 void dispatchSentReinvite(const SipMessage& msg);
321 void dispatchGlare(const SipMessage& msg);
322 void dispatchSentOptions(const SipMessage& msg);
326 void dispatchAnswered(const SipMessage& msg);
327 void dispatchWaitingToOffer(const SipMessage& msg);
329 void dispatchWaitingToTerminate(const SipMessage& msg);
330 void dispatchWaitingToHangup(const SipMessage& msg);
331 void dispatchTerminated(const SipMessage& msg);
332 void dispatchBye(const SipMessage& msg);
333 void dispatchInfo(const SipMessage& msg);
334 void dispatchMessage(const SipMessage& msg);
335 void dispatchOptions(const SipMessage& msg);
336
337 // True iff the supplied message is an ACK, a 2xx (INVITE) retransmission
338 // is currently outstanding (mInvite200 / mCurrentRetransmit200), and the
339 // ACK acknowledges that 2xx. Correlates on the CSeq sequence number
340 // (RFC 3261 13.2.2.4); robust under re-INVITE glare and a peer that
341 // re-uses the in-dialog CSeq.
342 bool isAckForCurrent200(const SipMessage& ack) const;
343
345 void start491Timer();
347
349 void sessionRefresh();
353 void startSessionTimer();
354 void handleSessionTimerResponse(const SipMessage& msg);
355 void handleSessionTimerRequest(SipMessage &response, const SipMessage& request);
356
357 static Data toData(State state);
358 void transition(State target);
359
360 std::unique_ptr<Contents> getOfferAnswer(const SipMessage& msg);
361 bool isReliable(const SipMessage& msg) const;
362 static std::unique_ptr<Contents> makeOfferAnswer(const Contents& offerAnswer);
363 static std::unique_ptr<Contents> makeOfferAnswer(const Contents& offerAnswer, const Contents* alternative);
364 static void setOfferAnswer(SipMessage& msg, const Contents& offerAnswer, const Contents* alternative = 0);
365 static void setOfferAnswer(SipMessage& msg, const Contents* offerAnswer);
367
368 void storePeerCapabilities(const SipMessage& msg);
369 bool updateMethodSupported() const;
371
372 std::shared_ptr<SipMessage> sendAck(const Contents *answer=0);
373 std::shared_ptr<SipMessage> sendBye();
374
376
378 void setCurrentLocalOfferAnswer(const SipMessage& msg);
379 void referNoSub(const SipMessage& msg);
380
391
392 Event toEvent(const SipMessage& msg, const Contents* offeranswer);
393
397
398 std::unique_ptr<Contents> mCurrentLocalOfferAnswer; // This gets set with mProposedLocalOfferAnswer after we receive an SDP answer from the remote end or when we send and SDP answer to the remote end
399 std::unique_ptr<Contents> mProposedLocalOfferAnswer; // This get set when we send an offer to the remote end
400
401 std::unique_ptr<Contents> mCurrentRemoteOfferAnswer; // This gets set with mProposedRemoteOfferAnswer after we send an SDP answer, or when we receive an SDP answer from the remote end
402 std::unique_ptr<Contents> mProposedRemoteOfferAnswer; // This gets set when we receive an offer from the remote end
403
404 std::shared_ptr<SipMessage> mLastLocalSessionModification; // last UPDATE or reINVITE sent
405 std::shared_ptr<SipMessage> mLastRemoteSessionModification; // last UPDATE or reINVITE received
406 std::shared_ptr<SipMessage> mInvite200; // 200 OK for reINVITE for retransmissions
407 std::shared_ptr<SipMessage> mLastNitResponse;
408
410
413
414 // Session Timer settings
421 bool mSessionExpirationPending; // Session-Expiration timer fired while a session modification was in flight
422
424 {
425 public:
426 QueuedNIT(std::shared_ptr<SipMessage> NIT, bool referSub=false)
427 : mNIT(NIT), mReferSubscription(referSub) {}
428 std::shared_ptr<SipMessage>& getNIT() { return mNIT; }
429 bool referSubscription() { return mReferSubscription; }
430 private:
431 std::shared_ptr<SipMessage> mNIT;
432 bool mReferSubscription;
433 };
434 std::queue<QueuedNIT*> mNITQueue;
435 void nitComplete();
437 std::shared_ptr<SipMessage> mLastSentNITRequest;
438
441
443
444 // Used when a user-specified EndReason is needed
446 ParserContainer<Token> mUserEndReasons; // This is used if set, otherwise mUserEndReason is used, if set
447
448 // Used to respond to 2xx retransmissions.
449 typedef HashMap<Data, std::shared_ptr<SipMessage>> AckMap;
451
452 private:
453 friend class Dialog;
454 friend class DialogUsageManager;
455
456 // Utility methods for handling particular methods
457 void dispatchOthers(const SipMessage& msg);
458 void dispatchUnhandledInvite(const SipMessage& msg);
459 void dispatchPrack(const SipMessage& msg);
460 void dispatchCancel(const SipMessage& msg);
461};
462
463}
464
465#endif
466
467/* ====================================================================
468 * The Vovida Software License, Version 1.0
469 *
470 * Copyright (c) 2026 SIP Spectrum, Inc. https://www.sipspectrum.com
471 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
472 *
473 * Redistribution and use in source and binary forms, with or without
474 * modification, are permitted provided that the following conditions
475 * are met:
476 *
477 * 1. Redistributions of source code must retain the above copyright
478 * notice, this list of conditions and the following disclaimer.
479 *
480 * 2. Redistributions in binary form must reproduce the above copyright
481 * notice, this list of conditions and the following disclaimer in
482 * the documentation and/or other materials provided with the
483 * distribution.
484 *
485 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
486 * and "Vovida Open Communication Application Library (VOCAL)" must
487 * not be used to endorse or promote products derived from this
488 * software without prior written permission. For written
489 * permission, please contact vocal@vovida.org.
490 *
491 * 4. Products derived from this software may not be called "VOCAL", nor
492 * may "VOCAL" appear in their name, without prior written
493 * permission of Vovida Networks, Inc.
494 *
495 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
496 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
497 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
498 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
499 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
500 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
501 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
502 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
503 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
504 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
505 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
506 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
507 * DAMAGE.
508 *
509 * ====================================================================
510 *
511 * This software consists of voluntary contributions made by Vovida
512 * Networks, Inc. and many individuals on behalf of Vovida Networks,
513 * Inc. For more information on Vovida Networks, Inc., please see
514 * <http://www.vovida.org/>.
515 *
516 */
517
518
519
520
Represents the "callid" element in the SIP grammar.
Definition CallId.hxx:18
Base class for all SIP body types.
Definition Contents.hxx:51
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
dcm! – kill typedef std::list<DialogId> DialogIdSet;
Definition Dialog.hxx:29
std::shared_ptr< SipMessage > & getNIT()
QueuedNIT(std::shared_ptr< SipMessage > NIT, bool referSub=false)
Base class for class ClientInviteSession and class ServerInviteSession.
virtual void flowTerminated()
std::unique_ptr< Contents > getOfferAnswer(const SipMessage &msg)
virtual void message(const Contents &contents)
sends a message request
const SdpContents & getLocalSdp() const
bool hasLocalOfferAnswer() const
virtual void infoCommand(const Contents &contents)
Tokens & getPeerSupportedEncodings()
std::shared_ptr< SipMessage > mLastNitResponse
bool hasProposedRemoteOfferAnswer() const
void dispatchOptions(const SipMessage &msg)
void dispatchSentReinvite(const SipMessage &msg)
void dispatchSentOptions(const SipMessage &msg)
InviteSession & operator=(const InviteSession &)=delete
Tokens & getPeerRequiresOptionsTags()
virtual void referCommand(const NameAddr &referTo, bool referSub=true)
const SdpContents & getRemoteSdp() const
bool hasProposedRemoteSdp() const
void transition(State target)
bool isSessionModificationInFlight() const
void dispatchTerminated(const SipMessage &msg)
void setCurrentLocalOfferAnswer(const SipMessage &msg)
virtual void rejectReferNoSub(int responseCode)
std::shared_ptr< SipMessage > mLastSentNITRequest
virtual void endCommand(EndReason reason=NotSpecified)
Asynchronously makes the specific dialog end.
Tokens & getPeerSupportedMethods()
bool expireSessionAfterFailedModification()
EncodeStream & dump(EncodeStream &strm) const override
std::shared_ptr< SipMessage > sendBye()
virtual void rejectNIT(int statusCode=488)
rejects an INFO or MESSAGE request with an error status code
virtual void reject(int statusCode, WarningCategory *warning=0)
Rejects an offer at the SIP level.
void dispatchSentUpdate(const SipMessage &msg)
virtual void provideAnswerCommand(const Contents &answer)
std::shared_ptr< SipMessage > getLastSentNITRequest() const
gets the last NIT request that was sent by the session
const Contents & getProposedRemoteOfferAnswer() const
Tokens & getPeerAllowedEvents()
NameAddrs mPeerPAssertedIdentities
void dispatchReceivedUpdateOrReinvite(const SipMessage &msg)
const Data & getEndReasonString(InviteSession::EndReason reason)
std::shared_ptr< SipMessage > mInvite200
void dispatchSentReinviteNoOffer(const SipMessage &msg)
unsigned int mSessionExpirationTimerSeq
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
bool sessionTimerSupportedLocalAndPeer() const
InviteSession(InviteSession &&)=delete
SipMessage mLastReferNoSubRequest
unsigned int mStaleReInviteTimerSeq
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
bool hasRemoteOfferAnswer() const
std::queue< QueuedNIT * > mNITQueue
virtual void refer(const NameAddr &referTo, bool referSub=true)
sends a refer request
void setSessionTimerHeaders(SipMessage &msg)
void dispatchSentReinviteAnswered(const SipMessage &msg)
void storePeerCapabilities(const SipMessage &msg)
void dispatchGlare(const SipMessage &msg)
HashMap< Data, std::shared_ptr< SipMessage > > AckMap
virtual void provideOfferCommand(const Contents &offer)
Provide asynchronous method access by using command.
void dispatchConnected(const SipMessage &msg)
void dispatchReceivedReinviteSentOffer(const SipMessage &msg)
virtual void acceptNIT(int statusCode=200, const Contents *contents=0)
accepts an INFO or MESSAGE request with a 2xx and an optional contents
InviteSession(const InviteSession &)=delete
virtual void onReadyToSend(SipMessage &msg) override
virtual void rejectNITCommand(int statusCode=488)
Asynchronously rejects an INFO or MESSAGE request with an error status code.
InviteSessionHandle getSessionHandle()
virtual void provideAnswer(const Contents &answer)
Similar to provideOffer - called to set the answer to be signaled to the peer.
void dispatchWaitingToOffer(const SipMessage &msg)
virtual void rejectCommand(int statusCode, WarningCategory *warning=0)
Asynchronously rejects an offer at the SIP level.
void handleSessionTimerResponse(const SipMessage &msg)
virtual void targetRefresh(const NameAddr &localUri)
will send a reINVITE (current offerAnswer) or UPDATE with new Contact header
virtual void info(const Contents &contents)
sends an info request
void dispatchMessage(const SipMessage &msg)
void dispatchWaitingToRequestOffer(const SipMessage &msg)
unsigned int mSessionRefreshTimerSeq
bool updateMethodSupported() const
const SdpContents & getProposedRemoteSdp() const
void referNoSub(const SipMessage &msg)
const Contents & getRemoteOfferAnswer() const
static void setOfferAnswer(SipMessage &msg, const Contents &offerAnswer, const Contents *alternative=0)
void dispatchWaitingToHangup(const SipMessage &msg)
std::unique_ptr< Contents > mCurrentRemoteOfferAnswer
Tokens & getPeerSupportedOptionTags()
void dispatchInfo(const SipMessage &msg)
void dispatch(const SipMessage &msg) override
Event toEvent(const SipMessage &msg, const Contents *offeranswer)
bool isAckForCurrent200(const SipMessage &ack) const
virtual void acceptNITCommand(int statusCode=200, const Contents *contents=0)
Asynchronously accepts an INFO or MESSAGE request with a 2xx and an optional contents.
virtual void acceptReferNoSub(int statusCode=200)
void dispatchBye(const SipMessage &msg)
void handleSessionTimerRequest(SipMessage &response, const SipMessage &request)
InviteSession & operator=(InviteSession &&)=delete
Mimes & getPeerSupportedMimeTypes()
const Contents & getLocalOfferAnswer() const
void dispatchWaitingToTerminate(const SipMessage &msg)
DialogUsageManager::EncryptionLevel getEncryptionLevel(const SipMessage &msg)
bool isReliable(const SipMessage &msg) const
virtual void messageCommand(const Contents &contents)
Tokens & getPeerSupportedLanguages()
void dispatchReinviteNoOfferGlare(const SipMessage &msg)
NameAddrs & getPeerPAssertedIdentities()
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)
std::shared_ptr< SipMessage > sendAck(const Contents *answer=0)
ParserContainer< Token > mUserEndReasons
void dispatchAnswered(const SipMessage &msg)
DialogUsageManager::EncryptionLevel mCurrentEncryptionLevel
Represents the "name-addr" and the "addr-spec" elements in the RFC 3261 grammar.
Definition NameAddr.hxx:19
Container class for ParserCategory, used by SipMessage to represent multi-valued headers (Contact,...
Provides an interface to process and generate SDP bodies (MIME content-type application/sdp).
Represents a SIP message.
Represents the "warning-value" element in the RFC 3261 grammar.
dcm! – add UnusedChecking(_enum) below;
unsigned int uint32_t
Definition Stun.hxx:34
#define EncodeStream