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

#include <ClientPublication.hxx>

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

List of all members.

Public Types

typedef Handle< ClientPublicationClientPublicationHandle

Public Member Functions

 ClientPublication (DialogUsageManager &dum, DialogSet &dialogSet, SharedPtr< SipMessage > pub)
ClientPublicationHandle getHandle ()
const DatagetEventType ()
const ContentsgetContents () const
void refresh (unsigned int expiration=0)
void update (const Contents *body)
virtual void end ()
void end (bool immediate)
void updateCommand (const Contents *body)
 Provide asynchronous method access by using command.
void refreshCommand (unsigned int expiration=0)
virtual void endCommand (bool immediate=false)
virtual void dispatch (const SipMessage &msg)
virtual void dispatch (const DumTimeout &timer)
virtual EncodeStreamdump (EncodeStream &strm) const

Protected Member Functions

virtual ~ClientPublication ()
virtual void send (SharedPtr< SipMessage > request)

Private Member Functions

 ClientPublication (const ClientPublication &)
ClientPublicationoperator= (const ClientPublication &)

Private Attributes

bool mWaitingForResponse
bool mPendingPublish
SharedPtr< SipMessagemPublish
Data mEventType
unsigned int mTimerSeq
const ContentsmDocument

Friends

class DialogSet

Detailed Description

Definition at line 9 of file ClientPublication.hxx.


Member Typedef Documentation

Definition at line 14 of file ClientPublication.hxx.


Constructor & Destructor Documentation

ClientPublication::ClientPublication ( DialogUsageManager dum,
DialogSet dialogSet,
SharedPtr< SipMessage pub 
)

Definition at line 23 of file ClientPublication.cxx.

References DebugLog, resip::Handled::mId, and value.

   : NonDialogUsage(dum, dialogSet),
     mWaitingForResponse(false),
     mPendingPublish(false),
     mPublish(req),
     mEventType(req->header(h_Event).value()),
     mTimerSeq(0),
     mDocument(mPublish->releaseContents().release())
{
   DebugLog( << "ClientPublication::ClientPublication: " << mId);   
}
ClientPublication::~ClientPublication ( ) [protected, virtual]

Definition at line 37 of file ClientPublication.cxx.

References DebugLog, resip::DialogSet::mClientPublication, resip::NonDialogUsage::mDialogSet, mDocument, and resip::Handled::mId.

{
   DebugLog( << "ClientPublication::~ClientPublication: " << mId);   
   mDialogSet.mClientPublication = 0;
   delete mDocument;
}
resip::ClientPublication::ClientPublication ( const ClientPublication ) [private]

Member Function Documentation

void ClientPublication::dispatch ( const SipMessage msg) [virtual]

Implements resip::BaseUsage.

Definition at line 95 of file ClientPublication.cxx.

References resip::Helper::aBitSmallerThan(), resip::DialogUsageManager::addTimer(), DebugLog, resip::SipMessage::exists(), resip::BaseUsage::getBaseHandle(), resip::DialogUsageManager::getClientPublicationHandler(), getHandle(), resip::SipMessage::getReceivedTransport(), h_StatusLine, resip::SipMessage::header(), InfoLog, resip::SipMessage::isRequest(), mDocument, resip::BaseUsage::mDum, mEventType, mPendingPublish, mPublish, mTimerSeq, mWaitingForResponse, resip::ClientPublicationHandler::onFailure(), resip::ClientPublicationHandler::onRemove(), resip::ClientPublicationHandler::onRequestRetry(), resip::ClientPublicationHandler::onSuccess(), resip::DumTimeout::Publication, refresh(), resip::resipMax(), send(), update(), and WarningLog.

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

{
   ClientPublicationHandler* handler = mDum.getClientPublicationHandler(mEventType);
   assert(handler);   

   if (msg.isRequest())
   {
      DebugLog( << "Dropping stray request to ClientPublication usage: " << msg);
   }
   else
   {
      const int code = msg.header(h_StatusLine).statusCode();
      if (code < 200)
      {
         return;
      }

      assert(code >= 200);
      mWaitingForResponse = false;

      if (code < 300)
      {
         if (mPublish->exists(h_Expires) && mPublish->header(h_Expires).value() == 0)
         {
            handler->onRemove(getHandle(), msg);
            delete this;
            return;
         }
         else if (msg.exists(h_SIPETag) && msg.exists(h_Expires))
         {
            mPublish->header(h_SIPIfMatch) = msg.header(h_SIPETag);
            if(!mPendingPublish)
            {
               mPublish->releaseContents();           
            }
            mDum.addTimer(DumTimeout::Publication, 
                          Helper::aBitSmallerThan(msg.header(h_Expires).value()), 
                          getBaseHandle(),
                          ++mTimerSeq);
            handler->onSuccess(getHandle(), msg);
         }
         else
         {
            // Any PUBLISH/200 must have an ETag. This should not happen. Not
            // sure what the app can do in this case. 
            WarningLog (<< "PUBLISH/200 received with no ETag " << mPublish->header(h_From).uri());
            handler->onFailure(getHandle(), msg);
            delete this;
            return;
         }
      }
      else
      {
         if (code == 412)
         {
            InfoLog(<< "SIPIfMatch failed -- republish");
            mPublish->remove(h_SIPIfMatch);
            update(mDocument);
            return;
         }         
         else if (code == 423) // interval too short
         {
            if (msg.exists(h_MinExpires))
            {
               mPublish->header(h_Expires).value() = msg.header(h_MinExpires).value();
               update(mDocument); // !dys! since contents not released until on success, no need to call update any more.
            }
            else
            {
               handler->onFailure(getHandle(), msg);
               delete this;
               return;
            }
         }
         else if (code == 408 ||
                  (code == 503 && msg.getReceivedTransport() == 0) ||
                  ((code == 404 ||
                    code == 413 ||
                    code == 480 ||
                    code == 486 ||
                    code == 500 ||
                    code == 503 ||
                    code == 600 ||
                    code == 603) &&
                   msg.exists(h_RetryAfter)))
         {
            int retryMinimum = 0;
            if (msg.exists(h_RetryAfter))
            {
               retryMinimum = msg.header(h_RetryAfter).value();
            }

            // RFC 3261:20.33 Retry-After
            int retry = handler->onRequestRetry(getHandle(), retryMinimum, msg);
            if (retry < 0)
            {
               DebugLog(<< "Application requested failure on Retry-After");
               handler->onFailure(getHandle(), msg);
               delete this;
               return;
            }
            else if (retry == 0 && retryMinimum == 0)
            {
               DebugLog(<< "Application requested immediate retry on Retry-After");
               refresh();
               return;
            }
            else
            {
               retry = resipMax(retry, retryMinimum);
               DebugLog(<< "Application requested delayed retry on Retry-After: " << retry);
               mDum.addTimer(DumTimeout::Publication, 
                             retry, 
                             getBaseHandle(),
                             ++mTimerSeq);       
               return;
               
            }
         }
         else
         {
            handler->onFailure(getHandle(), msg);
            delete this;
            return;
         }

      }

      if (mPendingPublish)
      {
         InfoLog (<< "Sending pending PUBLISH: " << mPublish->brief());
         send(mPublish);
      }
   }
}

Here is the call graph for this function:

void ClientPublication::dispatch ( const DumTimeout timer) [virtual]

Implements resip::BaseUsage.

Definition at line 232 of file ClientPublication.cxx.

References mTimerSeq, refresh(), and resip::DumTimeout::seq().

{
    if (timer.seq() == mTimerSeq)
    {
       refresh();
    }
}

Here is the call graph for this function:

EncodeStream & ClientPublication::dump ( EncodeStream strm) const [virtual]

Implements resip::BaseUsage.

Definition at line 351 of file ClientPublication.cxx.

References resip::Handled::mId, and mPublish.

{
   strm << "ClientPublication " << mId << " " << mPublish->header(h_From).uri();
   return strm;
}
void ClientPublication::end ( ) [virtual]

Implements resip::BaseUsage.

Definition at line 45 of file ClientPublication.cxx.

{
   end(false);
}
void ClientPublication::end ( bool  immediate)

Definition at line 51 of file ClientPublication.cxx.

References h_RequestLine, InfoLog, mPublish, and send().

{
   InfoLog (<< "End client publication to " << mPublish->header(h_RequestLine).uri());
   if(!immediate)
   {
      mPublish->header(h_Expires).value() = 0;
      send(mPublish);
   }
   else
   {
      delete this;
   }
}

Here is the call graph for this function:

void ClientPublication::endCommand ( bool  immediate = false) [virtual]

Definition at line 89 of file ClientPublication.cxx.

References resip::BaseUsage::mDum, and resip::TransactionUser::post().

{
   mDum.post(new ClientPublicationEndCommand(*this, immediate));
}

Here is the call graph for this function:

const Contents* resip::ClientPublication::getContents ( ) const [inline]

Definition at line 17 of file ClientPublication.hxx.

References mDocument.

{ return mDocument; }
const Data& resip::ClientPublication::getEventType ( ) [inline]

Definition at line 16 of file ClientPublication.hxx.

References mEventType.

{ return mEventType; }
ClientPublicationHandle ClientPublication::getHandle ( )

Definition at line 18 of file ClientPublication.cxx.

References resip::BaseUsage::getBaseHandle(), and resip::BaseUsage::mDum.

Referenced by dispatch(), and resip::DialogSet::getClientPublication().

{
   return ClientPublicationHandle(mDum, getBaseHandle().getId());
}

Here is the call graph for this function:

ClientPublication& resip::ClientPublication::operator= ( const ClientPublication ) [private]
void ClientPublication::refresh ( unsigned int  expiration = 0)

Definition at line 241 of file ClientPublication.cxx.

References mPublish, and send().

Referenced by dispatch().

{
   if (expiration == 0 && mPublish->exists(h_Expires))
   {
      expiration = mPublish->header(h_Expires).value();
   }
   send(mPublish);
}

Here is the call graph for this function:

void ClientPublication::refreshCommand ( unsigned int  expiration = 0)

Definition at line 276 of file ClientPublication.cxx.

References resip::BaseUsage::mDum, and resip::TransactionUser::post().

{
   mDum.post(new ClientPublicationRefreshCommand(*this, expiration));
}

Here is the call graph for this function:

void ClientPublication::send ( SharedPtr< SipMessage request) [protected, virtual]

Reimplemented from resip::NonDialogUsage.

Definition at line 335 of file ClientPublication.cxx.

References resip::BaseUsage::mDum, mPendingPublish, mWaitingForResponse, and resip::DialogUsageManager::send().

Referenced by dispatch(), end(), refresh(), and update().

{
   if (mWaitingForResponse)
   {
      mPendingPublish = true;
   }
   else
   {
      request->header(h_CSeq).sequence()++;
      mDum.send(request);
      mWaitingForResponse = true;
      mPendingPublish = false;
   }
}

Here is the call graph for this function:

void ClientPublication::update ( const Contents body)

Definition at line 282 of file ClientPublication.cxx.

References resip::Contents::clone(), InfoLog, mDocument, mPublish, and send().

Referenced by dispatch().

{
   InfoLog (<< "Updating presence document: " << mPublish->header(h_To).uri());

   if (mDocument != body)
   {
      delete mDocument;
      if (body)
      {
         mDocument = body->clone();
      }
      else
      {
         mDocument = body;
      }
   }

   mPublish->setContents(mDocument);
   send(mPublish);
}

Here is the call graph for this function:

void ClientPublication::updateCommand ( const Contents body)

Provide asynchronous method access by using command.

Definition at line 329 of file ClientPublication.cxx.

References resip::BaseUsage::mDum, and resip::TransactionUser::post().

{
   mDum.post(new ClientPublicationUpdateCommand(*this, body));
}

Here is the call graph for this function:


Friends And Related Function Documentation

friend class DialogSet [friend]

Definition at line 42 of file ClientPublication.hxx.


Member Data Documentation

Definition at line 50 of file ClientPublication.hxx.

Referenced by dispatch(), getContents(), update(), and ~ClientPublication().

Definition at line 48 of file ClientPublication.hxx.

Referenced by dispatch(), and getEventType().

Definition at line 45 of file ClientPublication.hxx.

Referenced by dispatch(), and send().

Definition at line 47 of file ClientPublication.hxx.

Referenced by dispatch(), dump(), end(), refresh(), and update().

unsigned int resip::ClientPublication::mTimerSeq [private]

Definition at line 49 of file ClientPublication.hxx.

Referenced by dispatch().

Definition at line 44 of file ClientPublication.hxx.

Referenced by dispatch(), and send().


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