📄 dialog.cxx
字号:
{ InfoLog ( << "Spurious INFO" ); return; } else { mInviteSession->dispatch(request); } break; case MESSAGE: if (mInviteSession == 0) { InfoLog ( << "Spurious MESSAGE" ); return; } else { mInviteSession->dispatch(request); } break; case ACK: case CANCEL: if (mInviteSession == 0) { InfoLog (<< "Drop stray ACK or CANCEL in dialog on the floor"); DebugLog (<< request); } else { mInviteSession->dispatch(request); } break; case SUBSCRIBE: { ServerSubscription* server = findMatchingServerSub(request); if (server) { server->dispatch(request); } else { if (request.exists(h_Event) && request.header(h_Event).value() == "refer") { InfoLog (<< "Received a subscribe to a non-existent refer subscription: " << request.brief()); SipMessage failure; makeResponse(failure, request, 403); mDum.sendResponse(failure); return; } else { if (mDum.checkEventPackage(request)) { server = makeServerSubscription(request); mServerSubscriptions.push_back(server); server->dispatch(request); } } } } break; case REFER: {// if (mInviteSession == 0)// {// InfoLog (<< "Received an in dialog refer in a non-invite dialog: " << request.brief());// SipMessage failure;// makeResponse(failure, request, 603);// mDum.sendResponse(failure);// return;// }// else if (!request.exists(h_ReferTo)) { InfoLog (<< "Received refer w/out a Refer-To: " << request.brief()); SipMessage failure; makeResponse(failure, request, 400); mDum.sendResponse(failure); return; } else { if (request.exists(h_ReferSub) && request.header(h_ReferSub).value()=="false") { assert(mInviteSession); mInviteSession->referNoSub(msg); } else { ServerSubscription* server = findMatchingServerSub(request); ServerSubscriptionHandle serverHandle; if (server) { serverHandle = server->getHandle(); server->dispatch(request); } else { server = makeServerSubscription(request); mServerSubscriptions.push_back(server); serverHandle = server->getHandle(); server->dispatch(request); } if (mInviteSession) { mDum.mInviteSessionHandler->onRefer(mInviteSession->getSessionHandle(), serverHandle, msg); } } } } break; case NOTIFY: { ClientSubscription* client = findMatchingClientSub(request); if (client) { client->dispatch(request); } else { BaseCreator* creator = mDialogSet.getCreator(); if (creator && (creator->getLastRequest()->header(h_RequestLine).method() == SUBSCRIBE || creator->getLastRequest()->header(h_RequestLine).method() == REFER)) { DebugLog (<< "Making subscription (from creator) request: " << *creator->getLastRequest()); ClientSubscription* sub = makeClientSubscription(*creator->getLastRequest()); mClientSubscriptions.push_back(sub); sub->dispatch(request); } else { if (mInviteSession != 0 && (!msg.exists(h_Event) || msg.header(h_Event).value() == "refer") && mDum.getClientSubscriptionHandler("refer")!=0) { DebugLog (<< "Making subscription from NOTIFY: " << msg); ClientSubscription* sub = makeClientSubscription(msg); mClientSubscriptions.push_back(sub); ClientSubscriptionHandle client = sub->getHandle(); mDum.mInviteSessionHandler->onReferAccepted(mInviteSession->getSessionHandle(), client, msg); sub->dispatch(request); } else { SharedPtr<SipMessage> response(new SipMessage); makeResponse(*response, msg, 406); send(response); } } } } break; default: assert(0); return; } } else if (msg.isResponse()) { // !jf! There is a substantial change in how this works in teltel-branch // from how it worked in main branch pre merge. // If the response doesn't match a cseq for a request I've sent, ignore // the response RequestMap::iterator r = mRequests.find(msg.header(h_CSeq).sequence()); if (r != mRequests.end()) { bool handledByAuth = false; if (mDum.mClientAuthManager.get() && mDum.mClientAuthManager->handle(*mDialogSet.getUserProfile(), *r->second, msg)) { InfoLog( << "about to re-send request with digest credentials" << r->second->brief()); assert (r->second->isRequest()); mLocalCSeq++; send(r->second); handledByAuth = true; } mRequests.erase(r); if (handledByAuth) return; } const SipMessage& response = msg; int code = response.header(h_StatusLine).statusCode(); // If this is a 200 response to the initial request, then store the routeset (if present) BaseCreator* creator = mDialogSet.getCreator(); if (creator && (creator->getLastRequest()->header(h_CSeq) == response.header(h_CSeq)) && code >=200 && code < 300) { if (response.exists(h_RecordRoutes)) { mRouteSet = response.header(h_RecordRoutes).reverse(); } else { // Ensure that if the route-set in the 200 is empty, then we overwrite any existing route-sets mRouteSet.clear(); } } // !jf! should this only be for 2xx responses? !jf! Propose no as an // answer !dcm! what is he on? switch (response.header(h_CSeq).method()) { case INVITE: if (mInviteSession == 0) { DebugLog ( << "Dialog::dispatch -- Created new client invite session" << msg.brief()); mInviteSession = makeClientInviteSession(response); mInviteSession->dispatch(response); } else { mInviteSession->dispatch(response); } break; case BYE: case ACK: case CANCEL: case INFO: case MESSAGE: case UPDATE: if (mInviteSession) { mInviteSession->dispatch(response); } // else drop on the floor break; case REFER: if(mInviteSession) { if (code >= 300) { mDum.mInviteSessionHandler->onReferRejected(mInviteSession->getSessionHandle(), msg); } else { //!dys! the OR condition below is not draft compliant. if (!mInviteSession->mReferSub && ((msg.exists(h_ReferSub) && msg.header(h_ReferSub).value()=="false") || !msg.exists(h_ReferSub))) { DebugLog(<< "refer accepted with norefersub"); mDum.mInviteSessionHandler->onReferAccepted(mInviteSession->getSessionHandle(), ClientSubscriptionHandle::NotValid(), msg); } // else no need for action - first Notify will cause onReferAccepted to be called } mInviteSession->nitComplete(); break; } // fall through, out of dialog refer was sent. case SUBSCRIBE: { int code = response.header(h_StatusLine).statusCode(); ClientSubscription* client = findMatchingClientSub(response); if (client) { client->dispatch(response); } else if (code < 300) { /* we're capturing the value from the expires header off the 2xx because the ClientSubscription is only created after receiving the NOTIFY that comes (usually) after this 2xx. We really should be creating the ClientSubscription at either the 2xx or the NOTIFY whichever arrives first. .mjf. Note: we're capturing a duration here (not the absolute time because all the inputs to ClientSubscription desling with the expiration are expecting duration type values from the headers. .mjf. */ if(response.exists(h_Expires)) { mDefaultSubExpiration = response.header(h_Expires).value(); } else { //?dcm? defaults to 3600 in ClientSubscription if no expires value //is provided anywhere...should we assume the value from the //sub in the basecreator if it exists? mDefaultSubExpiration = 0; } return; } else { //!dcm! -- can't subscribe in an existing Dialog, this is all //a bit of a hack; currently, spurious failure messages may cause callbacks BaseCreator* creator = mDialogSet.getCreator(); if (!creator || !creator->getLastRequest()->exists(h_Event)) { return; } else { ClientSubscriptionHandler* handler = mDum.getClientSubscriptionHandler(creator->getLastRequest()->header(h_Event).value()); if (handler) { ClientSubscription* sub = makeClientSubscription(*creator->getLastRequest()); mClientSubscriptions.push_back(sub); sub->dispatch(response); } } } } break; case NOTIFY: { //2xx responses are treated as retransmission quenchers(handled by //the stack). Failures are dispatched to all ServerSubsscriptions, //which may not be correct. int code = msg.header(h_StatusLine).statusCode(); if (code >= 300) { //!dcm! -- ick, write guard mDestroying = true; for (list<ServerSubscription*>::iterator it = mServerSubscriptions.begin(); it != mServerSubscriptions.end(); ) { ServerSubscription* s = *it; it++; s->dispatch(msg); } mDestroying = false; possiblyDie(); }// ServerSubscription* server = findMatchingServerSub(response);// if (server)// {// server->dispatch(response);// } } break; default: assert(0); return; }#if 0 // merged from head back to teltel-branch if (msg.header(h_StatusLine).statusCode() >= 400 && Helper::determineFailureMessageEffect(msg) == Helper::DialogTermination) { //kill all usages mDestroying = true; for (list<ServerSubscription*>::iterator it = mServerSubscriptions.begin(); it != mServerSubscriptions.end(); ) { ServerSubscription* s = *it; it++; s->dialogDestroyed(msg); } for (list<ClientSubscription*>::iterator it = mClientSubscriptions.begin(); it != mClientSubscriptions.end(); ) { ClientSubscription* s = *it; it++; s->dialogDestroyed(msg); } if (mInviteSession) { mInviteSession->dialogDestroyed(msg); } mDestroying = false; possiblyDie(); //should aways result in destruction of this return; }#endif }}ServerSubscription*Dialog::findMatchingServerSub(const SipMessage& msg){ for (std::list<ServerSubscription*>::iterator i=mServerSubscriptions.begin(); i != mServerSubscriptions.end(); ++i) { if ((*i)->matches(msg)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -