reSIProcate/DialogUsageManager  9694
ServerInviteSession.cxx
Go to the documentation of this file.
00001 #include "resip/stack/MultipartMixedContents.hxx"
00002 #include "resip/stack/MultipartAlternativeContents.hxx"
00003 #include "resip/dum/Dialog.hxx"
00004 #include "resip/dum/DialogEventStateManager.hxx"
00005 #include "resip/dum/DialogUsageManager.hxx"
00006 #include "resip/dum/DumTimeout.hxx"
00007 #include "resip/dum/InviteSessionHandler.hxx"
00008 #include "resip/dum/ServerInviteSession.hxx"
00009 #include "resip/dum/MasterProfile.hxx"
00010 #include "resip/dum/UsageUseException.hxx"
00011 #include "resip/dum/DumHelper.hxx"
00012 #include "resip/dum/DumCommand.hxx"
00013 #include "rutil/Logger.hxx"
00014 #include "rutil/compat.hxx"
00015 #include "rutil/WinLeakCheck.hxx"
00016 
00017 using namespace resip;
00018 
00019 #define RESIPROCATE_SUBSYSTEM Subsystem::DUM
00020 
00021 ServerInviteSession::ServerInviteSession(DialogUsageManager& dum, Dialog& dialog, const SipMessage& request)
00022    : InviteSession(dum, dialog),
00023      mFirstRequest(request),
00024      m1xx(new SipMessage),
00025      mCurrentRetransmit1xx(0)
00026 {
00027    assert(request.isRequest());
00028    mState = UAS_Start;
00029 }
00030 
00031 ServerInviteSessionHandle 
00032 ServerInviteSession::getHandle()
00033 {
00034    return ServerInviteSessionHandle(mDum, getBaseHandle().getId());
00035 }
00036 
00037 void 
00038 ServerInviteSession::redirect(const NameAddrs& contacts, int code)
00039 {
00040    InfoLog (<< toData(mState) << ": redirect(" << code << ")"); // -> " << contacts);
00041 
00042    switch (mState)
00043    {
00044       case UAS_EarlyNoOffer:
00045       case UAS_EarlyOffer:
00046       case UAS_EarlyProvidedAnswer:
00047       case UAS_EarlyProvidedOffer:
00048       case UAS_NegotiatedReliable:
00049       case UAS_FirstSentAnswerReliable:
00050       case UAS_FirstSentOfferReliable:
00051       case UAS_NoOffer:
00052       case UAS_NoOfferReliable:
00053       case UAS_Offer:
00054       case UAS_OfferProvidedAnswer:
00055       case UAS_ReceivedOfferReliable: 
00056       case UAS_ProvidedOffer:
00057       case UAS_ReceivedUpdate:
00058       case UAS_ReceivedUpdateWaitingAnswer:
00059       case UAS_SentUpdate:
00060       {
00061          // !jf! the cleanup for 3xx may be a bit strange if we are in the middle of
00062          // an offer/answer exchange with PRACK. 
00063          // e.g. we sent 183 reliably and then 302 before PRACK was received. Ideally,
00064          // we should send 200PRACK
00065          SharedPtr<SipMessage> response(new SipMessage);
00066          mDialog.makeResponse(*response, mFirstRequest, code);
00067          response->header(h_Contacts) = contacts;
00068          send(response);
00069 
00070          if (mDum.mDialogEventStateManager)
00071          {
00072             mDum.mDialogEventStateManager->onTerminated(mDialog, *response, InviteSessionHandler::Rejected);
00073          }
00074 
00075          transition(Terminated);
00076 
00077          mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::Referred); 
00078          mDum.destroy(this);
00079          break;
00080       }
00081 
00082       case UAS_Accepted:
00083       case UAS_WaitingToOffer:
00084       case UAS_WaitingToRequestOffer:
00085       case UAS_WaitingToHangup:
00086       case UAS_WaitingToTerminate:
00087       case UAS_SentUpdateAccepted:
00088       case UAS_Start:
00089       default:
00090          assert(0);
00091          throw UsageUseException("Can't redirect after accepted", __FILE__, __LINE__);
00092          break;
00093    }
00094 }
00095 
00096 class ServerInviteSessionRedirectCommand : public DumCommandAdapter
00097 {
00098 public:
00099    ServerInviteSessionRedirectCommand(ServerInviteSession& serverInviteSession, const NameAddrs& contacts, int code)
00100       : mServerInviteSession(serverInviteSession),
00101       mContacts(contacts),
00102       mCode(code)
00103    {
00104 
00105    }
00106 
00107    virtual void executeCommand()
00108    {
00109       mServerInviteSession.redirect(mContacts, mCode);
00110    }
00111 
00112    virtual EncodeStream& encodeBrief(EncodeStream& strm) const
00113    {
00114       return strm << "ServerInviteSessionRedirectCommand";
00115    }
00116 private:
00117    ServerInviteSession& mServerInviteSession;
00118    NameAddrs mContacts;
00119    int mCode;
00120 };
00121 
00122 void 
00123 ServerInviteSession::redirectCommand(const NameAddrs& contacts, int code)
00124 {
00125    mDum.post(new ServerInviteSessionRedirectCommand(*this, contacts, code));
00126 }
00127 
00128 void 
00129 ServerInviteSession::provisional(int code, bool earlyFlag)
00130 {
00131    InfoLog (<< toData(mState) << ": provisional(" << code << ")");
00132 
00133    switch (mState)
00134    {
00135       case UAS_Offer:
00136          transition(UAS_EarlyOffer);
00137          sendProvisional(code, earlyFlag);
00138          break;
00139 
00140       case UAS_OfferProvidedAnswer:
00141       case UAS_EarlyProvidedAnswer:
00142          transition(UAS_EarlyProvidedAnswer);
00143          sendProvisional(code, earlyFlag);
00144          break;
00145 
00146       case UAS_ProvidedOffer:
00147       case UAS_EarlyProvidedOffer:
00148          transition(UAS_EarlyProvidedOffer);
00149          sendProvisional(code, earlyFlag);
00150          break;
00151          
00152       case UAS_EarlyOffer:
00153          transition(UAS_EarlyOffer);
00154          sendProvisional(code, earlyFlag);
00155          break;
00156          
00157       case UAS_NoOffer:
00158       case UAS_EarlyNoOffer:
00159          transition(UAS_EarlyNoOffer);
00160          sendProvisional(code, earlyFlag);
00161          break;
00162          
00163 
00164       case UAS_NoOfferReliable:
00165       case UAS_NegotiatedReliable:
00166          // TBD
00167          assert(0);
00168          break;
00169          
00170       case UAS_Accepted:
00171       case UAS_WaitingToOffer:
00172       case UAS_WaitingToRequestOffer:
00173       case UAS_FirstSentAnswerReliable:
00174       case UAS_FirstSentOfferReliable:
00175       case UAS_ReceivedOfferReliable: 
00176       case UAS_ReceivedUpdate:
00177       case UAS_ReceivedUpdateWaitingAnswer:
00178       case UAS_SentUpdate:
00179       case UAS_SentUpdateAccepted:
00180       case UAS_Start:
00181       case UAS_WaitingToHangup:
00182       case UAS_WaitingToTerminate:
00183       default:
00184          assert(0);
00185          break;
00186    }
00187 }
00188 
00189 class ServerInviteSessionProvisionalCommand : public DumCommandAdapter
00190 {
00191 public:
00192    ServerInviteSessionProvisionalCommand(ServerInviteSession& serverInviteSession, int statusCode)
00193       : mServerInviteSession(serverInviteSession),
00194         mStatusCode(statusCode)
00195    {
00196    }
00197 
00198    virtual void executeCommand()
00199    {
00200       mServerInviteSession.provisional(mStatusCode);
00201    }
00202 
00203    virtual EncodeStream& encodeBrief(EncodeStream& strm) const
00204    {
00205       return strm << "ServerInviteSessionProvisionalCommand";
00206    }
00207 private:
00208    ServerInviteSession& mServerInviteSession;
00209    int mStatusCode;
00210 };
00211 
00212 void 
00213 ServerInviteSession::provisionalCommand(int statusCode)
00214 {
00215    mDum.post(new ServerInviteSessionProvisionalCommand(*this, statusCode));
00216 }
00217 
00218 void
00219 ServerInviteSession::provideOffer(const Contents& offer,
00220                                   DialogUsageManager::EncryptionLevel level, 
00221                                   const Contents* alternative)
00222 {
00223    InfoLog (<< toData(mState) << ": provideOffer");
00224    switch (mState)
00225    {
00226       case UAS_NoOffer:
00227          transition(UAS_ProvidedOffer);
00228          mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer, alternative);
00229          mProposedEncryptionLevel = level;
00230          break;
00231 
00232       case UAS_EarlyNoOffer:
00233          transition(UAS_EarlyProvidedOffer);
00234          mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer, alternative);
00235          mProposedEncryptionLevel = level;
00236          break;
00237          
00238       case UAS_NoOfferReliable:
00239          mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer, alternative);
00240          mProposedEncryptionLevel = level;
00241          // !jf! transition ? 
00242          break;
00243 
00244       case UAS_NegotiatedReliable:
00245          // queue offer
00246          transition(UAS_SentUpdate);
00247          mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer, alternative);
00248          mProposedEncryptionLevel = level;
00249          sendUpdate(offer);
00250          break;
00251          
00252       case UAS_Accepted:
00253          // queue the offer to be sent after the ACK is received
00254          transition(UAS_WaitingToOffer);
00255          mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer);
00256          mProposedEncryptionLevel = level;
00257          break;
00258 
00259       case UAS_WaitingToOffer:
00260          InviteSession::provideOffer(offer, level, alternative);
00261          break;
00262 
00263       case UAS_EarlyProvidedAnswer:
00264       case UAS_EarlyProvidedOffer:
00265       case UAS_FirstSentAnswerReliable:
00266       case UAS_FirstSentOfferReliable:
00267       case UAS_Offer:
00268       case UAS_EarlyOffer:
00269       case UAS_ReceivedOfferReliable: 
00270       case UAS_OfferProvidedAnswer:
00271       case UAS_ProvidedOffer:
00272       case UAS_ReceivedUpdate:
00273       case UAS_ReceivedUpdateWaitingAnswer:
00274       case UAS_SentUpdate:
00275       case UAS_SentUpdateAccepted:
00276       case UAS_Start:
00277       case UAS_WaitingToHangup:
00278       case UAS_WaitingToTerminate:
00279       case UAS_WaitingToRequestOffer:
00280       case UAS_AcceptedWaitingAnswer:
00281          assert(0);
00282          break;
00283       default:
00284          InviteSession::provideOffer(offer, level, alternative);
00285          break;
00286    }
00287 }
00288 
00289 void 
00290 ServerInviteSession::provideOffer(const Contents& offer)
00291 {
00292    this->provideOffer(offer, mCurrentEncryptionLevel, 0);
00293 }
00294 
00295 
00296 void
00297 ServerInviteSession::requestOffer()
00298 {
00299    InfoLog (<< toData(mState) << ": requestOffer");
00300    switch (mState)
00301    {
00302       case UAS_Accepted:
00303          // queue the request to be sent after the ACK is received
00304          transition(UAS_WaitingToRequestOffer);
00305          break;
00306 
00307       case UAS_WaitingToRequestOffer:
00308          InviteSession::requestOffer();
00309          break;
00310 
00311       default:
00312          InviteSession::requestOffer();
00313          break;
00314    }
00315 }
00316 
00317 void 
00318 ServerInviteSession::provideAnswer(const Contents& answer)
00319 {
00320    InviteSessionHandler* handler = mDum.mInviteSessionHandler;
00321    InfoLog (<< toData(mState) << ": provideAnswer");
00322    switch (mState)
00323    {
00324       case UAS_Offer:
00325          transition(UAS_OfferProvidedAnswer);
00326          mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer;
00327          mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer);
00328          break;
00329 
00330       case UAS_EarlyOffer:
00331          transition(UAS_EarlyProvidedAnswer);
00332          mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer;
00333          mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer);
00334          break;
00335          
00336       case UAS_ReceivedOfferReliable: 
00337          // send1XX-answer, timer::1xx
00338          transition(UAS_FirstSentAnswerReliable);
00339          break;
00340 
00341       case UAS_ReceivedUpdate:
00342          // send::200U-answer
00343          transition(UAS_NegotiatedReliable);
00344          break;
00345          
00346       case UAS_ReceivedUpdateWaitingAnswer:
00347          // send::2XXU-answer
00348          // send::2XXI
00349          transition(Connected);
00350          handler->onConnected(getSessionHandle(), *mInvite200);
00351          break;
00352 
00353       case UAS_Accepted:
00354       case UAS_WaitingToOffer:
00355       case UAS_WaitingToRequestOffer:
00356       case UAS_EarlyNoOffer:
00357       case UAS_EarlyProvidedAnswer:
00358       case UAS_EarlyProvidedOffer:
00359       case UAS_NegotiatedReliable:
00360       case UAS_FirstSentAnswerReliable:
00361       case UAS_FirstSentOfferReliable:
00362       case UAS_NoOffer:
00363       case UAS_NoOfferReliable:
00364       case UAS_OfferProvidedAnswer:
00365       case UAS_ProvidedOffer:
00366       case UAS_SentUpdate:
00367       case UAS_SentUpdateAccepted:
00368       case UAS_Start:
00369       case UAS_WaitingToHangup:
00370       case UAS_WaitingToTerminate:
00371       case UAS_AcceptedWaitingAnswer:
00372          assert(0);
00373          break;
00374       default:
00375          InviteSession::provideAnswer(answer);
00376          break;
00377    }
00378 }
00379 
00380 void
00381 ServerInviteSession::end()
00382 {
00383    end(NotSpecified);
00384 }
00385 
00386 void
00387 ServerInviteSession::end(const Data& userReason)
00388 {
00389    mUserEndReason = userReason;
00390    end(InviteSession::UserSpecified);
00391 }
00392 
00393 void 
00394 ServerInviteSession::end(EndReason reason)
00395 {
00396    InfoLog (<< toData(mState) << ": end");
00397    if (mEndReason == NotSpecified)
00398    {
00399       mEndReason = reason;   
00400    }
00401    
00402    switch (mState)
00403    {
00404       case UAS_EarlyNoOffer:
00405       case UAS_EarlyOffer:
00406       case UAS_EarlyProvidedAnswer:
00407       case UAS_EarlyProvidedOffer:
00408       case UAS_NoOffer:
00409       case UAS_Offer:
00410       case UAS_OfferProvidedAnswer:
00411       case UAS_ProvidedOffer:
00412          reject(480);
00413          break;         
00414          
00415       case UAS_ReceivedOfferReliable: 
00416       case UAS_NegotiatedReliable:
00417       case UAS_FirstSentOfferReliable:
00418       case UAS_FirstSentAnswerReliable:
00419       case UAS_NoOfferReliable:
00420       case UAS_ReceivedUpdate:   // !slg! todo: send 488U
00421       case UAS_ReceivedUpdateWaitingAnswer: // !slg! todo: send 488U
00422       case UAS_SentUpdate:
00423       case UAS_WaitingToTerminate:
00424          reject(480);
00425          break;
00426          
00427       case UAS_Start:
00428          assert(0);
00429          break;
00430 
00431       case UAS_Accepted:
00432       case UAS_WaitingToOffer:
00433       case UAS_WaitingToRequestOffer:
00434       case UAS_SentUpdateAccepted:
00435       case UAS_AcceptedWaitingAnswer:
00436          if(mCurrentRetransmit200)  // If retransmit200 timer is active then ACK is not received yet - wait for it
00437          {
00438             transition(UAS_WaitingToHangup);
00439          }
00440          else
00441          {
00442              // ACK has likely timedout - hangup immediately
00443              SharedPtr<SipMessage> msg = sendBye();
00444              transition(Terminated);
00445              mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalBye, msg.get());
00446          }
00447          break;
00448 
00449       case UAS_WaitingToHangup:     // This can happen if we are waiting for an ACK to hangup and the ACK timesout
00450           break;
00451          
00452       default:
00453          InviteSession::end(reason);
00454          break;
00455    }
00456 }
00457 
00458 void 
00459 ServerInviteSession::reject(int code, WarningCategory *warning)
00460 {
00461    InfoLog (<< toData(mState) << ": reject(" << code << ")");
00462 
00463    switch (mState)
00464    {
00465       case UAS_EarlyNoOffer:
00466       case UAS_EarlyOffer:
00467       case UAS_EarlyProvidedAnswer:
00468       case UAS_EarlyProvidedOffer:
00469       case UAS_NoOffer:
00470       case UAS_Offer:
00471       case UAS_OfferProvidedAnswer:
00472       case UAS_ProvidedOffer:
00473 
00474       case UAS_NegotiatedReliable:
00475       case UAS_FirstSentAnswerReliable:
00476       case UAS_FirstSentOfferReliable:
00477       case UAS_NoOfferReliable:
00478       case UAS_ReceivedOfferReliable: 
00479       case UAS_ReceivedUpdate:
00480       case UAS_SentUpdate:
00481       {
00482          // !jf! the cleanup for 3xx may be a bit strange if we are in the middle of
00483          // an offer/answer exchange with PRACK. 
00484          // e.g. we sent 183 reliably and then 302 before PRACK was received. Ideally,
00485          // we should send 200PRACK
00486          SharedPtr<SipMessage> response(new SipMessage);
00487          mDialog.makeResponse(*response, mFirstRequest, code);
00488          if(warning)
00489          {
00490             response->header(h_Warnings).push_back(*warning);
00491          }
00492          send(response);
00493 
00494          transition(Terminated);
00495          mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::Rejected); 
00496          mDum.destroy(this);
00497          break;
00498       }
00499 
00500       case UAS_Accepted:
00501       case UAS_WaitingToOffer:
00502       case UAS_WaitingToRequestOffer:
00503       case UAS_ReceivedUpdateWaitingAnswer:
00504       case UAS_SentUpdateAccepted:
00505       case UAS_Start:
00506       case UAS_WaitingToHangup:
00507       case UAS_WaitingToTerminate:
00508          assert(0);
00509          break;
00510 
00511       default:
00512          InviteSession::reject(code);
00513          break;
00514    }
00515 }
00516 
00517 void 
00518 ServerInviteSession::accept(int code)
00519 {
00520    InfoLog (<< toData(mState) << ": accept(" << code << ")");
00521    InviteSessionHandler* handler = mDum.mInviteSessionHandler;
00522    switch (mState)
00523    {
00524       case UAS_Offer:
00525       case UAS_EarlyOffer:
00526          assert(0);
00527          break;
00528 
00529       case UAS_OfferProvidedAnswer:
00530       case UAS_EarlyProvidedAnswer:
00531          transition(UAS_Accepted);
00532          sendAccept(code, mCurrentLocalOfferAnswer.get());
00533          handler->onConnected(getSessionHandle(), *mInvite200);
00534          break;
00535          
00536       case UAS_NoOffer:
00537       case UAS_EarlyNoOffer:
00538          assert(0);
00539          break;
00540 
00541       case UAS_ProvidedOffer:
00542       case UAS_EarlyProvidedOffer:
00543          transition(UAS_AcceptedWaitingAnswer);
00544          sendAccept(code, mProposedLocalOfferAnswer.get());
00545          break;
00546          
00547       case UAS_Accepted:
00548       case UAS_WaitingToOffer:
00549       case UAS_WaitingToRequestOffer:
00550          assert(0);  // Already Accepted
00551          break;
00552          
00553       case UAS_FirstSentAnswerReliable:
00554          // queue 2xx
00555          // waiting for PRACK
00556          transition(UAS_Accepted);
00557          mDialog.makeResponse(*mInvite200, mFirstRequest, code);
00558          handleSessionTimerRequest(*mInvite200, mFirstRequest);
00559          break;
00560          
00561       case UAS_NegotiatedReliable:
00562          transition(Connected);
00563          sendAccept(code, 0);
00564          handler->onConnected(getSessionHandle(), *mInvite200);
00565          break;
00566 
00567       case UAS_SentUpdate:
00568          transition(UAS_SentUpdateAccepted);
00569          sendAccept(code, 0);
00570          break;
00571 
00572       case UAS_ReceivedUpdate:
00573          transition(UAS_ReceivedUpdateWaitingAnswer);
00574          mDialog.makeResponse(*mInvite200, mFirstRequest, code);// queue 2xx
00575          handleSessionTimerRequest(*mInvite200, mFirstRequest);
00576          break;
00577          
00578       case UAS_FirstSentOfferReliable:
00579       case UAS_NoOfferReliable:
00580       case UAS_ReceivedOfferReliable: 
00581       case UAS_ReceivedUpdateWaitingAnswer:
00582       case UAS_SentUpdateAccepted:
00583       case UAS_Start:
00584       case UAS_WaitingToHangup:
00585       case UAS_WaitingToTerminate:
00586       default:
00587          assert(0);
00588          break;
00589    }
00590 }
00591 
00592 class ServerInviteSessionAcceptCommand : public DumCommandAdapter
00593 {
00594 public:
00595    ServerInviteSessionAcceptCommand(ServerInviteSession& serverInviteSession, int statusCode)
00596       : mServerInviteSession(serverInviteSession),
00597         mStatusCode(statusCode)
00598    {
00599    }
00600 
00601    virtual void executeCommand()
00602    {
00603       mServerInviteSession.accept(mStatusCode);
00604    }
00605 
00606    virtual EncodeStream& encodeBrief(EncodeStream& strm) const
00607    {
00608       return strm << "ServerInviteSessionAcceptCommand";
00609    }
00610 private:
00611    ServerInviteSession& mServerInviteSession;
00612    int mStatusCode;
00613 };
00614 
00615 void 
00616 ServerInviteSession::acceptCommand(int statusCode)
00617 {
00618    mDum.post(new ServerInviteSessionAcceptCommand(*this, statusCode));
00619 }
00620 
00621 void 
00622 ServerInviteSession::dispatch(const SipMessage& msg)
00623 {
00624    if (msg.isRequest())
00625    {
00626       if (msg.header(h_RequestLine).method() == INFO)
00627       {
00628          InviteSession::dispatchInfo(msg);
00629          return;
00630       }
00631       if (msg.header(h_RequestLine).method() == MESSAGE)
00632       {
00633          InviteSession::dispatchMessage(msg);
00634          return;
00635       }
00636    }
00637 
00638    switch (mState)
00639    {
00640       case UAS_Start:
00641          dispatchStart(msg);
00642          break;
00643 
00644       case UAS_Offer:
00645       case UAS_EarlyOffer:
00646       case UAS_EarlyProvidedAnswer:
00647       case UAS_NoOffer:
00648       case UAS_ProvidedOffer:
00649       case UAS_EarlyNoOffer:
00650       case UAS_EarlyProvidedOffer:
00651       case UAS_OfferProvidedAnswer:
00652          dispatchOfferOrEarly(msg);
00653          break;       
00654       case UAS_Accepted:
00655          dispatchAccepted(msg);
00656          break;
00657       case UAS_WaitingToOffer:
00658          dispatchWaitingToOffer(msg);
00659          break;
00660       case UAS_WaitingToRequestOffer:
00661          dispatchWaitingToRequestOffer(msg);
00662          break;
00663       case UAS_AcceptedWaitingAnswer:
00664          dispatchAcceptedWaitingAnswer(msg);
00665          break;         
00666       case UAS_NegotiatedReliable:
00667          dispatchEarlyReliable(msg);
00668          break;
00669       case UAS_FirstSentAnswerReliable:
00670          dispatchFirstEarlyReliable(msg);
00671          break;
00672       case UAS_FirstSentOfferReliable:
00673          dispatchFirstSentOfferReliable(msg);
00674          break;
00675       case UAS_NoOfferReliable:
00676          dispatchNoOfferReliable(msg);
00677          break;
00678       case UAS_ReceivedOfferReliable:
00679          dispatchOfferReliable(msg);
00680          break;
00681       case UAS_ReceivedUpdate:
00682          dispatchReceivedUpdate(msg);
00683          break;
00684       case UAS_ReceivedUpdateWaitingAnswer:
00685          dispatchReceivedUpdateWaitingAnswer(msg);
00686          break;
00687       case UAS_SentUpdate:
00688          dispatchSentUpdate(msg);
00689          break;
00690       case UAS_WaitingToHangup:
00691          dispatchWaitingToHangup(msg);
00692          break;
00693       case UAS_WaitingToTerminate:
00694          dispatchWaitingToTerminate(msg);
00695          break;
00696       case UAS_SentUpdateAccepted:
00697          dispatchSentUpdateAccepted(msg);
00698          break;
00699       default:
00700          InviteSession::dispatch(msg);
00701          break;
00702    }
00703 }
00704 
00705 void 
00706 ServerInviteSession::dispatch(const DumTimeout& timeout)
00707 {
00708    if (timeout.type() == DumTimeout::Retransmit1xx)
00709    {
00710       if (mCurrentRetransmit1xx && m1xx->header(h_CSeq).sequence() == timeout.seq())  // If timer isn't stopped and this timer is for last 1xx sent, then resend
00711       {
00712          send(m1xx);
00713          startRetransmit1xxTimer();
00714       }
00715    }
00716    else
00717    {
00718       InviteSession::dispatch(timeout);
00719    }
00720 }
00721 
00722 void
00723 ServerInviteSession::dispatchStart(const SipMessage& msg)
00724 {
00725    assert(msg.isRequest());
00726    assert(msg.header(h_CSeq).method() == INVITE);
00727 
00728    InviteSessionHandler* handler = mDum.mInviteSessionHandler;
00729    std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg);
00730    storePeerCapabilities(msg);
00731 
00732    if (mDum.mDialogEventStateManager)
00733    {
00734       mDum.mDialogEventStateManager->onTryingUas(mDialog, msg);
00735    }
00736 
00737    switch (toEvent(msg, offerAnswer.get()))
00738    {
00739       case OnInviteOffer:
00740          *mLastRemoteSessionModification = msg;
00741          transition(UAS_Offer);
00742          mProposedRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer);
00743          mCurrentEncryptionLevel = getEncryptionLevel(msg);
00744          handler->onNewSession(getHandle(), InviteSession::Offer, msg);
00745          if(!isTerminated())  
00746          {
00747             handler->onOffer(getSessionHandle(), msg, *offerAnswer);
00748          }
00749          break;
00750       case OnInvite:
00751          *mLastRemoteSessionModification = msg;
00752          transition(UAS_NoOffer);
00753          handler->onNewSession(getHandle(), InviteSession::None, msg);
00754          if(!isTerminated())  
00755          {
00756             handler->onOfferRequired(getSessionHandle(), msg);
00757          }
00758          break;
00759       case OnInviteReliableOffer:
00760          *mLastRemoteSessionModification = msg;
00761          transition(UAS_ReceivedOfferReliable);
00762          mProposedRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer);
00763          mCurrentEncryptionLevel = getEncryptionLevel(msg);
00764          handler->onNewSession(getHandle(), InviteSession::Offer, msg);
00765          if(!isTerminated())  
00766          {
00767             handler->onOffer(getSessionHandle(), msg, *offerAnswer);
00768          }
00769          break;
00770       case OnInviteReliable:
00771          *mLastRemoteSessionModification = msg;
00772          transition(UAS_NoOfferReliable);
00773          handler->onNewSession(getHandle(), InviteSession::None, msg);
00774          if(!isTerminated())  
00775          {
00776             handler->onOfferRequired(getSessionHandle(), msg);
00777          }
00778          break;
00779       default:
00780          assert(0);
00781          break;
00782    }
00783 }
00784 
00785 // Offer, Early, EarlyNoOffer, NoOffer
00786 void
00787 ServerInviteSession::dispatchOfferOrEarly(const SipMessage& msg)
00788 {
00789    std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg);
00790    switch (toEvent(msg, offerAnswer.get()))
00791    {
00792       case OnCancel:
00793          dispatchCancel(msg);
00794          break;
00795       case OnBye:
00796          dispatchBye(msg);
00797          break;
00798       default:
00799          assert(msg.isRequest());
00800          dispatchUnknown(msg);
00801          break;
00802    }
00803 }
00804 
00805 void
00806 ServerInviteSession::dispatchAccepted(const SipMessage& msg)
00807 {
00808    InviteSessionHandler* handler = mDum.mInviteSessionHandler;
00809    std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg);
00810    InfoLog (<< "dispatchAccepted: " << msg.brief());
00811    
00812    switch (toEvent(msg, offerAnswer.get()))
00813    {
00814       case OnInvite:
00815       case OnInviteReliable:
00816       case OnInviteOffer:
00817       case OnInviteReliableOffer:
00818       case OnUpdate:
00819       case OnUpdateOffer:
00820       {
00821          SharedPtr<SipMessage> response(new SipMessage);
00822          mDialog.makeResponse(*response, msg, 491);
00823          send(response);
00824          break;
00825       }
00826 
00827       case OnAck:
00828       case OnAckAnswer:  // .bwc. unsolicited body in ACK; it would probably make sense to just ignore.
00829       {
00830          mCurrentRetransmit200 = 0; // stop the 200 retransmit timer
00831          transition(Connected);
00832          handler->onConnectedConfirmed(getSessionHandle(), msg);  
00833          break;
00834       }
00835       
00836       case OnCancel:
00837       {
00838          // Cancel and 200 crossed
00839          SharedPtr<SipMessage> c200(new SipMessage);
00840          mDialog.makeResponse(*c200, msg, 200);
00841          send(c200);
00842          break;
00843       }
00844 
00845       case OnBye:
00846       {
00847          SharedPtr<SipMessage> b200(new SipMessage);
00848          mDialog.makeResponse(*b200, msg, 200);
00849          send(b200);
00850 
00851          transition(Terminated);
00852          handler->onTerminated(getSessionHandle(), InviteSessionHandler::RemoteBye, &msg);
00853          mDum.destroy(this);
00854          break;
00855       }
00856         
00857       
00858       default:
00859          if(msg.isRequest())
00860          {
00861             dispatchUnknown(msg);
00862          }
00863          break;
00864    }
00865 }
00866 
00867 void
00868 ServerInviteSession::dispatchWaitingToOffer(const SipMessage& msg)
00869 {
00870    InviteSessionHandler* handler = mDum.mInviteSessionHandler;
00871    std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg);
00872    InfoLog (<< "dispatchWaitingToOffer: " << msg.brief());
00873    
00874    switch (toEvent(msg, offerAnswer.get()))
00875    {
00876       case OnInvite:
00877       case OnInviteReliable:
00878       case OnInviteOffer:
00879       case OnInviteReliableOffer:
00880       case OnUpdate:
00881       case OnUpdateOffer:
00882       {
00883          SharedPtr<SipMessage> response(new SipMessage);
00884          mDialog.makeResponse(*response, msg, 491);
00885          send(response);
00886          break;
00887       }
00888 
00889       case OnAck:
00890       {
00891          assert(mProposedLocalOfferAnswer.get());
00892          mCurrentRetransmit200 = 0; // stop the 200 retransmit timer
00893          provideProposedOffer(); 
00894          break;
00895       }
00896 
00897       case OnAckAnswer:
00898       {
00899          mCurrentRetransmit200 = 0; // stop the 200 retransmit timer
00900          sendBye();
00901          transition(Terminated);
00902          handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); 
00903          break;
00904       }
00905       
00906       case OnCancel:
00907       {
00908          // Cancel and 200 crossed
00909          SharedPtr<SipMessage> c200(new SipMessage);
00910          mDialog.makeResponse(*c200, msg, 200);
00911          send(c200);
00912          break;
00913       }
00914 
00915       case OnBye:
00916       {
00917          SharedPtr<SipMessage> b200(new SipMessage);
00918          mDialog.makeResponse(*b200, msg, 200);
00919          send(b200);
00920 
00921          transition(Terminated);
00922          handler->onTerminated(getSessionHandle(), InviteSessionHandler::RemoteBye, &msg);
00923          mDum.destroy(this);
00924          break;
00925       }
00926               
00927       default:
00928          if(msg.isRequest())
00929          {
00930             dispatchUnknown(msg);
00931          }
00932          break;
00933    }
00934 }
00935 
00936 void
00937 ServerInviteSession::dispatchWaitingToRequestOffer(const SipMessage& msg)
00938 {
00939    InviteSessionHandler* handler = mDum.mInviteSessionHandler;
00940    std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg);
00941    InfoLog (<< "dispatchWaitingToRequestOffer: " << msg.brief());
00942    
00943    switch (toEvent(msg, offerAnswer.get()))
00944    {
00945       case OnInvite:
00946       case OnInviteReliable:
00947       case OnInviteOffer:
00948       case OnInviteReliableOffer:
00949       case OnUpdate:
00950       case OnUpdateOffer:
00951       {
00952          SharedPtr<SipMessage> response(new SipMessage);
00953          mDialog.makeResponse(*response, msg, 491);
00954          send(response);
00955          break;
00956       }
00957 
00958       case OnAck:
00959       {
00960          mCurrentRetransmit200 = 0; // stop the 200 retransmit timer
00961          requestOffer(); 
00962          break;
00963       }
00964 
00965       case OnAckAnswer:
00966       {
00967          mCurrentRetransmit200 = 0; // stop the 200 retransmit timer
00968          sendBye();
00969          transition(Terminated);
00970          handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); 
00971          break;
00972       }
00973       
00974       case OnCancel:
00975       {
00976          // Cancel and 200 crossed
00977          SharedPtr<SipMessage> c200(new SipMessage);
00978          mDialog.makeResponse(*c200, msg, 200);
00979          send(c200);
00980          break;
00981       }
00982 
00983       case OnBye:
00984       {
00985          SharedPtr<SipMessage> b200(new SipMessage);
00986          mDialog.makeResponse(*b200, msg, 200);
00987          send(b200);
00988 
00989          transition(Terminated);
00990          handler->onTerminated(getSessionHandle(), InviteSessionHandler::RemoteBye, &msg);
00991          mDum.destroy(this);
00992          break;
00993       }
00994               
00995       default:
00996          if(msg.isRequest())
00997          {
00998             dispatchUnknown(msg);
00999          }
01000          break;
01001    }
01002 }
01003 
01004 void
01005 ServerInviteSession::dispatchAcceptedWaitingAnswer(const SipMessage& msg)
01006 {
01007    InviteSessionHandler* handler = mDum.mInviteSessionHandler;
01008    std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg);
01009 
01010    switch (toEvent(msg, offerAnswer.get()))
01011    {
01012       case OnInvite:
01013       case OnInviteReliable:
01014       case OnInviteOffer:
01015       case OnInviteReliableOffer:
01016       case OnUpdate:
01017       case OnUpdateOffer:
01018       {
01019          SharedPtr<SipMessage> response(new SipMessage);
01020          mDialog.makeResponse(*response, msg, 491);
01021          send(response);
01022          break;
01023       }
01024 
01025       case OnAckAnswer:
01026       {
01027          mCurrentRetransmit200 = 0; // stop the 200 retransmit timer
01028          transition(Connected);
01029          setCurrentLocalOfferAnswer(msg);
01030          mCurrentEncryptionLevel = getEncryptionLevel(msg);
01031          mCurrentRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer);
01032          handler->onAnswer(getSessionHandle(), msg, *offerAnswer);
01033          if(!isTerminated())  // onAnswer callback may call end() or reject()
01034          {
01035             handler->onConnected(getSessionHandle(), msg);
01036          }
01037          break;
01038       }
01039 
01040       case OnAck:
01041       {
01042          mCurrentRetransmit200 = 0; // stop the 200 retransmit timer
01043          mEndReason = IllegalNegotiation;
01044          sendBye();
01045          transition(Terminated);
01046          handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg);
01047          break;
01048       }
01049          
01050       case OnCancel:
01051       {
01052          // no transition
01053 
01054          SharedPtr<SipMessage> c200(new SipMessage);
01055          mDialog.makeResponse(*c200, msg, 200);
01056          send(c200);
01057          break;
01058       }
01059 
01060       case OnPrack: // broken
01061       {
01062          // no transition
01063 
01064          SharedPtr<SipMessage> p200(new SipMessage);
01065          mDialog.makeResponse(*p200, msg, 200);
01066          send(p200);
01067          
01068          sendAccept(200, 0);         
01069          break;
01070       }
01071 
01072       default:
01073          if(msg.isRequest())
01074          {
01075             dispatchUnknown(msg);
01076          }
01077          break;
01078    }
01079 }
01080 
01081 void
01082 ServerInviteSession::dispatchOfferReliable(const SipMessage& msg)
01083 {
01084 }
01085 
01086 void
01087 ServerInviteSession::dispatchNoOfferReliable(const SipMessage& msg)
01088 {
01089 }
01090 
01091 void
01092 ServerInviteSession::dispatchFirstSentOfferReliable(const SipMessage& msg)
01093 {
01094 }
01095 
01096 void
01097 ServerInviteSession::dispatchFirstEarlyReliable(const SipMessage& msg)
01098 {
01099 }
01100 
01101 void
01102 ServerInviteSession::dispatchEarlyReliable(const SipMessage& msg)
01103 {
01104 }
01105 
01106 void
01107 ServerInviteSession::dispatchSentUpdate(const SipMessage& msg)
01108 {
01109 }
01110 
01111 void
01112 ServerInviteSession::dispatchSentUpdateAccepted(const SipMessage& msg)
01113 {
01114 }
01115 
01116 void
01117 ServerInviteSession::dispatchReceivedUpdate(const SipMessage& msg)
01118 {
01119 }
01120 
01121 void
01122 ServerInviteSession::dispatchReceivedUpdateWaitingAnswer(const SipMessage& msg)
01123 {
01124 }
01125 
01126 void
01127 ServerInviteSession::dispatchWaitingToTerminate(const SipMessage& msg)
01128 {
01129 }
01130 
01131 void
01132 ServerInviteSession::dispatchWaitingToHangup(const SipMessage& msg)
01133 {
01134    std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg);
01135 
01136    switch (toEvent(msg, offerAnswer.get()))
01137    {
01138       case OnPrack:
01139       case OnAck:
01140       case OnAckAnswer:
01141       {
01142          mCurrentRetransmit200 = 0; // stop the 200 retransmit timer
01143 
01144          SharedPtr<SipMessage> msg = sendBye();
01145          transition(Terminated);
01146          mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalBye, msg.get());
01147          break;
01148       }
01149       
01150       default:
01151          break;
01152    }
01153 }
01154 
01155 void
01156 ServerInviteSession::dispatchCancel(const SipMessage& msg)
01157 {
01158    SharedPtr<SipMessage> c200(new SipMessage);
01159    mDialog.makeResponse(*c200, msg, 200);
01160    send(c200);
01161 
01162    SharedPtr<SipMessage> i487(new SipMessage);
01163    mDialog.makeResponse(*i487, mFirstRequest, 487);
01164    send(i487);
01165 
01166    transition(Terminated);
01167 
01168    if (mDum.mDialogEventStateManager)
01169    {
01170       mDum.mDialogEventStateManager->onTerminated(mDialog, msg, InviteSessionHandler::RemoteCancel);
01171    }
01172 
01173    mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::RemoteCancel, &msg);
01174    mDum.destroy(this);
01175 }
01176 
01177 void
01178 ServerInviteSession::dispatchBye(const SipMessage& msg)
01179 {
01180    SharedPtr<SipMessage> b200(new SipMessage);
01181    mDialog.makeResponse(*b200, msg, 200);
01182    send(b200);
01183 // !dcm! -- pretty sure we shouldn't 487 after the BYE/200
01184    SharedPtr<SipMessage> i487(new SipMessage);
01185    mDialog.makeResponse(*i487, mFirstRequest, 487);
01186    send(i487);
01187 
01188    transition(Terminated);
01189 
01190    mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::RemoteBye, &msg);
01191    mDum.destroy(this);
01192 }
01193 
01194 void
01195 ServerInviteSession::dispatchUnknown(const SipMessage& msg)
01196 {
01197    SharedPtr<SipMessage> r481(new SipMessage); // !jf! what should we send here? 
01198    mDialog.makeResponse(*r481, msg, 481);
01199    send(r481);
01200    
01201    SharedPtr<SipMessage> i400(new SipMessage);
01202    mDialog.makeResponse(*i400, mFirstRequest, 400);
01203    send(i400);
01204 
01205    transition(Terminated);
01206    mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg);
01207    mDum.destroy(this);
01208 }
01209 
01210 void 
01211 ServerInviteSession::startRetransmit1xxTimer()
01212 {
01213    // RFC3261 13.3.1 says the UAS must send a non-100 provisional response every minute, to handle the possiblity of lost provisional responses
01214    mCurrentRetransmit1xx = mDialog.mDialogSet.getUserProfile()->get1xxRetransmissionTime();  
01215    if(mCurrentRetransmit1xx > 0)
01216    {    
01217       unsigned int seq = m1xx->header(h_CSeq).sequence();
01218       mDum.addTimer(DumTimeout::Retransmit1xx, mCurrentRetransmit1xx, getBaseHandle(), seq);
01219    }
01220 }
01221 
01222 void
01223 ServerInviteSession::sendProvisional(int code, bool earlyFlag)
01224 {
01225    mDialog.makeResponse(*m1xx, mFirstRequest, code);
01226    if(!earlyFlag)
01227    {
01228            m1xx->setContents(0);  // clear contents if present
01229    }
01230    else
01231    {
01232       switch (mState)
01233       {
01234          case UAS_OfferProvidedAnswer:
01235          case UAS_EarlyProvidedAnswer:
01236             if (mCurrentLocalOfferAnswer.get()) // early media
01237             {
01238                setOfferAnswer(*m1xx, mCurrentLocalOfferAnswer.get());
01239             }
01240             break;
01241          case UAS_ProvidedOffer:
01242          case UAS_EarlyProvidedOffer:
01243             if (mProposedLocalOfferAnswer.get()) 
01244             {
01245                setOfferAnswer(*m1xx, mProposedLocalOfferAnswer.get());
01246             }
01247             break;
01248 
01249          default:
01250             break;
01251       }
01252    }
01253    startRetransmit1xxTimer();
01254    DumHelper::setOutgoingEncryptionLevel(*m1xx, mProposedEncryptionLevel);
01255 
01256    if (mDum.mDialogEventStateManager)
01257    {
01258       mDum.mDialogEventStateManager->onEarly(mDialog, getSessionHandle());
01259    }
01260 
01261    send(m1xx);
01262 }
01263 
01264 void
01265 ServerInviteSession::sendAccept(int code, Contents* offerAnswer)
01266 {
01267    mDialog.makeResponse(*mInvite200, mFirstRequest, code);
01268    handleSessionTimerRequest(*mInvite200, mFirstRequest);
01269    if (offerAnswer)
01270    {
01271       setOfferAnswer(*mInvite200, offerAnswer);
01272    }
01273    mCurrentRetransmit1xx = 0; // Stop the 1xx timer
01274    startRetransmit200Timer(); // 2xx timer
01275    DumHelper::setOutgoingEncryptionLevel(*mInvite200, mCurrentEncryptionLevel);
01276 
01277    if (mDum.mDialogEventStateManager)
01278    {
01279       mDum.mDialogEventStateManager->onConfirmed(mDialog, getSessionHandle());
01280    }
01281 
01282    send(mInvite200);
01283 }
01284 
01285 void
01286 ServerInviteSession::sendUpdate(const Contents& offerAnswer)
01287 {
01288    if (updateMethodSupported())
01289    {
01290       mDialog.makeRequest(*mLastLocalSessionModification, UPDATE);
01291       InviteSession::setOfferAnswer(*mLastLocalSessionModification, offerAnswer);
01292       DumHelper::setOutgoingEncryptionLevel(*mLastLocalSessionModification, mProposedEncryptionLevel);
01293       send(mLastLocalSessionModification);
01294    }
01295    else
01296    {
01297       throw UsageUseException("Can't send UPDATE to peer", __FILE__, __LINE__);
01298    }
01299 }
01300 
01301 /* ====================================================================
01302  * The Vovida Software License, Version 1.0 
01303  * 
01304  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
01305  * 
01306  * Redistribution and use in source and binary forms, with or without
01307  * modification, are permitted provided that the following conditions
01308  * are met:
01309  * 
01310  * 1. Redistributions of source code must retain the above copyright
01311  *    notice, this list of conditions and the following disclaimer.
01312  * 
01313  * 2. Redistributions in binary form must reproduce the above copyright
01314  *    notice, this list of conditions and the following disclaimer in
01315  *    the documentation and/or other materials provided with the
01316 
01317  *    distribution.
01318  * 
01319  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
01320  *    and "Vovida Open Communication Application Library (VOCAL)" must
01321  *    not be used to endorse or promote products derived from this
01322  *    software without prior written permission. For written
01323  *    permission, please contact vocal@vovida.org.
01324  *
01325  * 4. Products derived from this software may not be called "VOCAL", nor
01326  *    may "VOCAL" appear in their name, without prior written
01327  *    permission of Vovida Networks, Inc.
01328  * 
01329  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
01330  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
01331  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
01332  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
01333  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
01334  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
01335  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
01336  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
01337  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
01338  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
01339  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
01340  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
01341  * DAMAGE.
01342  * 
01343  * ====================================================================
01344  * 
01345  * This software consists of voluntary contributions made by Vovida
01346  * Networks, Inc. and many individuals on behalf of Vovida Networks,
01347  * Inc.  For more information on Vovida Networks, Inc., please see
01348  * <http://www.vovida.org/>.
01349  *
01350  */