User Manual, Developers Guide and API Documentation

FlowManager.cpp

Go to the documentation of this file.
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 }

Generated on Thu May 24 03:32:01 2012 for openWNS by  doxygen 1.5.5