![]() |
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/AssociationsProxy.hpp> 00029 #include <LTE/rlc/UE.hpp> 00030 #include <LTE/macg/MACg.hpp> 00031 00032 #include <LTE/controlplane/associationHandler/IAssociationHandler.hpp> 00033 #include <LTE/helper/Keys.hpp> 00034 00035 #include <DLL/RANG.hpp> 00036 #include <DLL/StationManager.hpp> 00037 #include <WNS/simulator/Time.hpp> 00038 #include <WNS/probe/bus/utils.hpp> 00039 00040 #define A2N(a) layer2->getStationManager()->getStationByMAC(a)->getName() 00041 00042 using namespace lte::controlplane; 00043 00044 STATIC_FACTORY_REGISTER_WITH_CREATOR(AssociationsProxyBS, 00045 wns::ldk::ControlServiceInterface, 00046 "lte.controlplane.ENBAssociationsProxy", 00047 wns::ldk::CSRConfigCreator); 00048 00049 STATIC_FACTORY_REGISTER_WITH_CREATOR(AssociationsProxyUT, 00050 wns::ldk::ControlServiceInterface, 00051 "lte.controlplane.UEAssociationsProxy", 00052 wns::ldk::CSRConfigCreator); 00053 00054 AssociationsProxy::AssociationsProxy(wns::ldk::ControlServiceRegistry* csr, const wns::pyconfig::View& config) : 00055 wns::ldk::ControlService(csr), 00056 layer2(NULL), 00057 rlcReader(NULL), 00058 myModes(), 00059 logger(config.get("logger")), 00060 activeUsers(), 00061 probed(false) 00062 { 00063 for (int i = 0; i < config.len("modeNames"); ++i) { 00064 std::string modeName = config.get<std::string>("modeNames", i); 00065 myModes.push_back(modeName); 00066 } 00067 00068 wns::probe::bus::ContextProviderCollection* cpcParent = 00069 &getCSR()->getLayer()->getContextProviderCollection(); 00070 00071 numUsers = wns::probe::bus::collector(cpcParent, config, "numUsersProbeName"); 00072 } 00073 00074 AssociationsProxy::~AssociationsProxy() 00075 { 00076 layer2 = NULL; 00077 } 00078 00079 void 00080 AssociationsProxy::onCSRCreated() 00081 { 00082 layer2 = dynamic_cast<dll::ILayer2*>(getCSR()->getLayer()); 00083 rlcReader = layer2->getFUN()->getCommandReader("rlc"); 00084 } 00085 00086 void 00087 AssociationsProxy::periodically() 00088 { 00089 if(!probed && wns::simulator::getEventScheduler()->getTime() > 0.01) 00090 { 00091 numUsers->put(activeUsers.size()); 00092 probed = true; 00093 } 00094 // Walk through the modes 00095 for(std::list<std::string>::iterator iter = myModes.begin(); iter != myModes.end(); ++iter) 00096 { 00097 ModeName mode = *iter; 00098 00099 // Count connected users in this mode 00100 uint32_t userCounter = 0; 00101 for (UserInfoLookup::const_iterator user = activeUsers.begin(); 00102 user != activeUsers.end(); 00103 ++user) 00104 { 00105 ModeInfo modeInfo = user->second; 00106 if (modeInfo.mode == mode) ++userCounter; 00107 } 00108 } 00109 } 00110 00111 00113 // // 00114 // AssociationsProxyBS // 00115 // // 00117 00118 AssociationsProxyBS::AssociationsProxyBS(wns::ldk::ControlServiceRegistry* csr, const wns::pyconfig::View& config) : 00119 AssociationsProxy(csr, config), 00120 flowManagerENB(NULL), 00121 myUpperConvergence(NULL), 00122 upperSynchronizer(NULL), 00123 myRECRAPs(), 00124 preservedUsers() 00125 { 00126 } 00127 00128 AssociationsProxyBS::~AssociationsProxyBS() 00129 {} 00130 00131 void 00132 AssociationsProxyBS::onCSRCreated() 00133 { 00134 AssociationsProxy::onCSRCreated(); 00135 00136 wns::ldk::ControlServiceInterface* csi = layer2->getControlService<wns::ldk::ControlServiceInterface>("FlowManagerBS"); 00137 flowManagerENB = dynamic_cast<lte::controlplane::flowmanagement::IFlowManagerENB*>(csi); 00138 assureNotNull(flowManagerENB); 00139 00140 // Add my own address to the list of RAPs in my REC 00141 this->addRAPofREC(layer2->getDLLAddress()); 00142 00143 myUpperConvergence = layer2->getFUN()->findFriend<dll::APUpperConvergence*>("upperConvergence"); 00144 00145 upperSynchronizer = layer2->getFUN()->findFriend<wns::ldk::tools::Synchronizer*>("upperSynchronizer"); 00146 00147 startPeriodicTimeout(0.5); 00148 } 00149 00150 lte::controlplane::flowmanagement::IFlowSwitching::ControlPlaneFlowIDs 00151 AssociationsProxyBS::associatedPerMode(wns::service::dll::UnicastAddress userAdr, 00152 wns::service::dll::UnicastAddress rapAdr, 00153 ModeName mode) 00154 { 00155 assure(!hasAssociationTo(userAdr), "user has already associated!"); 00156 00157 // store user information 00158 ModeInfo userModeInfo; 00159 userModeInfo.mode = mode; 00160 userModeInfo.rapAdr = rapAdr; 00161 activeUsers.insert(std::pair<wns::service::dll::UnicastAddress, ModeInfo>(userAdr, userModeInfo)); 00162 00163 assure(hasAssociatedPerMode(userAdr, mode), "Store user information not correctly!"); 00164 00165 MESSAGE_BEGIN(NORMAL, logger, m, "Added user="); 00166 m << A2N(userAdr) << " for mode: " << userModeInfo.mode << " (RAP=" << A2N(userModeInfo.rapAdr) << ")."; 00167 MESSAGE_END(); 00168 00169 if (hasPreserved(userAdr)) 00170 { 00171 // flow gates keep close for the flow until Flow_Rebuild completed 00172 00173 // remove user from preservedUsers 00174 std::set<wns::service::dll::UnicastAddress>::iterator foundPreserve = preservedUsers.find(userAdr); 00175 preservedUsers.erase(foundPreserve); 00176 assure(!hasPreserved(userAdr), "remove preserved user not correctly!"); 00177 } 00178 00179 // update downlink route in RANG 00180 assure(!(myUpperConvergence->getRANG()->knowsAddress(userAdr)), "User is already known in RANG!"); 00181 myUpperConvergence->getRANG()->updateAPLookUp(userAdr, myUpperConvergence); 00182 00183 MESSAGE_BEGIN(NORMAL, logger, m, "Added user="); 00184 m << A2N(userAdr) << " to RANG."; 00185 MESSAGE_END(); 00186 lte::controlplane::flowmanagement::IFlowSwitching::ControlPlaneFlowIDs controlPlaneFlowIDs; 00187 if (rapAdr == layer2->getDLLAddress()) { // BS-to-UT singlehop 00188 controlPlaneFlowIDs = flowManagerENB->getControlPlaneFlowIDs(userAdr); 00189 } else { // multihop 00190 controlPlaneFlowIDs = flowManagerENB->getControlPlaneFlowIDs(rapAdr); 00191 } 00192 return controlPlaneFlowIDs; 00193 } 00194 00195 void 00196 AssociationsProxyBS::disassociatedPerMode(wns::service::dll::UnicastAddress userAdr, 00197 wns::service::dll::UnicastAddress targetAdr, 00198 ModeName mode) 00199 { 00200 assure(hasAssociatedPerMode(userAdr, mode), "Unknown user!"); 00201 00202 // update downlink route in RANG 00203 assure(myUpperConvergence->getRANG()->knowsAddress(userAdr), "User is unknown in RANG!"); 00204 myUpperConvergence->getRANG()->removeAddress(userAdr, myUpperConvergence); 00205 assure(!(myUpperConvergence->getRANG()->knowsAddress(userAdr)), "remove user in RANG not successfully!"); 00206 00207 UserInfoLookup::iterator foundUser = activeUsers.find(userAdr); 00208 00209 activeUsers.erase(foundUser); 00210 00211 MESSAGE_BEGIN(NORMAL, logger, m, "Removed user="); 00212 m << A2N(userAdr) << " for mode: " << mode << "."; 00213 MESSAGE_END(); 00214 00215 assure(!hasAssociationTo(userAdr), "Remove user information not correctly!"); 00216 00217 if (inMyREC(targetAdr)) 00218 { 00219 flowManagerENB->onDisassociationReq(userAdr, mode, /*preserved=*/inMyREC(targetAdr)); 00220 } 00221 else 00222 { 00223 // the targetAdr is either invalid (timeout or plain disassociation) or in another REC 00224 // and user is also not preserved, so we can "forget" this user 00225 flowManagerENB->onDisassociationReq(userAdr, mode, /*preserved=*/inMyREC(targetAdr)); 00226 } 00227 } 00228 00229 bool 00230 AssociationsProxyBS::hasAssociationTo(const wns::service::dll::UnicastAddress& dstAdr) const 00231 { 00232 UserInfoLookup::const_iterator foundUser = activeUsers.find(dstAdr); 00233 00234 return (foundUser != activeUsers.end()); 00235 } 00236 00237 bool 00238 AssociationsProxyBS::hasAssociatedPerMode(wns::service::dll::UnicastAddress userAdr, ModeName mode) const 00239 { 00240 UserInfoLookup::const_iterator foundUser = activeUsers.find(userAdr); 00241 00242 return ((foundUser != activeUsers.end()) && ((*foundUser).second.mode == mode)); 00243 } 00244 00245 wns::service::dll::UnicastAddress 00246 AssociationsProxyBS::getRAPforUserPerMode(wns::service::dll::UnicastAddress userAdr, ModeName mode) const 00247 { 00248 UserInfoLookup::const_iterator foundUser = activeUsers.find(userAdr); 00249 assure(foundUser != activeUsers.end(), "getRAPforUserPerMode: User "<<A2N(userAdr)<<" not found."); 00250 assure((*foundUser).second.mode == mode, "User hasn't associated per this mode but getRAP called from this mode!"); 00251 assure((*foundUser).second.rapAdr.isValid(), "invalid RAP of user!"); 00252 return (*foundUser).second.rapAdr; 00253 } 00254 00255 bool 00256 AssociationsProxyBS::inMyREC(wns::service::dll::UnicastAddress adr) const 00257 { 00258 std::set<wns::service::dll::UnicastAddress>::const_iterator found = myRECRAPs.find(adr); 00259 return (found != myRECRAPs.end()); 00260 } 00261 00262 void 00263 AssociationsProxyBS::addRAPofREC(wns::service::dll::UnicastAddress rap) 00264 { 00265 // Avoid adding the same RAP twice 00266 if (!inMyREC(rap)) 00267 myRECRAPs.insert(rap); 00268 } 00269 00270 bool 00271 AssociationsProxyBS::hasPreserved(wns::service::dll::UnicastAddress userAdr) const 00272 { 00273 std::set<wns::service::dll::UnicastAddress>::const_iterator found = preservedUsers.find(userAdr); 00274 return (found != preservedUsers.end()); 00275 } 00276 00278 // // 00279 // AssociationsProxyUT // 00280 // // 00282 00283 AssociationsProxyUT::AssociationsProxyUT(wns::ldk::ControlServiceRegistry* csr, const wns::pyconfig::View& config) : 00284 AssociationsProxy(csr, config), 00285 rlc(NULL), 00286 upperSynchronizer(NULL), 00287 macg(NULL), 00288 activeAssociation(), 00289 detectedModes(), 00290 interMode(), 00291 busy(false), 00292 plainDisassociation(false), 00293 preserve(false), 00294 associationStartTime(0.0), 00295 disAssociationStartTime(0.0), 00296 modePriorityLookup(), 00297 associationDurationProbe(NULL), 00298 initialaccessDurationProbe(NULL), 00299 initialaccessFirstTime(true), 00300 handoverDurationProbe(NULL) 00301 { 00302 wns::pyconfig::View modePriorityView = config.getView("modePriority"); 00303 unsigned int numModes = modePriorityView.get<int>("__len__()"); 00304 assure(numModes == myModes.size(), "Mismatch of mode priority!"); 00305 int priorityForNone = 0; 00306 for(unsigned int i=0; i < numModes; i++) 00307 { 00308 ModeName modeName = modePriorityView.get<ModeName>("keys()", i); 00309 int priority = modePriorityView.get<int>("values()", i); 00310 modePriorityLookup[modeName] = priority; 00311 priorityForNone = priority + 1 ; 00312 } 00313 modePriorityLookup["none"] = priorityForNone; 00314 } 00315 00316 AssociationsProxyUT::~AssociationsProxyUT() 00317 { 00318 if (associationDurationProbe != NULL) delete associationDurationProbe; associationDurationProbe = NULL; 00319 if (initialaccessDurationProbe != NULL) delete initialaccessDurationProbe; initialaccessDurationProbe = NULL; 00320 if (handoverDurationProbe != NULL) delete handoverDurationProbe; handoverDurationProbe = NULL; 00321 } 00322 00323 void 00324 AssociationsProxyUT::onCSRCreated() 00325 { 00326 AssociationsProxy::onCSRCreated(); 00327 00328 flowManagerUE = layer2->getControlService<lte::controlplane::flowmanagement::IFlowManagerUE>("FlowManagerUT"); 00329 00330 rlc = layer2->getFUN()->findFriend<lte::rlc::UERLC*>("rlc"); 00331 00332 upperSynchronizer = layer2->getFUN()->findFriend<wns::ldk::tools::Synchronizer*>("upperSynchronizer"); 00333 00334 // Only interested in the receptacle aspect of the macg FU to send a wakeup 00335 macg = layer2->getFUN()->findFriend<lte::macg::MACg*>("macg"); 00336 00337 for(std::list<std::string>::iterator iter = myModes.begin(); iter != myModes.end(); ++iter) 00338 { 00339 ModeName mode = *iter; 00340 detectedModes[mode] = wns::service::dll::UnicastAddress(); 00341 } 00342 00343 // set activeAssociation as none 00344 activeAssociation.mode = "none"; 00345 00346 // set interMode as none 00347 interMode.mode = "none"; 00348 00349 associationDurationProbe = new wns::probe::bus::ContextCollector( 00350 wns::probe::bus::ContextProviderCollection(getCSR()->getLayer()->getContextProviderCollection()), "lte.AssociationDuration"); 00351 00352 initialaccessDurationProbe = new wns::probe::bus::ContextCollector( 00353 wns::probe::bus::ContextProviderCollection(getCSR()->getLayer()->getContextProviderCollection()), "lte.InitialAccessDuration"); 00354 00355 handoverDurationProbe = new wns::probe::bus::ContextCollector( 00356 wns::probe::bus::ContextProviderCollection(getCSR()->getLayer()->getContextProviderCollection()), "lte.HandoverDuration"); 00357 } 00358 00359 // triggered by AssociationHandler after reception of AssociationAck from RAP: 00360 void 00361 AssociationsProxyUT::associatedPerMode(wns::service::dll::UnicastAddress rapAdr, 00362 wns::service::dll::UnicastAddress bsAdr, 00363 ModeName mode, 00364 lte::controlplane::flowmanagement::IFlowSwitching::ControlPlaneFlowIDs controlPlaneFlowIDs) 00365 { 00366 assure(!hasAssociationTo(bsAdr),"UT has already association to the BS!"); 00367 assure(!hasAssociation(), "UT has already association!"); 00368 flowManagerUE->setControlPlaneFlowIDs(rapAdr, controlPlaneFlowIDs); 00369 00370 activeAssociation.mode = mode; 00371 activeAssociation.rap = rapAdr; 00372 activeAssociation.bs = bsAdr; 00373 00374 MESSAGE_BEGIN(NORMAL, logger, m, "Stored RAP="); 00375 m << A2N(activeAssociation.rap) << " for mode=" << activeAssociation.mode 00376 << " (BS=" << A2N(activeAssociation.bs) << ")."; 00377 MESSAGE_END(); 00378 00379 assure(hasAssociationTo(bsAdr), "store association info not correctly!"); 00380 00381 // check this association is preserved 00382 if(preserve) 00383 { 00384 // reset preserve 00385 preserve = false; 00386 } 00387 flowManagerUE->onAssociatedPerMode(rapAdr, preserve); 00388 00389 // check this association is intra or inter mode handover 00390 if (interMode.mode != "none") 00391 { 00392 assure(interMode.rapAdr.isValid(), "Wrong information stored for interMode!"); 00393 // reset interMode 00394 interMode.mode = "none"; 00395 // reset interMode handover destination 00396 interMode.rapAdr = wns::service::dll::UnicastAddress(); 00397 } 00398 else 00399 { 00400 // Intra-Mode-Handover completed 00401 assure(!(interMode.rapAdr.isValid()), "Wrong information stored for interMode!"); 00402 // set destination to RLC, so that RLC ready to accept outgoing compounds 00403 rlc->setDestination(bsAdr); 00404 macg->wakeup(); 00405 } 00406 00407 // write the association duration Probe 00408 writeProbes(true); 00409 00410 if (disAssociationStartTime == 0.0) 00411 { 00412 // free again for new signaling, because it was an initial access 00413 // no need to wait for flow establishment 00414 busy = false; 00415 MESSAGE_SINGLE(NORMAL, logger, "Not busy any more."); 00416 } 00417 } // associatedPerMode 00418 00419 void 00420 AssociationsProxyUT::disassociatedPerMode(wns::service::dll::UnicastAddress rapAdr, ModeName mode, bool preserved) 00421 { 00422 assure(activeAssociation.rap == rapAdr, "UT has no association!"); 00423 00424 wns::service::dll::UnicastAddress bsAdr = activeAssociation.bs; 00425 00426 activeAssociation = AssociationInfo(); 00427 activeAssociation.mode = "none"; 00428 00429 MESSAGE_BEGIN(NORMAL, logger, m, "Removed RAP="); 00430 m << A2N(rapAdr) << " for mode=" << mode << "(BS=" << A2N(bsAdr) << ")."; 00431 MESSAGE_END(); 00432 00433 assure(!hasAssociationTo(bsAdr),"Reset association info not correctly!"); 00434 00435 if (plainDisassociation) 00436 { 00437 MESSAGE_SINGLE(NORMAL, logger, "Not busy any more."); 00438 busy = false; 00439 plainDisassociation = false; 00440 00441 //maybe wrong place to call, but for now enough for purposes: 00442 flowManagerUE->onPlainDisassociation(mode); 00443 00444 // check if other mode already detected 00445 ModeInfo otherDetected = getBestDetected(); 00446 if (otherDetected.rapAdr.isValid()) 00447 { 00448 busy = true; 00449 00450 MESSAGE_BEGIN(NORMAL, logger, m, "Associating mode=") ; 00451 m << mode << " (RAP=" << A2N(rapAdr) << ")."; 00452 MESSAGE_END(); 00453 00454 layer2->getFUN()->findFriend<lte::controlplane::associationHandler::IAssociationHandlerTriggers*>(mode+"_associationHandler") 00455 ->associateTo(rapAdr); 00456 00457 associationStartTime = wns::simulator::getEventScheduler()->getTime(); 00458 MESSAGE_SINGLE(NORMAL, logger, "disassociatedPerMode(): plainDisassociation, AssociationStartTime="<< associationStartTime); 00459 } 00460 else // no other detected modes, PlainDisAssociation 00461 { 00462 //disable AssociationDuration Probe Measurement 00463 associationStartTime = 0.0; 00464 MESSAGE_SINGLE(NORMAL, logger, "disassociatedPerMode(): plainDisassociation, AssociationStartTime="<< associationStartTime); 00465 00466 return; 00467 } 00468 } 00469 else //it is a HANDOVER 00470 { 00471 // check preserve 00472 if(preserved) 00473 { 00474 preserve = true; 00475 } 00476 else // no preserve 00477 { 00478 // reset the destination to RLC, so that RLC not accept outgoing compounds 00479 rlc->setDestination(wns::service::dll::UnicastAddress()); 00480 } 00481 associationStartTime = wns::simulator::getEventScheduler()->getTime(); 00482 MESSAGE_SINGLE(NORMAL, logger, "disassociatedPerMode(): HANDOVER, AssociationStartTime="<< associationStartTime); 00483 flowManagerUE->onDisassociatedPerMode(bsAdr, mode, preserved); 00484 } 00485 00486 // check if this disassociation is for inter or intra mode handover or 00487 // only the plain disassociation because of too low SINR 00488 if (interMode.rapAdr.isValid()) 00489 { 00490 // Inter-Mode-Handover to complete 00491 assure(interMode.mode != "none", "Mode name not found for inter mode handover!"); 00492 layer2->getFUN()->findFriend<lte::controlplane::associationHandler::IAssociationHandlerTriggers*> 00493 (interMode.mode+"_associationHandler")->associateTo(interMode.rapAdr); 00494 } 00495 //else is Intra-Mode-Handover, 00496 //the associationHandler continues with the association phase 00497 //signaling will be completed by associatedPerMode(rap, bs, mode) 00498 } // disassociatedPerMode 00499 00500 bool 00501 AssociationsProxyUT::hasAssociationTo(const wns::service::dll::UnicastAddress& destination) const 00502 { 00503 return (activeAssociation.bs == destination || activeAssociation.rap == destination); 00504 } 00505 00506 wns::service::dll::UnicastAddress 00507 AssociationsProxyUT::getBSforMode(ModeName mode) const 00508 { 00509 if (activeAssociation.mode == mode) 00510 return activeAssociation.bs; 00511 else 00512 return wns::service::dll::UnicastAddress(); 00513 } 00514 00515 void 00516 AssociationsProxyUT::disassociationOnTimeout(wns::service::dll::UnicastAddress dst, ModeName mode) 00517 { 00518 wns::service::dll::UnicastAddress bs = getBSforMode(mode); 00519 assure(bs.isValid(), "invalid base station!"); 00520 bool preserved = false; 00521 disassociatedPerMode(dst, mode, preserved); 00522 00523 dll::ILayer2* destination = layer2->getStationManager()->getStationByMAC(dst); 00524 00525 // associated to a BS 00526 if (bs == dst) 00527 destination->getFUN()->findFriend<lte::controlplane::associationHandler::IAssociationHandler*>(mode+"_associationHandler") 00528 ->disassociationOnTimeout(layer2->getDLLAddress(), mode); 00529 00530 // associated to a RN 00531 else 00532 destination->getFUN()->findFriend<lte::controlplane::associationHandler::IAssociationHandler*>(mode+"_BS_associationHandler") 00533 ->disassociationOnTimeout(layer2->getDLLAddress(), mode); 00534 } 00535 00536 bool 00537 AssociationsProxyUT::isBusy() const 00538 { 00539 return busy; 00540 } 00541 00542 void 00543 AssociationsProxyUT::modeDetected(ModeName mode, wns::service::dll::UnicastAddress rapAdr) 00544 { 00545 if (!(detectedModes[mode] == rapAdr)) 00546 { 00547 MESSAGE_BEGIN(NORMAL, logger, m, "Detected mode="); 00548 m << mode << " (RAP=" << A2N(rapAdr) << ")."; 00549 MESSAGE_END(); 00550 00551 // update detected mode(overwrite the RAP address) 00552 detectedModes[mode] = rapAdr; 00553 }// else the rap is already detected! nothing to do. 00554 00555 if (!busy) 00556 { 00557 // has no association -> associate the detected mode 00558 if (!hasAssociation()) 00559 { 00560 busy = true; 00561 00562 MESSAGE_BEGIN(NORMAL, logger, m, "Associating mode=") ; 00563 m << mode << " (RAP=" << A2N(rapAdr) << ")."; 00564 MESSAGE_END(); 00565 00566 layer2->getFUN()->findFriend<lte::controlplane::associationHandler::IAssociationHandlerTriggers*>(mode+"_associationHandler") 00567 ->associateTo(rapAdr); 00568 00569 associationStartTime = wns::simulator::getEventScheduler()->getTime(); 00570 MESSAGE_SINGLE(NORMAL, logger, "modeDetected(): AssociationStartTime="<< associationStartTime); 00571 } 00572 00573 else 00574 { 00575 if (activeAssociation.mode == mode) // Intra-Mode-HO decision 00576 { 00577 if (activeAssociation.rap == rapAdr) 00578 { 00579 // UT is already associated with this RAP. Nothing to do 00580 MESSAGE_SINGLE(NORMAL, logger, "modeDetected(): Already associated to " << A2N(rapAdr) << " per mode=" << mode); 00581 return; 00582 } 00583 else // Intra-Mode-HO 00584 { 00585 MESSAGE_SINGLE(NORMAL, logger, "modeDetected(): Intra-Mode(Inter- or Intra-rec)"); 00586 // only the best RAP per this detected mode will be 00587 // reported -> the new RAP is better than the old RAP 00588 assure(interMode.mode == "none", "Wrong information stored for interMode!"); 00589 busy = true; 00590 00591 MESSAGE_BEGIN(NORMAL, logger, m, "modeDetected(): Intra-Mode Handover for mode="); 00592 m << mode << ", target=" << A2N(rapAdr) << ")."; 00593 MESSAGE_END(); 00594 00595 //FlowManager has to release existing Flows to the RAP going to disassociate from 00596 flowManagerUE->disassociating(mode); 00597 //start time for HO interruption time 00598 //probe: 00599 disAssociationStartTime = wns::simulator::getEventScheduler()->getTime(); 00600 MESSAGE_SINGLE(NORMAL, logger, "disAssociationStartTime set (modeDetected): "<< disAssociationStartTime); 00601 layer2->getFUN()->findFriend<lte::controlplane::associationHandler::IAssociationHandlerTriggers*> 00602 (mode+"_associationHandler")->switchAssociationTo(rapAdr); 00603 } 00604 } 00605 else // Inter-Mode-HO 00606 { 00607 if (modePriorityLookup[mode] < modePriorityLookup[activeAssociation.mode]) // Decision for Inter-Mode-HO 00608 { 00609 // store the next association, disassociation first 00610 interMode.mode = mode; 00611 interMode.rapAdr = rapAdr; 00612 00613 busy = true; 00614 00615 MESSAGE_BEGIN(NORMAL, logger, m, "modeDetected(): Inter-Mode Handover for mode="); 00616 m << mode << ", target=" << A2N(rapAdr) << ")."; 00617 MESSAGE_END(); 00618 00619 //FlowManager has to release mode-dependent existing Flows to the RAP going to disassociate from 00620 flowManagerUE->disassociating(activeAssociation.mode); 00621 00622 //start time for HO interruption time 00623 //probe: 00624 disAssociationStartTime = wns::simulator::getEventScheduler()->getTime(); 00625 MESSAGE_SINGLE(NORMAL, logger, "modeDetected(): disAssociationStartTime="<< disAssociationStartTime); 00626 00627 layer2->getFUN() 00628 ->findFriend<lte::controlplane::associationHandler::IAssociationHandlerTriggers*> 00629 (activeAssociation.mode + "_associationHandler")->disassociate(rapAdr); 00630 } 00631 } 00632 } 00633 } 00634 } 00635 00636 void 00637 AssociationsProxyUT::disassociationNeeded(ModeName mode, wns::service::dll::UnicastAddress /*rapAdr*/) 00638 { 00639 // called from the associationHandler, 00640 // which was informed from BCHService that the SINR is now too low, 00641 // -> delete this detected Mode! 00642 if (detectedModes[mode].isValid()) 00643 { 00644 // reset the RAP address of the mode in detectedModes 00645 detectedModes[mode] = wns::service::dll::UnicastAddress(); 00646 } //else do nothing 00647 00648 if ((activeAssociation.mode == mode) && (!busy)) 00649 { 00650 // get the best of the detectedModes 00651 // Intra-Mode-HO impossible! 00652 // the best is either another mode or none 00653 interMode = getBestDetected(); 00654 00655 // set busy because of signaling 00656 busy = true; 00657 00658 MESSAGE_BEGIN(NORMAL, logger, m, "disassociationNeeded(): Disassociating mode="); 00659 m << mode << " (RAP=" << A2N(activeAssociation.rap) << ") because of threshold violation."; 00660 MESSAGE_END(); 00661 00662 // get the associationHandler of the active association 00663 lte::controlplane::associationHandler::IAssociationHandlerTriggers* ah = layer2->getFUN() 00664 ->findFriend<lte::controlplane::associationHandler::IAssociationHandlerTriggers*>(mode+"_associationHandler"); 00665 00666 if (interMode.rapAdr.isValid()) // other detected mode -> Inter-Mode-HO 00667 { 00668 assure(!(interMode.mode == mode), "disassociation because of threshold violation doesn't lead to Intra-Mode-HO!"); 00669 //setting disAssociationStartTime for HO interruption time probe: 00670 disAssociationStartTime = wns::simulator::getEventScheduler()->getTime(); 00671 MESSAGE_SINGLE(NORMAL, logger, "disassociationNeeded(): disAssociationStartTime="<< disAssociationStartTime); 00672 } 00673 else // no other modes detected -> plain disassociation 00674 { 00675 assure(interMode.mode == "none", "Wrong mode information stored in interMode!"); 00676 // set plainDisassociation so that associationsProxy resets busy after the disassociation 00677 plainDisassociation = true; 00678 MESSAGE_SINGLE(NORMAL, logger, "disassociationNeeded()plainDisassociation="<< plainDisassociation); 00679 // do not evaluate handoverduration because it is PlainDisassociation 00680 disAssociationStartTime = 0.0; 00681 MESSAGE_SINGLE(NORMAL, logger, "disassociationNeeded(): disAssociationStartTime="<< disAssociationStartTime); 00682 } 00683 //FlowManager has to release mode-dependent existing Flows to the RAP going to disassociate from 00684 flowManagerUE->disassociating(activeAssociation.mode); 00685 ah->disassociate(interMode.rapAdr); 00686 } 00687 } // disassociationNeeded 00688 00689 bool 00690 AssociationsProxyUT::hasAssociation() const 00691 { 00692 return (activeAssociation.mode != "none"); 00693 } 00694 00695 ModeInfo 00696 AssociationsProxyUT::getBestDetected() const 00697 { 00698 ModeInfo modeInfo; 00699 modeInfo.mode = "none"; 00700 int currentPriority = 0; 00701 00702 // result 00703 ModeInfo bestModeInfo; 00704 bestModeInfo.mode = "none"; 00705 int bestPriority = 0; 00706 00707 for(std::list<ModeName>::const_iterator iter = myModes.begin(); iter != myModes.end(); ++iter) 00708 { 00709 // get the RAP address of the mode in detectedModes 00710 ModeName modeName = (*iter); 00711 std::map<ModeName, wns::service::dll::UnicastAddress>::const_iterator foundDetected = detectedModes.find(modeName); 00712 wns::service::dll::UnicastAddress foundRAPAdr = (*foundDetected).second; 00713 if (!(foundRAPAdr.isValid())) // forget the undetected modes 00714 continue; 00715 std::map<ModeName, int>::const_iterator foundCurrentMode = modePriorityLookup.find(modeName); 00716 currentPriority = (*foundCurrentMode).second; 00717 00718 // the first update 00719 if(!(bestModeInfo.rapAdr.isValid())) 00720 { 00721 bestPriority = currentPriority; 00722 bestModeInfo.mode = modeName; 00723 bestModeInfo.rapAdr = foundRAPAdr; 00724 } 00725 else 00726 { 00727 // update the result if the current is better 00728 if(currentPriority < bestPriority) 00729 { 00730 bestPriority = currentPriority; 00731 bestModeInfo.mode = modeName; 00732 bestModeInfo.rapAdr = foundRAPAdr; 00733 } 00734 } 00735 } 00736 00737 return bestModeInfo; 00738 } // getBestDetected 00739 00740 void 00741 AssociationsProxyUT::writeProbes(const bool alreadyAfterAssociation) 00742 { 00743 wns::simulator::Time now = wns::simulator::getEventScheduler()->getTime(); 00744 if (alreadyAfterAssociation) 00745 { 00746 // here the duration of the association procedure itself is measured 00747 assure(associationStartTime > 0.0, "associationStartTime is 0 after association!"); 00748 associationDurationProbe->put(now - associationStartTime); 00749 MESSAGE_SINGLE(VERBOSE, logger, "AssociationStartTime: Writeprobes AssociationDuration written: "<<now - associationStartTime); 00750 } 00751 else 00752 { 00753 //InitialAccess after PlainDisassociation: 00754 if (disAssociationStartTime == 0.0) 00755 { 00756 //assure(associationStartTime > 0.0, "No InitialAccess without Association."); 00757 if(associationStartTime > 0.0) 00758 { 00759 if(initialaccessFirstTime == true) 00760 { 00761 //don't consider the first time. because association and starting an 00762 //application (building first flow) are independent 00763 initialaccessFirstTime = false; 00764 } 00765 else 00766 { 00767 // this is written after the association AND the first 00768 // flow is established, i.e. user plane data can be sent 00769 initialaccessDurationProbe->put(now - associationStartTime); 00770 // reset in order to measure only after the first flow 00771 // is established 00772 MESSAGE_SINGLE(VERBOSE, logger, "AssociationStartTime set 0.0. Writeprobes InitialAccess written: "<<now - associationStartTime); 00773 } 00774 associationStartTime = 0.0; 00775 } 00776 else 00777 MESSAGE_SINGLE(VERBOSE, logger, "AssociationStartTime: 0.0, disAssociationStartTime: 0.0. No InitialAccess to measure! (May be further more Flow(s)."); 00778 } 00779 // Handover: 00780 else 00781 { 00782 // this is written if and only if there was a 00783 // disassociation before the association AND again after 00784 // the first flow is established, i.e. user plane data 00785 // can be sent. This is a handover 00786 handoverDurationProbe->put(now - disAssociationStartTime); 00787 MESSAGE_SINGLE(VERBOSE, logger, "disAssociationStartTime set 0.0. Writeprobes HO-duration written: "<<now - disAssociationStartTime); 00788 00789 // reset in order to measure only after the first flow 00790 // is established 00791 disAssociationStartTime = 0.0; 00792 associationStartTime = 0.0; 00793 } 00794 } 00795 } // writeProbes 00796 00797 void 00798 AssociationsProxyUT::flowBuilt() 00799 { 00800 // false means that measurement is not already after association 00801 // procedure, but after the first flow is established 00802 writeProbes(false); 00803 busy = false; 00804 MESSAGE_SINGLE(NORMAL, logger, "flowBuilt(): Not busy any more."); 00805 }
1.5.5