User Manual, Developers Guide and API Documentation

AssociationsProxy.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/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 }

Generated on Mon May 21 03:32:02 2012 for openWNS by  doxygen 1.5.5