User Manual, Developers Guide and API Documentation

Lower2Copper.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  * Glue                                                                       *
00003  * __________________________________________________________________________ *
00004  *                                                                            *
00005  * Copyright (C) 2005-2006                                                    *
00006  * Lehrstuhl fuer Kommunikationsnetze (ComNets)                               *
00007  * Kopernikusstr. 16, D-52074 Aachen, Germany                                 *
00008  * phone: ++49-241-80-27910 (phone), fax: ++49-241-80-22242                   *
00009  * email: wns@comnets.rwth-aachen.de                                          *
00010  * www: http://wns.comnets.rwth-aachen.de                                     *
00011  ******************************************************************************/
00012 
00013 #include <GLUE/convergence/Lower2Copper.hpp>
00014 #include <GLUE/convergence/Upper.hpp>
00015 #include <GLUE/Component.hpp>
00016 
00017 #include <WNS/ldk/fun/FUN.hpp>
00018 
00019 #include <WNS/pyconfig/View.hpp>
00020 #include <WNS/module/Base.hpp>
00021 
00022 #include <WNS/probe/bus/json/probebus.hpp>
00023 #include <WNS/probe/bus/utils.hpp>
00024 
00025 #include <cstdlib>
00026 
00027 
00028 using namespace glue::convergence;
00029 
00030 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00031     Lower2Copper,
00032     wns::ldk::FunctionalUnit,
00033     "glue.convergence.Lower2Copper",
00034     wns::ldk::FUNConfigCreator);
00035 
00036 Lower2Copper::Lower2Copper(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& _config) :
00037     wns::ldk::CommandTypeSpecifier<LowerCommand>(fun),
00038     wns::ldk::HasReceptor<>(),
00039     wns::ldk::HasConnector<>(),
00040     wns::ldk::HasDeliverer<>(),
00041     wns::Cloneable<Lower2Copper>(),
00042 
00043     config(_config),
00044     logger(_config.get<wns::pyconfig::View>("logger")),
00045     dataTransmission(NULL),
00046     notificationService(NULL),
00047     isBlocking(_config.get<bool>("blocking"))
00048 {
00049     wns::probe::bus::ContextProviderCollection localContext(
00050         &fun->getLayer()->getContextProviderCollection());
00051     jsonTracing = wns::probe::bus::collector(localContext, config, "phyTraceProbeName");
00052 } // Lower2Copper
00053 
00054 Lower2Copper::~Lower2Copper()
00055 {
00056 } // ~Lower2Copper
00057 
00058 void Lower2Copper::onFUNCreated()
00059 {
00060     friends.unicastRouting =
00061         getFUN()->findFriend<glue::convergence::UnicastUpper*>(
00062             config.get<std::string>("unicastRouting"));
00063 
00064     friends.broadcastRouting =
00065         getFUN()->findFriend<glue::convergence::BroadcastUpper*>(
00066             config.get<std::string>("broadcastRouting"));
00067 } // onFUNCreated
00068 
00069 bool Lower2Copper::doIsAccepting(const wns::ldk::CompoundPtr& /* compound */) const
00070 {
00071     if (this->isBlocking == true)
00072     {
00073         return getDataTransmissionService()->isFree();
00074     }
00075     else
00076     {
00077         return true;
00078     }
00079 } // isAccepting
00080 
00081 void Lower2Copper::onCarrierIdle()
00082 {
00083     MESSAGE_BEGIN(NORMAL, logger, m, getFUN()->getName());
00084     m << ": carrier idle, accepting new transmissions";
00085     MESSAGE_END();
00086 
00087     getReceptor()->wakeup();
00088 }
00089 
00090 void Lower2Copper::onCarrierBusy()
00091 {
00092     // currently, we do nothing.
00093 }
00094 
00095 void Lower2Copper::onCollision()
00096 {
00097     // currently, we do nothing. In future we might stop ongoing transmissions
00098 } // onCollision
00099 
00100 void
00101 Lower2Copper::doSendData(const wns::ldk::CompoundPtr& compound)
00102 {
00103     assure(compound, "sendData called with an invalid compound.");
00104 
00105     if (hasCommandOf(friends.unicastRouting, compound)) {
00106         UnicastUpperCommand* command = friends.unicastRouting->getCommand(compound->getCommandPool());
00107         wns::simulator::Time now = wns::simulator::getEventScheduler()->getTime();
00108         LowerCommand* lc = activateCommand(compound->getCommandPool());
00109         lc->magic.txStartTime = now;
00110 
00111         /* Only the "real" Glue Layer support getStationType, the stubs in the tests do not*/
00112         wns::ldk::ILayer* layer = getFUN()->getLayer();
00113         Component* glueLayer = dynamic_cast<Component*>(layer);
00114         if(glueLayer != NULL)
00115             lc->magic.senderType = glueLayer->getStationType();
00116 
00117         getDataTransmissionService()->sendData(command->peer.targetMACAddress, compound);
00118     }
00119     else if (hasCommandOf(friends.broadcastRouting, compound)) {
00120         BroadcastUpperCommand* command = friends.broadcastRouting->getCommand(compound->getCommandPool());
00121         wns::simulator::Time now = wns::simulator::getEventScheduler()->getTime();
00122         LowerCommand* lc = activateCommand(compound->getCommandPool());
00123         lc->magic.txStartTime = now;
00124 
00125         /* Only the "real" Glue Layer support getStationType, the stubs in the tests do not*/
00126         wns::ldk::ILayer* layer = getFUN()->getLayer();
00127         Component* glueLayer = dynamic_cast<Component*>(layer);
00128         if(glueLayer != NULL)
00129             lc->magic.senderType = glueLayer->getStationType();
00130 
00131         getDataTransmissionService()->sendData(command->peer.targetMACAddress, compound);
00132     }
00133     else assure(false, "Not a routing Compound!");
00134 } // doSendData
00135 
00136 void Lower2Copper::doOnData(const wns::ldk::CompoundPtr& compound)
00137 {
00138     assure(compound, "onData called with an invalid compound.");
00139 
00140     MESSAGE_BEGIN(NORMAL, logger, m, getFUN()->getName());
00141     m << ": doOnData(), forwading to higher FU";
00142     MESSAGE_END();
00143 
00144     getDeliverer()->getAcceptor(compound)->onData(compound);
00145 } // doOnData
00146 
00147 void
00148 Lower2Copper::doWakeup()
00149 {
00150     // This will never be called ...
00151 } // doWakeup
00152 
00153 void
00154 Lower2Copper::onData(const wns::osi::PDUPtr& pdu, double ber, bool collision)
00155 {
00156     assure(wns::dynamicCast<wns::ldk::Compound>(pdu), "not a CompoundPtr");
00157 
00158     // FIRST: create a copy instead of working on the real compound
00159     wns::ldk::CompoundPtr compound = wns::staticCast<wns::ldk::Compound>(pdu)->copy();
00160 
00161 #ifndef NDEBUG
00162     if(jsonTracing->hasObservers())
00163         traceIncoming(compound, collision);
00164 #endif
00165 
00166     // In case of a collision -> throw away ... packet can't be decoded
00167     if (collision)
00168     {
00169         return;
00170     }
00171 
00172     if (hasCommandOf(friends.unicastRouting, compound)) {
00173         UnicastUpperCommand* uc = friends.unicastRouting->getCommand(compound->getCommandPool());
00174         if (uc->peer.targetMACAddress == address) {
00175             pushUp(compound, ber, pdu);
00176         }
00177     }
00178     else if (hasCommandOf(friends.broadcastRouting, compound)) {
00179         pushUp(compound, ber, pdu);
00180     }
00181     // else throw away
00182     // Data was not for us
00183     // should not happen with current copper implementation
00184 } // onData
00185 
00186 void
00187 Lower2Copper::setDataTransmissionService(wns::service::Service* phy)
00188 {
00189     assure(phy, "must be non-NULL");
00190     assureType(phy, wns::service::phy::copper::DataTransmission*);
00191     dataTransmission = dynamic_cast<wns::service::phy::copper::DataTransmission*>(phy);
00192 } // setDataTransmissionService
00193 
00194 wns::service::phy::copper::DataTransmission*
00195 Lower2Copper::getDataTransmissionService() const
00196 {
00197     assure(dataTransmission, "no copper::DataTransmission set. Did you call setDataTransmission()?");
00198     return dataTransmission;
00199 } // getDataTransmissionService
00200 
00201 void
00202 Lower2Copper::setNotificationService(wns::service::Service* phy)
00203 {
00204     assure(phy, "must be non-NULL");
00205     assureType(phy, wns::service::phy::copper::Notification*);
00206     notificationService = dynamic_cast<wns::service::phy::copper::Notification*>(phy);
00207     // attach for both, data handling an carrier sensing
00208     this->wns::Observer<wns::service::phy::copper::Handler>::startObserving(notificationService);
00209     this->wns::Observer<wns::service::phy::copper::CarrierSensing>::startObserving(notificationService);
00210     notificationService->setDLLUnicastAddress(address);
00211 } // setNotificationService
00212 
00213 wns::service::phy::copper::Notification*
00214 Lower2Copper::getNotificationService() const
00215 {
00216     assure(notificationService, "no copper::Notification set. Did you call setNotificationService()?");
00217     return notificationService;
00218 } // getNotificationService
00219 
00220 void
00221 Lower2Copper::setMACAddress(const wns::service::dll::UnicastAddress& _address)
00222 {
00223     address = _address;
00224     MESSAGE_SINGLE(NORMAL, logger, "setting MAC address of lowerConvergence to: " << address);
00225 } // setMACAddress
00226 
00227 void
00228 Lower2Copper::pushUp(const wns::ldk::CompoundPtr& compound, double ber, const wns::osi::PDUPtr& pdu)
00229 {
00230     LowerCommand* lc = getCommand(compound->getCommandPool());
00231     lc->local.per = 1.0 - pow(1.0 - ber, pdu->getLengthInBits());
00232     notifyBERConsumers(ber, pdu->getLengthInBits());
00233     this->wns::ldk::FunctionalUnit::onData(compound);
00234 } // pushUp
00235 
00236 void
00237 Lower2Copper::traceIncoming(wns::ldk::CompoundPtr compound, bool collision)
00238 {
00239     wns::probe::bus::json::Object objdoc;
00240 
00241     /* Only the "real" Glue Layer support getStationType, the stubs in the tests do not*/
00242     wns::ldk::ILayer* layer = getFUN()->getLayer();
00243     Component* myLayer = dynamic_cast<Component*>(layer);
00244     if(myLayer == NULL)
00245         return;
00246 
00247     LowerCommand* lc;
00248     lc = getCommand(compound->getCommandPool());
00249 
00250     UnicastUpperCommand* uc = 
00251         friends.unicastRouting->getCommand(compound->getCommandPool());
00252 
00253     wns::service::dll::UnicastAddress dstAdr;
00254 
00255     bool isBroadcast;
00256 
00257     if (hasCommandOf(friends.unicastRouting, compound)) 
00258     {
00259         dstAdr = uc->peer.targetMACAddress;
00260         isBroadcast = false;
00261     }
00262     else
00263     {
00264         isBroadcast = true;
00265     }
00266 
00267     std::string src;
00268     std::string dst("Broadcast");
00269     std::string me;
00270     std::string sender;
00271 
00272     std::stringstream s;
00273     std::stringstream m;
00274     std::stringstream d;
00275     std::stringstream snd;
00276 
00277     if(myLayer->getStationType() == StationTypes::router())
00278     {
00279         m << "BS";
00280     }
00281     else
00282     {
00283         m << "UT";
00284     }
00285 
00286     if(lc->magic.senderType == StationTypes::router())
00287     {
00288         s << "BS";
00289         snd << "BS";
00290         /* For now we assume the destination has the other station type */
00291         d << "UT";
00292     }
00293     else
00294     {
00295         s << "UT";
00296         snd << "UT";
00297         /* For now we assume the destination has the other station type */
00298         d << "BS";
00299     }
00300   
00301     s << uc->peer.sourceMACAddress;
00302     sender = s.str();
00303 
00304     m << address;
00305     me = m.str();
00306 
00307     /* Glue does not support L2 multihop, sender always is source */
00308     snd << uc->peer.sourceMACAddress;
00309     src = snd.str();
00310     
00311     if(!isBroadcast)
00312     {
00313         d << dstAdr;
00314         dst = d.str();
00315     }
00316 
00317     objdoc["Transmission"]["ReceiverID"] = wns::probe::bus::json::String(me);
00318     objdoc["Transmission"]["SenderID"] = wns::probe::bus::json::String(sender);
00319     objdoc["Transmission"]["SourceID"] = wns::probe::bus::json::String(src);
00320     objdoc["Transmission"]["DestinationID"] = wns::probe::bus::json::String(dst);
00321 
00322     wns::simulator::Time now = wns::simulator::getEventScheduler()->getTime();
00323 
00324     objdoc["Transmission"]["Start"] =
00325          wns::probe::bus::json::Number(lc->magic.txStartTime);
00326         
00327     objdoc["Transmission"]["Stop"] = wns::probe::bus::json::Number(now);
00328 
00329     // We abuse this to watch per station results
00330     objdoc["Transmission"]["Subchannel"] = wns::probe::bus::json::Number(
00331         uc->peer.sourceMACAddress.getInteger());
00332     
00333     objdoc["Transmission"]["TxPower"] = 
00334         wns::probe::bus::json::Number(0.0); // Unknown
00335     objdoc["Transmission"]["RxPower"] = 
00336         wns::probe::bus::json::Number(0.0);
00337     objdoc["Transmission"]["InterferencePower"] = 
00338         wns::probe::bus::json::Number(collision?200.0:-200.0);
00339 
00340     wns::probe::bus::json::probeJSON(jsonTracing, objdoc);
00341 }
00342 
00343 

Generated on Fri May 25 03:31:59 2012 for openWNS by  doxygen 1.5.5