|
reSIProcate/DialogUsageManager
9694
|
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 */
1.7.5.1