< Previous by Date Date Index Next by Date >
< Previous in Thread Thread Index  

Re: [reSIProcate] PRACK UAS support


Hi Scott,
An additional patch: if accept was called while waiting for prack, then
wasn't the 200 ok queued as it should.

best regards
Björn

On Wed, 2009-10-28 at 09:55 -0400, Scott Godin wrote:
> Thanks for this Bjorn - I apologize, I've been crazy busy lately -
> this is on my TODO list though.  : )
> 
> 
> Scott
> 
> On Mon, Oct 26, 2009 at 11:13 AM, Bjorn Andersson
> <bjorn.andersson@xxxxxxxxxx> wrote:
>         Hi Martin,
>         We discovered a bug the other day, so here is a patch for the
>         patch.
>         
>         Best Regards
>         Björn
> 
> 
--- ServerInviteSession.cxx.orig	2009-11-02 13:18:48.000000000 +0100
+++ ServerInviteSession.cxx	2009-11-02 13:24:12.000000000 +0100
@@ -338,57 +338,61 @@
          break;
    }
 }
 
 void 
 ServerInviteSession::provideAnswer(const SdpContents& answer)
 {
    InviteSessionHandler* handler = mDum.mInviteSessionHandler;
    InfoLog (<< toData(mState) << ": provideAnswer");
    mAnswerSentReliably = false;
    switch (mState)
    {
       case UAS_Offer:
          transition(UAS_OfferProvidedAnswer);
          mCurrentRemoteSdp = mProposedRemoteSdp;
          mCurrentLocalSdp = InviteSession::makeSdp(answer);
          break;
 
       case UAS_EarlyOffer:
          transition(UAS_EarlyProvidedAnswer);
          mCurrentRemoteSdp = mProposedRemoteSdp;
          mCurrentLocalSdp = InviteSession::makeSdp(answer);
          break;
          
       case UAS_ReceivedOfferReliable: 
-      case UAS_FirstNoAnswerReliable: 
          // send1XX-answer, timer::1xx
          mCurrentRemoteSdp = mProposedRemoteSdp;
          mCurrentLocalSdp = InviteSession::makeSdp(answer);
          transition(UAS_ReceivedOfferReliableProvidedAnswer);
          break;
 
+      case UAS_FirstNoAnswerReliable: 
+         mCurrentRemoteSdp = mProposedRemoteSdp;
+         mCurrentLocalSdp = InviteSession::makeSdp(answer);
+         break;
+
       case UAS_ReceivedUpdate:
          // send::200U-answer
          transition(UAS_NegotiatedReliable);
          break;
          
       case UAS_ReceivedUpdateWaitingAnswer:
          // send::2XXU-answer
          // send::2XXI
          transition(Connected);
          handler->onConnected(getSessionHandle(), *mInvite200);
          break;
 
       case UAS_NoAnswerReliable:
          mCurrentRemoteSdp = mProposedRemoteSdp;
          mCurrentLocalSdp = InviteSession::makeSdp(answer);
          break;
 
       case UAS_NegotiatedReliable:
          mCurrentRemoteSdp = mProposedRemoteSdp;
          mCurrentLocalSdp = InviteSession::makeSdp(answer);
          if(mPrackWithOffer.get())
          {
             SharedPtr<SipMessage> p200(new SipMessage);
             mDialog.makeResponse(*p200, *mPrackWithOffer, 200);
             setSdp(*p200, mCurrentLocalSdp.get());
@@ -492,50 +496,51 @@
       default:
          InviteSession::end(reason);
          break;
    }
 }
 
 void 
 ServerInviteSession::reject(int code, WarningCategory *warning)
 {
    InfoLog (<< toData(mState) << ": reject(" << code << ")");
 
    switch (mState)
    {
       case UAS_EarlyNoOffer:
       case UAS_EarlyOffer:
       case UAS_EarlyProvidedAnswer:
       case UAS_EarlyProvidedOffer:
       case UAS_NoOffer:
       case UAS_Offer:
       case UAS_OfferProvidedAnswer:
       case UAS_ProvidedOffer:
 
       case UAS_NegotiatedReliable:
       case UAS_FirstSentAnswerReliable:
       case UAS_FirstNoAnswerReliable:
+      case UAS_NoAnswerReliable:
       case UAS_FirstSentOfferReliable:
       case UAS_NoOfferReliable:
       case UAS_ReceivedOfferReliable: 
       case UAS_ReceivedUpdate:
       case UAS_SentUpdate:
       {
          // !jf! the cleanup for 3xx may be a bit strange if we are in the middle of
          // an offer/answer exchange with PRACK. 
          // e.g. we sent 183 reliably and then 302 before PRACK was received. Ideally,
          // we should send 200PRACK
          SharedPtr<SipMessage> response(new SipMessage);
          mDialog.makeResponse(*response, mFirstRequest, code);
          if(warning)
          {
             response->header(h_Warnings).push_back(*warning);
          }
          send(response);
 
          transition(Terminated);
          mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::Rejected); 
          mDum.destroy(this);
          break;
       }
 
       case UAS_Accepted:
@@ -570,50 +575,51 @@
       case UAS_OfferProvidedAnswer:
       case UAS_EarlyProvidedAnswer:
          transition(UAS_Accepted);
          sendAccept(code, mCurrentLocalSdp.get());
          handler->onConnected(getSessionHandle(), *mInvite200);
          break;
          
       case UAS_NoOffer:
       case UAS_EarlyNoOffer:
          assert(0);
 
       case UAS_ProvidedOffer:
       case UAS_EarlyProvidedOffer:
          transition(UAS_AcceptedWaitingAnswer);
          sendAccept(code, mProposedLocalSdp.get());
          break;
          
       case UAS_Accepted:
       case UAS_WaitingToOffer:
       case UAS_WaitingToRequestOffer:
          assert(0);  // Already Accepted
          break;
          
       case UAS_FirstSentAnswerReliable:
       case UAS_FirstSentOfferReliable:
+      case UAS_FirstNoAnswerReliable:
          // queue 2xx
          // waiting for PRACK
          InfoLog (<< "Waiting for PRACK. queued 200 OK" );
          mQueuedProvisionals.push_back( std::make_pair(code,false) );
          transition(UAS_Accepted);
          mDialog.makeResponse(*mInvite200, mFirstRequest, code);
          handleSessionTimerRequest(*mInvite200, mFirstRequest);
          break;
          
       case UAS_NegotiatedReliable:
       case UAS_ReceivedOfferReliableProvidedAnswer: 
          transition(UAS_Accepted);
          sendAccept(code, 0);
          handler->onConnected(getSessionHandle(), *mInvite200);
          break;
 
       case UAS_NoAnswerReliable:
          transition(UAS_Accepted);
          sendAccept(code, mCurrentLocalSdp.get());
          handler->onConnected(getSessionHandle(), *mInvite200);
          break;
 
       case UAS_SentUpdate:
          transition(UAS_SentUpdateAccepted);
          sendAccept(code, 0);