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

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

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

revision 5544 by jason, Tue Oct 18 01:11:48 2005 UTC revision 5555 by sgodin, Wed Oct 19 14:04:10 2005 UTC
# Line 173  Line 173 
173        case SentUpdateGlare:        case SentUpdateGlare:
174        case SentReinvite:        case SentReinvite:
175        case SentReinviteGlare:        case SentReinviteGlare:
176          case SentReinviteNoOffer:
177          case SentReinviteAnswered:
178          case SentReinviteNoOfferGlare:
179        case ReceivedUpdate:        case ReceivedUpdate:
180        case ReceivedReinvite:        case ReceivedReinvite:
181        case ReceivedReinviteNoOffer:        case ReceivedReinviteNoOffer:
# Line 190  Line 193 
193  {  {
194     switch (mState)     switch (mState)
195     {     {
       case UAC_Start:  
196        case UAC_Early:        case UAC_Early:
197        case UAC_EarlyWithOffer:        case UAC_EarlyWithOffer:
198        case UAC_EarlyWithAnswer:        case UAC_EarlyWithAnswer:
           
          //case UAC_Answered:  
          //case UAC_Terminated:  
199        case UAC_SentUpdateEarly:        case UAC_SentUpdateEarly:
       case UAC_SentUpdateConnected:  
200        case UAC_ReceivedUpdateEarly:        case UAC_ReceivedUpdateEarly:
201           //case UAC_SentAnswer:        case UAC_SentAnswer:
202        case UAC_QueuedUpdate:        case UAC_QueuedUpdate:
203             return true;
204          default:
205             return false;
206       }
207    }
208    
209    bool
210    InviteSession::isAccepted() const
211    {
212       switch (mState)
213       {
214        case UAS_Start:        case UAS_Start:
215        case UAS_Offer:        case UAS_Offer:
216        case UAS_OfferProvidedAnswer:        case UAS_OfferProvidedAnswer:
217        case UAS_EarlyOffer:        case UAS_EarlyOffer:
218          case UAS_EarlyProvidedOffer:
219        case UAS_EarlyProvidedAnswer:        case UAS_EarlyProvidedAnswer:
220        case UAS_EarlyNoOffer:        case UAS_EarlyNoOffer:
221        case UAS_FirstEarlyReliable:        case UAS_FirstEarlyReliable:
222          case UAS_FirstSentOfferReliable:
223        case UAS_EarlyReliable:        case UAS_EarlyReliable:
224           return true;           return true;
   
225        default:        default:
226           return false;           return false;
227     }     }
228  }  }
229    
   
230  bool  bool
231  InviteSession::isTerminated() const  InviteSession::isTerminated() const
232  {  {
# Line 247  Line 255 
255  }  }
256    
257  void  void
258    InviteSession::requestOffer()
259    {
260       switch (mState)
261       {
262          case Connected:
263          case WaitingToRequestOffer:
264             transition(SentReinviteNoOffer);
265             mDialog.makeRequest(mLastSessionModification, INVITE);
266             mLastSessionModification.remove(h_ProxyAuthorizations); // remove remote credentials.
267             mLastSessionModification.setContents(0);               // Clear the SDP contents from the INVITE
268             setSessionTimerHeaders(mLastSessionModification);
269    
270             InfoLog (<< "Sending " << mLastSessionModification.brief());
271             // call send to give app an chance to adorn the message.
272             send(mLastSessionModification);
273             break;
274    
275          case Answered:
276             // queue the offer to be sent after the ACK is received
277             transition(WaitingToRequestOffer);
278             break;        
279            
280          // ?slg? Can we handle all of the states listed in isConnected() ???
281          default:
282             WarningLog (<< "Can't requestOffer when not in Connected state");
283             throw DialogUsage::Exception("Can't request an offer", __FILE__,__LINE__);
284       }
285    }
286    
287    void
288  InviteSession::provideOffer(const SdpContents& offer,  InviteSession::provideOffer(const SdpContents& offer,
289                              DialogUsageManager::EncryptionLevel level,                              DialogUsageManager::EncryptionLevel level,
290                              const SdpContents* alternative)                              const SdpContents* alternative)
# Line 347  Line 385 
385           break;           break;
386        }        }
387    
388          case SentReinviteAnswered:
389             transition(Connected);
390             sendAck(&answer);
391    
392             mCurrentRemoteSdp = mProposedRemoteSdp;
393             mCurrentLocalSdp = InviteSession::makeSdp(answer);
394             break;
395    
396        default:        default:
397           WarningLog (<< "Can't provideAnswer when not in Connected state");           WarningLog (<< "Can't provideAnswer when not in Connected state");
398           throw DialogUsage::Exception("Can't provide an offer", __FILE__,__LINE__);           throw DialogUsage::Exception("Can't provide an offer", __FILE__,__LINE__);
# Line 375  Line 421 
421        case SentUpdate:        case SentUpdate:
422        case SentUpdateGlare:        case SentUpdateGlare:
423        case SentReinviteGlare:        case SentReinviteGlare:
424          case SentReinviteNoOfferGlare:
425          case SentReinviteAnswered:
426        {        {
427           // !jf! do we need to store the BYE somewhere?           // !jf! do we need to store the BYE somewhere?
428           sendBye();           sendBye();
# Line 384  Line 432 
432        }        }
433    
434        case SentReinvite:        case SentReinvite:
435          case SentReinviteNoOffer:
436           transition(WaitingToTerminate);           transition(WaitingToTerminate);
437           break;           break;
438    
# Line 608  Line 657 
657        case SentReinvite:        case SentReinvite:
658           dispatchSentReinvite(msg);           dispatchSentReinvite(msg);
659           break;           break;
660          case SentReinviteNoOffer:
661             dispatchSentReinviteNoOffer(msg);
662             break;
663          case SentReinviteAnswered:
664             dispatchSentReinviteAnswered(msg);
665             break;
666        case SentUpdateGlare:        case SentUpdateGlare:
667        case SentReinviteGlare:        case SentReinviteGlare:
668           // The behavior is the same except for timer which is handled in dispatch(Timer)           // The behavior is the same except for timer which is handled in dispatch(Timer)
669           dispatchGlare(msg);           dispatchGlare(msg);
670           break;           break;
671          case SentReinviteNoOfferGlare:
672             dispatchReinviteNoOfferGlare(msg);
673             break;
674        case ReceivedUpdate:        case ReceivedUpdate:
675        case ReceivedReinvite:        case ReceivedReinvite:
676        case ReceivedReinviteNoOffer:        case ReceivedReinviteNoOffer:
# Line 627  Line 685 
685        case WaitingToOffer:        case WaitingToOffer:
686           dispatchWaitingToOffer(msg);           dispatchWaitingToOffer(msg);
687           break;           break;
688          case WaitingToRequestOffer:
689             dispatchWaitingToRequestOffer(msg);
690             break;
691        case WaitingToTerminate:        case WaitingToTerminate:
692           dispatchWaitingToTerminate(msg);           dispatchWaitingToTerminate(msg);
693           break;           break;
# Line 688  Line 749 
749              assert(mProposedLocalSdp.get());              assert(mProposedLocalSdp.get());
750              //!dcm! -- should this be onIllegalNegotiation?              //!dcm! -- should this be onIllegalNegotiation?
751              mDum.mInviteSessionHandler->onOfferRejected(getSessionHandle(), 0);              mDum.mInviteSessionHandler->onOfferRejected(getSessionHandle(), 0);
752              if (dynamic_cast<MultipartAlternativeContents*>(mProposedLocalSdp.get()))              provideProposedOffer();
            {  
                provideOffer( *(dynamic_cast<SdpContents*>((dynamic_cast<MultipartAlternativeContents*>(mProposedLocalSdp.get()))->parts().back())),  
                              mProposedEncryptionLevel,  
                              dynamic_cast<SdpContents*>((dynamic_cast<MultipartAlternativeContents*>(mProposedLocalSdp.get()))->parts().front()));  
             }  
             else  
             {  
                provideOffer(*(dynamic_cast<SdpContents*>(mProposedLocalSdp.get())), mProposedEncryptionLevel, 0);  
             }  
753           }           }
754        }        }
755     }     }
# Line 717  Line 769 
769           InfoLog (<< "Retransmitting the reINVITE (glare condition timer)");           InfoLog (<< "Retransmitting the reINVITE (glare condition timer)");
770           send(mLastSessionModification);           send(mLastSessionModification);
771        }        }
772          else if (mState == SentReinviteNoOfferGlare)
773          {
774             transition(SentReinviteNoOffer);
775    
776             InfoLog (<< "Retransmitting the reINVITE-nooffer (glare condition timer)");
777             send(mLastSessionModification);
778          }
779     }     }
780     else if (timeout.type() == DumTimeout::SessionExpiration)     else if (timeout.type() == DumTimeout::SessionExpiration)
781     {     {
# Line 763  Line 822 
822           mLastSessionModification = msg;           mLastSessionModification = msg;
823           transition(ReceivedReinvite);           transition(ReceivedReinvite);
824           mCurrentEncryptionLevel = getEncryptionLevel(msg);           mCurrentEncryptionLevel = getEncryptionLevel(msg);
825             mProposedRemoteSdp = InviteSession::makeSdp(*sdp);
826    
827           //handler->onDialogModified(getSessionHandle(), Offer, msg);           //handler->onDialogModified(getSessionHandle(), Offer, msg);
828           handler->onOffer(getSessionHandle(), msg, *sdp);           handler->onOffer(getSessionHandle(), msg, *sdp);
829           break;           break;
# Line 783  Line 844 
844           //  See rfc3311 5.2, 4th paragraph.           //  See rfc3311 5.2, 4th paragraph.
845           mLastSessionModification = msg;           mLastSessionModification = msg;
846           mCurrentEncryptionLevel = getEncryptionLevel(msg);           mCurrentEncryptionLevel = getEncryptionLevel(msg);
847             mProposedRemoteSdp = InviteSession::makeSdp(*sdp);
848           handler->onOffer(getSessionHandle(), msg, *sdp);           handler->onOffer(getSessionHandle(), msg, *sdp);
849           break;           break;
850    
# Line 923  Line 985 
985           break;           break;
986    
987        case On2xxAnswer:        case On2xxAnswer:
988        case On2xxOffer:        case On2xxOffer:  // !slg! doesn't really make sense
989        {        {
990           transition(Connected);           transition(Connected);
991           handleSessionTimerResponse(msg);           handleSessionTimerResponse(msg);
# Line 1012  Line 1074 
1074  }  }
1075    
1076  void  void
1077    InviteSession::dispatchSentReinviteNoOffer(const SipMessage& msg)
1078    {
1079       InviteSessionHandler* handler = mDum.mInviteSessionHandler;
1080       std::auto_ptr<SdpContents> sdp = InviteSession::getSdp(msg);
1081    
1082       switch (toEvent(msg, sdp.get()))
1083       {
1084          case OnInvite:
1085          case OnInviteReliable:
1086          case OnInviteOffer:
1087          case OnInviteReliableOffer:
1088          case OnUpdate:
1089          case OnUpdateOffer:
1090          {
1091             SipMessage response;
1092             mDialog.makeResponse(response, msg, 491);
1093             BaseUsage::send(response);
1094             break;
1095          }
1096    
1097          case On1xx:
1098          case On1xxEarly:
1099             // Some UA's send a 100 response to a ReInvite - just ignore it
1100             break;
1101    
1102          case On2xxAnswer:  // !slg! doesn't really make sense
1103          case On2xxOffer:
1104          {
1105             transition(SentReinviteAnswered);
1106             handleSessionTimerResponse(msg);
1107             mLastSessionModification = msg;
1108             mCurrentEncryptionLevel = getEncryptionLevel(msg);
1109             mProposedRemoteSdp = InviteSession::makeSdp(*sdp);
1110             handler->onOffer(getSessionHandle(), msg, *sdp);
1111    
1112             // !jf! do I need to allow a reINVITE overlapping the retransmission of
1113             // the ACK when a 200I is received? If yes, then I need to store all
1114             // ACK messages for 64*T1
1115             break;
1116          }
1117    
1118          case On2xx:
1119             sendAck();
1120             transition(Connected);
1121             handleSessionTimerResponse(msg);
1122             handler->onIllegalNegotiation(getSessionHandle(), msg);
1123             mProposedLocalSdp.release();
1124             mProposedEncryptionLevel = DialogUsageManager::None;
1125             break;
1126    
1127          case On422Invite:
1128             if(msg.exists(h_MinSE))
1129             {
1130                // Change interval to min from 422 response
1131                mSessionInterval = msg.header(h_MinSE).value();
1132                mMinSE = mSessionInterval;
1133                setSessionTimerHeaders(mLastSessionModification);
1134                send(mLastSessionModification);
1135             }
1136             else
1137             {
1138                // Response must contact Min_SE - if not - just ignore
1139                // ?slg? callback?
1140                transition(Connected);
1141                mProposedLocalSdp.release();
1142                mProposedEncryptionLevel = DialogUsageManager::None;
1143             }
1144             break;
1145    
1146          case On491Invite:
1147             transition(SentReinviteNoOfferGlare);
1148             start491Timer();
1149             break;
1150    
1151          case OnGeneralFailure:
1152             sendBye();
1153             transition(Terminated);
1154             handler->onTerminated(getSessionHandle(), InviteSessionHandler::GeneralFailure, &msg);
1155             break;
1156    
1157          case OnInviteFailure:
1158          case On487Invite:
1159          case On489Invite:
1160             transition(Connected);
1161             mProposedLocalSdp.release();
1162             handler->onOfferRejected(getSessionHandle(), &msg);
1163             break;
1164    
1165          default:
1166             dispatchOthers(msg);
1167             break;
1168       }
1169    }
1170    
1171    void
1172  InviteSession::dispatchReceivedReinviteSentOffer(const SipMessage& msg)  InviteSession::dispatchReceivedReinviteSentOffer(const SipMessage& msg)
1173  {  {
1174     InviteSessionHandler* handler = mDum.mInviteSessionHandler;     InviteSessionHandler* handler = mDum.mInviteSessionHandler;
# Line 1058  Line 1215 
1215  {  {
1216     InviteSessionHandler* handler = mDum.mInviteSessionHandler;     InviteSessionHandler* handler = mDum.mInviteSessionHandler;
1217     MethodTypes method = msg.header(h_CSeq).method();     MethodTypes method = msg.header(h_CSeq).method();
1218     if (method == INVITE && msg.isRequest())     if (msg.isRequest() && (method == INVITE || method == UPDATE))
1219     {     {
1220        // Received inbound reinvite, when waiting to resend outbound reinvite or update        // Received inbound reinvite or update, when waiting to resend outbound reinvite or update
       transition(ReceivedReinvite);  
1221        handler->onOfferRejected(getSessionHandle(), &msg);        handler->onOfferRejected(getSessionHandle(), &msg);
1222          dispatchConnected(msg);  // act as if we received message in Connected state
1223     }     }
1224     else if (method == UPDATE && msg.isRequest())     else
1225     {     {
1226        // Received inbound update, when waiting to resend outbound reinvite or update        dispatchOthers(msg);
1227        transition(ReceivedUpdate);     }
1228        handler->onOfferRejected(getSessionHandle(), &msg);  }
1229    
1230    void
1231    InviteSession::dispatchReinviteNoOfferGlare(const SipMessage& msg)
1232    {
1233       InviteSessionHandler* handler = mDum.mInviteSessionHandler;
1234       MethodTypes method = msg.header(h_CSeq).method();
1235       if (msg.isRequest() && (method == INVITE || method == UPDATE))
1236       {
1237          // Received inbound reinvite or update, when waiting to resend outbound reinvite or update
1238          handler->onOfferRequestRejected(getSessionHandle(), msg);
1239          dispatchConnected(msg);  // act as if we received message in Connected state
1240     }     }
1241     else     else
1242     {     {
# Line 1111  Line 1279 
1279  }  }
1280    
1281  void  void
1282    InviteSession::dispatchSentReinviteAnswered(const SipMessage& msg)
1283    {
1284       dispatchOthers(msg);
1285    }
1286    
1287    void
1288  InviteSession::dispatchWaitingToOffer(const SipMessage& msg)  InviteSession::dispatchWaitingToOffer(const SipMessage& msg)
1289  {  {
1290     if (msg.isRequest() && msg.header(h_RequestLine).method() == ACK)     if (msg.isRequest() && msg.header(h_RequestLine).method() == ACK)
1291     {     {
1292        assert(mProposedLocalSdp.get());        assert(mProposedLocalSdp.get());
1293        mCurrentRetransmit200 = 0; // stop the 200 retransmit timer        mCurrentRetransmit200 = 0; // stop the 200 retransmit timer
1294        if (dynamic_cast<MultipartAlternativeContents*>(mProposedLocalSdp.get()))        provideProposedOffer();
       {  
          provideOffer( *(dynamic_cast<SdpContents*>((dynamic_cast<MultipartAlternativeContents*>(mProposedLocalSdp.get()))->parts().back())),  
                        mProposedEncryptionLevel,  
                        dynamic_cast<SdpContents*>((dynamic_cast<MultipartAlternativeContents*>(mProposedLocalSdp.get()))->parts().front()));  
1295        }        }
1296        else        else
1297        {        {
1298           provideOffer(*(dynamic_cast<SdpContents*>(mProposedLocalSdp.get())), mProposedEncryptionLevel, 0);        dispatchOthers(msg);
1299        }        }
1300     }     }
1301    
1302    void
1303    InviteSession::dispatchWaitingToRequestOffer(const SipMessage& msg)
1304    {
1305       if (msg.isRequest() && msg.header(h_RequestLine).method() == ACK)
1306       {
1307          assert(mProposedLocalSdp.get());
1308          mCurrentRetransmit200 = 0; // stop the 200 retransmit timer
1309          requestOffer();
1310       }
1311     else     else
1312     {     {
1313        dispatchOthers(msg);        dispatchOthers(msg);
# Line 1627  Line 1807 
1807           return "InviteSession::SentReinvite";           return "InviteSession::SentReinvite";
1808        case SentReinviteGlare:        case SentReinviteGlare:
1809           return "InviteSession::SentReinviteGlare";           return "InviteSession::SentReinviteGlare";
1810          case SentReinviteNoOffer:
1811             return "InviteSession::SentReinviteNoOffer";
1812          case SentReinviteAnswered:
1813             return "InviteSession::SentReinviteAnswered";
1814          case SentReinviteNoOfferGlare:
1815             return "InviteSession::SentReinviteNoOfferGlare";
1816        case ReceivedUpdate:        case ReceivedUpdate:
1817           return "InviteSession::ReceivedUpdate";           return "InviteSession::ReceivedUpdate";
1818        case ReceivedReinvite:        case ReceivedReinvite:
# Line 1639  Line 1825 
1825           return "InviteSession::Answered";           return "InviteSession::Answered";
1826        case WaitingToOffer:        case WaitingToOffer:
1827           return "InviteSession::WaitingToOffer";           return "InviteSession::WaitingToOffer";
1828          case WaitingToRequestOffer:
1829             return "InviteSession::WaitingToRequestOffer";
1830        case WaitingToTerminate:        case WaitingToTerminate:
1831           return "InviteSession::WaitingToTerminate";           return "InviteSession::WaitingToTerminate";
1832        case WaitingToHangup:        case WaitingToHangup:
# Line 1805  Line 1993 
1993     msg.setContents(sdp);     msg.setContents(sdp);
1994  }  }
1995    
1996    void
1997    InviteSession::provideProposedOffer()
1998    {
1999       if (dynamic_cast<MultipartAlternativeContents*>(mProposedLocalSdp.get()))
2000       {
2001          provideOffer( *(dynamic_cast<SdpContents*>((dynamic_cast<MultipartAlternativeContents*>(mProposedLocalSdp.get()))->parts().back())),
2002                        mProposedEncryptionLevel,
2003                        dynamic_cast<SdpContents*>((dynamic_cast<MultipartAlternativeContents*>(mProposedLocalSdp.get()))->parts().front()));
2004       }
2005       else
2006       {
2007          provideOffer(*(dynamic_cast<SdpContents*>(mProposedLocalSdp.get())), mProposedEncryptionLevel, 0);
2008       }
2009    }
2010    
2011  InviteSession::Event  InviteSession::Event
2012  InviteSession::toEvent(const SipMessage& msg, const SdpContents* sdp)  InviteSession::toEvent(const SipMessage& msg, const SdpContents* sdp)
2013  {  {

Legend:
Removed from v.5544  
changed lines
  Added in v.5555

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27