User Manual, Developers Guide and API Documentation

CSMACA.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/mac/CSMACA.hpp>
00014 #include <WNS/container/UntypedRegistry.hpp>
00015 #include <WNS/ldk/Layer.hpp>
00016 #include <WNS/service/phy/copper/Notification.hpp>
00017 
00018 using namespace glue::mac;
00019 
00020 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00021     CSMACA,
00022     wns::ldk::FunctionalUnit,
00023     "glue.CSMACA",
00024     wns::ldk::FUNConfigCreator);
00025 
00026 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00027     StopAndWait,
00028     wns::ldk::FunctionalUnit,
00029     "glue.StopAndWait",
00030     wns::ldk::FUNConfigCreator);
00031 
00032 
00033 CSMACA::CSMACA(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config) :
00034     wns::ldk::CommandTypeSpecifier<CSMACACommand>(fun),
00035     wns::ldk::HasReceptor<>(),
00036     wns::ldk::HasConnector<>(),
00037     wns::ldk::HasDeliverer<>(),
00038     wns::Cloneable<CSMACA>(),
00039     logger(config.get("logger")),
00040     iFrame(),
00041     ackFrame(),
00042     stopAndWaitARQName(config.get<std::string>("stopAndWaitARQName")),
00043     stopAndWaitARQ(NULL),
00044     backoff(
00045         this,
00046         config.get<wns::simulator::Time>("sifsLength"),
00047         config.get<wns::simulator::Time>("slotLength"),
00048         config.get<wns::simulator::Time>("ackLength"),
00049         wns::logger::Logger(config.get("backoffLogger"))),
00050     sifsLength(config.get<wns::simulator::Time>("sifsLength"))
00051 {
00052     MESSAGE_SINGLE(NORMAL, this->logger, "created");
00053     wns::node::component::Interface* component = getFUN()->getLayer();
00054     std::string notificationName = config.get<std::string>("phyNotification");
00055     typedef wns::service::phy::copper::Notification Notification;
00056 
00062     Notification* notification = component->getService<Notification*>(notificationName);
00063     backoff.startObserving(notification);
00064 }
00065 
00066 
00067 CSMACA::~CSMACA()
00068 {
00069 }
00070 
00071 bool
00072 CSMACA::doIsAccepting(const wns::ldk::CompoundPtr& _compound) const
00073 {
00074     if(stopAndWaitARQ->getCommand(_compound->getCommandPool())->isACK())
00075     {
00076         assure(this->ackFrame == wns::ldk::CompoundPtr(), "There may not be more than one ACK");
00077         // we're always accepting for ACKs
00078         return true;
00079     }
00080     else
00081     {
00082         // There is room for exactly one compound
00083         return this->iFrame == wns::ldk::CompoundPtr();
00084     }
00085 }
00086 
00087 void
00088 CSMACA::doSendData(const wns::ldk::CompoundPtr& _compound)
00089 {
00090     wns::ldk::arq::StopAndWaitCommand* sawCommand =
00091         stopAndWaitARQ->getCommand(_compound->getCommandPool());
00092 
00093     if (sawCommand->isACK() == true)
00094     {
00095         MESSAGE_SINGLE(NORMAL, this->logger, "ACK: waiting for SIFS");
00096         this->ackFrame = _compound;
00097         wns::simulator::getEventScheduler()->scheduleDelay(
00098             wns::events::MemberFunction<CSMACA>(this, &CSMACA::sifsExpired), this->sifsLength);
00099     }
00100     else
00101     {
00102         assure(this->iFrame == wns::ldk::CompoundPtr(), "already got a compound!");
00103         this->iFrame = _compound;
00104 
00105         MESSAGE_SINGLE(NORMAL, this->logger,
00106                        "Data arrived, requesting TXOP. Transmission counter is " << sawCommand->localTransmissionCounter);
00107         backoff.transmissionRequest(sawCommand->localTransmissionCounter>1);
00108     }
00109 }
00110 
00111 void
00112 CSMACA::doWakeup()
00113 {
00114     // simply forward the wakeup call
00115     this->getReceptor()->wakeup();
00116 }
00117 
00118 void
00119 CSMACA::doOnData(const wns::ldk::CompoundPtr& _compound)
00120 {
00121     this->getDeliverer()->getAcceptor(_compound)->onData(_compound);
00122 }
00123 
00124 void
00125 CSMACA::onFUNCreated()
00126 {
00127     // this CSMACA MAC works only with StopAndWait ARQ!!
00128     this->stopAndWaitARQ =
00129         this->getFUN()->findFriend<wns::ldk::arq::StopAndWait*>(this->stopAndWaitARQName);
00130 
00131     this->stopAndWaitARQ->preferACK(true);
00132 }
00133 
00134 void
00135 CSMACA::backoffExpired()
00136 {
00137     assure(this->iFrame != wns::ldk::CompoundPtr(), "Nothing to send");
00138     assure(this->getConnector()->hasAcceptor(this->iFrame) == true, "Trying to send although not accepting");
00139     MESSAGE_SINGLE(NORMAL, this->logger, "Backoff is elapsed sending compound: " << *(this->iFrame));
00140     this->getConnector()->getAcceptor(this->iFrame)->sendData(this->iFrame);
00141     this->iFrame = wns::ldk::CompoundPtr();
00142     // wakeup: we are ready to receive another compound
00143     this->getReceptor()->wakeup();
00144 }
00145 
00146 void
00147 CSMACA::sifsExpired()
00148 {
00149     assure(this->ackFrame != wns::ldk::CompoundPtr(), "No ACK to send");
00150     assure(this->getConnector()->hasAcceptor(this->ackFrame) == true, "Trying to send although not accepting");
00151     MESSAGE_SINGLE(NORMAL, this->logger, "SIFS is elapsed sending ACK: " << *(this->ackFrame));
00152     this->getConnector()->getAcceptor(this->ackFrame)->sendData(this->ackFrame);
00153     this->ackFrame = wns::ldk::CompoundPtr();
00154     // wakeup: we are ready to receive another compound
00155     this->getReceptor()->wakeup();
00156 }
00157 
00158 void
00159 CSMACA::onCarrierIdle()
00160 {
00161     this->wakeup();
00162 }
00163 
00164 
00165 StopAndWait::StopAndWait(wns::ldk::fun::FUN* fuNet, const wns::pyconfig::View& config) :
00166     wns::ldk::arq::StopAndWait(fuNet, config),
00167 
00168     shortResendTimeout(config.get<double>("shortResendTimeout")),
00169     longResendTimeout(config.get<double>("longResendTimeout"))
00170 {
00171     wns::node::component::Interface* component = getFUN()->getLayer();
00172     std::string dataTransmissionNotificationName = config.get<std::string>("phyDataTransmissionFeedback");
00173     std::string carrierSensingNotificationName = config.get<std::string>("phyNotification");
00174     typedef wns::service::phy::copper::DataTransmissionFeedback DataTransmissionFeedback;
00175     typedef wns::service::phy::copper::Notification carrierSensingNotification;
00176 
00182     DataTransmissionFeedback* dtfb = component->getService<DataTransmissionFeedback*>(dataTransmissionNotificationName);
00183     carrierSensingNotification *csn = component->getService<carrierSensingNotification*>(carrierSensingNotificationName);
00184 
00185     this->wns::Observer<wns::service::phy::copper::DataTransmissionFeedbackInterface>::startObserving(dtfb);
00186     this->wns::Observer<wns::service::phy::copper::CarrierSensing>::startObserving(csn);
00187 
00188     waitingForAckTransmission = false;
00189 }
00190 
00191 wns::ldk::CompoundPtr
00192 StopAndWait::getData()
00193 {
00194     sendNow = false;
00195     // send a copy
00196     return activeCompound->copy();
00197 }
00198 
00199 void
00200 StopAndWait::onDataSent(wns::osi::PDUPtr pdu)
00201 {
00202     assure(wns::dynamicCast<wns::ldk::Compound>(pdu), "not a CompoundPtr");
00203     wns::ldk::CompoundPtr compound = wns::dynamicCast<wns::ldk::Compound>(pdu);
00204 
00205     wns::ldk::arq::StopAndWaitCommand* sawCommand =
00206         this->getCommand(compound->getCommandPool());
00207     if (sawCommand->isACK() == true)
00208     {
00209         // For ack we don't start the timer, of course ...
00210         return;
00211     }
00212 
00213     assure(
00214         compound->getBirthmark() == activeCompound->getBirthmark(),
00215         "Compound which has been sent is not the compound we're currently transmitting.");
00216     this->setTimeout(shortResendTimeout);
00217     MESSAGE_SINGLE(VERBOSE, this->logger, "Data is send, waiting for ACK");
00218     waitingForAckTransmission = true;
00219 }
00220 
00221 void
00222 StopAndWait::onCarrierIdle()
00223 {
00224 }
00225 
00226 void StopAndWait::onCarrierBusy()
00227 {
00228     MESSAGE_SINGLE(VERBOSE, this->logger, "onCarrierBusy, waitForAck is " << waitingForAckTransmission);
00229     if(waitingForAckTransmission)
00230     {
00231         // This could be the ack that we are waiting on, so extend the timeout
00232         assure(hasTimeoutSet(), "Resend Timeout already finished, but carrier just got busy");
00233         this->cancelTimeout();
00234         this->setTimeout(longResendTimeout);
00235         waitingForAckTransmission = false;
00236     }
00237 }
00238 
00239 void StopAndWait::onTimeout()
00240 {
00241     waitingForAckTransmission = false;
00242     wns::ldk::arq::StopAndWait::onTimeout();
00243     MESSAGE_SINGLE(NORMAL, this->logger,
00244                    "Timeout, increase transmission counter to " << getCommand(activeCompound)->localTransmissionCounter);
00245 }
00246 
00247 void StopAndWait::onCollision()
00248 {
00249 }
00250 

Generated on Tue May 22 03:31:55 2012 for openWNS by  doxygen 1.5.5