reSIProcate/DialogUsageManager  9694
Public Member Functions | Private Member Functions | Private Attributes | Friends
resip::ClientInviteSession Class Reference

#include <ClientInviteSession.hxx>

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

List of all members.

Public Member Functions

 ClientInviteSession (DialogUsageManager &dum, Dialog &dialog, SharedPtr< SipMessage > request, const Contents *initialOffer, DialogUsageManager::EncryptionLevel level, ServerSubscriptionHandle serverSub=ServerSubscriptionHandle::NotValid())
ClientInviteSessionHandle getHandle ()
virtual void provideOffer (const Contents &offer)
 Called to set the offer that will be used in the next message that sends an offer.
virtual void provideOffer (const Contents &offer, DialogUsageManager::EncryptionLevel level, const Contents *alternative)
virtual void provideAnswer (const Contents &answer)
 Similar to provideOffer - called to set the answer to be signalled to the peer.
virtual void end (const Data &userReason)
 Makes the specific dialog end.
virtual void end (EndReason reason)
virtual void end ()
virtual void reject (int statusCode, WarningCategory *warning=0)
 Rejects an offer at the SIP level.
const ContentsgetEarlyMedia () const

Private Member Functions

virtual void dispatch (const SipMessage &msg)
virtual void dispatch (const DumTimeout &timer)
void dispatchStart (const SipMessage &msg)
void dispatchEarly (const SipMessage &msg)
void dispatchEarlyWithOffer (const SipMessage &msg)
void dispatchEarlyWithAnswer (const SipMessage &msg)
void dispatchAnswered (const SipMessage &msg)
void dispatchSentUpdateEarly (const SipMessage &msg)
void dispatchSentUpdateEarlyGlare (const SipMessage &msg)
void dispatchReceivedUpdateEarly (const SipMessage &msg)
void dispatchSentAnswer (const SipMessage &msg)
void dispatchQueuedUpdate (const SipMessage &msg)
void dispatchCancelled (const SipMessage &msg)
void handleRedirect (const SipMessage &msg)
void handleProvisional (const SipMessage &msg)
void handleFinalResponse (const SipMessage &msg)
void handleOffer (const SipMessage &msg, const Contents &offer)
void handleAnswer (const SipMessage &msg, const Contents &answer)
void sendPrackIfNeeded (const SipMessage &msg)
void sendPrack (const Contents &offerAnswer)
void cancel ()
void onForkAccepted ()
bool checkRseq (const SipMessage &msg)
void startCancelTimer ()
void startStaleCallTimer ()
void sendSipFrag (const SipMessage &response)
void onConnectedAspect (ClientInviteSessionHandle h, const SipMessage &msg)
void onProvisionalAspect (ClientInviteSessionHandle c, const SipMessage &msg)
void onFailureAspect (ClientInviteSessionHandle c, const SipMessage &msg)
 ClientInviteSession (const ClientInviteSession &)
ClientInviteSessionoperator= (const ClientInviteSession &)

Private Attributes

std::auto_ptr< ContentsmEarlyMedia
RAckCategory mRelRespInfo
unsigned int mStaleCallTimerSeq
unsigned int mCancelledTimerSeq
ServerSubscriptionHandle mServerSub

Friends

class Dialog

Detailed Description

Definition at line 12 of file ClientInviteSession.hxx.


Constructor & Destructor Documentation

ClientInviteSession::ClientInviteSession ( DialogUsageManager dum,
Dialog dialog,
SharedPtr< SipMessage request,
const Contents initialOffer,
DialogUsageManager::EncryptionLevel  level,
ServerSubscriptionHandle  serverSub = ServerSubscriptionHandle::NotValid() 
)

Definition at line 25 of file ClientInviteSession.cxx.

References resip::Contents::clone(), resip::InviteSession::mLastLocalSessionModification, resip::InviteSession::mProposedEncryptionLevel, resip::InviteSession::mProposedLocalOfferAnswer, resip::InviteSession::mState, and resip::InviteSession::UAC_Start.

                                                                             :
   InviteSession(dum, dialog),
   mStaleCallTimerSeq(1),
   mCancelledTimerSeq(1),
   mServerSub(serverSub)
{
   assert(request->isRequest());
   if(initialOffer)  
   {
      mProposedLocalOfferAnswer = auto_ptr<Contents>(initialOffer->clone());
      mProposedEncryptionLevel = level;
   }
   *mLastLocalSessionModification = *request;  // Copy message, so that modifications to mLastLocalSessionModification don't effect creator->getLastRequest

   mState=UAC_Start;
}

Here is the call graph for this function:

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

Member Function Documentation

void ClientInviteSession::cancel ( ) [private]
bool ClientInviteSession::checkRseq ( const SipMessage msg) [private]

Definition at line 1425 of file ClientInviteSession.cxx.

References resip::RAckCategory::cSequence(), DebugLog, resip::SipMessage::exists(), h_StatusLine, resip::SipMessage::header(), resip::SipMessage::isResponse(), resip::RAckCategory::method(), resip::RequestLine::method(), resip::SipMessage::method(), mRelRespInfo, and resip::RAckCategory::rSequence().

Referenced by dispatch().

{
   int code = msg.isResponse() ? msg.header(h_StatusLine).statusCode() : 0;
   if (msg.method() == INVITE && code > 100 && code < 200)
   {
      if (msg.exists(h_RSeq))
      {
         // store state about the provisional if reliable, so we can detect retransmissions
         unsigned int rseq = (unsigned int) msg.header(h_RSeq).value();
         unsigned int lastRseq = (unsigned int) mRelRespInfo.rSequence();
         
         if (rseq == lastRseq)
         {
            DebugLog(<< "Discarding reliable 1xx retranmission with rseq " << rseq);
            return true;
         }
         else if (lastRseq != 0 && rseq > lastRseq + 1)
         {
            DebugLog(<< "Discarding out of order reliable 1xx with rseq " << rseq);
            return true;
         }
         mRelRespInfo.rSequence() = rseq;
         mRelRespInfo.cSequence() = msg.header(h_CSeq).sequence();
         mRelRespInfo.method() = msg.header(h_CSeq).method();
      }
   }
   return false;
}

Here is the call graph for this function:

void ClientInviteSession::dispatch ( const SipMessage msg) [private, virtual]

Reimplemented from resip::InviteSession.

Definition at line 390 of file ClientInviteSession.cxx.

References checkRseq(), dispatchAnswered(), dispatchCancelled(), dispatchEarly(), dispatchEarlyWithAnswer(), dispatchEarlyWithOffer(), resip::InviteSession::dispatchInfo(), resip::InviteSession::dispatchMessage(), dispatchQueuedUpdate(), dispatchReceivedUpdateEarly(), dispatchSentAnswer(), dispatchSentUpdateEarly(), dispatchSentUpdateEarlyGlare(), dispatchStart(), end(), getHandle(), h_RequestLine, resip::SipMessage::header(), resip::SipMessage::isRequest(), resip::RequestLine::method(), resip::InviteSession::mState, resip::InviteSession::NotSpecified, onFailureAspect(), sendSipFrag(), resip::InviteSession::UAC_Answered, resip::InviteSession::UAC_Cancelled, resip::InviteSession::UAC_Early, resip::InviteSession::UAC_EarlyWithAnswer, resip::InviteSession::UAC_EarlyWithOffer, resip::InviteSession::UAC_QueuedUpdate, resip::InviteSession::UAC_ReceivedUpdateEarly, resip::InviteSession::UAC_SentAnswer, resip::InviteSession::UAC_SentUpdateEarly, resip::InviteSession::UAC_SentUpdateEarlyGlare, resip::InviteSession::UAC_Start, and WarningLog.

Referenced by dispatch().

{
  try
  {
     if (msg.isRequest())
     {
        if (msg.header(h_RequestLine).method() == INFO)
        {
           InviteSession::dispatchInfo(msg);
           return;
        }
        if (msg.header(h_RequestLine).method() == MESSAGE)
        {
           InviteSession::dispatchMessage(msg);
           return;
        }
     }

     if (checkRseq(msg))
     {
        return;
     }

     sendSipFrag(msg);
     switch(mState)
     {
        case UAC_Start:
           dispatchStart(msg);
           break;
        case UAC_Early:
           dispatchEarly(msg);
           break;
        case UAC_EarlyWithOffer:
           dispatchEarlyWithOffer(msg);
           break;
        case UAC_EarlyWithAnswer:
           dispatchEarlyWithAnswer(msg);
           break;
        case UAC_Answered:
           dispatchAnswered(msg);
           break;
        case UAC_SentUpdateEarly:
           dispatchSentUpdateEarly(msg);
           break;
        case UAC_SentUpdateEarlyGlare:
           dispatchSentUpdateEarlyGlare(msg);
           break;
        case UAC_ReceivedUpdateEarly:
           dispatchReceivedUpdateEarly(msg);
           break;
        case UAC_SentAnswer:
           dispatchSentAnswer(msg);
           break;
        case UAC_QueuedUpdate:
           dispatchQueuedUpdate(msg);
           break;
        case UAC_Cancelled:
           dispatchCancelled(msg);
           break;
        default:
           InviteSession::dispatch(msg);
           break;
     }
  }
  catch (BaseException& e)
  {
     WarningLog (<< "Caught: " << e);
     onFailureAspect(getHandle(), msg);
     end(NotSpecified); 
  }
}

Here is the call graph for this function:

void ClientInviteSession::dispatch ( const DumTimeout timer) [private, virtual]

Reimplemented from resip::InviteSession.

Definition at line 463 of file ClientInviteSession.cxx.

References resip::DumTimeout::Cancelled, resip::DialogUsageManager::destroy(), dispatch(), getHandle(), resip::InviteSession::getSessionHandle(), resip::DumTimeout::Glare, InfoLog, resip::Handle< T >::isValid(), resip::InviteSessionHandler::LocalCancel, resip::Dialog::makeRequest(), resip::Dialog::makeResponse(), mCancelledTimerSeq, resip::DialogUsage::mDialog, resip::BaseUsage::mDum, resip::DialogUsageManager::mInviteSessionHandler, resip::InviteSession::mLastLocalSessionModification, mServerSub, mStaleCallTimerSeq, resip::InviteSession::mState, resip::InviteSessionHandler::onForkDestroyed(), resip::InviteSessionHandler::onStaleCallTimeout(), resip::InviteSessionHandler::onTerminated(), resip::DialogUsage::send(), sendSipFrag(), resip::DumTimeout::seq(), resip::DumTimeout::StaleCall, resip::InviteSessionHandler::terminate(), resip::InviteSession::Terminated, resip::InviteSession::transition(), resip::DumTimeout::type(), resip::InviteSession::UAC_SentUpdateEarly, resip::InviteSession::UAC_SentUpdateEarlyGlare, and resip::DumTimeout::WaitingForForked2xx.

Here is the call graph for this function:

void ClientInviteSession::dispatchAnswered ( const SipMessage msg) [private]

Reimplemented from resip::InviteSession.

Definition at line 920 of file ClientInviteSession.cxx.

References resip::Message::brief(), resip::DialogUsageManager::destroy(), resip::InviteSession::dispatchBye(), resip::InviteSessionHandler::Error, getHandle(), resip::InviteSession::getOfferAnswer(), resip::InviteSession::getSessionHandle(), InfoLog, resip::BaseUsage::mDum, resip::InviteSession::On1xx, resip::InviteSession::On1xxEarly, resip::InviteSession::On1xxOffer, resip::InviteSession::On2xx, resip::InviteSession::On2xxAnswer, resip::InviteSession::On2xxOffer, resip::InviteSession::On422Invite, resip::InviteSession::OnBye, onFailureAspect(), resip::InviteSession::OnGeneralFailure, resip::InviteSession::OnRedirect, resip::InviteSession::sendBye(), resip::InviteSession::Terminated, resip::InviteSession::toEvent(), resip::InviteSession::transition(), and WarningLog.

Referenced by dispatch().

{
   //InviteSessionHandler* handler = mDum.mInviteSessionHandler;
   std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg);

   switch (toEvent(msg, offerAnswer.get()))
   {
      case On1xx:
      case On1xxEarly:
      case On1xxOffer:
         // late, so ignore
         break;

      case On2xxOffer:
      case On2xx:
      case On2xxAnswer:
         // retransmission
         break;

      case OnRedirect:
         // too late
         break;

      // .slg. This doesn't really make sense (after a 2xx)
      case OnGeneralFailure:
      case On422Invite:
         break;
#if 0 // !jf! don't think this is right
      {
         sendBye();
         InfoLog (<< "Failure:  error response: " << msg.brief());
         transition(Terminated);
         onFailureAspect(getHandle(), msg);
         handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg);
         mDum.destroy(this);
         break;
      }
#endif
      case OnBye:
         dispatchBye(msg);
         break;

      default:
         // !kh!
         // should not assert here for peer sent us garbage.
         WarningLog (<< "Don't know what this is : " << msg);         
         break;
   }

}

Here is the call graph for this function:

void ClientInviteSession::dispatchCancelled ( const SipMessage msg) [private]

Definition at line 1382 of file ClientInviteSession.cxx.

References resip::DialogUsageManager::destroy(), resip::InviteSession::dispatchBye(), resip::InviteSession::getOfferAnswer(), resip::InviteSession::getSessionHandle(), resip::InviteSessionHandler::LocalCancel, mCancelledTimerSeq, resip::BaseUsage::mDum, resip::DialogUsageManager::mInviteSessionHandler, resip::InviteSession::On2xx, resip::InviteSession::On2xxAnswer, resip::InviteSession::On2xxOffer, resip::InviteSession::On422Invite, resip::InviteSession::On487Invite, resip::InviteSession::On491Invite, resip::InviteSession::OnBye, resip::InviteSession::OnCancelFailure, resip::InviteSession::OnGeneralFailure, resip::InviteSession::OnInviteFailure, resip::InviteSession::OnRedirect, resip::InviteSessionHandler::onTerminated(), resip::InviteSession::sendAck(), resip::InviteSession::sendBye(), resip::InviteSession::Terminated, resip::InviteSession::toEvent(), and resip::InviteSession::transition().

Referenced by dispatch().

{
   InviteSessionHandler* handler = mDum.mInviteSessionHandler;
   std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg);

   switch (toEvent(msg, offerAnswer.get()))
   {
      case OnGeneralFailure:
      case OnCancelFailure:
      case On487Invite:
      case OnRedirect:
      case On422Invite:
      case On491Invite:
      case OnInviteFailure:
         transition(Terminated);
         handler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalCancel, &msg);
         mDum.destroy(this);
         break;

      case On2xx:
      case On2xxOffer:
      case On2xxAnswer:
      {
         // this is the 2xx crossing the CANCEL case
         sendAck();
         sendBye();
         transition(Terminated);
         handler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalCancel, &msg);
         mCancelledTimerSeq++;
         break;
      }

      case OnBye:
         dispatchBye(msg);
         break;

      default:
         break;
   }
}

Here is the call graph for this function:

void ClientInviteSession::dispatchEarly ( const SipMessage msg) [private]

Definition at line 793 of file ClientInviteSession.cxx.

References resip::Message::brief(), resip::InviteSession::Connected, resip::DialogUsageManager::destroy(), resip::InviteSession::dispatchBye(), resip::InviteSessionHandler::Error, resip::InviteSession::getEncryptionLevel(), getHandle(), resip::InviteSession::getOfferAnswer(), resip::InviteSession::getSessionHandle(), handleAnswer(), handleFinalResponse(), handleOffer(), handleProvisional(), InfoLog, resip::InviteSession::isTerminated(), resip::InviteSession::makeOfferAnswer(), resip::Dialog::makeResponse(), resip::InviteSession::mCurrentEncryptionLevel, resip::InviteSession::mCurrentRemoteOfferAnswer, resip::DialogUsage::mDialog, resip::BaseUsage::mDum, mEarlyMedia, resip::DialogUsageManager::mInviteSessionHandler, resip::InviteSession::mLastRemoteSessionModification, resip::InviteSession::mProposedLocalOfferAnswer, resip::InviteSession::mProposedRemoteOfferAnswer, resip::InviteSession::On1xx, resip::InviteSession::On1xxAnswer, resip::InviteSession::On1xxEarly, resip::InviteSession::On1xxOffer, resip::InviteSession::On2xx, resip::InviteSession::On2xxAnswer, resip::InviteSession::On2xxOffer, resip::InviteSession::On422Invite, resip::InviteSession::On487Invite, resip::InviteSessionHandler::onAnswer(), resip::InviteSession::OnBye, onConnectedAspect(), resip::InviteSessionHandler::onEarlyMedia(), onFailureAspect(), resip::InviteSession::OnGeneralFailure, resip::InviteSession::OnInviteFailure, resip::InviteSessionHandler::onOffer(), resip::InviteSession::OnRedirect, resip::InviteSessionHandler::onTerminated(), resip::InviteSession::OnUpdate, resip::InviteSession::OnUpdateOffer, resip::DialogUsage::send(), resip::InviteSession::sendAck(), resip::InviteSession::sendBye(), resip::InviteSession::setCurrentLocalOfferAnswer(), resip::InviteSession::Terminated, resip::InviteSession::toEvent(), resip::InviteSession::transition(), resip::InviteSession::UAC_Answered, resip::InviteSession::UAC_Early, resip::InviteSession::UAC_EarlyWithAnswer, resip::InviteSession::UAC_EarlyWithOffer, resip::InviteSession::UAC_ReceivedUpdateEarly, and WarningLog.

Referenced by dispatch().

{
   InviteSessionHandler* handler = mDum.mInviteSessionHandler;
   std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg);

   switch (toEvent(msg, offerAnswer.get()))
   {
      case On1xx:
         transition(UAC_Early);
         handleProvisional(msg);
         break;

      case On1xxEarly: // only unreliable
         transition(UAC_Early);
         handleProvisional(msg);
         if(!isTerminated())  
         {
            mEarlyMedia = InviteSession::makeOfferAnswer(*offerAnswer);
            handler->onEarlyMedia(getHandle(), msg, *offerAnswer);
         }
         break;

      case On1xxOffer:
         transition(UAC_EarlyWithOffer);
         handleOffer(msg, *offerAnswer);
         break;

      case On1xxAnswer:
         transition(UAC_EarlyWithAnswer);
         handleAnswer(msg, *offerAnswer);
         break;

      case On2xxOffer:
         transition(UAC_Answered);
         handleFinalResponse(msg);

         assert(mProposedLocalOfferAnswer.get() == 0);
         mCurrentEncryptionLevel = getEncryptionLevel(msg);
         mProposedRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer);

         handler->onOffer(getSessionHandle(), msg, *offerAnswer);
         if(!isTerminated())  
         {
            onConnectedAspect(getHandle(), msg);   
         }
         break;

      case On2xxAnswer:
         transition(Connected);
         sendAck();
         handleFinalResponse(msg);
         //mCurrentLocalOfferAnswer = mProposedLocalOfferAnswer;
         setCurrentLocalOfferAnswer(msg);
         mCurrentEncryptionLevel = getEncryptionLevel(msg);
         mCurrentRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer);
         handler->onAnswer(getSessionHandle(), msg, *offerAnswer);
         if(!isTerminated())  // onNewSession callback may call end() or reject()
         {
            onConnectedAspect(getHandle(), msg);
         }
         break;

      case On2xx:
      {
         sendAck();
         sendBye();
         InfoLog (<< "Failure:  2xx with no answer: " << msg.brief());
         transition(Terminated);
         onFailureAspect(getHandle(), msg);
         handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg);
         break;
      }

      case OnRedirect: // Redirects are handled by the DialogSet - if a 3xx gets here then it's because the redirect was intentionaly not handled and should be treated as an INVITE failure      
      case OnInviteFailure:
      case OnGeneralFailure:
      case On422Invite:
      case On487Invite:
         InfoLog (<< "Failure:  error response: " << msg.brief());
         transition(Terminated);
         onFailureAspect(getHandle(), msg);
         handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg);
         mDum.destroy(this);
         break;

      case OnBye:
         dispatchBye(msg);
         break;

      case OnUpdateOffer:
         if(mProposedLocalOfferAnswer.get())
         {
            WarningLog (<< "Invalid UPDATE with offer received in early state with pending offer: " << msg.brief());
            SharedPtr<SipMessage> response(new SipMessage);
            mDialog.makeResponse(*response, msg, 500);  // RFC3311 - section 5.2
            InfoLog (<< "Sending " << response->brief());
            send(response);
         }
         else
         {
            *mLastRemoteSessionModification = msg;
            transition(UAC_ReceivedUpdateEarly);
            mCurrentEncryptionLevel = getEncryptionLevel(msg);
            mProposedRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer);
            handler->onOffer(getSessionHandle(), msg, *offerAnswer);
         }
         break;

      case OnUpdate:
      {
         // ?slg? no offerAnswer in update - just respond immediately - do we need a callback?
         SharedPtr<SipMessage> response(new SipMessage);
         *mLastRemoteSessionModification = msg;
         mDialog.makeResponse(*response, msg, 200);
         send(response);
         break;
      }

      default:
         // !kh!
         // should not assert here for peer sent us garbage.
         WarningLog (<< "Don't know what this is : " << msg);
         break;
   }
}

Here is the call graph for this function:

void ClientInviteSession::dispatchEarlyWithAnswer ( const SipMessage msg) [private]

Definition at line 1179 of file ClientInviteSession.cxx.

References resip::Message::brief(), resip::InviteSession::Connected, resip::DialogUsageManager::destroy(), resip::InviteSession::dispatchBye(), resip::InviteSessionHandler::Error, resip::InviteSession::getEncryptionLevel(), getHandle(), resip::InviteSession::getOfferAnswer(), resip::InviteSession::getSessionHandle(), handleFinalResponse(), handleOffer(), handleProvisional(), InfoLog, resip::InviteSession::isTerminated(), resip::InviteSession::makeOfferAnswer(), resip::Dialog::makeResponse(), resip::InviteSession::mCurrentEncryptionLevel, resip::DialogUsage::mDialog, resip::BaseUsage::mDum, resip::DialogUsageManager::mInviteSessionHandler, resip::InviteSession::mLastRemoteSessionModification, resip::InviteSession::mProposedRemoteOfferAnswer, resip::InviteSession::On1xx, resip::InviteSession::On1xxOffer, resip::InviteSession::On2xx, resip::InviteSession::On2xxAnswer, resip::InviteSession::On2xxOffer, resip::InviteSession::On422Invite, resip::InviteSession::On487Invite, resip::InviteSession::On491Invite, resip::InviteSession::OnBye, onConnectedAspect(), onFailureAspect(), resip::InviteSession::OnGeneralFailure, resip::InviteSession::OnInviteFailure, resip::InviteSessionHandler::onOffer(), resip::InviteSession::OnRedirect, resip::InviteSessionHandler::onTerminated(), resip::InviteSession::OnUpdate, resip::InviteSession::OnUpdateOffer, resip::DialogUsage::send(), resip::InviteSession::sendAck(), resip::InviteSession::sendBye(), sendPrackIfNeeded(), resip::InviteSession::Terminated, resip::InviteSession::toEvent(), resip::InviteSession::transition(), resip::InviteSession::UAC_EarlyWithOffer, resip::InviteSession::UAC_ReceivedUpdateEarly, and WarningLog.

Referenced by dispatch(), and dispatchSentUpdateEarlyGlare().

{
   InviteSessionHandler* handler = mDum.mInviteSessionHandler;
   std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg);

   switch (toEvent(msg, offerAnswer.get()))
   {
      case On1xx:
         handleProvisional(msg);
         sendPrackIfNeeded(msg);
         break;
      case On1xxOffer:
         if(!isTerminated())  
         {
            transition(UAC_EarlyWithOffer);
            handleOffer(msg, *offerAnswer);
         }
         break;
      case On2xx:
         transition(Connected);
         sendAck();
         handleFinalResponse(msg);
         onConnectedAspect(getHandle(), msg);
         break;

      case On2xxAnswer:
      case On2xxOffer:
         sendAck();
         sendBye();
         InfoLog (<< "Failure:  illegal offer/answer: " << msg.brief());
         transition(Terminated);
         onFailureAspect(getHandle(), msg);
         handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg);
         break;

      case OnUpdateOffer:
         *mLastRemoteSessionModification = msg;
         transition(UAC_ReceivedUpdateEarly);
         mCurrentEncryptionLevel = getEncryptionLevel(msg);
         mProposedRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer);
         handler->onOffer(getSessionHandle(), msg, *offerAnswer);
         break;

      case OnUpdate:
      {
         // ?slg? no offerAnswer in update - just respond immediately - do we need a callback?
         SharedPtr<SipMessage> response(new SipMessage);
         *mLastRemoteSessionModification = msg;
         mDialog.makeResponse(*response, msg, 200);
         send(response);
         break;
      }

      case OnRedirect: // Redirects are handled by the DialogSet - if a 3xx gets here then it's because the redirect was intentionaly not handled and should be treated as an INVITE failure
      case OnInviteFailure:
      case OnGeneralFailure:
      case On422Invite:
      case On487Invite:
      case On491Invite:
         InfoLog (<< "Failure:  error response: " << msg.brief());
         transition(Terminated);
         onFailureAspect(getHandle(), msg);
         handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg);
         mDum.destroy(this);
         break;

      case OnBye:
         dispatchBye(msg);
         break;

      default:
         // !kh!
         // should not assert here for peer sent us garbage.
         WarningLog (<< "Don't know what this is : " << msg);
         break;
   }
}

Here is the call graph for this function:

void ClientInviteSession::dispatchEarlyWithOffer ( const SipMessage msg) [private]

Definition at line 972 of file ClientInviteSession.cxx.

References resip::Message::brief(), resip::DialogUsageManager::destroy(), resip::InviteSession::dispatchBye(), resip::InviteSessionHandler::Error, getHandle(), resip::InviteSession::getOfferAnswer(), resip::InviteSession::getSessionHandle(), handleProvisional(), InfoLog, resip::Dialog::makeResponse(), resip::DialogUsage::mDialog, resip::BaseUsage::mDum, resip::DialogUsageManager::mInviteSessionHandler, resip::InviteSession::mLastRemoteSessionModification, resip::InviteSession::On1xx, resip::InviteSession::On2xx, resip::InviteSession::On2xxAnswer, resip::InviteSession::On422Invite, resip::InviteSession::On487Invite, resip::InviteSession::On491Invite, resip::InviteSession::OnBye, onFailureAspect(), resip::InviteSession::OnGeneralFailure, resip::InviteSession::OnInviteFailure, resip::InviteSession::OnRedirect, resip::InviteSessionHandler::onTerminated(), resip::InviteSession::OnUpdate, resip::InviteSession::OnUpdateOffer, resip::DialogUsage::send(), resip::InviteSession::sendAck(), resip::InviteSession::sendBye(), sendPrackIfNeeded(), resip::InviteSession::Terminated, resip::InviteSession::toEvent(), resip::InviteSession::transition(), and WarningLog.

Referenced by dispatch().

{
   InviteSessionHandler* handler = mDum.mInviteSessionHandler;
   std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg);

   switch (toEvent(msg, offerAnswer.get()))
   {
      case On1xx: // must be reliable
         handleProvisional(msg);
         sendPrackIfNeeded(msg);
         break;

      case On2xx:
      case On2xxAnswer:
         sendAck();
         sendBye();
         InfoLog (<< "Failure:  no answer sent: " << msg.brief());
         transition(Terminated);
         onFailureAspect(getHandle(), msg);
         handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg);
         break;

      case OnRedirect: // Redirects are handled by the DialogSet - if a 3xx gets here then it's because the redirect was intentionaly not handled and should be treated as an INVITE failure      
      case OnInviteFailure:
      case OnGeneralFailure:
      case On422Invite:
      case On487Invite:
      case On491Invite:
         InfoLog (<< "Failure:  error response: " << msg.brief());
         transition(Terminated);
         onFailureAspect(getHandle(), msg);
         handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg);
         mDum.destroy(this);
         break;

      case OnBye:
         dispatchBye(msg);
         break;

      case OnUpdateOffer:
      {
         WarningLog (<< "Invalid UPDATE with offer received in early state with pending offer: " << msg.brief());
         SharedPtr<SipMessage> response(new SipMessage);
         mDialog.makeResponse(*response, msg, 500);  // RFC3311 - section 5.2
         InfoLog (<< "Sending " << response->brief());
         send(response);
         break;
      }

      case OnUpdate:
      {
         // ?slg? no offerAnswer in update - just respond immediately - do we need a callback?
         SharedPtr<SipMessage> response(new SipMessage);
         *mLastRemoteSessionModification = msg;
         mDialog.makeResponse(*response, msg, 200);
         send(response);
         break;
      }

      default:
         // !kh!
         // should not assert here for peer sent us garbage.
         WarningLog (<< "Don't know what this is : " << msg);
         break;
   }
}

Here is the call graph for this function:

void ClientInviteSession::dispatchQueuedUpdate ( const SipMessage msg) [private]

Definition at line 1101 of file ClientInviteSession.cxx.

References resip::Message::brief(), resip::DialogUsageManager::destroy(), resip::InviteSession::dispatchBye(), resip::InviteSessionHandler::Error, getHandle(), resip::InviteSession::getOfferAnswer(), resip::InviteSession::getSessionHandle(), handleFinalResponse(), handleProvisional(), InfoLog, resip::Dialog::makeRequest(), resip::DialogUsage::mDialog, resip::BaseUsage::mDum, resip::DialogUsageManager::mInviteSessionHandler, resip::InviteSession::mLastLocalSessionModification, resip::InviteSession::mProposedEncryptionLevel, resip::InviteSession::mProposedLocalOfferAnswer, resip::InviteSession::On1xx, resip::InviteSession::On1xxAnswer, resip::InviteSession::On1xxOffer, resip::InviteSession::On200Prack, resip::InviteSession::On2xx, resip::InviteSession::On2xxAnswer, resip::InviteSession::On2xxOffer, resip::InviteSession::On422Invite, resip::InviteSession::On487Invite, resip::InviteSession::On491Invite, resip::InviteSession::OnBye, onConnectedAspect(), onFailureAspect(), resip::InviteSession::OnGeneralFailure, resip::InviteSession::OnInviteFailure, resip::InviteSession::OnRedirect, resip::InviteSessionHandler::onTerminated(), resip::DialogUsage::send(), resip::InviteSession::sendAck(), resip::InviteSession::sendBye(), sendPrackIfNeeded(), resip::InviteSession::SentUpdate, resip::InviteSession::setOfferAnswer(), resip::DumHelper::setOutgoingEncryptionLevel(), resip::InviteSession::Terminated, resip::InviteSession::toEvent(), resip::InviteSession::transition(), resip::InviteSession::UAC_SentUpdateEarly, and WarningLog.

Referenced by dispatch().

{
   InviteSessionHandler* handler = mDum.mInviteSessionHandler;
   std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg);

   switch (toEvent(msg, offerAnswer.get()))
   {
      case On200Prack:
         transition(UAC_SentUpdateEarly);
         {
            mDialog.makeRequest(*mLastLocalSessionModification, UPDATE);
            InviteSession::setOfferAnswer(*mLastLocalSessionModification, mProposedLocalOfferAnswer.get());

            DumHelper::setOutgoingEncryptionLevel(*mLastLocalSessionModification, mProposedEncryptionLevel);
            send(mLastLocalSessionModification);
         }
         break;

      case On2xx:
         transition(SentUpdate);
         {
            sendAck();

            SharedPtr<SipMessage> update(new SipMessage);
            mDialog.makeRequest(*update, UPDATE);
            InviteSession::setOfferAnswer(*update, mProposedLocalOfferAnswer.get());
            DumHelper::setOutgoingEncryptionLevel(*update, mProposedEncryptionLevel);
            send(update);
         }
         handleFinalResponse(msg);
         onConnectedAspect(getHandle(), msg);
         break;

      case On2xxAnswer:
      case On2xxOffer:
      case On1xxAnswer:
      case On1xxOffer:
         sendAck();
         sendBye();
         InfoLog (<< "Failure:  illegal offer/answer: " << msg.brief());
         transition(Terminated);
         onFailureAspect(getHandle(), msg);
         handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg);
         break;

      case On1xx:
         handleProvisional(msg);
         sendPrackIfNeeded(msg);
         break;

      case OnRedirect: // Redirects are handled by the DialogSet - if a 3xx gets here then it's because the redirect was intentionaly not handled and should be treated as an INVITE failure
      case OnInviteFailure:
      case OnGeneralFailure:
      case On422Invite:
      case On487Invite:
      case On491Invite:
         InfoLog (<< "Failure:  error response: " << msg.brief());
         transition(Terminated);
         onFailureAspect(getHandle(), msg);
         handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg);
         mDum.destroy(this);
         break;

      case OnBye:
         dispatchBye(msg);
         break;

      default:
         // !kh!
         // should not assert here for peer sent us garbage.
         WarningLog (<< "Don't know what this is : " << msg);
         break;
   }
}

Here is the call graph for this function:

void ClientInviteSession::dispatchReceivedUpdateEarly ( const SipMessage msg) [private]

Definition at line 1363 of file ClientInviteSession.cxx.

References WarningLog.

Referenced by dispatch().

{
   /*
   InviteSessionHandler* handler = mDum.mInviteSessionHandler;
   std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg);

   switch (toEvent(msg, offerAnswer.get()))
   {
      default:
         // !kh!
         // should not assert here for peer sent us garbage.
         WarningLog (<< "Don't know what this is : " << msg);
         break;
   }
   */
   WarningLog (<< "Ignoring message received in ReceivedUpdateEarly: " << msg);
}
void ClientInviteSession::dispatchSentAnswer ( const SipMessage msg) [private]

Definition at line 1040 of file ClientInviteSession.cxx.

References resip::Message::brief(), resip::InviteSession::Connected, resip::DialogUsageManager::destroy(), resip::InviteSession::dispatchBye(), resip::InviteSessionHandler::Error, getHandle(), resip::InviteSession::getOfferAnswer(), resip::InviteSession::getSessionHandle(), handleFinalResponse(), handleProvisional(), InfoLog, resip::BaseUsage::mDum, resip::DialogUsageManager::mInviteSessionHandler, resip::InviteSession::On1xx, resip::InviteSession::On1xxAnswer, resip::InviteSession::On1xxOffer, resip::InviteSession::On200Prack, resip::InviteSession::On2xx, resip::InviteSession::On2xxAnswer, resip::InviteSession::On2xxOffer, resip::InviteSession::On422Invite, resip::InviteSession::On487Invite, resip::InviteSession::On491Invite, resip::InviteSession::OnBye, onConnectedAspect(), onFailureAspect(), resip::InviteSession::OnGeneralFailure, resip::InviteSession::OnInviteFailure, resip::InviteSession::OnRedirect, resip::InviteSessionHandler::onTerminated(), resip::InviteSession::sendAck(), resip::InviteSession::sendBye(), sendPrackIfNeeded(), resip::InviteSession::Terminated, resip::InviteSession::toEvent(), resip::InviteSession::transition(), resip::InviteSession::UAC_EarlyWithAnswer, and WarningLog.

Referenced by dispatch().

{
   InviteSessionHandler* handler = mDum.mInviteSessionHandler;
   std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg);

   switch (toEvent(msg, offerAnswer.get()))
   {
      case On200Prack:
         transition(UAC_EarlyWithAnswer);
         break;

      case On2xx:
         transition(Connected);
         sendAck();
         handleFinalResponse(msg);
         onConnectedAspect(getHandle(), msg);
         break;

      case On2xxAnswer:
      case On2xxOffer:
      case On1xxAnswer:
      case On1xxOffer:
         sendAck();
         sendBye();
         InfoLog (<< "Failure:  illegal offer/answer: " << msg.brief());
         transition(Terminated);
         onFailureAspect(getHandle(), msg);
         handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg);
         break;

      case On1xx:
         handleProvisional(msg);
         sendPrackIfNeeded(msg);
         break;

      case OnRedirect: // Redirects are handled by the DialogSet - if a 3xx gets here then it's because the redirect was intentionaly not handled and should be treated as an INVITE failure
      case OnInviteFailure:
      case OnGeneralFailure:
      case On422Invite:
      case On487Invite:
      case On491Invite:
         InfoLog (<< "Failure:  error response: " << msg.brief());
         transition(Terminated);
         onFailureAspect(getHandle(), msg);
         handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg);
         mDum.destroy(this);
         break;

      case OnBye:
         dispatchBye(msg);
         break;

      default:
         // !kh!
         // should not assert here for peer sent us garbage.
         WarningLog (<< "Don't know what this is : " << msg);
         break;
   }
}

Here is the call graph for this function:

void ClientInviteSession::dispatchSentUpdateEarly ( const SipMessage msg) [private]

Definition at line 1258 of file ClientInviteSession.cxx.

References resip::Message::brief(), resip::DialogUsageManager::destroy(), resip::InviteSessionHandler::Error, resip::InviteSession::getEncryptionLevel(), getHandle(), resip::InviteSession::getOfferAnswer(), resip::InviteSession::getSessionHandle(), InfoLog, resip::InviteSession::makeOfferAnswer(), resip::Dialog::makeResponse(), resip::InviteSession::mCurrentEncryptionLevel, resip::InviteSession::mCurrentRemoteOfferAnswer, resip::DialogUsage::mDialog, resip::BaseUsage::mDum, resip::DialogUsageManager::mInviteSessionHandler, resip::InviteSession::mLastRemoteSessionModification, resip::InviteSession::On200Update, resip::InviteSession::On2xx, resip::InviteSession::On422Invite, resip::InviteSession::On487Invite, resip::InviteSession::On491Update, resip::InviteSessionHandler::onAnswer(), onFailureAspect(), resip::InviteSession::OnGeneralFailure, resip::InviteSession::OnInviteFailure, resip::InviteSession::OnRedirect, resip::InviteSessionHandler::onTerminated(), resip::InviteSession::OnUpdate, resip::InviteSession::OnUpdateOffer, resip::DialogUsage::send(), resip::InviteSession::sendAck(), resip::InviteSession::SentUpdate, resip::InviteSession::setCurrentLocalOfferAnswer(), resip::InviteSession::start491Timer(), resip::InviteSession::Terminated, resip::InviteSession::toEvent(), resip::InviteSession::transition(), resip::InviteSession::UAC_EarlyWithAnswer, resip::InviteSession::UAC_SentUpdateEarlyGlare, and WarningLog.

Referenced by dispatch().

{
   InviteSessionHandler* handler = mDum.mInviteSessionHandler;
   std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg);

   switch (toEvent(msg, offerAnswer.get()))
   {
      case On200Update:
         transition(UAC_EarlyWithAnswer);
         setCurrentLocalOfferAnswer(msg);
         mCurrentEncryptionLevel = getEncryptionLevel(msg);
         mCurrentRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer);
         handler->onAnswer(getSessionHandle(), msg, *offerAnswer);
         break;
         
      case OnUpdateOffer:
         {
            SharedPtr<SipMessage> response(new SipMessage);
            mDialog.makeResponse(*response, msg, 491);
            send(response);
         }
         break;
         
      case OnUpdate:
      {
         // ?slg? no offerAnswer in update - just respond immediately - do we need a callback?
         SharedPtr<SipMessage> response(new SipMessage);
         *mLastRemoteSessionModification = msg;
         mDialog.makeResponse(*response, msg, 200);
         send(response);
         break;
      }

      case On491Update:
         transition(UAC_SentUpdateEarlyGlare);
         start491Timer();
         break;

      case On2xx:
         transition(SentUpdate);         
         sendAck();
         break;
         
      case OnRedirect: // Redirects are handled by the DialogSet - if a 3xx gets
                       // here then it's because the redirect was intentionaly
                       // not handled and should be treated as an INVITE failure
      case OnInviteFailure:
      case OnGeneralFailure:
      case On422Invite:
      case On487Invite:
         InfoLog (<< "Failure:  error response: " << msg.brief());
         transition(Terminated);
         onFailureAspect(getHandle(), msg);
         handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg);
         mDum.destroy(this);
         break;

      default:
         WarningLog (<< "Don't know what this is : " << msg);
         break;
   }
}

Here is the call graph for this function:

void ClientInviteSession::dispatchSentUpdateEarlyGlare ( const SipMessage msg) [private]

dcm! TODO This block below is repeated many, many times...refactor into a method. Prob. represents the effective ClientInvite superstate.

Definition at line 1322 of file ClientInviteSession.cxx.

References resip::Message::brief(), resip::DialogUsageManager::destroy(), dispatchEarlyWithAnswer(), resip::InviteSessionHandler::Error, getHandle(), resip::InviteSession::getOfferAnswer(), resip::InviteSession::getSessionHandle(), InfoLog, resip::BaseUsage::mDum, resip::DialogUsageManager::mInviteSessionHandler, resip::InviteSession::On2xx, resip::InviteSession::On422Invite, resip::InviteSession::On487Invite, onFailureAspect(), resip::InviteSession::OnGeneralFailure, resip::InviteSession::OnInviteFailure, resip::InviteSessionHandler::onOfferRejected(), resip::InviteSession::OnRedirect, resip::InviteSessionHandler::onTerminated(), resip::InviteSession::OnUpdateOffer, resip::InviteSession::sendAck(), resip::InviteSession::SentUpdateGlare, resip::InviteSession::Terminated, resip::InviteSession::toEvent(), resip::InviteSession::transition(), and WarningLog.

Referenced by dispatch().

{
   InviteSessionHandler* handler = mDum.mInviteSessionHandler;
   std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg);

   switch (toEvent(msg, offerAnswer.get()))
   {
      case OnUpdateOffer:
         handler->onOfferRejected(getSessionHandle(), &msg);
         //will cause transition to UAC_ReceivedUpdateEarly
         dispatchEarlyWithAnswer(msg);
         break;
         
      case On2xx:
         //transition to connected state machine
         transition(SentUpdateGlare);         
         sendAck();
         break;
      case OnRedirect: // Redirects are handled by the DialogSet - if a 3xx gets
                       // here then it's because the redirect was intentionaly
                       // not handled and should be treated as an INVITE failure
      case OnInviteFailure:
      case OnGeneralFailure:
      case On422Invite:
      case On487Invite:
         InfoLog (<< "Failure:  error response: " << msg.brief());
         transition(Terminated);
         onFailureAspect(getHandle(), msg);
         handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg);
         mDum.destroy(this);
         break;

      default:
         WarningLog (<< "Don't know what this is : " << msg);
         break;
   }
}

Here is the call graph for this function:

void ClientInviteSession::dispatchStart ( const SipMessage msg) [private]

dcm! according to draft-ietf-sipping-offeranswer there can be a non

Definition at line 659 of file ClientInviteSession.cxx.

References resip::InviteSession::Answer, resip::Message::brief(), resip::InviteSession::Connected, resip::DialogUsageManager::destroy(), resip::InviteSession::dispatchBye(), resip::InviteSessionHandler::Error, resip::InviteSession::getEncryptionLevel(), getHandle(), resip::InviteSession::getOfferAnswer(), resip::InviteSession::getSessionHandle(), h_StatusLine, handleAnswer(), handleFinalResponse(), handleOffer(), handleProvisional(), resip::SipMessage::header(), InfoLog, resip::SipMessage::isResponse(), resip::InviteSession::isTerminated(), resip::InviteSession::makeOfferAnswer(), resip::InviteSession::mCurrentEncryptionLevel, resip::InviteSession::mCurrentRemoteOfferAnswer, resip::BaseUsage::mDum, mEarlyMedia, resip::RequestLine::method(), resip::DialogUsageManager::mInviteSessionHandler, resip::InviteSession::mProposedLocalOfferAnswer, resip::InviteSession::mProposedRemoteOfferAnswer, resip::InviteSession::None, resip::InviteSession::Offer, resip::InviteSession::On1xx, resip::InviteSession::On1xxAnswer, resip::InviteSession::On1xxEarly, resip::InviteSession::On1xxOffer, resip::InviteSession::On2xx, resip::InviteSession::On2xxAnswer, resip::InviteSession::On2xxOffer, resip::InviteSession::On422Invite, resip::InviteSession::On487Invite, resip::InviteSession::On491Invite, resip::InviteSession::OnBye, onConnectedAspect(), onFailureAspect(), resip::InviteSession::OnGeneralFailure, resip::InviteSession::OnInviteFailure, resip::InviteSession::OnRedirect, resip::InviteSession::sendAck(), resip::InviteSession::sendBye(), sendPrackIfNeeded(), resip::InviteSession::setCurrentLocalOfferAnswer(), resip::InviteSession::Terminated, resip::InviteSession::toEvent(), resip::InviteSession::transition(), resip::InviteSession::UAC_Answered, resip::InviteSession::UAC_Early, resip::InviteSession::UAC_EarlyWithAnswer, resip::InviteSession::UAC_EarlyWithOffer, and WarningLog.

Referenced by dispatch().

{
   assert(msg.isResponse());
   assert(msg.header(h_StatusLine).statusCode() > 100);
   assert(msg.header(h_CSeq).method() == INVITE);

   InviteSessionHandler* handler = mDum.mInviteSessionHandler;
   std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg);

   InviteSession::Event event = toEvent(msg, offerAnswer.get());

   switch (event)
   {
      case On1xx:
         transition(UAC_Early);
         handler->onNewSession(getHandle(), InviteSession::None, msg);
         if(!isTerminated())  
         {
            handleProvisional(msg);
            sendPrackIfNeeded(msg); //may wish to move emprty PRACK handling
                                 //outside the state machine            
         }
         break;

      case On1xxEarly:
         // reliable 1xx followed by a reliable 1xx.  Also, the intial 1xx
         // doesn't have to have an offer. However, DUM will only generate
         // reliabled 1xx responses when 100rel is available.

         transition(UAC_Early);
         mEarlyMedia = InviteSession::makeOfferAnswer(*offerAnswer);
         handler->onNewSession(getHandle(), InviteSession::None, msg);
         if(!isTerminated())  
         {
            handleProvisional(msg);
            if(!isTerminated())  
            {
               handler->onEarlyMedia(getHandle(), msg, *offerAnswer);
            }
         }
         break;

      case On1xxOffer:
         transition(UAC_EarlyWithOffer);
         handler->onNewSession(getHandle(), InviteSession::Offer, msg);
         if(!isTerminated())  
         {
            handleOffer(msg, *offerAnswer);
         }
         break;

      case On1xxAnswer:
         transition(UAC_EarlyWithAnswer);
         handler->onNewSession(getHandle(), InviteSession::Answer, msg);
         if(!isTerminated())  
         {
            handleAnswer(msg, *offerAnswer);
         }
         break;

      case On2xxOffer:
         transition(UAC_Answered);
         handleFinalResponse(msg);
         mProposedRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer);
         handler->onNewSession(getHandle(), InviteSession::Offer, msg);
         assert(mProposedLocalOfferAnswer.get() == 0);
         mCurrentEncryptionLevel = getEncryptionLevel(msg);
         if(!isTerminated())  
         {
            handler->onOffer(getSessionHandle(), msg, *offerAnswer);
            if(!isTerminated())   //?jf? can this be terminated here but not above? .slg. yes application can call end()
            {
               onConnectedAspect(getHandle(), msg);  
            }
         }
         break;

      case On2xxAnswer:
         transition(Connected);
         sendAck();
         handleFinalResponse(msg);
         //mCurrentLocalOfferAnswer = mProposedLocalOfferAnswer;
         setCurrentLocalOfferAnswer(msg);
         mCurrentEncryptionLevel = getEncryptionLevel(msg);
         mCurrentRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer);
         handler->onNewSession(getHandle(), InviteSession::Answer, msg);
         if(!isTerminated())  // onNewSession callback may call end() or reject()
         {
            handler->onAnswer(getSessionHandle(), msg, *offerAnswer);
            if(!isTerminated())  // onAnswer callback may call end() or reject()
            {
               onConnectedAspect(getHandle(), msg);
            }
         }
         break;

      case On2xx:
      {
         sendAck();
         sendBye();
         InfoLog (<< "Failure:  2xx with no answer: " << msg.brief());
         transition(Terminated);
         onFailureAspect(getHandle(), msg);
         handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg);
         break;
      }

      case OnRedirect: // Redirects are handled by the DialogSet - if a 3xx gets here then it's because the redirect was intentionaly not handled and should be treated as an INVITE failure      
      case OnInviteFailure:
      case OnGeneralFailure:
      case On422Invite:
      case On487Invite:
      case On491Invite:
         InfoLog (<< "Failure:  error response: " << msg.brief());
         transition(Terminated);
         onFailureAspect(getHandle(), msg);
         handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg);
         mDum.destroy(this);
         break;

      case OnBye:
         dispatchBye(msg);
         break;

      default:
         // !kh!
         // should not assert here for peer sent us garbage.
         WarningLog (<< "Don't know what this is : " << msg);
         break;
   }
}

Here is the call graph for this function:

void ClientInviteSession::end ( const Data userReason) [virtual]

Makes the specific dialog end.

Will send a BYE (not a CANCEL)

Reimplemented from resip::InviteSession.

Definition at line 188 of file ClientInviteSession.cxx.

References end(), resip::InviteSession::mUserEndReason, and resip::InviteSession::UserSpecified.

Here is the call graph for this function:

void ClientInviteSession::end ( EndReason  reason) [virtual]

Reimplemented from resip::InviteSession.

Definition at line 195 of file ClientInviteSession.cxx.

References end(), resip::SharedPtr< T >::get(), resip::InviteSession::getSessionHandle(), InfoLog, resip::InviteSessionHandler::LocalBye, resip::BaseUsage::mDum, resip::InviteSession::mEndReason, resip::DialogUsageManager::mInviteSessionHandler, resip::InviteSession::mState, resip::InviteSession::NotSpecified, resip::InviteSessionHandler::onTerminated(), resip::InviteSession::sendBye(), resip::InviteSession::Terminated, resip::InviteSession::toData(), resip::InviteSession::transition(), resip::InviteSession::UAC_Answered, resip::InviteSession::UAC_Cancelled, resip::InviteSession::UAC_Early, resip::InviteSession::UAC_EarlyWithAnswer, resip::InviteSession::UAC_EarlyWithOffer, resip::InviteSession::UAC_QueuedUpdate, resip::InviteSession::UAC_ReceivedUpdateEarly, resip::InviteSession::UAC_SentAnswer, resip::InviteSession::UAC_SentUpdateEarly, resip::InviteSession::UAC_Start, and WarningLog.

{
   InfoLog (<< toData(mState) << ": end");
   if (mEndReason == NotSpecified)
   {
      mEndReason = reason;   
   }

   switch(mState)
   {
      case UAC_Early:
      case UAC_EarlyWithOffer:
      case UAC_EarlyWithAnswer:
      case UAC_Answered:
      case UAC_SentUpdateEarly:
      case UAC_ReceivedUpdateEarly:
      case UAC_SentAnswer:
      case UAC_QueuedUpdate:
      case UAC_Cancelled: // !jf! possibly incorrect to always BYE in UAC_Cancelled
      {
         SharedPtr<SipMessage> msg = sendBye();
         transition(Terminated);
         mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalBye, msg.get()); 
         break;
      }

      case UAC_Start:
         WarningLog (<< "Try to end when in state=" << toData(mState));
         assert(0);
         break;

      case Terminated:
         // no-op
         break;

      default:
         InviteSession::end(reason);
         break;
   }
}

Here is the call graph for this function:

void ClientInviteSession::end ( ) [virtual]

Reimplemented from resip::InviteSession.

Definition at line 182 of file ClientInviteSession.cxx.

References resip::InviteSession::NotSpecified.

Referenced by dispatch(), end(), and handleProvisional().

const Contents & ClientInviteSession::getEarlyMedia ( ) const

Definition at line 54 of file ClientInviteSession.cxx.

References mEarlyMedia.

{
   return *mEarlyMedia;
}
ClientInviteSessionHandle ClientInviteSession::getHandle ( )
void ClientInviteSession::handleAnswer ( const SipMessage msg,
const Contents answer 
) [private]
void ClientInviteSession::handleFinalResponse ( const SipMessage msg) [private]

Definition at line 563 of file ClientInviteSession.cxx.

References h_StatusLine, resip::InviteSession::handleSessionTimerResponse(), resip::SipMessage::header(), resip::SipMessage::isResponse(), mStaleCallTimerSeq, and resip::InviteSession::storePeerCapabilities().

Referenced by dispatchEarly(), dispatchEarlyWithAnswer(), dispatchQueuedUpdate(), dispatchSentAnswer(), and dispatchStart().

{
   assert(msg.isResponse());
   assert(msg.header(h_StatusLine).statusCode() >= 200);
   assert(msg.header(h_StatusLine).statusCode() < 300);

   handleSessionTimerResponse(msg);
   storePeerCapabilities(msg);
   ++mStaleCallTimerSeq;  // disable stale call timer
}

Here is the call graph for this function:

void ClientInviteSession::handleOffer ( const SipMessage msg,
const Contents offer 
) [private]
void ClientInviteSession::handleProvisional ( const SipMessage msg) [private]

Definition at line 530 of file ClientInviteSession.cxx.

References resip::Message::brief(), end(), resip::SipMessage::exists(), getHandle(), h_StatusLine, resip::SipMessage::header(), InfoLog, resip::InviteSession::isReliable(), resip::SipMessage::isResponse(), resip::InviteSession::mLastLocalSessionModification, resip::InviteSession::NotSpecified, onFailureAspect(), onProvisionalAspect(), and startStaleCallTimer().

Referenced by dispatchEarly(), dispatchEarlyWithAnswer(), dispatchEarlyWithOffer(), dispatchQueuedUpdate(), dispatchSentAnswer(), dispatchStart(), handleAnswer(), and handleOffer().

{
   assert(msg.isResponse());
   assert(msg.header(h_StatusLine).statusCode() < 200);
   assert(msg.header(h_StatusLine).statusCode() > 100);

   //.dcm. Kept the following checks here rather than discardMessage as the
   // state machine can be affected(termination).

   // !dcm! should we really end the InviteSession or should be discard the 1xx instead?
   if (msg.header(h_CSeq).sequence() != mLastLocalSessionModification->header(h_CSeq).sequence())
   {
      InfoLog (<< "Failure:  CSeq doesn't match invite: " << msg.brief());
      onFailureAspect(getHandle(), msg);
      end(NotSpecified);
      return;
   }
   else if (isReliable(msg))
   {
      if (!msg.exists(h_RSeq))
      {
         InfoLog (<< "Failure:  No RSeq in 1xx: " << msg.brief());
         onFailureAspect(getHandle(), msg);
         end(NotSpecified);
         return;
      }
   }

   startStaleCallTimer();
   onProvisionalAspect(getHandle(), msg);
}

Here is the call graph for this function:

void ClientInviteSession::handleRedirect ( const SipMessage msg) [private]
void ClientInviteSession::onConnectedAspect ( ClientInviteSessionHandle  h,
const SipMessage msg 
) [private]
void ClientInviteSession::onFailureAspect ( ClientInviteSessionHandle  c,
const SipMessage msg 
) [private]
void ClientInviteSession::onForkAccepted ( ) [private]

Definition at line 313 of file ClientInviteSession.cxx.

References resip::DialogUsageManager::addTimerMs(), resip::BaseUsage::getBaseHandle(), InfoLog, resip::BaseUsage::mDum, resip::InviteSession::mState, resip::Timer::TH, resip::InviteSession::toData(), resip::InviteSession::UAC_Early, resip::InviteSession::UAC_EarlyWithAnswer, resip::InviteSession::UAC_EarlyWithOffer, resip::InviteSession::UAC_ReceivedUpdateEarly, resip::InviteSession::UAC_SentUpdateEarly, and resip::DumTimeout::WaitingForForked2xx.

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

{
   switch(mState)
   {
      case UAC_Early:
      case UAC_EarlyWithOffer:
      case UAC_EarlyWithAnswer:
      case UAC_SentUpdateEarly:
      case UAC_ReceivedUpdateEarly:
         InfoLog (<< toData(mState) << ": onForkAccepted");
         // !jf! should we avoid creating another timer here? I don't think it
         // matters. Default timer is for 32secs. This is here to handle the
         // cleanup on forked INVITEs that have sent a provisional response but
         // don't ever receive a final response. 
         mDum.addTimerMs(DumTimeout::WaitingForForked2xx, Timer::TH, getBaseHandle(), 1); 
         break;
      default:
         // If the dialog is already set up (or cancelled) we disregard. 
         break;
   }
}

Here is the call graph for this function:

void ClientInviteSession::onProvisionalAspect ( ClientInviteSessionHandle  c,
const SipMessage msg 
) [private]
ClientInviteSession& resip::ClientInviteSession::operator= ( const ClientInviteSession ) [private]
void ClientInviteSession::provideAnswer ( const Contents answer) [virtual]

Similar to provideOffer - called to set the answer to be signalled to the peer.

May result in message being sent synchronously depending on the state.

Reimplemented from resip::InviteSession.

Definition at line 116 of file ClientInviteSession.cxx.

References resip::InviteSession::Connected, InfoLog, resip::InviteSession::makeOfferAnswer(), resip::Dialog::makeResponse(), resip::InviteSession::mCurrentEncryptionLevel, resip::InviteSession::mCurrentLocalOfferAnswer, resip::InviteSession::mCurrentRemoteOfferAnswer, resip::DialogUsage::mDialog, resip::InviteSession::mLastRemoteSessionModification, resip::InviteSession::mProposedRemoteOfferAnswer, resip::InviteSession::mState, resip::DialogUsage::send(), resip::InviteSession::sendAck(), sendPrack(), resip::InviteSession::setOfferAnswer(), resip::DumHelper::setOutgoingEncryptionLevel(), resip::InviteSession::Terminated, resip::InviteSession::toData(), resip::InviteSession::transition(), resip::InviteSession::UAC_Answered, resip::InviteSession::UAC_Cancelled, resip::InviteSession::UAC_Early, resip::InviteSession::UAC_EarlyWithAnswer, resip::InviteSession::UAC_EarlyWithOffer, resip::InviteSession::UAC_QueuedUpdate, resip::InviteSession::UAC_ReceivedUpdateEarly, resip::InviteSession::UAC_SentAnswer, resip::InviteSession::UAC_SentUpdateEarly, and resip::InviteSession::UAC_Start.

{
   InfoLog (<< toData(mState) << ": provideAnswer");

   switch(mState)
   {
      case UAC_EarlyWithOffer:
      {
         transition(UAC_SentAnswer);

         //  Remember proposed local offerAnswer.
         mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer;
         mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer);

         //  Creates an PRACK request with application supplied offer.
         sendPrack(answer);
         break;
      }

      case UAC_Answered:
      {
         transition(Connected);
         sendAck(&answer);

         mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer;
         mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer);
         // mLastSessionModification = ack;  // ?slg? is this needed?
         break;
      }
      case UAC_ReceivedUpdateEarly:
      {
         transition(UAC_EarlyWithAnswer); //.dcm. earlyWithAnwer is a strange
                                          //name...maybe earlyEstablished?
         //this sequence is repeated in many places...due for refactoring.
         //see ReceivedUpdate handling in InviteSession.
         //?dcm? are session timers allowed in the early dialog?

         SharedPtr<SipMessage> response(new SipMessage);
         mDialog.makeResponse(*response, *mLastRemoteSessionModification, 200);
         InviteSession::setOfferAnswer(*response, answer, 0);
         mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer);
         mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer;
         InfoLog (<< "Sending " << response->brief());
         DumHelper::setOutgoingEncryptionLevel(*response, mCurrentEncryptionLevel);
         send(response);
         break;
      }
        
      case UAC_Start:
      case UAC_Early:
      case UAC_EarlyWithAnswer:
      case UAC_SentUpdateEarly:
      case UAC_SentAnswer:
      case UAC_Cancelled:
      case UAC_QueuedUpdate:
      case Terminated:
         assert(0);
         break;

      default:
         InviteSession::provideAnswer(answer);
         break;
   }
}

Here is the call graph for this function:

void ClientInviteSession::provideOffer ( const Contents offer) [virtual]

Called to set the offer that will be used in the next message that sends an offer.

For a UAC in an early dialog, this can be used to send an UPDATE request with an offer.

Reimplemented from resip::InviteSession.

Definition at line 110 of file ClientInviteSession.cxx.

References resip::InviteSession::mCurrentEncryptionLevel.

Referenced by provideOffer().

{
   this->provideOffer(offer, mCurrentEncryptionLevel, 0);
}
void ClientInviteSession::provideOffer ( const Contents offer,
DialogUsageManager::EncryptionLevel  level,
const Contents alternative 
) [virtual]

Reimplemented from resip::InviteSession.

Definition at line 60 of file ClientInviteSession.cxx.

References InfoLog, resip::InviteSession::makeOfferAnswer(), resip::Dialog::makeRequest(), resip::DialogUsage::mDialog, resip::InviteSession::mLastLocalSessionModification, resip::InviteSession::mProposedEncryptionLevel, resip::InviteSession::mProposedLocalOfferAnswer, resip::InviteSession::mState, provideOffer(), resip::DialogUsage::send(), resip::InviteSession::setOfferAnswer(), resip::DumHelper::setOutgoingEncryptionLevel(), resip::InviteSession::Terminated, resip::InviteSession::toData(), resip::InviteSession::transition(), resip::InviteSession::UAC_Answered, resip::InviteSession::UAC_Cancelled, resip::InviteSession::UAC_Early, resip::InviteSession::UAC_EarlyWithAnswer, resip::InviteSession::UAC_EarlyWithOffer, resip::InviteSession::UAC_QueuedUpdate, resip::InviteSession::UAC_ReceivedUpdateEarly, resip::InviteSession::UAC_SentAnswer, resip::InviteSession::UAC_SentUpdateEarly, and resip::InviteSession::UAC_Start.

{
   InfoLog (<< toData(mState) << ": provideOffer");

   switch(mState)
   {
      case UAC_EarlyWithAnswer:
      {
         transition(UAC_SentUpdateEarly);

         //  Creates an UPDATE request with application supplied offer.
         mDialog.makeRequest(*mLastLocalSessionModification, UPDATE);
         InviteSession::setOfferAnswer(*mLastLocalSessionModification, offer);

         //  Remember proposed local offferAnswer.
         mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer, alternative);
         mProposedEncryptionLevel = level;

         //  Send the req and do state transition.
         DumHelper::setOutgoingEncryptionLevel(*mLastLocalSessionModification, mProposedEncryptionLevel);
         send(mLastLocalSessionModification);
         break;
      }

      case UAC_SentAnswer:
         // just queue it for later
         transition(UAC_QueuedUpdate);
         mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer, alternative);
         mProposedEncryptionLevel = level;
         break;

      case UAC_Start:
      case UAC_Early:
      case UAC_EarlyWithOffer:
      case UAC_Answered:
      case UAC_SentUpdateEarly:
      case UAC_ReceivedUpdateEarly:
      case UAC_Cancelled:
      case UAC_QueuedUpdate:
      case Terminated:
         assert(0);
         break;

      default:
         InviteSession::provideOffer(offer, level, alternative);
         break;
   }
}

Here is the call graph for this function:

void ClientInviteSession::reject ( int  statusCode,
WarningCategory warning = 0 
) [virtual]

Rejects an offer at the SIP level.

For a UAC in an early dialog this typically only makes sense, when rejecting an UPDATE request that contains an offer in an early dialog.

Reimplemented from resip::InviteSession.

Definition at line 237 of file ClientInviteSession.cxx.

References resip::SharedPtr< T >::get(), resip::InviteSession::getSessionHandle(), InfoLog, resip::InviteSessionHandler::LocalBye, resip::Dialog::makeResponse(), resip::DialogUsage::mDialog, resip::BaseUsage::mDum, resip::DialogUsageManager::mInviteSessionHandler, resip::InviteSession::mLastRemoteSessionModification, resip::InviteSession::mState, resip::InviteSessionHandler::onTerminated(), resip::DialogUsage::send(), resip::InviteSession::sendAck(), resip::InviteSession::sendBye(), resip::InviteSession::Terminated, resip::InviteSession::toData(), resip::InviteSession::transition(), resip::InviteSession::UAC_Answered, resip::InviteSession::UAC_Cancelled, resip::InviteSession::UAC_Early, resip::InviteSession::UAC_EarlyWithAnswer, resip::InviteSession::UAC_EarlyWithOffer, resip::InviteSession::UAC_ReceivedUpdateEarly, resip::InviteSession::UAC_SentAnswer, resip::InviteSession::UAC_SentUpdateEarly, resip::InviteSession::UAC_Start, and WarningLog.

{
   InfoLog (<< toData(mState) << ": reject(" << statusCode << ")");

   switch(mState)
   {
      case UAC_ReceivedUpdateEarly:
      {
         SharedPtr<SipMessage> response(new SipMessage);
         mDialog.makeResponse(*response, *mLastRemoteSessionModification, statusCode);
         if(warning)
         {
            response->header(h_Warnings).push_back(*warning);
         }

         //  Send the req and do state transition.
         send(response);
         transition(UAC_EarlyWithAnswer);
         break;
      }

      case UAC_Answered:{
         // We received an offer in a 2xx response, and we want to reject it
         // ACK with no body, then send bye
         sendAck();
         SharedPtr<SipMessage> msg = sendBye();
         transition(Terminated);
         mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalBye, msg.get()); 
         break;
      }

      case UAC_Start:
      case UAC_Early:
      case UAC_EarlyWithOffer:
      case UAC_EarlyWithAnswer:
      case UAC_SentUpdateEarly:
      case UAC_SentAnswer:
      case UAC_Cancelled:
         WarningLog (<< "Try to reject when in state=" << toData(mState));
         assert(0);
         break;

      default:
         InviteSession::reject(statusCode, warning);
         break;
   }
}

Here is the call graph for this function:

void ClientInviteSession::sendPrack ( const Contents offerAnswer) [private]

Definition at line 621 of file ClientInviteSession.cxx.

References resip::Dialog::makeRequest(), resip::InviteSession::mCurrentEncryptionLevel, resip::DialogUsage::mDialog, mRelRespInfo, resip::DialogUsage::send(), resip::InviteSession::setOfferAnswer(), and resip::DumHelper::setOutgoingEncryptionLevel().

Referenced by provideAnswer().

{
   SharedPtr<SipMessage> prack(new SipMessage);
   mDialog.makeRequest(*prack, PRACK);
   prack->header(h_RAck)= mRelRespInfo;
   
   InviteSession::setOfferAnswer(*prack, offerAnswer);

   //  Remember last session modification.
   // mLastSessionModification = prack; // ?slg? is this needed?

   DumHelper::setOutgoingEncryptionLevel(*prack, mCurrentEncryptionLevel);
   send(prack);
}

Here is the call graph for this function:

void ClientInviteSession::sendPrackIfNeeded ( const SipMessage msg) [private]

Definition at line 602 of file ClientInviteSession.cxx.

References h_StatusLine, resip::SipMessage::header(), resip::InviteSession::isReliable(), resip::SipMessage::isResponse(), resip::Dialog::makeRequest(), resip::DialogUsage::mDialog, mRelRespInfo, and resip::DialogUsage::send().

Referenced by dispatchEarlyWithAnswer(), dispatchEarlyWithOffer(), dispatchQueuedUpdate(), dispatchSentAnswer(), dispatchStart(), and handleAnswer().

{
   assert(msg.isResponse());
   assert(msg.header(h_StatusLine).statusCode() < 200);
   assert(msg.header(h_StatusLine).statusCode() > 100);
   
   if (isReliable(msg))
   {
      SharedPtr<SipMessage> prack(new SipMessage);
      mDialog.makeRequest(*prack, PRACK);
      prack->header(h_RAck) = mRelRespInfo;
      send(prack);
   }
}

Here is the call graph for this function:

void ClientInviteSession::sendSipFrag ( const SipMessage response) [private]

Definition at line 356 of file ClientInviteSession.cxx.

References resip::DialogSet::getUserProfile(), h_CallId, h_StatusLine, resip::SipMessage::header(), resip::SipMessage::isResponse(), resip::Handle< T >::isValid(), resip::DialogUsage::mDialog, resip::Dialog::mDialogSet, resip::SipFrag::message(), mServerSub, resip::InviteSession::mState, resip::InviteSession::UAC_Cancelled, and resip::InviteSession::UAC_Start.

Referenced by dispatch().

{
   if (mServerSub.isValid())
   {
      if (msg.isResponse() && mState >= UAC_Start && mState <= UAC_Cancelled)
      {
         int code = msg.header(h_StatusLine).statusCode();
         if (code > 100)
         {
            SipFrag contents;
            contents.message().header(h_StatusLine) = msg.header(h_StatusLine);
            if(mDialog.mDialogSet.getUserProfile()->getExtraHeadersInReferNotifySipFragEnabled())
            {
               contents.message().header(h_Vias) = msg.header(h_Vias);
               contents.message().header(h_From) = msg.header(h_From);
               contents.message().header(h_To) = msg.header(h_To);
               contents.message().header(h_CallId) = msg.header(h_CallId);
               contents.message().header(h_CSeq) = msg.header(h_CSeq);
               contents.message().header(h_Contacts) = msg.header(h_Contacts);
            }
            if (code < 200)
            {
               mServerSub->send(mServerSub->update(&contents));
            }
            else
            {
               mServerSub->end(NoResource, &contents);
            }
         }
      }
   }
}

Here is the call graph for this function:

void ClientInviteSession::startCancelTimer ( ) [private]
void ClientInviteSession::startStaleCallTimer ( ) [private]

Friends And Related Function Documentation

friend class Dialog [friend]

Reimplemented from resip::InviteSession.

Definition at line 99 of file ClientInviteSession.hxx.


Member Data Documentation

Definition at line 92 of file ClientInviteSession.hxx.

Referenced by dispatch(), dispatchCancelled(), and startCancelTimer().

Definition at line 88 of file ClientInviteSession.hxx.

Referenced by dispatchEarly(), dispatchStart(), and getEarlyMedia().

Definition at line 90 of file ClientInviteSession.hxx.

Referenced by checkRseq(), sendPrack(), and sendPrackIfNeeded().

Definition at line 93 of file ClientInviteSession.hxx.

Referenced by dispatch(), and sendSipFrag().

Definition at line 91 of file ClientInviteSession.hxx.

Referenced by dispatch(), handleFinalResponse(), and startStaleCallTimer().


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