📄 dialogusagemanager.cxx
字号:
InfoLog(<<"Got a DumFeatureMessage" << featureMsg); tid = featureMsg->getTransactionId(); } } if (tid == Data::Empty && mOutgoingMessageInterceptor.get()) { mOutgoingMessageInterceptor->process(message.get()); return; } else if (tid != Data::Empty && !mOutgoingFeatureList.empty()) { FeatureChainMap::iterator it; //efficiently find or create FeatureChain, should prob. be a utility template { FeatureChainMap::iterator lb = mOutgoingFeatureChainMap.lower_bound(tid); if (lb != mOutgoingFeatureChainMap.end() && !(mOutgoingFeatureChainMap.key_comp()(tid, lb->first))) { it = lb; } else { it = mOutgoingFeatureChainMap.insert(lb, FeatureChainMap::value_type(tid, new DumFeatureChain(*this, mOutgoingFeatureList, *mOutgoingTarget))); } } DumFeatureChain::ProcessingResult res = it->second->process(message.get()); if (res & DumFeatureChain::ChainDoneBit) { delete it->second; mOutgoingFeatureChainMap.erase(it); } if (res & DumFeatureChain::EventTakenBit) { message.release(); return; } } OutgoingEvent* event = dynamic_cast<OutgoingEvent*>(message.get()); //assert(event); //.dcm. a TID collision can cause a message to be delivered to a finished //chain. This is probably because pseudorandom was being used on Win32. if (event) { if (event->message()->isRequest()) { DialogSet* ds = findDialogSet(DialogSetId(*event->message())); UserProfile* userProfile; if (ds == 0) { userProfile = getMasterUserProfile().get(); } else { userProfile = ds->getUserProfile().get(); } assert(userProfile); //!dcm! -- unique SharedPtr to auto_ptr conversion prob. a worthwhile //optimzation here. SharedPtr would ahve to be changed; would //throw/assert if not unique. std::auto_ptr<SipMessage> toSend(static_cast<SipMessage*>(event->message()->clone())); // .bwc. Protect ourselves from garbage with an isWellFormed() check. // (Code in Dialog doesn't check for well-formedness in the // Record-Route stack, so bad stuff there can end up here) if (event->message()->exists(h_Routes) && !event->message()->header(h_Routes).empty() && event->message()->header(h_Routes).front().isWellFormed() && !event->message()->header(h_Routes).front().uri().exists(p_lr)) { Helper::processStrictRoute(*toSend); sendUsingOutboundIfAppropriate(*userProfile, toSend); } else { sendUsingOutboundIfAppropriate(*userProfile, toSend); } } else { sendResponse(*event->message()); } }}voidDialogUsageManager::sendUsingOutboundIfAppropriate(UserProfile& userProfile, auto_ptr<SipMessage> msg){ //a little inefficient, branch parameter might be better DialogId id(*msg); if (userProfile.hasOutboundProxy() && !findDialog(id)) { DebugLog ( << "Using outbound proxy: " << userProfile.getOutboundProxy().uri() << " -> " << msg->brief()); if (userProfile.getExpressOutboundAsRouteSetEnabled()) { // prepend the outbound proxy to the service route msg->header(h_Routes).push_front(NameAddr(userProfile.getOutboundProxy().uri())); mStack.send(msg, this); } else { mStack.sendTo(msg, userProfile.getOutboundProxy().uri(), this); } } else { DebugLog (<< "Send: " << msg->brief()); mStack.send(msg, this); }}voidDialogUsageManager::end(DialogSetId setid){ DialogSet* ds = findDialogSet(setid); if (ds == 0) { throw Exception("Request no longer exists", __FILE__, __LINE__); } else { ds->end(); }}voidDialogUsageManager::destroy(const BaseUsage* usage){ if (mShutdownState != Destroying) { post(new DestroyUsage(usage->mHandle)); } else { InfoLog(<< "DialogUsageManager::destroy() not posting to stack"); }}voidDialogUsageManager::destroy(DialogSet* dset){ if (mShutdownState != Destroying) { post(new DestroyUsage(dset)); } else { InfoLog(<< "DialogUsageManager::destroy() not posting to stack"); }}voidDialogUsageManager::destroy(Dialog* d){ if (mShutdownState != Destroying) { post(new DestroyUsage(d)); } else { InfoLog(<< "DialogUsageManager::destroy() not posting to stack"); }}Dialog*DialogUsageManager::findDialog(const DialogId& id){ DialogSet* ds = findDialogSet(id.getDialogSetId()); if (ds) { return ds->findDialog(id); } else { return 0; }}InviteSessionHandleDialogUsageManager::findInviteSession(DialogId id){ Dialog* dialog = findDialog(id); if (dialog && dialog->mInviteSession) { return dialog->mInviteSession->getSessionHandle(); } return InviteSessionHandle::NotValid();}pair<InviteSessionHandle, int>DialogUsageManager::findInviteSession(CallId replaces){ //486/481/603 decision making logic where? App may not wish to keep track of //invitesession state //Logic is here for now. InviteSessionHandle is = findInviteSession(DialogId(replaces.value(), replaces.param(p_toTag), replaces.param(p_fromTag))); int ErrorStatusCode = 481; // Call/Transaction Does Not Exist // If we matched a session - Do RFC3891 Section 3 Processing if(is.isValid()) { // Note some missing checks are: // 1. If the Replaces header field matches more than one dialog, the UA must act as // if no match was found // 2. Verify that the initiator of the new Invite is authorized if(is->isTerminated()) { ErrorStatusCode = 603; // Declined is = InviteSessionHandle::NotValid(); } else if(is->isConnected()) { // Check if early-only flag is present in replaces header if(replaces.exists(p_earlyOnly)) { ErrorStatusCode = 486; // Busy Here is = InviteSessionHandle::NotValid(); } } else if(!is->isEarly()) { // replaces can't be used on early dialogs that were not initiated by this UA - ie. InviteSession::Proceeding state ErrorStatusCode = 481; // Call/Transaction Does Not Exist is = InviteSessionHandle::NotValid(); } } return make_pair(is, ErrorStatusCode);}voidDialogUsageManager::internalProcess(std::auto_ptr<Message> msg){ // After a Stack ShutdownMessage has been received, don't do anything else in dum if (mShutdownState == Shutdown) { return; } { TransactionUserMessage* tuMsg = dynamic_cast<TransactionUserMessage*>(msg.get()); if (tuMsg) { InfoLog (<< "TU unregistered "); assert(mShutdownState == RemovingTransactionUser); assert(tuMsg->type() == TransactionUserMessage::TransactionUserRemoved); mShutdownState = Shutdown; if (mDumShutdownHandler) { mDumShutdownHandler->onDumCanBeDeleted(); mDumShutdownHandler = 0; // prevent mDumShutdownHandler getting called more than once } return; } } { DestroyUsage* destroyUsage = dynamic_cast<DestroyUsage*>(msg.get()); if (destroyUsage) { //DebugLog(<< "Destroying usage" ); destroyUsage->destroy(); return; } } { DumTimeout* dumMsg = dynamic_cast<DumTimeout*>(msg.get()); if (dumMsg) { //DebugLog(<< "Timeout Message" ); if (!dumMsg->getBaseUsage().isValid()) { return; } dumMsg->getBaseUsage()->dispatch(*dumMsg); return; } } { KeepAliveTimeout* keepAliveMsg = dynamic_cast<KeepAliveTimeout*>(msg.get()); if (keepAliveMsg) { //DebugLog(<< "Keep Alive Message" ); if (mKeepAliveManager.get()) { mKeepAliveManager->process(*keepAliveMsg); } return; } } { ConnectionTerminated* terminated = dynamic_cast<ConnectionTerminated*>(msg.get()); if (terminated) { DebugLog(<< "connection terminated message"); if (mConnectionTerminatedEventDispatcher.dispatch(msg.get())) { msg.release(); } return; } } { DumCommand* command = dynamic_cast<DumCommand*>(msg.get()); if (command) { //DebugLog(<< "DumCommand" ); command->executeCommand(); return; } } { ExternalMessageBase* externalMessage = dynamic_cast<ExternalMessageBase*>(msg.get()); if (externalMessage) { processExternalMessage(externalMessage); return; } } incomingProcess(msg);}voidDialogUsageManager::processExternalMessage(ExternalMessageBase* externalMessage){ bool handled = false; for(std::vector<ExternalMessageHandler*>::iterator i = mExternalMessageHandlers.begin(); i != mExternalMessageHandlers.end(); ++i) { (*i)->onMessage(externalMessage, handled); if (handled) { break; } }}void DialogUsageManager::incomingProcess(std::auto_ptr<Message> msg){ //call or create feature chain if appropriate Data tid = Data::Empty; { SipMessage* sipMsg = dynamic_cast<SipMessage*>(msg.get()); if (sipMsg) { tid = sipMsg->getTransactionId(); bool garbage=false; Data reason; if(!sipMsg->header(h_From).isWellFormed()) { garbage=true; reason.append("Malformed From, ",16); } if(!sipMsg->header(h_To).isWellFormed()) { garbage=true; reason.append("Malformed To, ",14); } if(!sipMsg->header(h_CallId).isWellFormed()) { garbage=true; reason.append("Malformed Call-Id, ",19); } if(garbage) { if(sipMsg->isRequest() && sipMsg->method()!=ACK) { // .bwc. Either we need to trim the last comma off, or make this // a proper sentence fragment. This is more fun. reason.append("fix your code!",14); SipMessage failure; makeResponse(failure, *sipMsg, 400, reason); sendResponse(failure); } // .bwc. Only forge a response when appropriate, but return in any // case. return; } } DumFeatureMessage* featureMsg = dynamic_cast<DumFeatureMessage*>(msg.get()); if (featureMsg) { //DebugLog(<<"Got a DumFeatureMessage" << featureMsg); tid = featureMsg->getTransactionId(); } } if (tid != Data::Empty && !mIncomingFeatureList.empty()) { FeatureChainMap::iterator it; //efficiently find or create FeatureChain, should prob. be a utility template { FeatureChainMap::iterator lb = mIncomingFeatureChainMap.lower_bound(tid); if (lb != mIncomingFeatureChainMap.end() && !(mIncomingFeatureChainMap.key_comp()(tid, lb->first))) { it = lb; } else { assert(dynamic_cast<SipMessage*>(msg.get()));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -