/[resiprocate]/main/resip/dum/InviteSession.hxx
ViewVC logotype

Contents of /main/resip/dum/InviteSession.hxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10695 - (show annotations) (download)
Fri Nov 22 23:12:34 2013 UTC (5 years, 11 months ago) by sgodin
File MIME type: text/plain
File size: 19896 byte(s)
-Merged from b-uasprack-20130904
  -added UAS Prack support to DUM!  Original implementation taken from b-uasprack-20091103
  -many changes, fixes and enhancements from original branch
  -MasterProfile setting setUasReliableProvisionalMode is used to enable
  -added mode called SupportedEssential where we will send reliable provisionals only if they
   are a provisional that is carrying an offer or answer  - required for 3GPP IMS flows 
  -added resubmit timer for reliable responses to ensure we send a reliable provisional at least 
   every 2.5 minutes  -new profile setting: set1xxRelResubmitTime to support this
  -updated state diagrams and added new PRACK flow diagrams to dum/doc directory (removed old diagrams)
  -fixed update glare handling for UAC prack 
  -added in support for UAC Prack to be able to send an offer in the first PRACK response 
  (must call provideOffer from onAnswer callback)
  -made a helper method on DialogUsageManager to set advertised capabilities 
  -fixed missing break in ClientInviteSession::dispatchReceivedUpdateEarly 
  

  
  
1 #if !defined(RESIP_INVITESESSION_HXX)
2 #define RESIP_INVITESESSION_HXX
3
4 #include "resip/stack/SipMessage.hxx"
5 #include "resip/stack/Contents.hxx"
6 #include "resip/dum/DialogUsage.hxx"
7 #include "resip/dum/DialogUsageManager.hxx"
8
9 #include <map>
10 #include <queue>
11
12 namespace resip
13 {
14
15 class Contents;
16 class SdpContents;
17
18 /** Base class for class ClientInviteSession and class ServerInviteSession.
19 Implements common attributes and behavior (i.e.t post connected) of the two
20 classes.
21 */
22 class InviteSession : public DialogUsage
23 {
24 public:
25 /** Called to set the offer that will be used in the next message that
26 sends an offer. If possible, this will synchronously send the
27 appropriate request or response. In some cases, the UAS might have to
28 call accept in order to cause the message to be sent. */
29 virtual void provideOffer(const Contents& offer);
30 virtual void provideOffer(const Contents& offer, DialogUsageManager::EncryptionLevel level, const Contents* alternative);
31
32 /** Similar to provideOffer - called to set the answer to be signalled to
33 the peer. May result in message being sent synchronously depending on
34 the state. */
35 virtual void provideAnswer(const Contents& answer);
36
37 /** Called to request that the far end provide an offer. This will cause a
38 reinvite with no body to be sent. */
39 virtual void requestOffer();
40
41 typedef enum
42 {
43 None, // means no Offer or Answer (may have body)
44 Offer,
45 Answer
46 } OfferAnswerType;
47
48 // WARNING: Do not change this list without appropriately adjusting the
49 // EndReasons array in InviteSession.cxx
50 enum EndReason
51 {
52 NotSpecified=0,
53 UserHangup,
54 AppRejectedSdp,
55 IllegalNegotiation,
56 AckNotReceived,
57 SessionExpired,
58 StaleReInvite,
59 ENDREASON_MAX, // Maximum used by the global array in InviteSession.cxx
60 UserSpecified // User-specified reason - doesn't use the array in InviteSession.cxx
61 };
62
63 /** Makes the specific dialog end. Will send a BYE (not a CANCEL) */
64 virtual void end(const Data& userReason);
65 virtual void end(EndReason reason);
66 virtual void end(); // reason == NotSpecified ; same as above - required for BaseUsage pure virtual
67
68 /** Rejects an offer at the SIP level. Can also be used to
69 send a 488 to a reINVITE or UPDATE */
70 virtual void reject(int statusCode, WarningCategory *warning = 0);
71
72 /** will send a reINVITE (current offerAnswer) or UPDATE with new Contact header */
73 virtual void targetRefresh(const NameAddr& localUri);
74
75 // Following methods are for sending requests within a dialog
76
77 /** sends a refer request */
78 virtual void refer(const NameAddr& referTo, bool referSub = true);
79 virtual void refer(const NameAddr& referTo, std::auto_ptr<resip::Contents> contents, bool referSub = true);
80
81 /** sends a refer request with a replaces header */
82 virtual void refer(const NameAddr& referTo, InviteSessionHandle sessionToReplace, bool referSub = true);
83 virtual void refer(const NameAddr& referTo, InviteSessionHandle sessionToReplace, std::auto_ptr<resip::Contents> contents, bool referSub = true);
84 virtual void refer(const NameAddr& referTo, const CallId& replaces, bool referSub = true);
85 virtual void refer(const NameAddr& referTo, const CallId& replaces, std::auto_ptr<resip::Contents> contents, bool referSub = true);
86
87 /** sends an info request */
88 virtual void info(const Contents& contents);
89
90 /** sends a message request
91
92 @warning From RFC3428 - The authors recognize that there may be valid reasons to
93 send MESSAGE requests in the context of a dialog. For
94 example, one participant in a voice session may wish to
95 send an IM to another participant, and associate that IM
96 with the session. But implementations SHOULD NOT create
97 dialogs for the primary purpose of associating MESSAGE
98 requests with one another.
99 */
100 virtual void message(const Contents& contents);
101
102 /** accepts an INFO or MESSAGE request with a 2xx and an optional contents */
103 virtual void acceptNIT(int statusCode = 200, const Contents * contents = 0);
104
105 /** rejects an INFO or MESSAGE request with an error status code */
106 virtual void rejectNIT(int statusCode = 488);
107
108 /** gets the last NIT request that was sent by the session
109
110 @warning Can return a NULL SharedPtr if none was sent
111 */
112 const SharedPtr<SipMessage> getLastSentNITRequest() const;
113
114 /**
115 * Provide asynchronous method access by using command
116 */
117 virtual void provideOfferCommand(const Contents& offer);
118 virtual void provideOfferCommand(const Contents& offer, DialogUsageManager::EncryptionLevel level, const Contents* alternative);
119 virtual void provideAnswerCommand(const Contents& answer);
120 /** Asynchronously makes the specific dialog end. Will send a BYE (not a CANCEL) */
121 virtual void endCommand(EndReason reason = NotSpecified);
122 /** Asynchronously rejects an offer at the SIP level. Can also be used to
123 send a 488 to a reINVITE or UPDATE */
124 virtual void rejectCommand(int statusCode, WarningCategory *warning = 0);
125 virtual void referCommand(const NameAddr& referTo, bool referSub = true);
126 virtual void referCommand(const NameAddr& referTo, InviteSessionHandle sessionToReplace, bool referSub = true);
127 virtual void infoCommand(const Contents& contents);
128 virtual void messageCommand(const Contents& contents);
129 /** Asynchronously accepts an INFO or MESSAGE request with a 2xx and an optional contents */
130 virtual void acceptNITCommand(int statusCode = 200, const Contents * contents = 0);
131 /** Asynchronously rejects an INFO or MESSAGE request with an error status code */
132 virtual void rejectNITCommand(int statusCode = 488);
133
134 virtual void acceptReferNoSub(int statusCode = 200);
135 virtual void rejectReferNoSub(int responseCode);
136
137 bool hasLocalOfferAnswer() const;
138 const Contents& getLocalOfferAnswer() const;
139 bool hasRemoteOfferAnswer() const;
140 const Contents& getRemoteOfferAnswer() const;
141 bool hasProposedRemoteOfferAnswer() const;
142 const Contents& getProposedRemoteOfferAnswer() const;
143
144 // Note: The following fn's are for backwards compatibility and are only valid to call
145 // if the InviteSessionHandler is not in Generic mode (ie.
146 // InviteSessionHandler::isGenericOfferAnswer is false)
147 bool hasLocalSdp() const;
148 const SdpContents& getLocalSdp() const;
149 bool hasRemoteSdp() const;
150 const SdpContents& getRemoteSdp() const;
151 bool hasProposedRemoteSdp() const;
152 const SdpContents& getProposedRemoteSdp() const;
153
154 bool isConnected() const;
155 bool isTerminated() const;
156 bool isEarly() const; // UAC Early states
157 bool isAccepted() const; // UAS States after accept is called
158
159 Tokens& getPeerSupportedMethods() { return mPeerSupportedMethods; }
160 Tokens& getPeerSupportedOptionTags() { return mPeerSupportedOptionTags; }
161 Mimes& getPeerSupportedMimeTypes() { return mPeerSupportedMimeTypes; }
162 Tokens& getPeerSupportedEncodings() { return mPeerSupportedEncodings; }
163 Tokens& getPeerSupportedLanguages() { return mPeerSupportedLanguages; }
164 Tokens& getPeerAllowedEvents() { return mPeerAllowedEvents; }
165 Data& getPeerUserAgent() { return mPeerUserAgent; }
166 NameAddrs& getPeerPAssertedIdentities() { return mPeerPAssertedIdentities; }
167
168 virtual EncodeStream& dump(EncodeStream& strm) const;
169 InviteSessionHandle getSessionHandle();
170
171 protected:
172
173 typedef enum
174 {
175 Undefined, // Not used
176 Connected,
177 SentUpdate, // Sent an UPDATE
178 SentUpdateGlare, // got a 491
179 SentReinvite, // Sent a reINVITE
180 SentReinviteGlare, // Got a 491
181 SentReinviteNoOffer, // Sent a reINVITE with no offer (requestOffer)
182 SentReinviteAnswered, // Sent a reINVITE no offer and received a 200-offer
183 SentReinviteNoOfferGlare, // Got a 491
184 ReceivedUpdate, // Received an UPDATE
185 ReceivedReinvite, // Received a reINVITE
186 ReceivedReinviteNoOffer, // Received a reINVITE with no offer
187 ReceivedReinviteSentOffer, // Sent a 200 to a reINVITE with no offer
188 Answered,
189 WaitingToOffer,
190 WaitingToRequestOffer,
191 WaitingToTerminate, // Waiting for 2xx response before sending BYE
192 WaitingToHangup, // Waiting for ACK before sending BYE
193 Terminated, // Ended. waiting to delete
194
195 UAC_Start,
196 UAC_Early,
197 UAC_EarlyWithOffer,
198 UAC_EarlyWithAnswer,
199 UAC_Answered,
200 UAC_SentUpdateEarly,
201 UAC_SentUpdateEarlyGlare,
202 UAC_ReceivedUpdateEarly,
203 UAC_SentAnswer,
204 UAC_QueuedUpdate,
205 UAC_Cancelled,
206
207 UAS_Start,
208 UAS_Offer,
209 UAS_OfferProvidedAnswer,
210 UAS_EarlyOffer,
211 UAS_EarlyProvidedAnswer,
212
213 UAS_NoOffer,
214 UAS_ProvidedOffer,
215 UAS_EarlyNoOffer,
216 UAS_EarlyProvidedOffer,
217 UAS_Accepted,
218 UAS_WaitingToOffer,
219 UAS_WaitingToRequestOffer,
220
221 UAS_AcceptedWaitingAnswer,
222 UAS_OfferReliable,
223 UAS_OfferReliableProvidedAnswer,
224 UAS_NoOfferReliable,
225 UAS_ProvidedOfferReliable,
226 UAS_FirstSentOfferReliable,
227 UAS_FirstSentAnswerReliable,
228 UAS_NoAnswerReliableWaitingPrack,
229 UAS_NegotiatedReliable,
230 UAS_NoAnswerReliable,
231 UAS_SentUpdate,
232 UAS_SentUpdateAccepted,
233 UAS_SentUpdateGlare,
234 UAS_ReceivedUpdate,
235 UAS_ReceivedUpdateWaitingAnswer,
236 UAS_WaitingToHangup
237 // !!!!WARNING!!!! when adding new UAS state - make sure you check if they
238 // need to be added to the isAccepted method
239 } State;
240
241 typedef enum
242 {
243 OnRedirect, // 3xx
244 OnGeneralFailure, // 481 or 408
245 OnInvite, // UAS
246 OnInviteOffer,// UAS
247 OnInviteReliableOffer, // UAS
248 OnInviteReliable, // UAS
249 OnCancel, // UAS
250 OnBye,
251 On200Bye,
252 On1xx, // UAC
253 On1xxEarly, // UAC
254 On1xxOffer, // UAC
255 On1xxAnswer, // UAC
256 On2xx,
257 On2xxOffer,
258 On2xxAnswer,
259 On422Invite,
260 On487Invite,
261 On491Invite,
262 OnInviteFailure,
263 OnAck,
264 OnAckAnswer,
265 On200Cancel, // UAC
266 OnCancelFailure, // UAC
267 OnUpdate,
268 OnUpdateOffer,
269 OnUpdateRejected,
270 On422Update,
271 On491Update,
272 On200Update,
273 OnPrack, // UAS
274 On200Prack, // UAC
275 Unknown
276 } Event;
277
278 typedef enum
279 {
280 NitComplete,
281 NitProceeding
282 } NitState;
283
284 InviteSession(DialogUsageManager& dum, Dialog& dialog);
285 virtual ~InviteSession();
286 virtual void dialogDestroyed(const SipMessage& msg);
287 virtual void onReadyToSend(SipMessage& msg);
288 virtual void flowTerminated();
289
290 virtual void dispatch(const SipMessage& msg);
291 virtual void dispatch(const DumTimeout& timer);
292
293 // Utility methods (one for each State)
294 void dispatchConnected(const SipMessage& msg);
295 void dispatchSentUpdate(const SipMessage& msg);
296 void dispatchSentReinvite(const SipMessage& msg);
297 void dispatchSentReinviteNoOffer(const SipMessage& msg);
298 void dispatchSentReinviteAnswered(const SipMessage& msg);
299 void dispatchGlare(const SipMessage& msg);
300 void dispatchReinviteNoOfferGlare(const SipMessage& msg);
301 void dispatchReceivedUpdateOrReinvite(const SipMessage& msg);
302 void dispatchReceivedReinviteSentOffer(const SipMessage& msg);
303 void dispatchAnswered(const SipMessage& msg);
304 void dispatchWaitingToOffer(const SipMessage& msg);
305 void dispatchWaitingToRequestOffer(const SipMessage& msg);
306 void dispatchWaitingToTerminate(const SipMessage& msg);
307 void dispatchWaitingToHangup(const SipMessage& msg);
308 void dispatchTerminated(const SipMessage& msg);
309 void dispatchBye(const SipMessage& msg);
310 void dispatchInfo(const SipMessage& msg);
311 void dispatchMessage(const SipMessage& msg);
312
313 void startRetransmit200Timer();
314 void start491Timer();
315 void startStaleReInviteTimer();
316
317 void setSessionTimerHeaders(SipMessage& msg);
318 void sessionRefresh();
319 void setSessionTimerPreferences();
320 void startSessionTimer();
321 void handleSessionTimerResponse(const SipMessage& msg);
322 void handleSessionTimerRequest(SipMessage &response, const SipMessage& request);
323
324 static Data toData(State state);
325 void transition(State target);
326
327 std::auto_ptr<Contents> getOfferAnswer(const SipMessage& msg);
328 bool isReliable(const SipMessage& msg) const;
329 static std::auto_ptr<Contents> makeOfferAnswer(const Contents& offerAnswer);
330 static std::auto_ptr<Contents> makeOfferAnswer(const Contents& offerAnswer, const Contents* alternative);
331 static void setOfferAnswer(SipMessage& msg, const Contents& offerAnswer, const Contents* alternative = 0);
332 static void setOfferAnswer(SipMessage& msg, const Contents* offerAnswer);
333 void provideProposedOffer();
334
335 void storePeerCapabilities(const SipMessage& msg);
336 bool updateMethodSupported() const;
337
338 void sendAck(const Contents *answer=0);
339 SharedPtr<SipMessage> sendBye();
340
341 const Data& getEndReasonString(InviteSession::EndReason reason);
342
343 DialogUsageManager::EncryptionLevel getEncryptionLevel(const SipMessage& msg);
344 void setCurrentLocalOfferAnswer(const SipMessage& msg);
345 void referNoSub(const SipMessage& msg);
346
347 Tokens mPeerSupportedMethods;
348 Tokens mPeerSupportedOptionTags;
349 Mimes mPeerSupportedMimeTypes;
350 Tokens mPeerSupportedEncodings;
351 Tokens mPeerSupportedLanguages;
352 Tokens mPeerAllowedEvents;
353 Data mPeerUserAgent;
354 NameAddrs mPeerPAssertedIdentities;
355
356 Event toEvent(const SipMessage& msg, const Contents* offeranswer);
357
358 State mState;
359 NitState mNitState;
360 NitState mServerNitState;
361
362 std::auto_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
363 std::auto_ptr<Contents> mProposedLocalOfferAnswer; // This get set when we send an offer to the remote end
364
365 std::auto_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
366 std::auto_ptr<Contents> mProposedRemoteOfferAnswer; // This gets set when we receive an offer from the remote end
367
368 SharedPtr<SipMessage> mLastLocalSessionModification; // last UPDATE or reINVITE sent
369 SharedPtr<SipMessage> mLastRemoteSessionModification; // last UPDATE or reINVITE received
370 SharedPtr<SipMessage> mInvite200; // 200 OK for reINVITE for retransmissions
371 SharedPtr<SipMessage> mLastNitResponse;
372
373 SipMessage mLastReferNoSubRequest;
374
375 unsigned long mCurrentRetransmit200;
376 unsigned int mStaleReInviteTimerSeq;
377
378 // Session Timer settings
379 UInt32 mSessionInterval;
380 UInt32 mMinSE;
381 bool mSessionRefresher;
382 unsigned int mSessionTimerSeq;
383 bool mSessionRefreshReInvite;
384
385 class QueuedNIT
386 {
387 public:
388 QueuedNIT(SharedPtr<SipMessage> NIT, bool referSub=false)
389 : mNIT(NIT), mReferSubscription(referSub) {}
390 SharedPtr<SipMessage>& getNIT() { return mNIT; }
391 bool referSubscription() { return mReferSubscription; }
392 private:
393 SharedPtr<SipMessage> mNIT;
394 bool mReferSubscription;
395 };
396 std::queue<QueuedNIT*> mNITQueue;
397 void nitComplete();
398 bool mReferSub;
399 SharedPtr<SipMessage> mLastSentNITRequest;
400
401 DialogUsageManager::EncryptionLevel mCurrentEncryptionLevel;
402 DialogUsageManager::EncryptionLevel mProposedEncryptionLevel; // UPDATE or RE-INVITE or PRACK
403
404 EndReason mEndReason;
405
406 // Used when a user-specified EndReason is needed
407 Data mUserEndReason;
408
409 // Used to respond to 2xx retransmissions.
410 typedef HashMap<Data, SharedPtr<SipMessage> > AckMap;
411 AckMap mAcks;
412
413 private:
414 friend class Dialog;
415 friend class DialogUsageManager;
416
417 // disabled
418 InviteSession(const InviteSession&);
419 InviteSession& operator=(const InviteSession&);
420
421 // Utility methods for handling particular methods
422 void dispatchOthers(const SipMessage& msg);
423 void dispatchUnhandledInvite(const SipMessage& msg);
424 void dispatchPrack(const SipMessage& msg);
425 void dispatchCancel(const SipMessage& msg);
426 };
427
428 }
429
430 #endif
431
432 /* ====================================================================
433 * The Vovida Software License, Version 1.0
434 *
435 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
436 *
437 * Redistribution and use in source and binary forms, with or without
438 * modification, are permitted provided that the following conditions
439 * are met:
440 *
441 * 1. Redistributions of source code must retain the above copyright
442 * notice, this list of conditions and the following disclaimer.
443 *
444 * 2. Redistributions in binary form must reproduce the above copyright
445 * notice, this list of conditions and the following disclaimer in
446 * the documentation and/or other materials provided with the
447 * distribution.
448 *
449 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
450 * and "Vovida Open Communication Application Library (VOCAL)" must
451 * not be used to endorse or promote products derived from this
452 * software without prior written permission. For written
453 * permission, please contact vocal@vovida.org.
454 *
455 * 4. Products derived from this software may not be called "VOCAL", nor
456 * may "VOCAL" appear in their name, without prior written
457 * permission of Vovida Networks, Inc.
458 *
459 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
460 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
461 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
462 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
463 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
464 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
465 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
466 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
467 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
468 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
469 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
470 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
471 * DAMAGE.
472 *
473 * ====================================================================
474 *
475 * This software consists of voluntary contributions made by Vovida
476 * Networks, Inc. and many individuals on behalf of Vovida Networks,
477 * Inc. For more information on Vovida Networks, Inc., please see
478 * <http://www.vovida.org/>.
479 *
480 */
481
482
483
484

Properties

Name Value
svn:eol-style native
svn:mime-type text/plain

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27