reSIProcate/DialogUsageManager  9694
Public Types | Public Member Functions | Protected Member Functions | Private Member Functions | Private Attributes | Friends
resip::ServerSubscription Class Reference

dcm! -- no Subscription State expires parameter generation yet. More...

#include <ServerSubscription.hxx>

Inheritance diagram for resip::ServerSubscription:
Inheritance graph
[legend]
Collaboration diagram for resip::ServerSubscription:
Collaboration graph
[legend]

List of all members.

Public Types

typedef Handle
< ServerSubscription
ServerSubscriptionHandle

Public Member Functions

ServerSubscriptionHandle getHandle ()
const DatagetSubscriber () const
UInt32 getTimeLeft ()
SharedPtr< SipMessageaccept (int statusCode=202)
SharedPtr< SipMessagereject (int responseCode)
SharedPtr< SipMessageneutralNotify ()
void setSubscriptionState (SubscriptionState state)
SharedPtr< SipMessageupdate (const Contents *document)
void end (TerminateReason reason, const Contents *document=0)
virtual void end ()
virtual void send (SharedPtr< SipMessage > msg)
virtual void sendCommand (SharedPtr< SipMessage > msg)
virtual void dispatch (const SipMessage &msg)
virtual void dispatch (const DumTimeout &timer)
virtual EncodeStreamdump (EncodeStream &strm) const

Protected Member Functions

virtual ~ServerSubscription ()
virtual void dialogDestroyed (const SipMessage &msg)
void onReadyToSend (SipMessage &msg)
virtual void flowTerminated ()

Private Member Functions

 ServerSubscription (DialogUsageManager &dum, Dialog &dialog, const SipMessage &req)
void makeNotifyExpires ()
void makeNotify ()
bool shouldDestroyAfterSendingFailure (const SipMessage &msg)
 ServerSubscription (const ServerSubscription &)
ServerSubscriptionoperator= (const ServerSubscription &)

Private Attributes

Data mSubscriber
SipMessage mLastSubscribe
UInt32 mExpires
UInt64 mAbsoluteExpiry

Friends

class Dialog

Detailed Description

dcm! -- no Subscription State expires parameter generation yet.

Definition at line 12 of file ServerSubscription.hxx.


Member Typedef Documentation

Definition at line 15 of file ServerSubscription.hxx.


Constructor & Destructor Documentation

ServerSubscription::~ServerSubscription ( ) [protected, virtual]

Definition at line 39 of file ServerSubscription.cxx.

References DebugLog, resip::BaseSubscription::getDocumentKey(), resip::BaseSubscription::getEventType(), resip::DialogUsage::mDialog, resip::BaseUsage::mDum, resip::Dialog::mServerSubscriptions, and resip::DialogUsageManager::mServerSubscriptions.

{
   DebugLog(<< "ServerSubscription::~ServerSubscription");
   
   Data key = getEventType() + getDocumentKey();

   std::pair<DialogUsageManager::ServerSubscriptions::iterator,DialogUsageManager::ServerSubscriptions::iterator> subs;
   subs = mDum.mServerSubscriptions.equal_range(key);
   for (DialogUsageManager::ServerSubscriptions::iterator i=subs.first; i!=subs.second; ++i)
   {
      if (i->second == this)
      {
         mDum.mServerSubscriptions.erase(i);
         break;
      }
   }
   
   mDialog.mServerSubscriptions.remove(this);
}

Here is the call graph for this function:

ServerSubscription::ServerSubscription ( DialogUsageManager dum,
Dialog dialog,
const SipMessage req 
) [private]

Definition at line 22 of file ServerSubscription.cxx.

References resip::BaseSubscription::getDocumentKey(), resip::BaseSubscription::getEventType(), h_RequestLine, resip::SipMessage::header(), resip::BaseUsage::mDum, resip::RequestLine::method(), resip::DialogUsageManager::mServerSubscriptions, and resip::BaseSubscription::mSubscriptionId.

   : BaseSubscription(dum, dialog, req),
     mSubscriber(req.header(h_From).uri().getAor()),
     mExpires(60),
     mAbsoluteExpiry(0)
{
   if (req.header(h_RequestLine).method() == REFER && req.header(h_To).exists(p_tag))
   {
      // If this is an in-dialog REFER, then use a subscription id
      mSubscriptionId = Data(req.header(h_CSeq).sequence());
   }   
   Data key = getEventType() + getDocumentKey();
   mDum.mServerSubscriptions.insert(DialogUsageManager::ServerSubscriptions::value_type(key, this));
}

Here is the call graph for this function:

resip::ServerSubscription::ServerSubscription ( const ServerSubscription ) [private]

Member Function Documentation

SharedPtr< SipMessage > ServerSubscription::accept ( int  statusCode = 202)

Definition at line 74 of file ServerSubscription.cxx.

References resip::Dialog::makeResponse(), resip::DialogUsage::mDialog, mExpires, resip::BaseSubscription::mLastResponse, and mLastSubscribe.

{
   mDialog.makeResponse(*mLastResponse, mLastSubscribe, statusCode);
   mLastResponse->header(h_Expires).value() = mExpires;
   return mLastResponse;
}

Here is the call graph for this function:

void ServerSubscription::dialogDestroyed ( const SipMessage msg) [protected, virtual]
void ServerSubscription::dispatch ( const SipMessage msg) [virtual]

dcm! -- need to have a mechanism to retrieve default & acceptable

dcm! -- should initial state be pending?

Implements resip::BaseUsage.

Definition at line 204 of file ServerSubscription.cxx.

References resip::Helper::ApplicationDependant, resip::Message::brief(), DebugLog, resip::Helper::determineFailureMessageEffect(), resip::Helper::DialogTermination, resip::DialogUsage::getAppDialog(), getHandle(), resip::DialogUsageManager::getServerSubscriptionHandler(), h_StatusLine, resip::SipMessage::header(), resip::SipMessage::isRequest(), resip::Handle< T >::isValid(), makeNotifyExpires(), resip::Dialog::makeResponse(), resip::DialogUsage::mDialog, resip::BaseUsage::mDum, resip::BaseSubscription::mEventType, mExpires, resip::BaseSubscription::mLastRequest, resip::BaseSubscription::mLastResponse, mLastSubscribe, resip::BaseSubscription::mSubscriptionState, resip::Helper::OptionalRetryAfter, reject(), resip::Helper::RetryAfter, send(), resip::Helper::TransactionTermination, and resip::Helper::UsageTermination.

Referenced by resip::Dialog::dispatch().

{
   DebugLog( << "ServerSubscriptionHandler::dispatch: " << msg.brief());

   ServerSubscriptionHandler* handler = mDum.getServerSubscriptionHandler(mEventType);
   assert(handler);

   if (msg.isRequest())
   {      
      //expiration times for an event package--part of handler API?
      //added to handler for now.
      mLastSubscribe = msg;      
   
      int errorResponseCode = 0;
      handler->getExpires(msg,mExpires,errorResponseCode);
      if (errorResponseCode >= 400)
      {
         handler->onError(getHandle(), msg);
         SharedPtr<SipMessage> response = reject(errorResponseCode);

         if (errorResponseCode == 423 && handler->hasMinExpires())
         {
            response->header(h_MinExpires).value() = handler->getMinExpires();             
         }
         send(response);
         return;
      }     

      InviteSessionHandle invSession;
      if (getAppDialog().isValid())
      {
         invSession = getAppDialog()->getInviteSession();
      }

      if (mExpires == 0)
      {
         /* This is to handle the case where mExpires is zero because the client
            is attempting to poll.  In order for polling to work, the subscription
            handler needs to get the onNewSubscription call. .mjf.
          */
         if (mSubscriptionState == Invalid)
         {
            mSubscriptionState = Terminated;
            if (mEventType != "refer" )
            {
               handler->onNewSubscription(getHandle(), msg);
            }
            else if (!invSession.isValid())
            {
               handler->onNewSubscriptionFromRefer(getHandle(), msg);
            }
         }

         makeNotifyExpires();
         handler->onExpiredByClient(getHandle(), msg, *mLastRequest);
         
         mDialog.makeResponse(*mLastResponse, mLastSubscribe, 200);
         mLastResponse->header(h_Expires).value() = mExpires;
         send(mLastResponse);

         send(mLastRequest);  // Send Notify Expires
         return;
      }
      if (mSubscriptionState == Invalid)
      {
         mSubscriptionState = Init;
         if (mEventType != "refer")
         {
            DebugLog(<< "onNewSubscription called");
            handler->onNewSubscription(getHandle(), msg);
         }
         else if (!invSession.isValid())
         {
            DebugLog(<< "onNewSubscriptionFromRefer called");
            handler->onNewSubscriptionFromRefer(getHandle(), msg);
         }
      }
      else
      {
         DebugLog(<< "onRefresh called");
         handler->onRefresh(getHandle(), msg);            
      }
   }
   else
   {     
      //.dcm. - will need to change if retry-afters are reaching here
      mLastRequest->releaseContents();
      int code = msg.header(h_StatusLine).statusCode();
      if (code < 300)
      { 
         return;
      }
      else if (code < 400)
      {
         //in dialog NOTIFY got redirected? Bizarre...
         handler->onError(getHandle(), msg);
         handler->onTerminated(getHandle());
         delete this;         
      }
      else
      {
         switch(Helper::determineFailureMessageEffect(msg))
         {
            case Helper::TransactionTermination:
               DebugLog( << "ServerSubscriptionHandler::TransactionTermination: " << msg.brief());
               handler->onNotifyRejected(getHandle(), msg);
               break;
            case Helper::UsageTermination:
            case Helper::RetryAfter:
            case Helper::OptionalRetryAfter:
            case Helper::ApplicationDependant: 
            case Helper::DialogTermination:
               DebugLog( << "ServerSubscriptionHandler::UsageTermination: " << msg.brief());
               handler->onError(getHandle(), msg);
               handler->onTerminated(getHandle());
               delete this;
               break;
         }
      }
   }
}

Here is the call graph for this function:

void ServerSubscription::dispatch ( const DumTimeout timer) [virtual]
EncodeStream & ServerSubscription::dump ( EncodeStream strm) const [virtual]

Implements resip::BaseUsage.

Definition at line 435 of file ServerSubscription.cxx.

References mSubscriber.

{
   strm << "ServerSubscription " << mSubscriber;
   return strm;
}
void ServerSubscription::end ( TerminateReason  reason,
const Contents document = 0 
)

Definition at line 359 of file ServerSubscription.cxx.

References makeNotify(), resip::BaseSubscription::mLastRequest, resip::BaseSubscription::mSubscriptionState, and send().

Referenced by resip::Dialog::end().

{
   mSubscriptionState = Terminated;
   makeNotify();
   mLastRequest->header(h_SubscriptionState).param(p_reason) = getTerminateReasonString(reason);   
   if (document)
   {
      mLastRequest->setContents(document);
   }
   send(mLastRequest);
}

Here is the call graph for this function:

void ServerSubscription::end ( ) [virtual]

Implements resip::BaseUsage.

Definition at line 372 of file ServerSubscription.cxx.

{
   end(Timeout);
}
void ServerSubscription::flowTerminated ( ) [protected, virtual]
ServerSubscriptionHandle ServerSubscription::getHandle ( )
const Data& resip::ServerSubscription::getSubscriber ( ) const [inline]

Definition at line 18 of file ServerSubscription.hxx.

References mSubscriber.

{ return mSubscriber; }
UInt32 ServerSubscription::getTimeLeft ( )

Definition at line 60 of file ServerSubscription.cxx.

References resip::Timer::getTimeSecs(), and mAbsoluteExpiry.

Referenced by makeNotify().

{
   UInt32 timeleft =  UInt32(mAbsoluteExpiry - Timer::getTimeSecs());
   if (timeleft < 0) // .kw. this can NEVER happen since unsigned!
   {
      return 0;
   }
   else
   {
      return timeleft;
   }
}

Here is the call graph for this function:

void ServerSubscription::makeNotify ( ) [private]

Definition at line 337 of file ServerSubscription.cxx.

References resip::Data::empty(), getTimeLeft(), resip::Dialog::makeRequest(), resip::DialogUsage::mDialog, resip::BaseSubscription::mEventType, resip::BaseSubscription::mLastRequest, resip::BaseSubscription::mSubscriptionId, and resip::BaseSubscription::mSubscriptionState.

Referenced by end(), makeNotifyExpires(), neutralNotify(), and update().

{
   mDialog.makeRequest(*mLastRequest, NOTIFY);
   mLastRequest->header(h_SubscriptionState).value() = getSubscriptionStateString(mSubscriptionState);
   if (mSubscriptionState == Terminated)
   {
      mLastRequest->header(h_SubscriptionState).remove(p_expires);      
   }
   else
   {
      mLastRequest->header(h_SubscriptionState).param(p_expires) = getTimeLeft();
   }
   
   mLastRequest->header(h_Event).value() = mEventType;   
   if (!mSubscriptionId.empty())
   {
      mLastRequest->header(h_Event).param(p_id) = mSubscriptionId;
   }
}

Here is the call graph for this function:

void ServerSubscription::makeNotifyExpires ( ) [private]

Definition at line 329 of file ServerSubscription.cxx.

References makeNotify(), resip::BaseSubscription::mLastRequest, and resip::BaseSubscription::mSubscriptionState.

Referenced by dispatch().

{
   mSubscriptionState = Terminated;
   makeNotify();
   mLastRequest->header(h_SubscriptionState).param(p_reason) = getTerminateReasonString(Timeout);   
}

Here is the call graph for this function:

SharedPtr< SipMessage > ServerSubscription::neutralNotify ( )

Definition at line 400 of file ServerSubscription.cxx.

References makeNotify(), and resip::BaseSubscription::mLastRequest.

{
   makeNotify();
   mLastRequest->releaseContents();   
   return mLastRequest;
}

Here is the call graph for this function:

void ServerSubscription::onReadyToSend ( SipMessage msg) [protected, virtual]
ServerSubscription& resip::ServerSubscription::operator= ( const ServerSubscription ) [private]
SharedPtr< SipMessage > ServerSubscription::reject ( int  responseCode)

Definition at line 82 of file ServerSubscription.cxx.

References resip::Dialog::makeResponse(), resip::DialogUsage::mDialog, resip::BaseSubscription::mLastResponse, and mLastSubscribe.

Referenced by dispatch().

{
   if (statusCode < 300)
   {
      throw UsageUseException("Must reject with a code greater than or equal to 300", __FILE__, __LINE__);
   }
   mDialog.makeResponse(*mLastResponse, mLastSubscribe, statusCode);
   return mLastResponse;
}

Here is the call graph for this function:

void ServerSubscription::send ( SharedPtr< SipMessage msg) [virtual]

Reimplemented from resip::DialogUsage.

Definition at line 94 of file ServerSubscription.cxx.

References resip::DialogUsageManager::addTimer(), resip::BaseUsage::getBaseHandle(), getHandle(), resip::DialogUsageManager::getServerSubscriptionHandler(), resip::Timer::getTimeSecs(), h_StatusLine, mAbsoluteExpiry, resip::BaseUsage::mDum, resip::BaseSubscription::mEventType, resip::BaseSubscription::mSubDlgState, resip::BaseSubscription::mSubscriptionState, resip::BaseSubscription::mTimerSeq, resip::ServerSubscriptionHandler::onTerminated(), shouldDestroyAfterSendingFailure(), resip::BaseSubscription::SubDlgEstablished, and resip::DumTimeout::Subscription.

Referenced by dispatch(), and end().

{
   ServerSubscriptionHandler* handler = mDum.getServerSubscriptionHandler(mEventType);
   assert(handler);   
   if (msg->isResponse())
   {
      int code = msg->header(h_StatusLine).statusCode();
      if (code < 200)
      {
         DialogUsage::send(msg);
      }
      else if (code < 300)
      {
         if(msg->exists(h_Expires))
         {
            mDum.addTimer(DumTimeout::Subscription, msg->header(h_Expires).value(), getBaseHandle(), ++mTimerSeq);
            DialogUsage::send(msg);
            mAbsoluteExpiry = Timer::getTimeSecs() + msg->header(h_Expires).value();            
            mSubDlgState = SubDlgEstablished;            
         }
         else
         {
            throw UsageUseException("2xx to a Subscribe MUST contain an Expires header", __FILE__, __LINE__);
         }
      }
      else if (code < 400)
      {
         DialogUsage::send(msg);
         handler->onTerminated(getHandle());
         delete this;
         return;
      }
      else
      {
         if (shouldDestroyAfterSendingFailure(*msg))
         {
            DialogUsage::send(msg);
            handler->onTerminated(getHandle());
            delete this;
            return;
         }
         else
         {
            DialogUsage::send(msg);
         }
      }
   }
   else
   {
      DialogUsage::send(msg);
      if (mSubscriptionState == Terminated)
      {
         handler->onTerminated(getHandle());
         delete this;
      }
   }
}

Here is the call graph for this function:

virtual void resip::ServerSubscription::sendCommand ( SharedPtr< SipMessage msg) [inline, virtual]

Reimplemented from resip::DialogUsage.

Definition at line 37 of file ServerSubscription.hxx.

void ServerSubscription::setSubscriptionState ( SubscriptionState  state)

Definition at line 198 of file ServerSubscription.cxx.

References resip::BaseSubscription::mSubscriptionState.

{
   mSubscriptionState = state;
}
bool ServerSubscription::shouldDestroyAfterSendingFailure ( const SipMessage msg) [private]

Definition at line 153 of file ServerSubscription.cxx.

References resip::Helper::ApplicationDependant, resip::Helper::determineFailureMessageEffect(), resip::Helper::DialogTermination, h_StatusLine, resip::SipMessage::header(), resip::BaseSubscription::mLastResponse, resip::BaseSubscription::mSubDlgState, resip::Helper::OptionalRetryAfter, resip::Helper::RetryAfter, resip::BaseSubscription::SubDlgEstablished, resip::BaseSubscription::SubDlgInitial, resip::BaseSubscription::SubDlgTerminating, resip::Helper::TransactionTermination, and resip::Helper::UsageTermination.

Referenced by send().

{
   int code = msg.header(h_StatusLine).statusCode();
   switch(mSubDlgState)
   {
      case SubDlgInitial:
         return true;
      case SubDlgTerminating: //terminated state not using in ServerSubscription
         assert(0);
         return true;
      case SubDlgEstablished:
      {
         if (code == 405)
         {
            return true;
         }
         switch (Helper::determineFailureMessageEffect(*mLastResponse))
         {
            case Helper::TransactionTermination:
            case Helper::RetryAfter:
               break;
            case Helper::OptionalRetryAfter:
            case Helper::ApplicationDependant: 
               // .bwc. Uh, no. ApplicationDependent should imply that the 
               // app-writer has decided what to do. We don't decide here. And 
               // OptionalRetryAfter certainly doesn't mean we should tear the 
               // Usage down.
//               throw UsageUseException("Not a reasonable code to reject a SUBSCIRBE(refresh) inside a dialog.", 
//                                       __FILE__, __LINE__);
               break;            
            case Helper::DialogTermination: //?dcm? -- throw or destroy this?
            case Helper::UsageTermination:
               return true;
         }
         break;
      }
      default: // !jf!
         assert(0);
         break;
         
   }
   return false;   
}

Here is the call graph for this function:

SharedPtr< SipMessage > ServerSubscription::update ( const Contents document)

Definition at line 392 of file ServerSubscription.cxx.

References makeNotify(), and resip::BaseSubscription::mLastRequest.

{
   makeNotify();
   mLastRequest->setContents(document);
   return mLastRequest;
}

Here is the call graph for this function:


Friends And Related Function Documentation

friend class Dialog [friend]

Reimplemented from resip::BaseSubscription.

Definition at line 57 of file ServerSubscription.hxx.


Member Data Documentation

Definition at line 76 of file ServerSubscription.hxx.

Referenced by getTimeLeft(), and send().

Definition at line 71 of file ServerSubscription.hxx.

Referenced by accept(), and dispatch().

Definition at line 69 of file ServerSubscription.hxx.

Referenced by accept(), dispatch(), and reject().

Definition at line 66 of file ServerSubscription.hxx.

Referenced by dump(), and getSubscriber().


The documentation for this class was generated from the following files: