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

Diff of /main/resip/dum/InviteSession.cxx

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3363 by sgodin, Fri Oct 1 12:13:58 2004 UTC revision 3392 by sgodin, Tue Oct 12 18:12:57 2004 UTC
# Line 4  Line 4 
4  #include "resiprocate/dum/Dialog.hxx"  #include "resiprocate/dum/Dialog.hxx"
5  #include "resiprocate/dum/DialogUsageManager.hxx"  #include "resiprocate/dum/DialogUsageManager.hxx"
6  #include "resiprocate/dum/InviteSession.hxx"  #include "resiprocate/dum/InviteSession.hxx"
7    #include "resiprocate/dum/ClientInviteSession.hxx"
8    #include "resiprocate/dum/ServerInviteSession.hxx"
9  #include "resiprocate/dum/InviteSessionHandler.hxx"  #include "resiprocate/dum/InviteSessionHandler.hxx"
10  #include "resiprocate/dum/Profile.hxx"  #include "resiprocate/dum/Profile.hxx"
11  #include "resiprocate/dum/UsageUseException.hxx"  #include "resiprocate/dum/UsageUseException.hxx"
# Line 40  Line 42 
42       mNextOfferOrAnswerSdp(0),       mNextOfferOrAnswerSdp(0),
43       mUserConnected(false),       mUserConnected(false),
44       mQueuedBye(0),       mQueuedBye(0),
45         mSessionInterval(0),
46         mSessionRefresherUAS(false),
47         mSessionTimerSeq(0),
48       mDestroyer(this),       mDestroyer(this),
49       mCurrentRetransmit200(Timer::T1)       mCurrentRetransmit200(Timer::T1)
50  {  {
# Line 79  Line 84 
84     int cseq = mLastIncomingRequest.header(h_CSeq).sequence();     int cseq = mLastIncomingRequest.header(h_CSeq).sequence();
85     SipMessage& finalResponse = mFinalResponseMap[cseq];     SipMessage& finalResponse = mFinalResponseMap[cseq];
86     mDialog.makeResponse(finalResponse, mLastIncomingRequest, 200);     mDialog.makeResponse(finalResponse, mLastIncomingRequest, 200);
87    
88       // Add Session Timer info to response (if required)
89       handleSessionTimerRequest(mLastIncomingRequest, finalResponse);
90    
91       // Check if we should add our capabilites to the invite success response
92       if(mDum.getProfile()->isAdvertisedCapability(Headers::Allow)) finalResponse.header(h_Allows) = mDum.getProfile()->getAllowedMethods();
93       if(mDum.getProfile()->isAdvertisedCapability(Headers::AcceptEncoding)) finalResponse.header(h_AcceptEncodings) = mDum.getProfile()->getSupportedEncodings();
94       if(mDum.getProfile()->isAdvertisedCapability(Headers::AcceptLanguage)) finalResponse.header(h_AcceptLanguages) = mDum.getProfile()->getSupportedLanguages();
95       if(mDum.getProfile()->isAdvertisedCapability(Headers::Supported)) finalResponse.header(h_Supporteds) = mDum.getProfile()->getSupportedOptionTags();
96    
97     return finalResponse;     return finalResponse;
98  }  }
99    
# Line 177  Line 192 
192        assert(mAckMap.find(timeout.seq()) != mFinalResponseMap.end());        assert(mAckMap.find(timeout.seq()) != mFinalResponseMap.end());
193        mAckMap.erase(timeout.seq());        mAckMap.erase(timeout.seq());
194     }     }
195       else if (timeout.type() == DumTimeout::SessionExpiration)
196       {
197          if(timeout.seq() == mSessionTimerSeq)
198          {
199              if(mState != Terminated)
200              {
201                 send(end());  // end expired session
202              }
203          }
204       }
205       else if (timeout.type() == DumTimeout::SessionRefresh)
206       {
207          if(timeout.seq() == mSessionTimerSeq)
208          {
209             if(mState == Connected)
210             {
211                mState = ReInviting;
212                setOffer(mCurrentLocalSdp);
213                // Should likely call targetRefresh when implemented - for now only ReInvites are used
214                mDialog.makeRequest(mLastRequest, INVITE);
215                if(mSessionInterval >= 90)
216                {
217                   mLastRequest.header(h_SessionExpires).value() = mSessionInterval;
218                   mLastRequest.header(h_SessionExpires).param(p_refresher) = Data(mSessionRefresherUAS ? "uas" : "uac");
219                }
220                send(mLastRequest);
221             }
222          }
223       }
224    }
225    
226    void
227    InviteSession::handleSessionTimerResponse(const SipMessage& msg)
228    {
229       // If session timers are locally supported then handle response
230       if(mDum.getProfile()->getSupportedOptionTags().find(Token(Symbols::Timer)))
231       {
232          bool fUAS = dynamic_cast<ServerInviteSession*>(this) != NULL;
233    
234          // Process Session Timer headers
235          if(msg.exists(h_Requires) && msg.header(h_Requires).find(Token(Symbols::Timer)))
236          {
237             if(msg.exists(h_SessionExpires))
238             {
239                mSessionInterval = msg.header(h_SessionExpires).value();
240                mSessionRefresherUAS = fUAS;  // Default to us as refresher
241                if(msg.header(h_SessionExpires).exists(p_refresher))
242                {
243                    mSessionRefresherUAS = (msg.header(h_SessionExpires).param(p_refresher) == Data("uas"));                    
244                }
245             }
246             else
247             {
248                // If no Session Expires in response then session timer is to be 'turned off'
249                mSessionInterval = 0;
250             }
251          }
252          else if(msg.exists(h_SessionExpires))  // If UAS decides to be the refresher - then he MAY not set the Requires header to timer
253          {
254             mSessionInterval = msg.header(h_SessionExpires).value();
255             mSessionRefresherUAS = fUAS;  // Default to us as refresher
256             if(msg.header(h_SessionExpires).exists(p_refresher))
257             {
258                 mSessionRefresherUAS = (msg.header(h_SessionExpires).param(p_refresher) == Data("uas"));                    
259             }
260          }
261          // Note:  If no Requires or Session-Expires, then UAS does not support Session Timers - we are free to use our settings
262    
263          if(mSessionInterval >= 90)  // 90 is the absolute minimum
264          {
265             // Check if we are the refresher
266             if((fUAS && mSessionRefresherUAS) || (!fUAS && !mSessionRefresherUAS))
267             {
268                // Start Session-Refresh Timer to mSessionInterval / 2 (recommended by draft-ietf-sip-session-timer-15)
269                mDum.addTimer(DumTimeout::SessionRefresh, mSessionInterval / 2, getBaseHandle(), ++mSessionTimerSeq);
270             }
271             else
272             {
273                // Start Session-Expiration Timer to mSessionInterval - BYE should be sent a minimum of 32 or SessionInterval/3 seconds before the session expires (recommended by draft-ietf-sip-session-timer-15)
274                mDum.addTimer(DumTimeout::SessionExpiration, mSessionInterval - resipMin(32,mSessionInterval/3), getBaseHandle(), ++mSessionTimerSeq);
275             }
276          }
277       }
278    }
279    
280    void
281    InviteSession::handleSessionTimerRequest(const SipMessage& request, SipMessage &response)
282    {
283       // If session timers are locally supported then add necessary headers to response
284       if(mDum.getProfile()->getSupportedOptionTags().find(Token(Symbols::Timer)))
285       {
286          bool fUAS = dynamic_cast<ServerInviteSession*>(this) != NULL;
287    
288          // Check if we are the refresher
289          if((fUAS && mSessionRefresherUAS) || (!fUAS && !mSessionRefresherUAS))
290          {
291             // If we receive a reinvite, but we are the refresher - don't process for session timers (probably just a TargetRefresh or hold request)
292             return;
293          }
294    
295          mSessionInterval = mDum.getProfile()->getDefaultSessionTime();  // Used only if UAC doesn't request a time
296          mSessionRefresherUAS = true;  // Used only if UAC doesn't request a time
297    
298          // Check if far-end supports
299          bool farEndSupportsTimer = false;
300          if(request.exists(h_Supporteds) && request.header(h_Supporteds).find(Token(Symbols::Timer)))
301          {
302             farEndSupportsTimer = true;
303             if(request.exists(h_SessionExpires))
304             {
305                // Use Session Interval requested by UAC - if none then use local settings
306                mSessionInterval = request.header(h_SessionExpires).value();
307                mSessionRefresherUAS = fUAS;  // Default to us as refresher
308                if(request.header(h_SessionExpires).exists(p_refresher))
309                {
310                    mSessionRefresherUAS = (request.header(h_SessionExpires).param(p_refresher) == Data("uas"));                    
311                }
312             }
313          }
314    
315          // Add Session-Expires if required
316          if(mSessionInterval >= 90)
317          {
318             if(farEndSupportsTimer)
319             {
320                response.header(h_Requires).push_back(Token(Symbols::Timer));
321             }
322             response.header(h_SessionExpires).value() = mSessionInterval;
323             response.header(h_SessionExpires).param(p_refresher) = Data(mSessionRefresherUAS ? "uas" : "uac");
324    
325             // Check if we are the refresher
326             if((fUAS && mSessionRefresherUAS) || (!fUAS && !mSessionRefresherUAS))
327             {
328                // Start Session-Refresh Timer to mSessionInterval / 2 (recommended by draft-ietf-sip-session-timer-15)
329                mDum.addTimer(DumTimeout::SessionRefresh, mSessionInterval / 2, getBaseHandle(), ++mSessionTimerSeq);
330             }
331             else
332             {
333                // Start Session-Expiration Timer to mSessionInterval - BYE should be sent a minimum of 32 or SessionInterval/3 seconds before the session expires (recommended by draft-ietf-sip-session-timer-15)
334                mDum.addTimer(DumTimeout::SessionExpiration, mSessionInterval - resipMin(32,mSessionInterval/3), getBaseHandle(), ++mSessionTimerSeq);
335             }
336          }
337       }
338  }  }
339    
340  void  void
# Line 397  Line 555 
555                          send(mLastRequest);                          send(mLastRequest);
556                          return;                          return;
557                       }                       }
558    
559                         // Handle any Session Timer headers in response
560                         handleSessionTimerResponse(msg);
561    
562                       if (offans.first != None)                       if (offans.first != None)
563                       {                       {
564                          if (offans.first == Answer)                          if (offans.first == Answer)
# Line 428  Line 590 
590                       }                       }
591                    }                    }
592                 }                 }
593                   else if(code == 408 || code == 481)  
594                   {
595                       // If ReInvite response is Timeout (408) or Transaction Does not Exits (481) - end dialog
596                       mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), msg);
597                       guard.destroy();
598                   }            
599                 else                 else
600                 {                 {
601                      // !slg! handle 491 response and retry???
602    
603                    mState = Connected;                    mState = Connected;
604                    //user has called end, so no more callbacks relating to                    //user has called end, so no more callbacks relating to
605                    //this usage other than onTerminated                    //this usage other than onTerminated

Legend:
Removed from v.3363  
changed lines
  Added in v.3392

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27