![]() |
User Manual, Developers Guide and API Documentation |
![]() |
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
1.5.5