![]() |
User Manual, Developers Guide and API Documentation |
![]() |
00001 /******************************************************************************* 00002 * This file is part of openWNS (open Wireless Network Simulator) 00003 * _____________________________________________________________________________ 00004 * 00005 * Copyright (C) 2004-2007 00006 * Chair of Communication Networks (ComNets) 00007 * Kopernikusstr. 5, D-52074 Aachen, Germany 00008 * phone: ++49-241-80-27910, 00009 * fax: ++49-241-80-22242 00010 * email: info@openwns.org 00011 * www: http://www.openwns.org 00012 * _____________________________________________________________________________ 00013 * 00014 * openWNS is free software; you can redistribute it and/or modify it under the 00015 * terms of the GNU Lesser General Public License version 2 as published by the 00016 * Free Software Foundation; 00017 * 00018 * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY 00019 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00020 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00021 * details. 00022 * 00023 * You should have received a copy of the GNU Lesser General Public License 00024 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00025 * 00026 ******************************************************************************/ 00027 00028 #include <LTE/controlplane/flowmanagement/FlowManager.hpp> 00029 #include <LTE/controlplane/flowmanagement/flowhandler/FlowHandlerBS.hpp> 00030 #include <LTE/controlplane/flowmanagement/flowhandler/FlowHandlerUT.hpp> 00031 #include <LTE/controlplane/AssociationsProxy.hpp> 00032 #include <LTE/upperconvergence/eNB.hpp> 00033 #include <LTE/upperconvergence/UE.hpp> 00034 #include <LTE/rlc/RLCCommand.hpp> 00035 00036 #include <WNS/ldk/CommandTypeSpecifier.hpp> 00037 #include <WNS/Assure.hpp> 00038 #include <WNS/service/dll/Address.hpp> 00039 #include <WNS/service/dll/StationTypes.hpp> 00040 #include <WNS/StaticFactory.hpp> 00041 00042 #define A2N(a) (((a).getInteger()>0) ? layer2->getStationManager()->getStationByMAC(a)->getName() : "DLL<0") 00043 00044 using namespace lte::controlplane; 00045 using namespace lte::controlplane::flowmanagement; 00046 using namespace wns::service::dll; 00047 00048 STATIC_FACTORY_REGISTER_WITH_CREATOR(lte::controlplane::flowmanagement::FlowManagerBS, 00049 wns::ldk::ControlServiceInterface, 00050 "lte.controlplane.flowmanagement.FlowManagerBS", 00051 wns::ldk::CSRConfigCreator); 00052 00053 STATIC_FACTORY_REGISTER_WITH_CREATOR(lte::controlplane::flowmanagement::FlowManagerUT, 00054 wns::ldk::ControlServiceInterface, 00055 "lte.controlplane.flowmanagement.FlowManagerUT", 00056 wns::ldk::CSRConfigCreator); 00057 00058 FlowManager::FlowManager(wns::ldk::ControlServiceRegistry* csr, const wns::pyconfig::View& config) : 00059 layer2(), 00060 plainDisassociation(false), 00061 rlcReader(NULL), 00062 logger(config.get("logger")), 00063 flowIDPool(config.get<simTimeType>("flowIDUnbindDelay"), 1, 57343), // 0 is reserved for ControlPlane 00064 broadcastFlowIDPool(config.get<simTimeType>("flowIDUnbindDelay"), 57344, 65535), // Upper area is for broadcasting 00065 separator("_"), 00066 flowSeparatorNames(), 00067 flowSeparators(), 00068 upperSynchronizer(NULL), 00069 upperFlowGate(NULL), 00070 arqFlowGate(NULL) 00071 { 00072 bchFlowID_ = broadcastFlowIDPool.suggestPort(); 00073 broadcastFlowIDPool.bind(bchFlowID_); 00074 00075 for (int i = 0; i < config.len("modeNames"); ++i) { 00076 std::string modeName = config.get<std::string>("modeNames", i); 00077 myModes.push_back(modeName); 00078 } 00079 00080 for (int ii = 0; ii < config.len("flowSeparatorNames"); ++ii) 00081 { 00082 std::string FSName = config.get<std::string>("flowSeparatorNames", ii); 00083 flowSeparatorNames.push_back(FSName); 00084 } 00085 00086 wns::pyconfig::View transactionIdConfig(config, "transactionIdDistribution"); 00087 std::string tIdDisName = transactionIdConfig.get<std::string>("__plugin__"); 00088 transactionIdDistribution = 00089 wns::distribution::DistributionFactory::creator(tIdDisName)->create(transactionIdConfig); 00090 } 00091 00092 FlowManager::~FlowManager() 00093 { 00094 } 00095 00096 std::string 00097 FlowManager::getFlowTable() const 00098 { // this base class prints ControlPlane FlowIDs only 00099 std::stringstream out; 00100 out << std::endl; 00101 out << "FlowTable (" << logger.getLoggerName() <<"):"<< std::endl; 00102 for (ControlPlaneFlowIdTable::const_iterator iter = controlPlaneFlowIdsForPeer.begin(); 00103 iter != controlPlaneFlowIdsForPeer.end(); 00104 ++iter) 00105 { 00106 wns::service::dll::UnicastAddress peerAdr = iter->first; 00107 ControlPlaneFlowIDs flowIDs = iter->second; 00108 out << printControlPlaneFlowIDs(flowIDs) << " for peer="<<A2N(peerAdr) << std::endl; 00109 } 00110 return out.str(); 00111 } 00112 00113 std::string 00114 FlowManager::printControlPlaneFlowIDs(ControlPlaneFlowIDs flowIDs) const 00115 { 00116 std::stringstream out; 00117 out << "ControlPlaneFlowIDs=("; 00118 00119 for (ControlPlaneFlowIDs::const_iterator iter = flowIDs.begin(); 00120 iter != flowIDs.end(); 00121 ++iter) 00122 { 00123 FlowID flowID = iter->second; 00124 out << flowID << ", "; 00125 } 00126 out << ")"; 00127 return out.str(); 00128 } 00129 00130 bool 00131 FlowManager::isControlPlaneFlowID(FlowID flowID, 00132 ControlPlaneFlowIDs flowIDs) const 00133 { 00134 bool found = false; 00135 for (ControlPlaneFlowIDs::const_iterator iter = flowIDs.begin(); 00136 iter != flowIDs.end(); 00137 ++iter) 00138 { 00139 if (iter->second == flowID) 00140 { 00141 found = true; 00142 break; 00143 } 00144 } 00145 return found; 00146 } 00147 00148 bool 00149 FlowManager::isControlPlaneFlowID(wns::service::dll::UnicastAddress peerAddress, 00150 wns::service::dll::FlowID flowID) const 00151 { 00152 bool found = false; 00153 if (controlPlaneFlowIdsForPeer.knows(peerAddress)) { 00154 ControlPlaneFlowIDs flowIDs = controlPlaneFlowIdsForPeer.find(peerAddress); 00155 for (ControlPlaneFlowIDs::const_iterator iter = flowIDs.begin(); iter != flowIDs.end(); ++iter) 00156 { 00157 if (iter->second == flowID) { found = true; break; } 00158 } 00159 } 00160 return found; 00161 } 00162 00163 lte::helper::TransactionID 00164 FlowManager::drawNewTransactionID() const { 00165 lte::helper::TransactionID transactionId=0; 00166 int count=10; // should not take longer than this #trials 00167 bool cond1,cond2,cond3; 00168 do { // find a new transactionId which is not known in any existing table 00169 transactionId = static_cast<int>((*transactionIdDistribution)()); 00170 MESSAGE_SINGLE(NORMAL, logger, "drawNewTransactionID(): transactionId="<<transactionId); 00171 cond1 = TransactionIDToTlFlowID.knows(transactionId); 00172 cond2 = TransactionIDToOldFlowID.knows(transactionId); 00173 cond3 = TransactionIDToQoSClass.knows(transactionId); 00174 } while ((--count>0) && (cond1 || cond2 || cond3)); 00175 assure(count>0,"timeout while drawNewTransactionID()"); 00176 return transactionId; 00177 } 00178 00179 FlowID 00180 FlowManager::getBCHFlowID() 00181 { 00182 return bchFlowID_; 00183 } 00184 00185 FlowID 00186 FlowManager::getFlowIDin(FlowID flowIDout) 00187 { 00188 assure(flowIDout>0,"flowID="<<flowIDout<<", must be >0"); 00189 bool foundFlowID = false; 00190 for (SwitchingTable::const_iterator iter = FlowIDInToFlowIDOut.begin(); 00191 iter != FlowIDInToFlowIDOut.end(); 00192 ++iter) 00193 { 00194 MESSAGE_SINGLE(NORMAL, logger, "switching table entries flowIn "<<iter->first<<" , out "<<iter->second); 00195 00196 if(iter->second == flowIDout) 00197 { 00198 foundFlowID = true; 00199 MESSAGE_SINGLE(NORMAL, logger, "FlowID switched from out "<<flowIDout<<" to in: "<<iter->first); 00200 return iter->first; 00201 } 00202 } 00203 if(foundFlowID==false) 00204 { 00205 MESSAGE_SINGLE(NORMAL, logger, "No such FlowIDout: "<<flowIDout<<getFlowTable()) 00206 assure(foundFlowID, "No such FlowIDout: "<<flowIDout); 00207 return FlowID(0); 00208 } 00209 return FlowID(0); 00210 } 00211 00212 FlowID 00213 FlowManager::getFlowIDout(FlowID flowIDin) 00214 { 00215 assure(flowIDin>0,"flowID="<<flowIDin<<", must be >0"); 00216 assure(FlowIDInToFlowIDOut.knows(flowIDin),"No such FlowIDin="<<flowIDin<<getFlowTable()); 00217 00218 MESSAGE_SINGLE(NORMAL, logger, "FlowID switched from in "<<flowIDin<<" to out: "<<FlowIDInToFlowIDOut.find(flowIDin)); 00219 00220 return FlowIDInToFlowIDOut.find(flowIDin); 00221 } 00222 00223 void 00224 FlowManager::insertFlowIDToUT(FlowID flowID, wns::service::dll::UnicastAddress utAddress) 00225 { 00226 assure(flowID>0,"flowID="<<flowID<<", must be >0"); 00227 FlowIDToUT.insert(flowID, utAddress); 00228 MESSAGE_SINGLE(NORMAL, logger, "Registering FlowID="<<flowID<<" for "<<A2N(utAddress)); 00229 } 00230 00231 void 00232 FlowManager::deleteFlowsForUT(wns::service::dll::UnicastAddress utAddress) 00233 { 00234 MESSAGE_SINGLE(NORMAL, logger, "deleteFlowsForUT("<<A2N(utAddress)<<")"); 00235 MESSAGE_SINGLE(NORMAL, logger, "FlowIDToUT.size()="<<FlowIDToUT.size()); 00236 for (FlowIDTable::const_iterator iter = FlowIDToUT.begin(); 00237 iter != FlowIDToUT.end(); 00238 ++iter) 00239 { 00240 if(iter->second == utAddress) 00241 { 00242 MESSAGE_SINGLE(NORMAL, logger, "Found FlowID="<<iter->first<<" in FlowIDTable for "<<A2N(utAddress)); 00243 MESSAGE_SINGLE(NORMAL, logger, "FlowID="<<iter->first<<" deleted from FlowIDTable for "<<A2N(utAddress)); 00244 flowIDPool.unbind(iter->first); 00245 FlowIDToUT.erase(iter->first); 00246 } 00247 } 00248 } 00249 00250 wns::service::dll::UnicastAddress 00251 FlowManager::getUTForFlow(FlowID flowID) 00252 { 00253 wns::service::dll::UnicastAddress utAddress; 00254 // maybe a user plane flow ID 00255 if (FlowIDToUT.knows(flowID)) 00256 { 00257 utAddress = FlowIDToUT.find(flowID); 00258 } 00259 else // or maybe a control plane flow ID 00260 { 00261 for (ControlPlaneFlowIdTable::const_iterator iter = controlPlaneFlowIdsForPeer.begin(); 00262 iter != controlPlaneFlowIdsForPeer.end(); 00263 ++iter) 00264 { 00265 if (isControlPlaneFlowID(flowID, iter->second)) // found 00266 { 00267 utAddress = iter->first; break; 00268 } 00269 } 00270 } 00271 assure(utAddress.getInteger()>0,"getUTForFlow("<<flowID<<") cannot be found"); 00272 MESSAGE_SINGLE(NORMAL, logger, "getUTForFlow("<<flowID<<")="<<A2N(utAddress)); 00273 return utAddress; 00274 } 00275 00276 FlowManager::FlowIdList 00277 FlowManager::getFlowsForUT(wns::service::dll::UnicastAddress utAddress) 00278 { 00279 FlowIdList flowIdList; 00280 MESSAGE_SINGLE(NORMAL, logger, "getFlowsForUT("<<A2N(utAddress)<<")"); 00281 for (FlowIDTable::const_iterator iter = FlowIDToUT.begin(); 00282 iter != FlowIDToUT.end(); 00283 ++iter) 00284 { 00285 if(iter->second == utAddress) 00286 { 00287 FlowID flowId = iter->first; 00288 MESSAGE_SINGLE(NORMAL, logger, "Found FlowID="<<flowId<<" in FlowIDTable for "<<A2N(utAddress)); 00289 flowIdList.push_back(flowId); 00290 } 00291 } 00292 return flowIdList; 00293 } 00294 00295 bool 00296 FlowManager::hasFlowIDout(FlowID flowIDout) 00297 { 00298 assure(flowIDout>0,"flowID="<<flowIDout<<", must be >0"); 00299 bool foundFlowID = false; 00300 for (SwitchingTable::const_iterator iter = FlowIDInToFlowIDOut.begin(); 00301 iter != FlowIDInToFlowIDOut.end(); 00302 ++iter) 00303 { 00304 if(iter->second == flowIDout) 00305 { 00306 foundFlowID = true; 00307 } 00308 } 00309 return foundFlowID; 00310 } 00311 00312 // asked in wns::ldk::flowseparator::CreateOnValidFlow 00313 // RN overloads this method, see below 00314 bool 00315 FlowManager::isValidFlow(const wns::ldk::ConstKeyPtr& key) const 00316 { 00317 const lte::helper::key::FlowID* _key = dynamic_cast<const lte::helper::key::FlowID*>(key.getPtr()); 00318 bool knows = FlowIDToUT.knows(_key->flowID); 00319 if (!knows) { 00320 //MESSAGE_SINGLE(VERBOSE, logger, "isValidFlow("<<key->str()<<"="<<_key->flowID<<") == false"<<getFlowTable()); 00321 MESSAGE_SINGLE(VERBOSE, logger, "isValidFlow("<<key->str()<<"="<<_key->flowID<<") == false"); 00322 } 00323 return knows; 00324 } 00325 00326 bool 00327 FlowManager::isValidFlowId(FlowID flowID) const 00328 { 00329 if (flowID==0) { return true; } // temporary Controlplane flowID for RNs at simulation start 00330 bool valid = FlowIDToUT.knows(flowID); 00331 if (!valid) 00332 { // can it be a controlPlane FlowId? 00333 for (ControlPlaneFlowIdTable::const_iterator iter = controlPlaneFlowIdsForPeer.begin(); 00334 iter != controlPlaneFlowIdsForPeer.end(); 00335 ++iter) 00336 { 00337 if (isControlPlaneFlowID(flowID, iter->second)) // found 00338 { 00339 valid=true; break; 00340 } 00341 } 00342 } 00343 valid &= !hasPreserved(flowID); // in case of intra-REC HO of a UT from/via RN to its BS 00344 MESSAGE_SINGLE(NORMAL, logger, "isValidFlowId("<<flowID<<")="<<valid<<(hasPreserved(flowID)?" preserved":"")); 00345 return valid; 00346 } 00347 00348 int 00349 FlowManager::countFlows() const 00350 { 00351 int count=0; // =FlowIDToUT.size(); ? 00352 for (FlowIDTable::const_iterator iter = FlowIDToUT.begin(); iter != FlowIDToUT.end(); ++iter) count++; 00353 assure(count==FlowIDToUT.size(),"FlowManager::countFlows(): error counting flows"); 00354 return FlowIDToUT.size(); 00355 } 00356 00357 int 00358 FlowManager::countFlows(wns::service::dll::UnicastAddress utAddress) const 00359 { 00360 int count=0; 00361 for (FlowIDTable::const_iterator iter = FlowIDToUT.begin(); iter != FlowIDToUT.end(); ++iter) 00362 { 00363 if(iter->second == utAddress) { count++; } 00364 } 00365 return count; 00366 } 00367 00368 void 00369 FlowManager::deleteSwitchingTableForUT(wns::service::dll::UnicastAddress utAddress) 00370 { 00371 for (FlowIDTable::const_iterator iter = FlowIDToUT.begin(); 00372 iter != FlowIDToUT.end(); 00373 ++iter) 00374 { 00375 if(iter->second == utAddress) 00376 { 00377 FlowIDInToFlowIDOut.erase(iter->first); 00378 MESSAGE_SINGLE(NORMAL, logger, "FlowID="<<iter->first<<" deleted from SwitchingTable for "<<A2N(utAddress)); 00379 } 00380 } 00381 } 00382 00383 void 00384 FlowManager::deleteFlowSeparator(FlowID flowID) 00385 { 00386 assure(flowID>0,"flowID="<<flowID<<", must be >0"); 00387 wns::ldk::ConstKeyPtr key(new lte::helper::key::FlowID(flowID)); 00388 // delete user's (downlink and uplink) flows from the flowseparators 00389 for (std::list<wns::ldk::FlowSeparator*>::iterator itr = flowSeparators.begin(); itr != flowSeparators.end(); ++itr) 00390 { 00391 if((*itr)->getInstance(key)) 00392 (*itr)->removeInstance(key); 00393 MESSAGE_SINGLE(NORMAL, logger, "Upper FlowSeparator deleted for FlowID="<<flowID); 00394 } 00395 } 00396 00397 void 00398 FlowManager::deleteAllFlowSeparators(wns::service::dll::UnicastAddress utAddress) 00399 { 00400 for (FlowIDTable::const_iterator iter = FlowIDToUT.begin(); 00401 iter != FlowIDToUT.end(); 00402 ++iter) 00403 { 00404 if(iter->second == utAddress) 00405 { 00406 wns::ldk::ConstKeyPtr key(new lte::helper::key::FlowID(iter->first)); 00407 for (std::list<wns::ldk::FlowSeparator*>::iterator itr = flowSeparators.begin(); itr != flowSeparators.end(); ++itr) 00408 { 00409 if((*itr)->getInstance(key)) 00410 (*itr)->removeInstance(key); 00411 MESSAGE_SINGLE(NORMAL, logger, "Upper FlowSeparator deleted for FlowID="<<iter->first); 00412 } 00413 } 00414 } 00415 } 00416 00417 void 00418 FlowManager::deleteAllUpperFlows(wns::service::dll::UnicastAddress Adr) 00419 { 00420 // first clean up the upperSynchronizer's buffer 00421 assure(upperSynchronizer, "upperSynchronizer not set."); 00422 assure(arqFlowGate, "arqFlowGate not set."); 00423 assure(upperFlowGate, "upperFlowGate not set."); 00424 00425 wns::ldk::CompoundPtr compound = upperSynchronizer->hasSomethingToSend(); 00426 if(compound != wns::ldk::CompoundPtr()){ 00427 lte::rlc::RLCCommand* rlcCommand = rlcReader->readCommand<lte::rlc::RLCCommand>(compound->getCommandPool()); 00428 if(rlcCommand->peer.destination == Adr) 00429 { 00430 // getSomethingToSend() takes the compund out of the Synchronizer 00431 compound = upperSynchronizer->getSomethingToSend(); 00432 MESSAGE_SINGLE(NORMAL, logger, "Drop outgoing compound in buffer of upperSynchronizer!"); 00433 } 00434 } 00435 00436 for (FlowIDTable::const_iterator iter = FlowIDToUT.begin(); 00437 iter != FlowIDToUT.end(); 00438 ++iter) 00439 { 00440 if(iter->second == Adr) 00441 { 00442 wns::ldk::ConstKeyPtr key(new lte::helper::key::FlowID(iter->first)); 00443 // destroy Flow in gates 00444 upperFlowGate->destroyFlow(key); 00445 arqFlowGate->destroyFlow(key); 00446 MESSAGE_SINGLE(NORMAL, logger, "Upper Flow deleted for FlowID="<<iter->first); 00447 } 00448 } 00449 } 00450 00451 void 00452 FlowManager::closeUpperFlows(wns::service::dll::UnicastAddress userAdr) 00453 { 00454 assure(arqFlowGate, "arqFlowGate not set."); 00455 assure(upperFlowGate, "upperFlowGate not set."); 00456 00457 for (FlowIDTable::const_iterator iter = FlowIDToUT.begin(); 00458 iter != FlowIDToUT.end(); 00459 ++iter) 00460 { 00461 if(iter->second == userAdr) 00462 { 00463 wns::ldk::ConstKeyPtr key(new lte::helper::key::FlowID(iter->first)); 00464 upperFlowGate->closeFlow(key); 00465 arqFlowGate->closeFlow(key); 00466 MESSAGE_SINGLE(NORMAL, logger, "FlowID="<<iter->first<<" closed for UT="<<userAdr); 00467 } 00468 } 00469 } 00470 00471 void 00472 FlowManager::closeUpperFlow(FlowID flowID) 00473 { 00474 assure(flowID>0,"flowID="<<flowID<<", must be >0"); 00475 assure(arqFlowGate, "arqFlowGate not set."); 00476 assure(upperFlowGate, "upperFlowGate not set."); 00477 00478 wns::ldk::ConstKeyPtr key(new lte::helper::key::FlowID(flowID)); 00479 upperFlowGate->closeFlow(key); 00480 arqFlowGate->closeFlow(key); 00481 MESSAGE_SINGLE(NORMAL, logger, "FlowID="<<flowID<<" closed."); 00482 } 00483 00484 void 00485 FlowManager::openUpperFlow(FlowID flowID) 00486 { 00487 assure(flowID>0,"flowID="<<flowID<<", must be >0"); 00488 assure(arqFlowGate, "arqFlowGate not set."); 00489 assure(upperFlowGate, "upperFlowGate not set."); 00490 00491 wns::ldk::ConstKeyPtr key(new lte::helper::key::FlowID(flowID)); 00492 upperFlowGate->openFlow(key); 00493 arqFlowGate->openFlow(key); 00494 MESSAGE_SINGLE(NORMAL, logger, "FlowID="<<flowID<<" opened in Upper Gates."); 00495 } 00496 00497 bool 00498 FlowManager::hasPreserved(wns::service::dll::UnicastAddress userAdr) const 00499 { 00500 std::set<wns::service::dll::UnicastAddress>::const_iterator found = preservedUsers.find(userAdr); 00501 return (found != preservedUsers.end()); 00502 } 00503 00504 bool 00505 FlowManager::hasPreserved(FlowID flowID) const 00506 { 00507 assure(flowID>=0,"flowID="<<flowID<<", must be >=0"); 00508 std::set<FlowID>::const_iterator found = preservedFlowIDs.find(flowID); 00509 return (found != preservedFlowIDs.end()); 00510 } 00511 00512 void 00513 FlowManager::registerPreservedUser(wns::service::dll::UnicastAddress userAdr) 00514 { 00515 preservedUsers.insert(userAdr); 00516 MESSAGE_SINGLE(NORMAL, logger, "Registered Preserved User: "<<userAdr); 00517 } 00518 00519 void 00520 FlowManager::registerPreservedFlowID(FlowID flowID) 00521 { 00522 assure(flowID>0,"flowID="<<flowID<<", must be >0"); 00523 preservedFlowIDs.insert(flowID); 00524 MESSAGE_SINGLE(NORMAL, logger, "Registered Preserved FlowID="<<flowID); 00525 } 00526 00527 void 00528 FlowManager::deletePreservedUser(wns::service::dll::UnicastAddress userAdr) 00529 { 00530 preservedUsers.erase(userAdr); 00531 MESSAGE_SINGLE(NORMAL, logger, "Erased Preserved User: "<<userAdr); 00532 } 00533 00534 00535 00537 // // 00538 // FlowManagerBS // 00539 // // 00541 00542 FlowManagerBS::FlowManagerBS(wns::ldk::ControlServiceRegistry* csr, const wns::pyconfig::View& config) : 00543 FlowManager(csr, config), 00544 ControlService(csr) 00545 { 00546 } 00547 00548 FlowManagerBS::~FlowManagerBS() 00549 {} 00550 00551 wns::service::qos::QoSClass 00552 FlowManagerBS::getQoSClassForBSFlowID(FlowID dllFlowID) const 00553 { 00554 if (dllFlowID == bchFlowID_) 00555 { 00556 return lte::helper::QoSClasses::PBCH(); 00557 } 00558 // flowID=0 is the rare case of RN-to-BS at the beginning 00559 if (dllFlowID==0) { 00560 return lte::helper::QoSClasses::PCCH(); 00561 } 00562 assure(DllFlowIDToQoSClass.knows(dllFlowID),"expected the QoSClass to be known for flowID="<<dllFlowID<<getFlowTable()); 00563 return DllFlowIDToQoSClass.find(dllFlowID); 00564 } 00565 00566 wns::service::qos::QoSClass 00567 FlowManagerBS::getQoSClassForUTFlowID(FlowID /*dllFlowID*/) const 00568 { 00569 assure(false,"FlowManagerBS::getQoSClassForUTFlowID(): does not exist"); 00570 } 00571 00572 void 00573 FlowManagerBS::setControlPlaneFlowIDs(wns::service::dll::UnicastAddress peerAddress, ControlPlaneFlowIDs flowIDs) 00574 { 00575 // can overwrite old entry, but must be the same content 00576 if (controlPlaneFlowIdsForPeer.knows(peerAddress)) { 00577 ControlPlaneFlowIDs oldFlowIDs = controlPlaneFlowIdsForPeer.find(peerAddress); 00578 assure(flowIDs == oldFlowIDs,"setControlPlaneFlowIDs("<<A2N(peerAddress)<<","<<printControlPlaneFlowIDs(flowIDs)<<") overwrites oldFlowID="<<printControlPlaneFlowIDs(oldFlowIDs)<<getFlowTable()); 00579 } else { // new 00580 MESSAGE_SINGLE(NORMAL, logger, "setControlPlaneFlowIDs("<<A2N(peerAddress)<<",flowIDs="<<printControlPlaneFlowIDs(flowIDs)<<")"); 00581 controlPlaneFlowIdsForPeer.insert(peerAddress, flowIDs); 00582 00583 int qosClass = lte::helper::QoSClasses::PHICH(); 00584 assure(flowIDs.size()== 3, "Expected exactly 3 control plane FlowIDs (PBCH, PCCH, DCCH, PHICH), but got " << flowIDs.size()); 00585 for (ControlPlaneFlowIDs::const_iterator iter = flowIDs.begin(); 00586 iter != flowIDs.end(); 00587 ++iter) 00588 { 00589 FlowID flowID = iter->second; 00590 assure(!DllFlowIDToQoSClass.knows(flowID),"DllFlowIDToQoSClass("<<flowID<<") already registered"); 00591 // qosClass matches the QoS class ENUM from lte::helper::QoSClasses, i.e. PCCH=1, DCCH=2, PHICH=3 00592 DllFlowIDToQoSClass.insert(flowID, qosClass); 00593 qosClass++; 00594 } 00595 } 00596 } 00597 00598 std::string 00599 FlowManagerBS::getFlowTable() const 00600 { 00601 std::stringstream out; 00602 out << FlowManager::getFlowTable(); // base class prints ControlPlane FlowIDs 00603 for (FlowIDTable::const_iterator iter = FlowIDToUT.begin(); 00604 iter != FlowIDToUT.end(); 00605 ++iter) 00606 { 00607 FlowID flowID = iter->first; 00608 wns::service::dll::UnicastAddress peerAdr = iter->second; 00609 wns::service::qos::QoSClass qosClass = lte::helper::QoSClasses::UNDEFINED(); 00610 if (DllFlowIDToQoSClass.knows(flowID)) 00611 qosClass = DllFlowIDToQoSClass.find(flowID); 00612 out << "D-FID="<<flowID<<": peer="<<A2N(peerAdr)<<", QoS="<<lte::helper::QoSClasses::toString(qosClass) << std::endl; 00613 } 00614 return out.str(); 00615 } 00616 00617 void 00618 FlowManagerBS::buildFlow(wns::service::tl::FlowID /*flowID*/, wns::service::qos::QoSClass /*qosClass*/) 00619 {} 00620 00621 void 00622 FlowManagerBS::flowBuilt(FlowID flowID) 00623 { 00624 assure(flowID>0,"flowID="<<flowID<<", must be >0"); 00625 openUpperFlow(flowID); 00626 //erase preserved FlowID: 00627 preservedFlowIDs.erase(flowID); 00628 } 00629 00630 FlowManager::ControlPlaneFlowIDs 00631 FlowManagerBS::getControlPlaneFlowIDs(wns::service::dll::UnicastAddress peerAddress) 00632 { 00633 ControlPlaneFlowIDs controlPlaneFlowIDs; 00634 if (controlPlaneFlowIdsForPeer.knows(peerAddress)) { 00635 controlPlaneFlowIDs = controlPlaneFlowIdsForPeer.find(peerAddress); 00636 MESSAGE_SINGLE(VERBOSE, logger, "getControlPlaneFlowIDs("<<A2N(peerAddress)<<"): flowIDs="<<printControlPlaneFlowIDs(controlPlaneFlowIDs)); 00637 } 00638 else 00639 { 00640 for (int qosClass = lte::helper::QoSClasses::PHICH(); 00641 qosClass <= lte::helper::QoSClasses::DCCH(); 00642 ++qosClass) 00643 { 00644 // flow IDs for PCCH, DCCH and PHICH are assigned now 00645 FlowID flowID = flowIDPool.suggestPort(); 00646 flowIDPool.bind(flowID); 00647 controlPlaneFlowIDs[qosClass] = flowID; 00648 00649 if (!DllFlowIDToQoSClass.knows(flowID)) 00650 DllFlowIDToQoSClass.insert(flowID, qosClass); 00651 } 00652 controlPlaneFlowIdsForPeer.insert(peerAddress, controlPlaneFlowIDs); 00653 MESSAGE_SINGLE(NORMAL, logger, "getControlPlaneFlowIDs("<<A2N(peerAddress)<<"): flowIDs="<<printControlPlaneFlowIDs(controlPlaneFlowIDs)<<" NEW"); 00654 } 00655 return controlPlaneFlowIDs; 00656 } 00657 00658 void 00659 FlowManagerBS::forwardFlowRequest(lte::helper::TransactionID _transactionID, 00660 lte::controlplane::flowmanagement::flowhandler::FlowHandlerBS* _flowHandlerBS, 00661 wns::service::dll::UnicastAddress utAddress, 00662 FlowID oldFlowID, 00663 wns::service::qos::QoSClass qosClass) 00664 { 00665 MESSAGE_SINGLE(NORMAL, logger, "FlowManagerBS::forwardFlowRequest(UT="<<A2N(utAddress)<<",TID="<<_transactionID<<",oldFID="<<oldFlowID<<",QoS="<<lte::helper::QoSClasses::toString(qosClass)<<")"); 00666 if(hasPreserved(oldFlowID)) 00667 { 00668 //(no new flow id if preserved) and reconfigure switching table (oldFlowID) 00669 //FlowConfirm... 00670 MESSAGE_SINGLE(NORMAL, logger, "Intra-REC Handover (preserved) for User:"<<A2N(utAddress)<<" Confirming FlowID="<<oldFlowID); 00671 _flowHandlerBS->flowConfirm(_transactionID, oldFlowID, utAddress); 00672 assure(qosClass == DllFlowIDToQoSClass.find(oldFlowID),"oldFlowID does not know qosClass"<<getFlowTable()); 00673 } 00674 else 00675 { 00676 //select (outgoing) transactionID for request to RANG 00677 lte::helper::TransactionID transactionIdBS = drawNewTransactionID(); 00678 //save transactionID's 00679 TransactionIdOutToIn.insert(transactionIdBS, _transactionID); 00680 //save FlowHandler to answer to later 00681 TransactionIdOutToFlowHandler.insert(transactionIdBS, _flowHandlerBS); 00682 TransactionIDToQoSClass.insert(_transactionID, qosClass); // other transactionID here! 00683 //call BSUpperConvergence toget a flowID from the RANG 00684 FlowID _flowIDout = bsUpperConvergence->requestFlow(transactionIdBS, utAddress); 00685 00686 assure(_flowIDout>0,"flowID="<<_flowIDout<<", must be >0"); 00687 // _flowIDout is the FlowID chosen by the RANG 00688 // we've got to choose a new FlowIDIn for the lower hop and save this 00689 // pair (FlowIDIn, FlowIDout) in the switching table of the BS. 00690 00691 // choose FlowID for UT or RN 00692 FlowID flowIDin = flowIDPool.suggestPort(); 00693 flowIDPool.bind(flowIDin); 00694 assure(!FlowIDToUT.knows(flowIDin), "This FlowID="<<flowIDin<<" is already in the FlowIDTable."<<getFlowTable()); 00695 MESSAGE_SINGLE(NORMAL, logger, "registerFlowID(): Newly chosen flowIDin="<<flowIDin); 00696 00697 // create new closed flow 00698 upperFlowGate->createFlow(wns::ldk::ConstKeyPtr(new lte::helper::key::FlowID(flowIDin))); 00699 arqFlowGate->createFlow(wns::ldk::ConstKeyPtr(new lte::helper::key::FlowID(flowIDin))); 00700 00701 insertFlowIDToUT(flowIDin, utAddress); 00702 00703 // get TransactionIdin for TransactionIdOut 00704 assure(TransactionIdOutToIn.knows(transactionIdBS), "TransactionID not known!"); 00705 lte::helper::TransactionID transactionIdIn = TransactionIdOutToIn.find(transactionIdBS); 00706 00707 assure(TransactionIDToQoSClass.knows(transactionIdIn),"TransactionIDToQoSClass(transactionIdIn="<<transactionIdIn<<") unknown"<<getFlowTable()); 00708 wns::service::qos::QoSClass qosClass = TransactionIDToQoSClass.find(transactionIdIn); 00709 TransactionIDToQoSClass.erase(transactionIdIn); 00710 assure(qosClass!=lte::helper::QoSClasses::UNDEFINED(),"undefined qosClass"); 00711 DllFlowIDToQoSClass.insert(flowIDin,qosClass); 00712 00713 FlowIDInToFlowIDOut.insert(flowIDin, _flowIDout); 00714 MESSAGE_SINGLE(NORMAL, logger, "Updating Switching table: New (FlowIDin, FlowIDout): ("<<flowIDin<<", "<<_flowIDout<<")"); 00715 00716 // get the right FlowHandlerBS 00717 assure(TransactionIdOutToFlowHandler.knows(transactionIdBS),"No FlowHandlerBS registered for transactionID : "<<transactionIdIn); 00718 lte::controlplane::flowmanagement::flowhandler::FlowHandlerBS* flowHandlerBS = 00719 TransactionIdOutToFlowHandler.find(transactionIdBS); 00720 00721 // delete transactionIDs from containers 00722 TransactionIdOutToIn.erase(transactionIdBS); 00723 TransactionIdOutToFlowHandler.erase(transactionIdBS); 00724 00725 // trigger FlowHandlerBS to Flow_Confirm 00726 flowHandlerBS->flowConfirm(transactionIdIn, flowIDin, utAddress); 00727 } 00728 } 00729 00730 void 00731 FlowManagerBS::onCSRCreated() 00732 { 00733 layer2 = dynamic_cast<dll::Layer2*>(getCSR()->getLayer()); 00734 00735 for( std::list<std::string>::iterator iter = flowSeparatorNames.begin(); iter != flowSeparatorNames.end(); ++iter) 00736 { 00737 wns::ldk::FlowSeparator* fs = layer2->getFUN()->findFriend<wns::ldk::FlowSeparator*>(*iter); 00738 flowSeparators.push_back(fs); 00739 } 00740 00741 //get handle to the AssociationsProxyBS 00742 wns::ldk::ControlServiceInterface* csi = layer2->getControlService<wns::ldk::ControlServiceInterface>("AssociationsProxy"); 00743 aProxyBS = dynamic_cast<lte::controlplane::AssociationsProxyBS*>(csi); 00744 assureNotNull(aProxyBS); 00745 00746 rlcReader = layer2->getFUN()->getCommandReader("rlc"); 00747 bsUpperConvergence = layer2->getFUN()->findFriend<lte::upperconvergence::ENBUpperConvergence*> 00748 ("upperConvergence"); 00749 assure(bsUpperConvergence, "No BSUpperConvergence set."); 00750 00751 upperSynchronizer = layer2->getFUN()->findFriend<wns::ldk::tools::Synchronizer*>("upperSynchronizer"); 00752 upperFlowGate = layer2->getFUN()->findFriend<wns::ldk::FlowGate*>("upperFlowGate"); 00753 arqFlowGate = layer2->getFUN()->findFriend<wns::ldk::FlowGate*>("arqFlowGate"); 00754 assure(upperSynchronizer, "No upperSynchronizer set."); 00755 assure(upperFlowGate, "No upperFlowGate set."); 00756 assure(arqFlowGate, "No arqFlowGate set."); 00757 } 00758 00759 void 00760 FlowManagerBS::releaseFlow(FlowID flowID) 00761 { 00762 assure(flowID>0,"flowID="<<flowID<<", must be >0"); 00763 //the FlowID entries in the switching table have to be deleted 00764 //the FlowID has also to be unbound from the FLowIDPool 00765 //so this FlowID could be chosen again in future FlowRequests. 00766 //finally we have to tell the RANG to delete this flow too. 00767 //RANG has to be informed of the FlowRelease 00768 FlowID flowIDOut = getFlowIDout(flowID); 00769 bsUpperConvergence->releaseFlow(flowIDOut); 00770 00771 FlowIDInToFlowIDOut.erase(flowID); 00772 00773 MESSAGE_SINGLE(NORMAL, logger, "Updating Switching table: Erasing (FlowIDin, FlowIDout): ("<<flowID<<", "<<flowIDOut<<")"); 00774 00775 flowIDPool.unbind(flowID); 00776 } 00777 00778 void 00779 FlowManagerBS::deleteFlowsInRang(wns::service::dll::UnicastAddress userAdr) 00780 { 00781 for (FlowIDTable::const_iterator iter = FlowIDToUT.begin(); 00782 iter != FlowIDToUT.end(); 00783 ++iter) 00784 { 00785 if(iter->second == userAdr) 00786 { 00787 bsUpperConvergence->deleteFlow(getFlowIDout(iter->first)); 00788 } 00789 } 00790 } 00791 00792 void 00793 FlowManagerBS::deleteLowerFlow(FlowID flowID) 00794 { 00795 assure(flowID>0,"flowID="<<flowID<<", must be >0"); 00796 //destroy lower flows for myModes 00797 for(std::list<std::string>::iterator iter = myModes.begin(); iter != myModes.end(); ++iter) 00798 { 00799 ModeName mode = *iter; 00800 lte::controlplane::flowmanagement::flowhandler::FlowHandlerBS* flowHandlerBS = 00801 layer2->getFUN()->findFriend<lte::controlplane::flowmanagement::flowhandler::FlowHandlerBS*> 00802 (mode+"_FlowHandler"); 00803 00804 flowHandlerBS->destroyFlow(flowID); 00805 MESSAGE_SINGLE(NORMAL, logger, "Lower Flow deleted for FlowID="<<flowID); 00806 } 00807 } 00808 00809 void 00810 FlowManagerBS::deleteAllLowerFlows(wns::service::dll::UnicastAddress userAdr, ModeName mode) 00811 { 00812 //destroy lower flows for mode 00813 lte::controlplane::flowmanagement::flowhandler::FlowHandlerBS* flowHandlerBS = 00814 layer2->getFUN()->findFriend<lte::controlplane::flowmanagement::flowhandler::FlowHandlerBS*> 00815 (mode+"_FlowHandler"); 00816 00817 for (FlowIDTable::const_iterator iter = FlowIDToUT.begin(); 00818 iter != FlowIDToUT.end(); 00819 ++iter) 00820 { 00821 if(iter->second == userAdr) 00822 { 00823 flowHandlerBS->destroyFlow(iter->first); 00824 } 00825 } 00826 } 00827 00828 void 00829 FlowManagerBS::preserveFlows(wns::service::dll::UnicastAddress userAdr) 00830 { 00831 for (FlowIDTable::const_iterator iter = FlowIDToUT.begin(); 00832 iter != FlowIDToUT.end(); 00833 ++iter) 00834 { 00835 if(iter->second == userAdr) 00836 { 00837 FlowID flowID = iter->first; 00838 closeUpperFlow(flowID); 00839 MESSAGE_SINGLE(NORMAL, logger, "preserveFlows("<<userAdr<<") for FlowID="<<flowID<<" for Intra-REC HO."); 00840 assure(!hasPreserved(flowID), "FlowID has already been preserved!"); 00841 registerPreservedFlowID(flowID); 00842 assure(hasPreserved(flowID), "preserve not correctly!"); 00843 } 00844 } 00845 } 00846 00847 void 00848 FlowManagerBS::onDisassociationReq(wns::service::dll::UnicastAddress userAdr, ModeName mode, bool preserved) 00849 { 00850 if(preserved) // can keep state in macg FUs (e.g. ARQ state), because intra-REC handover 00851 { 00852 MESSAGE_SINGLE(NORMAL, logger, "onDisassociationReq("<<A2N(userAdr)<<","<<mode<<","<<preserved<<"): Preserving context of " << A2N(userAdr)); 00853 //preserve upper flows 00854 preserveFlows(userAdr); 00855 deleteAllLowerFlows(userAdr, mode); 00856 } 00857 else 00858 { 00859 MESSAGE_SINGLE(NORMAL, logger, "onDisassociationReq("<<A2N(userAdr)<<","<<mode<<","<<preserved<<"): Deleting context of " << A2N(userAdr)); 00860 deleteAllFlowSeparators(userAdr); // deletes all upper flow separators for this user 00861 deleteAllUpperFlows(userAdr); // deletes all upper flow gates for this user and if nnecessary the packet in the upper synchronizer 00862 deleteFlowsInRang(userAdr); // deletes the flows of this user in the RANG 00863 deleteAllLowerFlows(userAdr, mode); // deletes the mode-dependent lower flow separators and gates for this user by means of the FlowHandler 00864 deleteSwitchingTableForUT(userAdr); // deletes flows in FlowIDInToFlowIDOut for this user 00865 deleteFlowsForUT(userAdr); // deletes flows in FlowIDToUT for this user and frees the FlowIDs in the flowIDPool 00866 } 00867 } 00868 00869 // called from FlowHandler, which was notified by AssociationObserver 00870 void 00871 FlowManagerBS::onAssociated(wns::service::dll::UnicastAddress /*userAdr*/, wns::service::dll::UnicastAddress /*dstAdr*/) 00872 {} 00873 00874 // called from FlowHandler, which was notified by AssociationObserver at the very end. 00875 void 00876 FlowManagerBS::onDisassociated(wns::service::dll::UnicastAddress userAdr, wns::service::dll::UnicastAddress dstAdr) 00877 { 00878 MESSAGE_SINGLE(NORMAL, logger, "onDisassociated(from "<<A2N(userAdr)<<" to "<<A2N(dstAdr)<<")"); // "via" case is filtered out in FlowHandler 00879 assure(dstAdr == layer2->getDLLAddress(),"not for me ?!"); 00880 assure(controlPlaneFlowIdsForPeer.knows(userAdr),"controlPlaneFlowIdsForPeer("<<A2N(userAdr)<<") not known"<<getFlowTable()); 00881 ControlPlaneFlowIDs flowIDs = controlPlaneFlowIdsForPeer.find(userAdr); 00882 for (ControlPlaneFlowIDs::const_iterator iter = flowIDs.begin(); 00883 iter != flowIDs.end(); 00884 ++iter) 00885 { 00886 FlowID flowID = iter->second; 00887 assure(DllFlowIDToQoSClass.knows(flowID),"DllFlowIDToQoSClass("<<flowID<<") unknown"); 00888 DllFlowIDToQoSClass.erase(flowID); 00889 } 00890 controlPlaneFlowIdsForPeer.erase(userAdr); 00891 } 00892 00894 // // 00895 // FlowManagerUT // 00896 // // 00898 00899 FlowManagerUT::FlowManagerUT(wns::ldk::ControlServiceRegistry* csr, const wns::pyconfig::View& config) : 00900 FlowManager(csr, config), 00901 ControlService(csr) 00902 { 00903 } 00904 00905 FlowManagerUT::~FlowManagerUT() 00906 {} 00907 00908 wns::service::qos::QoSClass 00909 FlowManagerUT::getQoSClassForBSFlowID(FlowID /*dllFlowID*/) const 00910 { 00911 assure(false,"FlowManagerUT::getQoSClassForBSFlowID(): does not exist"); 00912 } 00913 00914 wns::service::qos::QoSClass 00915 FlowManagerUT::getQoSClassForUTFlowID(FlowID dllFlowID) const 00916 { 00917 if (dllFlowID == bchFlowID_) 00918 { 00919 return lte::helper::QoSClasses::PBCH(); 00920 } 00921 assure(dllFlowID>0,"flowID="<<dllFlowID<<", must be >0"); 00922 assure(DllFlowIDToQoSClass.knows(dllFlowID),"expected the QoSClass to be known for flowID="<<dllFlowID<<getFlowTable()); 00923 return DllFlowIDToQoSClass.find(dllFlowID); 00924 } 00925 00926 void 00927 FlowManagerUT::setControlPlaneFlowIDs(wns::service::dll::UnicastAddress peerAddress, ControlPlaneFlowIDs flowIDs) 00928 { 00929 // can overwrite old entry, but must be the same content 00930 if (controlPlaneFlowIdsForPeer.knows(peerAddress)) { 00931 ControlPlaneFlowIDs oldFlowIDs = controlPlaneFlowIdsForPeer.find(peerAddress); 00932 assure(flowIDs == oldFlowIDs,"setControlPlaneFlowIDs("<<A2N(peerAddress)<<","<<printControlPlaneFlowIDs(flowIDs)<<") overwrites oldFlowIDs="<<printControlPlaneFlowIDs(oldFlowIDs)<<getFlowTable()); 00933 } else { // new 00934 MESSAGE_SINGLE(NORMAL, logger, "setControlPlaneFlowIDs("<<A2N(peerAddress)<<", flowIDs="<<printControlPlaneFlowIDs(flowIDs)<<")"); 00935 controlPlaneFlowIdsForPeer.insert(peerAddress, flowIDs); 00936 00937 int qosClass = lte::helper::QoSClasses::PHICH(); 00938 assure(flowIDs.size()== 3, "Expected exactly 3 control plane FlowIDs (PCCH, DCCH, PHICH), but got " << flowIDs.size()); 00939 for (ControlPlaneFlowIDs::const_iterator iter = flowIDs.begin(); 00940 iter != flowIDs.end(); 00941 ++iter) 00942 { 00943 FlowID flowID = iter->second; 00944 assure(!DllFlowIDToQoSClass.knows(flowID),"DllFlowIDToQoSClass("<<flowID<<") already registered"); 00945 DllFlowIDToQoSClass.insert(flowID, qosClass); 00946 qosClass++; 00947 } 00948 } 00949 } 00950 00951 std::string 00952 FlowManagerUT::getFlowTable() const 00953 { 00954 std::stringstream out; 00955 out << FlowManager::getFlowTable(); // base class prints ControlPlane FlowIDs 00956 for (FlowIDTable::const_iterator iter = FlowIDToUT.begin(); 00957 iter != FlowIDToUT.end(); 00958 ++iter) 00959 { 00960 FlowID flowID = iter->first; 00961 wns::service::dll::UnicastAddress peerAdr = iter->second; 00962 wns::service::qos::QoSClass qosClass = lte::helper::QoSClasses::UNDEFINED(); 00963 if (DllFlowIDToQoSClass.knows(flowID)) 00964 qosClass = DllFlowIDToQoSClass.find(flowID); 00965 out << "FID="<<flowID<<": peer="<<A2N(peerAdr)<<", QoS="<<lte::helper::QoSClasses::toString(qosClass) << std::endl; 00966 } 00967 return out.str(); 00968 } 00969 00970 void 00971 FlowManagerUT::buildFlow(wns::service::tl::FlowID flowID, wns::service::qos::QoSClass qosClass) 00972 { 00973 // get an association from the associationProxy. 00974 if(aProxyUT->hasAssociation()) 00975 { 00976 wns::service::dll::UnicastAddress destinationAddress = aProxyUT->getBestDetected().rapAdr; 00977 std::string usedMode = aProxyUT->getBestDetected().mode; 00978 //select a mode and get the FlowHandler for this mode(association) 00979 lte::controlplane::flowmanagement::flowhandler::FlowHandlerUT* flowHandlerUT = 00980 layer2->getFUN()->findFriend<lte::controlplane::flowmanagement::flowhandler::FlowHandlerUT*> 00981 (usedMode+"_FlowHandler"); 00982 00983 TlFlowIDToFlowHandler.insert(flowID, flowHandlerUT); 00984 00985 lte::helper::TransactionID transactionId = drawNewTransactionID(); 00986 TransactionIDToTlFlowID.insert(transactionId, flowID); 00987 TransactionIDToQoSClass.insert(transactionId, qosClass); 00988 MESSAGE_SINGLE(NORMAL, logger, "buildFlow(tl::FlowID="<<flowID<<"," // tl::flowID is not an int here! 00989 <<lte::helper::QoSClasses::toString(qosClass) 00990 <<"): dest="<<A2N(destinationAddress) 00991 <<", transactionId="<<transactionId<<", mode="<<usedMode); 00992 assure(qosClass!=lte::helper::QoSClasses::UNDEFINED(),"undefined qosClass for FlowID="<<flowID); 00993 flowHandlerUT->flowReq(transactionId, destinationAddress, 0/* means unused */, qosClass); 00994 } 00995 else 00996 { 00997 MESSAGE_SINGLE(NORMAL, logger, "Terminal currently not associated. Waiting for new Association."); 00998 } 00999 } 01000 01001 void 01002 FlowManagerUT::getAssociations() 01003 { 01004 std::string mode = aProxyUT->getBestDetected().mode; 01005 selectedMode = mode; 01006 } 01007 01008 void 01009 FlowManagerUT::flowBuilt(lte::helper::TransactionID _transactionId, FlowID _dllFlowID) 01010 { 01011 assure(_dllFlowID>0,"flowID="<<_dllFlowID<<", must be >0"); 01012 bool rebuiltFlow = false; 01013 if(TransactionIDToOldFlowID.knows(_transactionId)) 01014 { 01015 rebuiltFlow = true; 01016 } 01017 01018 if(rebuiltFlow) // new flowID for existing Flow either preserved or not: 01019 { 01020 if(hasPreserved(_dllFlowID)) // Intra-REC 01021 { 01022 MESSAGE_SINGLE(NORMAL, logger, "Opening UpperFlowGates for preserved FlowID="<<TransactionIDToOldFlowID.find(_transactionId)); 01023 01024 // erase preserved FlowID 01025 preservedFlowIDs.erase(_dllFlowID); 01026 01027 // delete TransactionID-stuff: 01028 TransactionIDToOldFlowID.erase(_transactionId); 01029 TransactionIDToTlFlowID.erase(_transactionId); 01030 TransactionIDToQoSClass.erase(_transactionId); 01031 assure(DllFlowIDToQoSClass.knows(_dllFlowID),"expected the QoSClass to be known for flowID="<<_dllFlowID<<getFlowTable()); 01032 01033 // open Gates 01034 upperFlowGate->openFlow(wns::ldk::ConstKeyPtr(new lte::helper::key::FlowID(_dllFlowID))); 01035 arqFlowGate->openFlow(wns::ldk::ConstKeyPtr(new lte::helper::key::FlowID(_dllFlowID))); 01036 } 01037 else // Inter-REC or PlainDisassociation 01038 { 01039 if(!DroppedFlowIDs.knows(TransactionIDToOldFlowID.find(_transactionId))) // Inter-REC 01040 { 01041 01042 MESSAGE_SINGLE(NORMAL, logger, "Flow_rebuilt for old FlowID="<<TransactionIDToOldFlowID.find(_transactionId)<<", new FlowID="<< _dllFlowID); 01043 01044 assure(TransactionIDToTlFlowID.knows(_transactionId),"There is no Transaction with transactionId=" << _transactionId); 01045 assure(TransactionIDToQoSClass.knows(_transactionId),"expected the QoSClass to be known for transactionId="<<_transactionId); 01046 01047 //insert into table 01048 wns::service::tl::FlowID tlFlowID = TransactionIDToTlFlowID.find(_transactionId); 01049 wns::service::qos::QoSClass qosClass = TransactionIDToQoSClass.find(_transactionId); 01050 01051 //erase old entries: 01052 TlFlowIDToDllFlowID.erase(tlFlowID); 01053 FlowID oldFlowID = TransactionIDToOldFlowID.find(_transactionId); 01054 DllFlowIDToTlFlowID.erase(oldFlowID); 01055 DllFlowIDToQoSClass.erase(oldFlowID); 01056 MESSAGE_SINGLE(NORMAL, logger, "Erasing old FlowID="<<TransactionIDToOldFlowID.find(_transactionId)<<" from FlowIDTable."); 01057 FlowIDToUT.erase(TransactionIDToOldFlowID.find(_transactionId)); 01058 01059 //destroy flowseparator instances for old flowid: 01060 deleteFlowSeparator(TransactionIDToOldFlowID.find(_transactionId)); 01061 01062 // clear UpperSynchronizer for old flowid: 01063 if(upperSynchronizer->hasSomethingToSend()){ 01064 wns::ldk::CompoundPtr compound = upperSynchronizer->getSomethingToSend(); 01065 MESSAGE_SINGLE(NORMAL, logger, "Drop outgoing compound in buffer of upperSynchronizer!"); 01066 } 01067 01068 // destroy closed old gates: 01069 upperFlowGate->destroyFlow(wns::ldk::ConstKeyPtr( 01070 new lte::helper::key::FlowID(TransactionIDToOldFlowID.find(_transactionId)))); 01071 01072 arqFlowGate->destroyFlow(wns::ldk::ConstKeyPtr( 01073 new lte::helper::key::FlowID(TransactionIDToOldFlowID.find(_transactionId)))); 01074 01075 // add new entries: 01076 TlFlowIDToDllFlowID.insert(tlFlowID, _dllFlowID); 01077 DllFlowIDToTlFlowID.insert(_dllFlowID, tlFlowID); 01078 DllFlowIDToQoSClass.insert(_dllFlowID, qosClass); 01079 insertFlowIDToUT(_dllFlowID, layer2->getDLLAddress()); 01080 01081 // delete TransactionID-stuff: 01082 TransactionIDToOldFlowID.erase(_transactionId); 01083 TransactionIDToTlFlowID.erase(_transactionId); 01084 TransactionIDToQoSClass.erase(_transactionId); 01085 01086 // inform UpperConvergence of built flow 01087 utUpperConvergence->onFlowBuilt(tlFlowID, _dllFlowID, false); 01088 // create new gates 01089 upperFlowGate->createFlow(wns::ldk::ConstKeyPtr(new lte::helper::key::FlowID(_dllFlowID))); 01090 arqFlowGate->createFlow(wns::ldk::ConstKeyPtr(new lte::helper::key::FlowID(_dllFlowID))); 01091 upperFlowGate->openFlow(wns::ldk::ConstKeyPtr(new lte::helper::key::FlowID(_dllFlowID))); 01092 arqFlowGate->openFlow(wns::ldk::ConstKeyPtr(new lte::helper::key::FlowID(_dllFlowID))); 01093 } 01094 else // plainDisassociation 01095 { 01096 MESSAGE_SINGLE(NORMAL, logger, "Flow_rebuilt for dropped FlowID: "<<TransactionIDToOldFlowID.find(_transactionId)<<", new FlowID: "<< _dllFlowID); 01097 01098 assure(TransactionIDToTlFlowID.knows(_transactionId),"There is no Transaction with transactionId=" << _transactionId); 01099 assure(TransactionIDToQoSClass.knows(_transactionId),"expected the QoSClass to be known for transactionId="<<_transactionId); 01100 01101 // insert into table 01102 wns::service::tl::FlowID tlFlowID = TransactionIDToTlFlowID.find(_transactionId); 01103 wns::service::qos::QoSClass qosClass = TransactionIDToQoSClass.find(_transactionId); 01104 01105 // erase old entries: 01106 TlFlowIDToDllFlowID.erase(tlFlowID); 01107 FlowID oldFlowID = TransactionIDToOldFlowID.find(_transactionId); 01108 DllFlowIDToTlFlowID.erase(oldFlowID); 01109 DllFlowIDToQoSClass.erase(oldFlowID); 01110 MESSAGE_SINGLE(NORMAL, logger, "Erasing old FlowID: "<<TransactionIDToOldFlowID.find(_transactionId)<<" from DroppedFlowIDs-Table."); 01111 DroppedFlowIDs.erase(TransactionIDToOldFlowID.find(_transactionId)); 01112 01113 // add new entries: 01114 TlFlowIDToDllFlowID.insert(tlFlowID, _dllFlowID); 01115 DllFlowIDToTlFlowID.insert(_dllFlowID, tlFlowID); 01116 DllFlowIDToQoSClass.insert(_dllFlowID, qosClass); 01117 insertFlowIDToUT(_dllFlowID, layer2->getDLLAddress()); 01118 01119 // delete TransactionID-stuff: 01120 TransactionIDToOldFlowID.erase(_transactionId); 01121 TransactionIDToTlFlowID.erase(_transactionId); 01122 TransactionIDToQoSClass.erase(_transactionId); 01123 01124 // inform UpperConvergence of built flow 01125 utUpperConvergence->onFlowBuilt(tlFlowID, _dllFlowID, false); 01126 // create new gates 01127 upperFlowGate->createFlow(wns::ldk::ConstKeyPtr(new lte::helper::key::FlowID(_dllFlowID))); 01128 arqFlowGate->createFlow(wns::ldk::ConstKeyPtr(new lte::helper::key::FlowID(_dllFlowID))); 01129 upperFlowGate->openFlow(wns::ldk::ConstKeyPtr(new lte::helper::key::FlowID(_dllFlowID))); 01130 arqFlowGate->openFlow(wns::ldk::ConstKeyPtr(new lte::helper::key::FlowID(_dllFlowID))); 01131 } 01132 } 01133 } 01134 else // Totally new Flow 01135 { 01136 MESSAGE_SINGLE(NORMAL, logger, "New Flow built. FlowID: "<<_dllFlowID); 01137 01138 // assure(TransactionIDToTlFlowID.knows(_transactionId),"There is no Transaction with transactionId=" << _transactionId); 01139 // assure(TransactionIDToQoSClass.knows(_transactionId),"expected the QoSClass to be known for transactionId="<<_transactionId); 01140 01141 if (TransactionIDToTlFlowID.knows(_transactionId)) { 01142 // insert into table 01143 wns::service::tl::FlowID tlFlowID = TransactionIDToTlFlowID.find(_transactionId); 01144 TlFlowIDToDllFlowID.insert(tlFlowID, _dllFlowID); 01145 DllFlowIDToTlFlowID.insert(_dllFlowID, tlFlowID); 01146 wns::service::qos::QoSClass qosClass = TransactionIDToQoSClass.find(_transactionId); 01147 DllFlowIDToQoSClass.insert(_dllFlowID, qosClass); 01148 01149 TransactionIDToTlFlowID.erase(_transactionId); 01150 TransactionIDToQoSClass.erase(_transactionId); 01151 01152 insertFlowIDToUT(_dllFlowID, layer2->getDLLAddress()); 01153 01154 //inform UpperConvergence of built flow 01155 utUpperConvergence->onFlowBuilt(tlFlowID, _dllFlowID, true); 01156 01157 // create new flow 01158 upperFlowGate->createFlow(wns::ldk::ConstKeyPtr(new lte::helper::key::FlowID(_dllFlowID))); 01159 arqFlowGate->createFlow(wns::ldk::ConstKeyPtr(new lte::helper::key::FlowID(_dllFlowID))); 01160 upperFlowGate->openFlow(wns::ldk::ConstKeyPtr(new lte::helper::key::FlowID(_dllFlowID))); 01161 arqFlowGate->openFlow(wns::ldk::ConstKeyPtr(new lte::helper::key::FlowID(_dllFlowID))); 01162 } 01163 } 01164 // inform the AssociationsProxy for probe measurement purposes and that 01165 // the contingently the handover is finished 01166 aProxyUT->flowBuilt(); 01167 MESSAGE_SINGLE(NORMAL, logger, "Probes written: "<<_dllFlowID); 01168 } // FlowManagerUT::flowBuilt() 01169 01170 FlowManager::ControlPlaneFlowIDs 01171 FlowManagerUT::getControlPlaneFlowIDs(wns::service::dll::UnicastAddress peerAddress) 01172 { 01173 ControlPlaneFlowIDs flowIDs; 01174 if (controlPlaneFlowIdsForPeer.knows(peerAddress)) 01175 { 01176 flowIDs = controlPlaneFlowIdsForPeer.find(peerAddress); 01177 } 01178 else 01179 { // can only be the (one and only) RAP we are associated to, i.e. there is only one entry 01180 assure(controlPlaneFlowIdsForPeer.begin() != controlPlaneFlowIdsForPeer.end(),"controlPlaneFlowIdsForPeer is empty"<<getFlowTable()); 01181 flowIDs = controlPlaneFlowIdsForPeer.begin()->second; 01182 } 01183 MESSAGE_SINGLE(VERBOSE, logger, "getControlPlaneFlowIDs("<<A2N(peerAddress)<<"): flowIDs="<<printControlPlaneFlowIDs(flowIDs)); 01184 return flowIDs; 01185 } 01186 01187 void 01188 FlowManagerUT::releaseFlow(wns::service::tl::FlowID flowID) 01189 { 01190 assure(TlFlowIDToDllFlowID.knows(flowID), "There is no Flow for this FlowID="<<flowID<<" available."<<getFlowTable()); 01191 lte::controlplane::flowmanagement::flowhandler::FlowHandlerUT* flowHandlerUT = TlFlowIDToFlowHandler.find(flowID); 01192 assure(flowHandlerUT, "FlowHandler not found."); 01193 flowHandlerUT->releaseFlow(TlFlowIDToDllFlowID.find(flowID)); 01194 } 01195 01196 void 01197 FlowManagerUT::flowReleased(FlowID flowID) 01198 { 01199 assure(flowID>0,"flowID="<<flowID<<", must be >0"); 01200 wns::service::tl::FlowID tmpTlFlowID = DllFlowIDToTlFlowID.find(flowID); 01201 TlFlowIDToFlowHandler.erase(tmpTlFlowID); 01202 MESSAGE_SINGLE(NORMAL, logger, "Flow released for FlowID="<<flowID); 01203 } 01204 01205 std::string 01206 FlowManagerUT::selectMode() 01207 { 01208 return selectedMode; 01209 } 01210 01211 void 01212 FlowManagerUT::onCSRCreated() 01213 { 01214 layer2 = dynamic_cast<dll::Layer2*>(getCSR()->getLayer()); 01215 01216 for( std::list<std::string>::iterator iter = flowSeparatorNames.begin(); iter != flowSeparatorNames.end(); ++iter) 01217 { 01218 wns::ldk::FlowSeparator* fs = layer2->getFUN()->findFriend<wns::ldk::FlowSeparator*>(*iter); 01219 flowSeparators.push_back(fs); 01220 } 01221 01222 //get handle to the AssociationsProxyUT 01223 wns::ldk::ControlServiceInterface* csi = layer2->getControlService<wns::ldk::ControlServiceInterface>("AssociationsProxy"); 01224 aProxyUT = dynamic_cast<lte::controlplane::AssociationsProxyUT*>(csi); 01225 assureNotNull(aProxyUT); 01226 01227 rlcReader = layer2->getFUN()->getCommandReader("rlc"); 01228 01229 upperSynchronizer = layer2->getFUN()->findFriend<wns::ldk::tools::Synchronizer*>("upperSynchronizer"); 01230 upperFlowGate = layer2->getFUN()->findFriend<wns::ldk::FlowGate*>("upperFlowGate"); 01231 arqFlowGate = layer2->getFUN()->findFriend<wns::ldk::FlowGate*>("arqFlowGate"); 01232 01233 utUpperConvergence = layer2->getFUN()->findFriend<lte::upperconvergence::UEUpperConvergence*> 01234 ("upperConvergence"); 01235 01236 assure(upperFlowGate, "No upperFlowGate set."); 01237 assure(arqFlowGate, "No arqFlowGate set."); 01238 assure(utUpperConvergence, "No UpperConvergence set."); 01239 } 01240 01241 // after a plaindisassociation, the packets from the existing flows are dropped. 01242 // layer 2 has to know that there are packets being dropped. 01243 void 01244 FlowManagerUT::insertDroppedFlowIDs() 01245 { 01246 MESSAGE_SINGLE(NORMAL, logger, "FLOWIDFORUTSIZE: "<<FlowIDToUT.size()); 01247 01248 for (FlowIDTable::const_iterator iter = FlowIDToUT.begin(); 01249 iter != FlowIDToUT.end(); 01250 ++iter) 01251 { 01252 FlowID dllFlowID = iter->first; 01253 FlowID droppedFlowID = dllFlowID + 65536; // outside the normal bounds 01254 wns::service::tl::FlowID tlFlowID = DllFlowIDToTlFlowID.find(dllFlowID); 01255 wns::service::qos::QoSClass qosClass = DllFlowIDToQoSClass.find(dllFlowID); 01256 MESSAGE_SINGLE(NORMAL, logger, "Deleted FlowID="<<dllFlowID<<", inserted FlowIDtoBeDropped="<< droppedFlowID<< " for TLFlowID="<<tlFlowID); 01257 DllFlowIDToTlFlowID.erase(dllFlowID); 01258 DllFlowIDToTlFlowID.insert(droppedFlowID, tlFlowID); 01259 DllFlowIDToQoSClass.erase(dllFlowID); 01260 DllFlowIDToQoSClass.insert(droppedFlowID, qosClass); 01261 DroppedFlowIDs.insert(droppedFlowID, layer2->getDLLAddress()); 01262 TlFlowIDToDllFlowID.erase(tlFlowID); 01263 TlFlowIDToDllFlowID.insert(tlFlowID, droppedFlowID); 01264 utUpperConvergence->onFlowBuilt(tlFlowID, droppedFlowID, false); 01265 } 01266 FlowIDToUT.clear(); 01267 } 01268 01269 // called by AssociationProxy 01270 void 01271 FlowManagerUT::onAssociatedPerMode(wns::service::dll::UnicastAddress rapAdr, bool preserved) 01272 { 01273 if(preserved) 01274 { 01275 MESSAGE_SINGLE(NORMAL, logger, "AssociatedPerMode: Intra_Rec Handover."); 01276 } 01277 else 01278 { 01279 MESSAGE_SINGLE(NORMAL, logger, "AssociatedPerMode: Inter_Rec Handover."); 01280 } 01281 reBuildFlows(rapAdr, preserved); 01282 } 01283 01284 // called by AssociationsProxy 01285 void 01286 FlowManagerUT::disassociating(ModeName mode) 01287 { 01288 MESSAGE_SINGLE(NORMAL, logger, "About to Disassociate. Close UL-Flows."); 01289 closeUpperFlows(layer2->getDLLAddress()); 01290 closeLowerFlows(mode); 01291 } 01292 01293 // disassociation due to following handover (called by AssociationsProxy) 01294 void 01295 FlowManagerUT::onDisassociatedPerMode(wns::service::dll::UnicastAddress /*bsAdr*/, ModeName mode, bool preserved) 01296 { 01297 if(preserved) 01298 { 01299 MESSAGE_SINGLE(NORMAL, logger, "DisassociatedPerMode: Intra-REC Handover."); 01300 for (FlowIDTable::const_iterator iter = FlowIDToUT.begin(); 01301 iter != FlowIDToUT.end(); 01302 ++iter) 01303 { 01304 MESSAGE_SINGLE(NORMAL, logger, "Preserving FlowID="<<iter->first); 01305 registerPreservedFlowID(iter->first); 01306 } 01307 } 01308 else 01309 { 01310 MESSAGE_SINGLE(NORMAL, logger, "DisassociatedPerMode: Inter-REC Handover."); 01311 } 01312 deleteAllLowerFlows(mode); 01313 } 01314 01315 // disassociation from old RAP without any new RAP (called by AssociationsProxy) 01316 void 01317 FlowManagerUT::onPlainDisassociation(ModeName mode) 01318 { 01319 plainDisassociation = true; 01320 MESSAGE_SINGLE(NORMAL, logger, "PlainDisassociation: Deleting all Flows. All packets are being dropped till new Association."); 01321 deleteAllFlowSeparators(layer2->getDLLAddress()); 01322 deleteAllUpperFlows(layer2->getDLLAddress()); 01323 deleteAllLowerFlows(mode); 01324 insertDroppedFlowIDs(); 01325 } 01326 01327 // notified by AssociationObserver 01328 void 01329 FlowManagerUT::onAssociated(wns::service::dll::UnicastAddress /*userAdr*/, wns::service::dll::UnicastAddress /*dstAdr*/) 01330 {} 01331 01332 // notified by AssociationObserver at the very end. 01333 void 01334 FlowManagerUT::onDisassociated(wns::service::dll::UnicastAddress userAdr, wns::service::dll::UnicastAddress dstAdr) 01335 { 01336 MESSAGE_SINGLE(NORMAL, logger, "onDisassociated(from "<<A2N(userAdr)<<" to "<<A2N(dstAdr)<<")"); 01337 assure(userAdr == layer2->getDLLAddress(),"not for me ?!"); 01338 assure(controlPlaneFlowIdsForPeer.knows(dstAdr),"controlPlaneFlowIdsForPeer("<<A2N(dstAdr)<<") not known"<<getFlowTable()); 01339 ControlPlaneFlowIDs flowIDs = controlPlaneFlowIdsForPeer.find(dstAdr); 01340 for (ControlPlaneFlowIDs::const_iterator iter = flowIDs.begin(); 01341 iter != flowIDs.end(); 01342 ++iter) 01343 { 01344 FlowID flowID = iter->second; 01345 assure(DllFlowIDToQoSClass.knows(flowID),"DllFlowIDToQoSClass("<<flowID<<") unknown"); 01346 DllFlowIDToQoSClass.erase(flowID); 01347 } 01348 controlPlaneFlowIdsForPeer.erase(dstAdr); 01349 } 01350 01351 void 01352 FlowManagerUT::reBuildFlows(wns::service::dll::UnicastAddress /*bsAdr*/, bool preserved) 01353 { 01354 wns::service::dll::UnicastAddress destinationAddress = aProxyUT->getBestDetected().rapAdr; 01355 std::string usedMode = aProxyUT->getBestDetected().mode; 01356 01357 //select a mode and get the FlowHandler for this mode(association) 01358 lte::controlplane::flowmanagement::flowhandler::FlowHandlerUT* flowHandlerUT = 01359 layer2->getFUN()->findFriend<lte::controlplane::flowmanagement::flowhandler::FlowHandlerUT*> 01360 (usedMode+"_FlowHandler"); 01361 01362 if(preserved) 01363 { 01364 for (FlowIDTable::const_iterator iter = FlowIDToUT.begin(); 01365 iter != FlowIDToUT.end(); 01366 ++iter) 01367 { 01368 FlowID dllFlowID = iter->first; 01369 MESSAGE_SINGLE(NORMAL, logger, "Flow_Establishment triggered for preserved FlowID="<<dllFlowID); 01370 lte::helper::TransactionID transactionId = drawNewTransactionID(); 01371 TransactionIDToOldFlowID.insert(transactionId, dllFlowID); 01372 TransactionIDToTlFlowID.insert(transactionId, DllFlowIDToTlFlowID.find(dllFlowID)); 01373 assure(DllFlowIDToQoSClass.knows(dllFlowID),"expected the QoSClass to be known for flowID="<<dllFlowID<<getFlowTable()); 01374 wns::service::qos::QoSClass qosClass = DllFlowIDToQoSClass.find(dllFlowID); 01375 TransactionIDToQoSClass.insert(transactionId, qosClass); 01376 flowHandlerUT->flowReq(transactionId, destinationAddress, dllFlowID, qosClass); 01377 } 01378 } 01379 else 01380 { 01381 if(!plainDisassociation) 01382 { 01383 for (FlowIDTable::const_iterator iter = FlowIDToUT.begin(); 01384 iter != FlowIDToUT.end(); 01385 ++iter) 01386 { 01387 FlowID dllFlowID = iter->first; 01388 MESSAGE_SINGLE(NORMAL, logger, "New Flow_Establishment triggered for old FlowID="<<dllFlowID); 01389 lte::helper::TransactionID transactionId = drawNewTransactionID(); 01390 TransactionIDToOldFlowID.insert(transactionId, dllFlowID); 01391 01392 TransactionIDToTlFlowID.insert(transactionId, DllFlowIDToTlFlowID.find(dllFlowID)); 01393 assure(DllFlowIDToQoSClass.knows(dllFlowID),"expected the QoSClass to be known for flowID="<<dllFlowID<<getFlowTable()); 01394 wns::service::qos::QoSClass qosClass = DllFlowIDToQoSClass.find(dllFlowID); 01395 TransactionIDToQoSClass.insert(transactionId, qosClass); 01396 flowHandlerUT->flowReq(transactionId, destinationAddress, dllFlowID, qosClass); 01397 } 01398 } 01399 else 01400 { 01401 for (FlowIDTable::const_iterator iter = DroppedFlowIDs.begin(); 01402 iter != DroppedFlowIDs.end(); 01403 ++iter) 01404 { 01405 FlowID dllFlowID = iter->first; 01406 MESSAGE_SINGLE(NORMAL, logger, "New Flow_Establishment triggered for existing but yet dropped FlowID="<<dllFlowID); 01407 lte::helper::TransactionID transactionId = drawNewTransactionID(); 01408 TransactionIDToOldFlowID.insert(transactionId, dllFlowID); 01409 TransactionIDToTlFlowID.insert(transactionId, DllFlowIDToTlFlowID.find(dllFlowID)); 01410 assure(DllFlowIDToQoSClass.knows(dllFlowID),"expected the QoSClass to be known for flowID="<<dllFlowID<<getFlowTable()); 01411 wns::service::qos::QoSClass qosClass = DllFlowIDToQoSClass.find(dllFlowID); 01412 TransactionIDToQoSClass.insert(transactionId, qosClass); 01413 flowHandlerUT->flowReq(transactionId, destinationAddress, dllFlowID, qosClass); 01414 } 01415 plainDisassociation = false; 01416 } 01417 } 01418 } 01419 01420 void 01421 FlowManagerUT::deleteLowerFlow(FlowID flowID) 01422 { 01423 //destroy lower flows for myModes 01424 for(std::list<std::string>::iterator iter = myModes.begin(); iter != myModes.end(); ++iter) 01425 { 01426 ModeName mode = *iter; 01427 lte::controlplane::flowmanagement::flowhandler::FlowHandlerUT* flowHandlerUT = 01428 layer2->getFUN()->findFriend<lte::controlplane::flowmanagement::flowhandler::FlowHandlerUT*> 01429 (mode+"_FlowHandler"); 01430 flowHandlerUT->destroyFlow(flowID); 01431 MESSAGE_SINGLE(NORMAL, logger, "Lower Flow deleted for FlowID="<<flowID); 01432 } 01433 } 01434 01435 void 01436 FlowManagerUT::deleteAllLowerFlows(ModeName mode) 01437 { 01438 lte::controlplane::flowmanagement::flowhandler::FlowHandlerUT* flowHandlerUT = 01439 layer2->getFUN()->findFriend<lte::controlplane::flowmanagement::flowhandler::FlowHandlerUT*> 01440 (mode+"_FlowHandler"); 01441 01442 for (FlowIDTable::const_iterator iter = FlowIDToUT.begin(); 01443 iter != FlowIDToUT.end(); 01444 ++iter) 01445 { 01446 flowHandlerUT->destroyFlow(iter->first); 01447 MESSAGE_SINGLE(NORMAL, logger, "Lower Flow deleted for FlowID="<<iter->first); 01448 } 01449 } 01450 01451 void 01452 FlowManagerUT::closeLowerFlows(ModeName mode) 01453 { 01454 //close lower flows for mode 01455 lte::controlplane::flowmanagement::flowhandler::FlowHandlerUT* flowHandlerUT = 01456 layer2->getFUN()->findFriend<lte::controlplane::flowmanagement::flowhandler::FlowHandlerUT*> 01457 (mode+"_FlowHandler"); 01458 01459 for (FlowIDTable::const_iterator iter = FlowIDToUT.begin(); 01460 iter != FlowIDToUT.end(); 01461 ++iter) 01462 { 01463 flowHandlerUT->closeFlow(iter->first); 01464 } 01465 }
1.5.5