User Manual, Developers Guide and API Documentation

FrameSynchronization.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  * WiMeMac                                                                    *
00003  * This file is part of openWNS (open Wireless Network Simulator)
00004  * _____________________________________________________________________________
00005  *
00006  * Copyright (C) 2004-2011
00007  * Chair of Communication Networks (ComNets)
00008  * Kopernikusstr. 5, D-52074 Aachen, Germany
00009  * phone: ++49-241-80-27910,
00010  * fax: ++49-241-80-22242
00011  * email: info@openwns.org
00012  * www: http://www.openwns.org
00013  * _____________________________________________________________________________
00014  *
00015  * openWNS is free software; you can redistribute it and/or modify it under the
00016  * terms of the GNU Lesser General Public License version 2 as published by the
00017  * Free Software Foundation;
00018  *
00019  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00020  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00021  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00022  * details.
00023  *
00024  * You should have received a copy of the GNU Lesser General Public License
00025  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00026  *
00027  ******************************************************************************/
00028 
00029 #include <WIMEMAC/convergence/FrameSynchronization.hpp>
00030 #include <WIMEMAC/convergence/PhyUser.hpp>
00031 #include <WIMEMAC/convergence/PreambleGenerator.hpp>
00032 
00033 #include <WNS/ldk/Layer.hpp>
00034 #include <WNS/ldk/crc/CRC.hpp>
00035 #include <WNS/probe/bus/utils.hpp>
00036 
00037 #include <DLL/Layer2.hpp>
00038 
00039 using namespace wimemac::convergence;
00040 
00041 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00042     FrameSynchronization,
00043     wns::ldk::probe::Probe,
00044     "wimemac.convergence.FrameSynchronization",
00045     wns::ldk::FUNConfigCreator);
00046 
00047 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00048     FrameSynchronization,
00049     wns::ldk::FunctionalUnit,
00050     "wimemac.convergence.FrameSynchronization",
00051     wns::ldk::FUNConfigCreator);
00052 
00053 FrameSynchronization::FrameSynchronization(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config):
00054     wns::ldk::fu::Plain<FrameSynchronization, FrameSynchronizationCommand>(fun),
00055     wns::ldk::probe::Probe(),
00056 
00057     logger(config.get("logger")),
00058     curState(Idle),
00059     synchronizedToAddress(),
00060     slcCapture(config.get<wns::Ratio>("myConfig.slcCapture")),
00061     slgCapture(config.get<wns::Ratio>("myConfig.slgCapture")),
00062     idleCapture(config.get<wns::Ratio>("myConfig.idleCapture")),
00063     detectionThreshold(config.get<wns::Ratio>("myConfig.detectionThreshold")),
00064     signalRxErrorAlthoughNotSynchronized(config.get<bool>("myConfig.signalRxErrorAlthoughNotSynchronized")),
00065     lastFrameEnd(0),
00066     managerName(config.get<std::string>("managerName")),
00067     crcCommandName(config.get<std::string>("crcCommandName"))
00068 {
00069     // read the localIDs from the config
00070     wns::probe::bus::ContextProviderCollection localContext(&fun->getLayer()->getContextProviderCollection());
00071     for (int ii = 0; ii<config.len("localIDs.keys()"); ++ii)
00072     {
00073         std::string key = config.get<std::string>("localIDs.keys()",ii);
00074         unsigned long int value  = config.get<unsigned long int>("localIDs.values()",ii);
00075         localContext.addProvider(wns::probe::bus::contextprovider::Constant(key, value));
00076         MESSAGE_SINGLE(VERBOSE, logger, "Using Local IDName '"<<key<<"' with value: "<<value);
00077     }
00078 
00079 }
00080 
00081 FrameSynchronization::~FrameSynchronization()
00082 {
00083 
00084 }
00085 
00086 void FrameSynchronization::doSendData(const wns::ldk::CompoundPtr& compound)
00087 {
00088     // Stop any synchronization
00089     switch(curState)
00090     {
00091     case Idle:
00092         break;
00093     case Synchronized:
00094         // signal end of frame to each observer
00095         MESSAGE_SINGLE(NORMAL, logger, "Send data during decoding -> signal rx error");
00096         this->wns::Subject<IRxStartEnd>::forEachObserver(OnRxStartEnd(0, false, true));
00097         // Fall through to set state to Idle
00098     case waitForFinalDelivery:
00099     case Garbled:
00100         MESSAGE_SINGLE(NORMAL, logger, "Send data during reception -> reset curState to idle");
00101         lastFrameEnd = wns::simulator::getEventScheduler()->getTime();
00102         if(hasTimeoutSet())
00103             cancelTimeout();
00104         curState = Idle;
00105         synchronizedToAddress = wns::service::dll::UnicastAddress();
00106         break;
00107     default:
00108         assure(false, "Unknown state");
00109     }
00110 
00111     // pass through
00112     getConnector()->getAcceptor(compound)->sendData(compound);
00113 }
00114 
00115 void FrameSynchronization::doOnData(const wns::ldk::CompoundPtr& compound)
00116 {
00117     if(friends.manager->isPreamble(compound->getCommandPool()))
00118     {
00119         this->processPreamble(compound);
00120     }
00121     else
00122     {
00123         this->processPSDU(compound);
00124     }
00125 }
00126 
00127 void FrameSynchronization::processPreamble(const wns::ldk::CompoundPtr& compound)
00128 {
00129     assure(friends.manager->isPreamble(compound->getCommandPool()),
00130            "called processPreamble for non-preamble");
00131 
00132     bool crcOk = getFUN()->getCommandReader(crcCommandName)->readCommand<wimemac::convergence::ErrorModellingCommand>(compound->getCommandPool())->local.checkOK;
00133 
00134     wns::simulator::Time fDur = friends.manager->getpsduDuration(compound->getCommandPool());
00135     if(!friends.manager->hasPayload(compound->getCommandPool())) fDur = 0;
00136 
00137     wns::Ratio sinr = getFUN()->getCommandReader(crcCommandName)->readCommand<wimemac::convergence::ErrorModellingCommand>(compound->getCommandPool())->local.sinr;
00138 
00139     if(sinr < detectionThreshold)
00140     {
00141         MESSAGE_SINGLE(NORMAL, logger, "ProcessPreamble(idle), SINR= " << sinr << " below detection threshold -> DROP");
00142         return;
00143     }
00144 
00145     wns::Ratio captureThreshold;
00146     switch(curState)
00147     {
00148     case Idle:
00149         MESSAGE_SINGLE(NORMAL, logger, "ProcessPreamble(idle), SINR= " << sinr << " CRC " << crcOk);
00150         assure(lastFrameEnd <= wns::simulator::getEventScheduler()->getTime(), "State is idle, but last frame has not finished");
00151         assure(!this->hasTimeoutSet(), "State is idle, but timeout is set");
00152         captureThreshold = idleCapture;
00153         break;
00154 
00155     case Synchronized:
00156         MESSAGE_SINGLE(NORMAL, logger, "processPreamble(synchronized), SINR= " << sinr << " CRC " << crcOk);
00157         assure(lastFrameEnd >= wns::simulator::getEventScheduler()->getTime(), "State is synchronized, but lastFrameEnd is over");
00158         assure(this->hasTimeoutSet(), "State is decoding, but no timeout set");
00159         captureThreshold = slcCapture;
00160         break;
00161 
00162     case waitForFinalDelivery:
00163         MESSAGE_SINGLE(NORMAL, logger, "processPreamble(waitForFinalDelivery), SINR= " << sinr << " CRC " << crcOk);
00164         assure(this->hasTimeoutSet(), "State is waitForFinalDelivery, but no timeout set");
00165         assure(lastFrameEnd+10e-9 >= wns::simulator::getEventScheduler()->getTime(), "State is waitForFinalDelivery, but lastFrameEnd is over");
00166         captureThreshold = slcCapture;
00167         break;
00168 
00169     case Garbled:
00170         MESSAGE_SINGLE(NORMAL, logger, "processPreamble(garbled), SINR= " << sinr << " CRC " << crcOk);
00171         assure(this->hasTimeoutSet(), "State is garbled, but no timeout set");
00172         assure(lastFrameEnd >= wns::simulator::getEventScheduler()->getTime(), "State is garbled, but lastFrameEnd is over");
00173         captureThreshold = slgCapture;
00174         break;
00175 
00176     default:
00177         assure(false, "Unknown state");
00178     }
00179 
00180     if (sinr > captureThreshold)
00181     {
00182         // capture has taken place
00183         if(curState == Synchronized)
00184         {
00185             // signal end of frame to each observer
00186             MESSAGE_SINGLE(NORMAL, logger, "ProcessPreamble -> Capture current decoding, signal rx end");
00187             this->wns::Subject<IRxStartEnd>::forEachObserver(OnRxStartEnd(0, false, true));
00188         }
00189 
00190         if(crcOk)
00191         {
00192 //             if(friends.manager->hasPayload(compound->getCommandPool()))
00193 //             {
00194                 this->syncToNewPreamble(fDur, friends.manager->getTransmitterAddress(compound->getCommandPool()));
00195 //             }
00196 //             else
00197 //             {
00198 //                 if((wns::simulator::getEventScheduler()->getTime()) > lastFrameEnd)
00199 //                 {
00200 //                     // only change lastFrameEnd if the new frame is longer than the current one
00201 //                     lastFrameEnd = wns::simulator::getEventScheduler()->getTime();
00202 //                     MESSAGE_SINGLE(NORMAL, logger, "Rx preamble without payload, sync ended " << lastFrameEnd);
00203 //                 }
00204 //                 else
00205 //                 {
00206 //                     MESSAGE_SINGLE(NORMAL, logger, "Rx preamble without payload, sync ended " << wns::simulator::getEventScheduler()->getTime() << ", afterwards garbled until " << lastFrameEnd);
00207 //                 }
00208 //             }
00209 
00210             // deliver preamble
00211             getDeliverer()->getAcceptor(compound)->onData(compound);
00212         }
00213         else
00214         {
00215             this->failedSyncToNewPreamble(fDur);
00216         }
00217     }
00218     else
00219     {
00220         if ((curState == Synchronized) or (curState == waitForFinalDelivery))
00221         {
00222             // special handling if the state is synchronized:
00223             // Wait for the end of the current frame, and then change into the garbled state if neccessary
00224             if(wns::simulator::getEventScheduler()->getTime() + fDur > lastFrameEnd)
00225             {
00226                 lastFrameEnd = wns::simulator::getEventScheduler()->getTime() + fDur;
00227                 MESSAGE_SINGLE(NORMAL, logger, "Rx preamble while synchronized, but no capture, decode frame and then garbled until " << lastFrameEnd);
00228             }
00229             else
00230             {
00231                 MESSAGE_SINGLE(NORMAL, logger, "Rx preamble while synchronized, no capture, frame is shorter than current one");
00232             }
00233         }
00234         else
00235         {
00236             this->failedSyncToNewPreamble(fDur);
00237         }
00238     }
00239 }
00240 
00241 void FrameSynchronization::failedSyncToNewPreamble(wns::simulator::Time fDur)
00242 {
00243     if((wns::simulator::getEventScheduler()->getTime() + fDur) >= lastFrameEnd)
00244     {
00245         lastFrameEnd = wns::simulator::getEventScheduler()->getTime() + fDur;
00246         this->setNewTimeout(fDur);
00247         MESSAGE_SINGLE(NORMAL, logger, "Rx preamble, but no sync possible -> garbled until " << lastFrameEnd);
00248     }
00249     else
00250     {
00251         assure(this->hasTimeoutSet(), "lastFrameEnd is not over, but no timeout set");
00252         MESSAGE_SINGLE(NORMAL, logger, "Rx another preamble, but no sync possible -> garbled for " << fDur << " and afterwards until " << lastFrameEnd);
00253     }
00254     this->synchronizedToAddress = wns::service::dll::UnicastAddress();
00255     curState = Garbled;
00256 }
00257 
00258 void FrameSynchronization::syncToNewPreamble(const wns::simulator::Time fDur, const wns::service::dll::UnicastAddress transmitter)
00259 {
00260     //MESSAGE_SINGLE(NORMAL, logger, "Rx preamble, signal rxStart");
00261     //assure(fDur > 0, "Preamble must have duration larger than zero");
00262     if (fDur > 0)
00263     {
00264         this->wns::Subject<IRxStartEnd>::forEachObserver(OnRxStartEnd(fDur, true, false));
00265 
00266         this->setNewTimeout(fDur);
00267         if((wns::simulator::getEventScheduler()->getTime() + fDur) > lastFrameEnd)
00268         {
00269             // only change lastFrameEnd if the new frame is longer than the current one
00270             lastFrameEnd = wns::simulator::getEventScheduler()->getTime() + fDur;
00271             MESSAGE_SINGLE(NORMAL, logger, "Rx preamble, synced until " << lastFrameEnd);
00272         }
00273         else
00274         {
00275             MESSAGE_SINGLE(NORMAL, logger, "Rx preamble, synced for " << fDur << ", afterwards garbled until " << lastFrameEnd);
00276         }
00277         this->synchronizedToAddress = transmitter;
00278         curState = Synchronized;
00279     }
00280     else MESSAGE_SINGLE(NORMAL, logger, "Rx preamble without payload, rx already ended");
00281 }
00282 
00283 void FrameSynchronization::onTimeout()
00284 {
00285     if(curState == Synchronized)
00286     {
00287         // finished reception
00288         MESSAGE_SINGLE(NORMAL, logger, "End of decoding, signal rxEnd");
00289         this->wns::Subject<IRxStartEnd>::forEachObserver(OnRxStartEnd(0, false, false));
00290         curState = waitForFinalDelivery;
00291         setTimeout(10e-9);
00292         return;
00293     }
00294 
00295     // Frame reception as indicated by the preamble is over, stop synchronization
00296     if(lastFrameEnd > wns::simulator::getEventScheduler()->getTime())
00297     {
00298         // there are still active transmissions, but the preamble was missed
00299         curState = Garbled;
00300         this->setTimeout(lastFrameEnd-wns::simulator::getEventScheduler()->getTime());
00301         MESSAGE_SINGLE(NORMAL, logger, "End of frame, change state to garbled until " << lastFrameEnd);
00302     }
00303     else
00304     {
00305         MESSAGE_SINGLE(NORMAL, logger, "End of frame, change state to idle");
00306         curState = Idle;
00307     }
00308     this->synchronizedToAddress = wns::service::dll::UnicastAddress();
00309 }
00310 
00311 void FrameSynchronization::processPSDU(const wns::ldk::CompoundPtr& compound)
00312 {
00313     assure(!friends.manager->isPreamble(compound->getCommandPool()),
00314            "called processPSDU for non-psdu");
00315 
00316     MESSAGE_BEGIN(NORMAL, logger, m, "");
00317     m << "Received psdu. Synchronized: " << (curState == Synchronized or curState == waitForFinalDelivery);
00318     m << "; Transmitter ok: " << (friends.manager->getTransmitterAddress(compound->getCommandPool()) == this->synchronizedToAddress);
00319     m << "; CRC ok: " << (getFUN()->getCommandReader(crcCommandName)->
00320                           readCommand<wimemac::convergence::ErrorModellingCommand>(compound->getCommandPool())->
00321                           local.checkOK);
00322     MESSAGE_END();
00323 
00324     wns::Ratio sinr = getFUN()->getCommandReader(crcCommandName)->readCommand<wimemac::convergence::ErrorModellingCommand>(compound->getCommandPool())->local.sinr;
00325 
00326     if((curState == Synchronized or curState == waitForFinalDelivery) and
00327        (friends.manager->getTransmitterAddress(compound->getCommandPool()) == this->synchronizedToAddress))
00328     {
00329         if(getFUN()->getCommandReader(crcCommandName)->readCommand<wimemac::convergence::ErrorModellingCommand>(compound->getCommandPool())->local.checkOK)
00330         {
00331             MESSAGE_SINGLE(NORMAL, logger, "Received matching psdu for current synchronization");
00332             getDeliverer()->getAcceptor(compound)->onData(compound);
00333         }
00334         else
00335         {
00336             MESSAGE_SINGLE(NORMAL, logger, "Received (synchronized) psdu, but CRC error -> DROP");
00337             // Signal rxError event
00338             this->wns::Subject<IRxStartEnd>::forEachObserver(OnRxStartEnd(0, false, true));
00339         }
00340     }
00341     else
00342     {
00343         MESSAGE_SINGLE(NORMAL, logger, "Received psdu, but not synchronized -> DROP");
00344         // signal rxError only in case the user specifically asked for this kind
00345         // of strange behavior (i.e. not synchronized --> CRC cannot be checked
00346         // at all!
00347         if(this->signalRxErrorAlthoughNotSynchronized)
00348         {
00349             this->wns::Subject<IRxStartEnd>::forEachObserver(OnRxStartEnd(0, false, true));
00350         }
00351     }
00352 
00353     // delivery occured
00354     if((curState == waitForFinalDelivery) and (friends.manager->getTransmitterAddress(compound->getCommandPool()) == this->synchronizedToAddress))
00355     {
00356         assure(hasTimeoutSet(), "State is waitForFinalDelivery, but no timeout set");
00357         cancelTimeout();
00358         onTimeout();
00359     }
00360 }
00361 
00362 void FrameSynchronization::onFUNCreated()
00363 {
00364     friends.manager = getFUN()->findFriend<wimemac::lowerMAC::IManagerServices*>(managerName);
00365 }
00366 
00367 bool FrameSynchronization::doIsAccepting(const wns::ldk::CompoundPtr& compound) const
00368 {
00369     return getConnector()->hasAcceptor(compound);
00370 }
00371 
00372 void FrameSynchronization::doWakeup()
00373 {
00374     getReceptor()->wakeup();
00375 }

Generated on Sun May 27 03:32:06 2012 for openWNS by  doxygen 1.5.5