|
reSIProcate/DialogUsageManager
9694
|
00001 #include "resip/dum/RedirectManager.hxx" 00002 #include "resip/stack/NameAddr.hxx" 00003 #include "rutil/Logger.hxx" 00004 #include "resip/dum/RedirectHandler.hxx" 00005 #include "resip/dum/DialogUsageManager.hxx" 00006 #include "resip/dum/DialogSet.hxx" 00007 #include "resip/dum/AppDialogSet.hxx" 00008 #include "rutil/WinLeakCheck.hxx" 00009 00010 #define RESIPROCATE_SUBSYSTEM Subsystem::DUM 00011 00012 using namespace resip; 00013 00014 bool 00015 RedirectManager::handle(DialogSet& dSet, SipMessage& origRequest, const SipMessage& response) 00016 { 00017 assert( response.isResponse() ); 00018 assert( origRequest.isRequest() ); 00019 00020 //380, 305 fall through to the application 00021 int code = response.header(h_StatusLine).statusCode(); 00022 if (code < 300 || code == 380 || code == 305) 00023 { 00024 return false; 00025 } 00026 else if (code >= 300 && code < 400) 00027 { 00028 RedirectHandler* handler = dSet.mDum.getRedirectHandler(); 00029 DialogSetId id(origRequest); 00030 RedirectedRequestMap::iterator it = mRedirectedRequestMap.find(id); 00031 00032 if (it == mRedirectedRequestMap.end()) 00033 { 00034 DebugLog( << "RedirectManager::handle: new TargetSet: " << id); 00035 mRedirectedRequestMap[id] = new TargetSet(origRequest, mOrdering); 00036 it = mRedirectedRequestMap.find(id); 00037 } 00038 if (handler) 00039 { 00040 handler->onRedirectReceived(dSet.mAppDialogSet->getHandle(), response); 00041 } 00042 TargetSet& tSet = *it->second; 00043 tSet.addTargets(response); 00044 00045 while(tSet.makeNextRequest(origRequest)) 00046 { 00047 if (handler) 00048 { 00049 if (handler->onTryingNextTarget(dSet.mAppDialogSet->getHandle(), origRequest)) 00050 { 00051 return true; 00052 } 00053 } 00054 else 00055 { 00056 return true; 00057 } 00058 } 00059 delete it->second; 00060 mRedirectedRequestMap.erase(it); 00061 return false; 00062 } 00063 //5xx, 6xx different? 00064 return false; 00065 } 00066 00067 void 00068 RedirectManager::setOrdering(const Ordering& order) 00069 { 00070 mOrdering = order; 00071 } 00072 00073 void 00074 RedirectManager::TargetSet::addTargets(const SipMessage& msg) 00075 { 00076 if (msg.exists(h_Contacts)) 00077 { 00078 for (NameAddrs::const_iterator it = msg.header(h_Contacts).begin(); it != msg.header(h_Contacts).end(); it++) 00079 { 00080 if (mTargetSet.find(*it) == mTargetSet.end()) 00081 { 00082 DebugLog( << "RedirectManager::TargetSet::addTargets:target: " << *it); 00083 mTargetSet.insert(*it); 00084 mTargetQueue.push(*it); 00085 } 00086 } 00087 } 00088 } 00089 00090 bool 00091 RedirectManager::TargetSet::makeNextRequest(SipMessage& request) 00092 { 00093 request = mRequest; 00094 //dispaly name, check if it's an invite, recurse if it isn't, throw if 00095 //exhausted? Or make a boolean, elimnate hasTarget 00096 while(!mTargetQueue.empty()) 00097 { 00098 try 00099 { 00100 request.mergeUri(mTargetQueue.top().uri()); 00101 mTargetQueue.pop(); 00102 if (request.isRequest()) 00103 { 00104 switch(request.header(h_RequestLine).method()) 00105 { 00106 case ACK: 00107 case BYE: 00108 case CANCEL: 00109 case PRACK: 00110 break; 00111 default: 00112 DebugLog(<< "RedirectManager::TargetSet::makeNextRequest: " << request); 00113 request.header(h_CSeq).sequence()++; 00114 return true; 00115 } 00116 } 00117 } 00118 catch(BaseException&) 00119 { 00120 DebugLog(<< "RedirectManager::TargetSet::makeNextRequest: error generating request"); 00121 mTargetQueue.pop(); 00122 } 00123 } 00124 return false; 00125 } 00126 00127 bool RedirectManager::Ordering::operator()(const NameAddr& lhs, const NameAddr& rhs) const 00128 { 00129 if (lhs.exists(p_q)) 00130 { 00131 if (rhs.exists(p_q)) 00132 { 00133 return lhs.param(p_q) < rhs.param(p_q); 00134 } 00135 else 00136 { 00137 return lhs.param(p_q) < 1000; // 1.0 00138 } 00139 } 00140 else 00141 { 00142 // Note: if lhs is not present and treated as 1.0, it will never to less than rhs 00143 return false; 00144 } 00145 } 00146 00147 void RedirectManager::removeDialogSet(DialogSetId id) 00148 { 00149 RedirectedRequestMap::iterator it = mRedirectedRequestMap.find(id); 00150 00151 if (it != mRedirectedRequestMap.end()) 00152 { 00153 delete it->second; 00154 mRedirectedRequestMap.erase(it); 00155 } 00156 } 00157 00158 00159 /* ==================================================================== 00160 * The Vovida Software License, Version 1.0 00161 * 00162 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00163 * 00164 * Redistribution and use in source and binary forms, with or without 00165 * modification, are permitted provided that the following conditions 00166 * are met: 00167 * 00168 * 1. Redistributions of source code must retain the above copyright 00169 * notice, this list of conditions and the following disclaimer. 00170 * 00171 * 2. Redistributions in binary form must reproduce the above copyright 00172 * notice, this list of conditions and the following disclaimer in 00173 * the documentation and/or other materials provided with the 00174 * distribution. 00175 * 00176 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00177 * and "Vovida Open Communication Application Library (VOCAL)" must 00178 * not be used to endorse or promote products derived from this 00179 * software without prior written permission. For written 00180 * permission, please contact vocal@vovida.org. 00181 * 00182 * 4. Products derived from this software may not be called "VOCAL", nor 00183 * may "VOCAL" appear in their name, without prior written 00184 * permission of Vovida Networks, Inc. 00185 * 00186 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00187 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00188 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00189 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00190 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00191 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00192 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00193 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00194 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00195 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00196 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00197 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00198 * DAMAGE. 00199 * 00200 * ==================================================================== 00201 * 00202 * This software consists of voluntary contributions made by Vovida 00203 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00204 * Inc. For more information on Vovida Networks, Inc., please see 00205 * <http://www.vovida.org/>. 00206 * 00207 */
1.7.5.1