#include <Ieee80211Mac.h>
Various comments in the code refer to the Wireless LAN Medium Access Control (MAC) and Physical Layer(PHY) Specifications ANSI/IEEE Std 802.11, 1999 Edition (R2003)
For more info, see the NED file.
TODO: support fragmentation TODO: PCF mode TODO: CF period TODO: pass radio power to upper layer TODO: transmission complete notification to upper layer TODO: STA TCF timer syncronization, see Chapter 11 pp 123
Parts of the implementation have been taken over from the Mobility Framework's Mac80211 module.
Ieee80211Mac state variables | |
Various state information checked and modified according to the state machine. | |
enum | State { IDLE, DEFER, WAITDIFS, BACKOFF, WAITACK, WAITBROADCAST, WAITCTS, WAITSIFS, RECEIVE } |
enum | Mode { DCF, PCF } |
cFSM | fsm |
Mode | mode |
int | sequenceNumber |
bool | lastReceiveFailed |
bool | backoff |
bool | nav |
simtime_t | backoffPeriod |
int | retryCounter |
RadioState::State | radioState |
Ieee80211DataOrMgmtFrameList | transmissionQueue |
Ieee80211ASFTupleList | asfTuplesList |
IPassiveQueue * | queueModule |
cMessage * | pendingRadioConfigMsg |
Configuration parameters | |
These are filled in during the initialization phase and not supposed to change afterwards. | |
MACAddress | address |
double | bitrate |
double | basicBitrate |
int | maxQueueSize |
int | rtsThreshold |
int | transmissionLimit |
int | cwMinData |
int | cwMinBroadcast |
static const int | fragmentationThreshold = 2346 |
Public Member Functions | |
Construction functions | |
Ieee80211Mac () | |
virtual | ~Ieee80211Mac () |
Protected Member Functions | |
virtual Ieee80211Frame * | setBasicBitrate (Ieee80211Frame *frame) |
Attaches a PhyControlInfo to the frame which will cause it to be sent at basicBitrate not bitrate (e.g. 2Mbps instead of 11Mbps). Used with ACK, CTS, RTS. | |
Initialization functions | |
virtual int | numInitStages () const |
Initialization of the module and its variables. | |
virtual void | initialize (int) |
Initialization of the module and some variables. | |
virtual void | registerInterface () |
virtual void | initializeQueueModule () |
Message handing functions | |
Functions called from other classes to notify about state changes and to handle messages. | |
virtual void | receiveChangeNotification (int category, const cPolymorphic *details) |
Called by the NotificationBoard whenever a change occurs we're interested in. | |
virtual void | handleCommand (cMessage *msg) |
Handle commands (msg kind+control info) coming from upper layers. | |
virtual void | handleSelfMsg (cMessage *msg) |
Handle timer self messages. | |
virtual void | handleUpperMsg (cPacket *msg) |
Handle messages from upper layer. | |
virtual void | handleLowerMsg (cPacket *msg) |
Handle messages from lower (physical) layer. | |
virtual void | handleWithFSM (cMessage *msg) |
Handle all kinds of messages and notifications with the state machine. | |
Timing functions | |
Calculate various timings based on transmission rate and physical layer charactersitics. | |
virtual simtime_t | getSIFS () |
virtual simtime_t | getSlotTime () |
virtual simtime_t | getDIFS () |
virtual simtime_t | getEIFS () |
virtual simtime_t | getPIFS () |
virtual simtime_t | computeBackoffPeriod (Ieee80211Frame *msg, int r) |
Timer functions | |
These functions have the side effect of starting the corresponding timers. | |
virtual void | scheduleSIFSPeriod (Ieee80211Frame *frame) |
virtual void | scheduleDIFSPeriod () |
virtual void | cancelDIFSPeriod () |
virtual void | scheduleDataTimeoutPeriod (Ieee80211DataOrMgmtFrame *frame) |
virtual void | scheduleBroadcastTimeoutPeriod (Ieee80211DataOrMgmtFrame *frame) |
virtual void | cancelTimeoutPeriod () |
virtual void | scheduleCTSTimeoutPeriod () |
virtual void | scheduleReservePeriod (Ieee80211Frame *frame) |
Schedule network allocation period according to 9.2.5.4. | |
virtual void | invalidateBackoffPeriod () |
Generates a new backoff period based on the contention window. | |
virtual bool | isInvalidBackoffPeriod () |
virtual void | generateBackoffPeriod () |
virtual void | decreaseBackoffPeriod () |
virtual void | scheduleBackoffPeriod () |
virtual void | cancelBackoffPeriod () |
Frame transmission functions | |
virtual void | sendACKFrameOnEndSIFS () |
virtual void | sendACKFrame (Ieee80211DataOrMgmtFrame *frame) |
virtual void | sendRTSFrame (Ieee80211DataOrMgmtFrame *frameToSend) |
virtual void | sendCTSFrameOnEndSIFS () |
virtual void | sendCTSFrame (Ieee80211RTSFrame *rtsFrame) |
virtual void | sendDataFrameOnEndSIFS (Ieee80211DataOrMgmtFrame *frameToSend) |
virtual void | sendDataFrame (Ieee80211DataOrMgmtFrame *frameToSend) |
virtual void | sendBroadcastFrame (Ieee80211DataOrMgmtFrame *frameToSend) |
Frame builder functions | |
virtual Ieee80211DataOrMgmtFrame * | buildDataFrame (Ieee80211DataOrMgmtFrame *frameToSend) |
virtual Ieee80211ACKFrame * | buildACKFrame (Ieee80211DataOrMgmtFrame *frameToACK) |
virtual Ieee80211RTSFrame * | buildRTSFrame (Ieee80211DataOrMgmtFrame *frameToSend) |
virtual Ieee80211CTSFrame * | buildCTSFrame (Ieee80211RTSFrame *rtsFrame) |
virtual Ieee80211DataOrMgmtFrame * | buildBroadcastFrame (Ieee80211DataOrMgmtFrame *frameToSend) |
Utility functions | |
virtual void | finishCurrentTransmission () |
virtual void | giveUpCurrentTransmission () |
virtual void | retryCurrentTransmission () |
virtual void | sendDownPendingRadioConfigMsg () |
Send down the change channel message to the physical layer if there is any. | |
virtual void | setMode (Mode mode) |
Change the current MAC operation mode. | |
virtual Ieee80211DataOrMgmtFrame * | getCurrentTransmission () |
Returns the current frame being transmitted. | |
virtual void | resetStateVariables () |
Reset backoff, backoffPeriod and retryCounter for IDLE state. | |
virtual bool | isMediumStateChange (cMessage *msg) |
Used by the state machine to identify medium state change events. This message is currently optimized away and not sent through the kernel. | |
virtual bool | isMediumFree () |
Tells if the medium is free according to the physical and virtual carrier sense algorithm. | |
virtual bool | isBroadcast (Ieee80211Frame *msg) |
Returns true if message is a broadcast message. | |
virtual bool | isForUs (Ieee80211Frame *msg) |
Returns true if message destination address is ours. | |
virtual bool | isDataOrMgmtFrame (Ieee80211Frame *frame) |
Checks if the frame is a data or management frame. | |
virtual Ieee80211Frame * | getFrameReceivedBeforeSIFS () |
Returns the last frame received before the SIFS period. | |
virtual void | popTransmissionQueue () |
Deletes frame at the front of queue. | |
virtual double | computeFrameDuration (Ieee80211Frame *msg) |
Computes the duration (in seconds) of the transmission of a frame over the physical channel. 'bits' should be the total length of the MAC frame in bits, but excluding the physical layer framing (preamble etc.). | |
virtual double | computeFrameDuration (int bits, double bitrate) |
virtual void | logState () |
Logs all state information. | |
const char * | modeName (int mode) |
Produce a readable name of the given MAC operation mode. | |
Protected Attributes | |
Timer messages | |
cMessage * | endSIFS |
cMessage * | endDIFS |
cMessage * | endBackoff |
cMessage * | endTimeout |
cMessage * | endReserve |
cMessage * | mediumStateChange |
Statistics | |
long | numRetry |
long | numSentWithoutRetry |
long | numGivenUp |
long | numCollision |
long | numSent |
long | numReceived |
long | numSentBroadcast |
long | numReceivedBroadcast |
cOutVector | stateVector |
cOutVector | radioStateVector |
Private Types | |
typedef std::list < Ieee80211DataOrMgmtFrame * > | Ieee80211DataOrMgmtFrameList |
typedef std::list < Ieee80211ASFTuple * > | Ieee80211ASFTupleList |
Classes | |
struct | Ieee80211ASFTuple |
typedef std::list<Ieee80211DataOrMgmtFrame*> Ieee80211Mac::Ieee80211DataOrMgmtFrameList [private] |
typedef std::list<Ieee80211ASFTuple*> Ieee80211Mac::Ieee80211ASFTupleList [private] |
enum Ieee80211Mac::State |
enum Ieee80211Mac::Mode |
Ieee80211Mac::Ieee80211Mac | ( | ) |
00050 { 00051 endSIFS = NULL; 00052 endDIFS = NULL; 00053 endBackoff = NULL; 00054 endTimeout = NULL; 00055 endReserve = NULL; 00056 mediumStateChange = NULL; 00057 pendingRadioConfigMsg = NULL; 00058 }
Ieee80211Mac::~Ieee80211Mac | ( | ) | [virtual] |
00061 { 00062 cancelAndDelete(endSIFS); 00063 cancelAndDelete(endDIFS); 00064 cancelAndDelete(endBackoff); 00065 cancelAndDelete(endTimeout); 00066 cancelAndDelete(endReserve); 00067 cancelAndDelete(mediumStateChange); 00068 00069 if (pendingRadioConfigMsg) 00070 delete pendingRadioConfigMsg; 00071 }
virtual int Ieee80211Mac::numInitStages | ( | ) | const [inline, protected, virtual] |
void Ieee80211Mac::initialize | ( | int | stage | ) | [protected, virtual] |
Initialization of the module and some variables.
Reimplemented from WirelessMacBase.
00077 { 00078 WirelessMacBase::initialize(stage); 00079 00080 if (stage == 0) 00081 { 00082 EV << "Initializing stage 0\n"; 00083 00084 // initialize parameters 00085 maxQueueSize = par("maxQueueSize"); 00086 bitrate = par("bitrate"); 00087 basicBitrate = 2e6; //FIXME make it parameter 00088 rtsThreshold = par("rtsThresholdBytes"); 00089 00090 // the variable is renamed due to a confusion in the standard 00091 // the name retry limit would be misleading, see the header file comment 00092 transmissionLimit = par("retryLimit"); 00093 if (transmissionLimit == -1) transmissionLimit = 7; 00094 ASSERT(transmissionLimit > 0); 00095 00096 cwMinData = par("cwMinData"); 00097 if (cwMinData == -1) cwMinData = CW_MIN; 00098 ASSERT(cwMinData >= 0); 00099 00100 cwMinBroadcast = par("cwMinBroadcast"); 00101 if (cwMinBroadcast == -1) cwMinBroadcast = 31; 00102 ASSERT(cwMinBroadcast >= 0); 00103 00104 const char *addressString = par("address"); 00105 if (!strcmp(addressString, "auto")) { 00106 // assign automatic address 00107 address = MACAddress::generateAutoAddress(); 00108 // change module parameter from "auto" to concrete address 00109 par("address").setStringValue(address.str().c_str()); 00110 } 00111 else 00112 address.setAddress(addressString); 00113 00114 // subscribe for the information of the carrier sense 00115 nb->subscribe(this, NF_RADIOSTATE_CHANGED); 00116 00117 // initalize self messages 00118 endSIFS = new cMessage("SIFS"); 00119 endDIFS = new cMessage("DIFS"); 00120 endBackoff = new cMessage("Backoff"); 00121 endTimeout = new cMessage("Timeout"); 00122 endReserve = new cMessage("Reserve"); 00123 mediumStateChange = new cMessage("MediumStateChange"); 00124 00125 // interface 00126 registerInterface(); 00127 00128 // obtain pointer to external queue 00129 initializeQueueModule(); 00130 00131 // state variables 00132 fsm.setName("Ieee80211Mac State Machine"); 00133 mode = DCF; 00134 sequenceNumber = 0; 00135 radioState = RadioState::IDLE; 00136 retryCounter = 0; 00137 backoffPeriod = -1; 00138 backoff = false; 00139 lastReceiveFailed = false; 00140 nav = false; 00141 00142 // statistics 00143 numRetry = 0; 00144 numSentWithoutRetry = 0; 00145 numGivenUp = 0; 00146 numCollision = 0; 00147 numSent = 0; 00148 numReceived = 0; 00149 numSentBroadcast = 0; 00150 numReceivedBroadcast = 0; 00151 stateVector.setName("State"); 00152 stateVector.setEnum("Ieee80211Mac"); 00153 radioStateVector.setName("RadioState"); 00154 radioStateVector.setEnum("RadioState"); 00155 00156 // initialize watches 00157 WATCH(fsm); 00158 WATCH(radioState); 00159 WATCH(retryCounter); 00160 WATCH(backoff); 00161 WATCH(nav); 00162 00163 WATCH(numRetry); 00164 WATCH(numSentWithoutRetry); 00165 WATCH(numGivenUp); 00166 WATCH(numCollision); 00167 WATCH(numSent); 00168 WATCH(numReceived); 00169 WATCH(numSentBroadcast); 00170 WATCH(numReceivedBroadcast); 00171 } 00172 }
void Ieee80211Mac::registerInterface | ( | ) | [protected, virtual] |
Referenced by initialize().
00175 { 00176 IInterfaceTable *ift = InterfaceTableAccess().getIfExists(); 00177 if (!ift) 00178 return; 00179 00180 InterfaceEntry *e = new InterfaceEntry(); 00181 00182 // interface name: NetworkInterface module's name without special characters ([]) 00183 char *interfaceName = new char[strlen(getParentModule()->getFullName()) + 1]; 00184 char *d = interfaceName; 00185 for (const char *s = getParentModule()->getFullName(); *s; s++) 00186 if (isalnum(*s)) 00187 *d++ = *s; 00188 *d = '\0'; 00189 00190 e->setName(interfaceName); 00191 delete [] interfaceName; 00192 00193 // address 00194 e->setMACAddress(address); 00195 e->setInterfaceToken(address.formInterfaceIdentifier()); 00196 00197 // FIXME: MTU on 802.11 = ? 00198 e->setMtu(par("mtu")); 00199 00200 // capabilities 00201 e->setBroadcast(true); 00202 e->setMulticast(true); 00203 e->setPointToPoint(false); 00204 00205 // add 00206 ift->addInterface(e, this); 00207 }
void Ieee80211Mac::initializeQueueModule | ( | ) | [protected, virtual] |
Referenced by initialize().
00210 { 00211 // use of external queue module is optional -- find it if there's one specified 00212 if (par("queueModule").stringValue()[0]) 00213 { 00214 cModule *module = getParentModule()->getSubmodule(par("queueModule").stringValue()); 00215 queueModule = check_and_cast<IPassiveQueue *>(module); 00216 00217 EV << "Requesting first two frames from queue module\n"; 00218 queueModule->requestPacket(); 00219 // needed for backoff: mandatory if next message is already present 00220 queueModule->requestPacket(); 00221 } 00222 }
void Ieee80211Mac::receiveChangeNotification | ( | int | category, | |
const cPolymorphic * | details | |||
) | [protected, virtual] |
Called by the NotificationBoard whenever a change occurs we're interested in.
Implements INotifiable.
00325 { 00326 Enter_Method_Silent(); 00327 printNotificationBanner(category, details); 00328 00329 if (category == NF_RADIOSTATE_CHANGED) 00330 { 00331 RadioState::State newRadioState = check_and_cast<RadioState *>(details)->getState(); 00332 00333 // FIXME: double recording, because there's no sample hold in the gui 00334 radioStateVector.record(radioState); 00335 radioStateVector.record(newRadioState); 00336 00337 radioState = newRadioState; 00338 00339 handleWithFSM(mediumStateChange); 00340 } 00341 }
void Ieee80211Mac::handleCommand | ( | cMessage * | msg | ) | [protected, virtual] |
Handle commands (msg kind+control info) coming from upper layers.
Implements WirelessMacBase.
00267 { 00268 if (msg->getKind()==PHY_C_CONFIGURERADIO) 00269 { 00270 EV << "Passing on command " << msg->getName() << " to physical layer\n"; 00271 if (pendingRadioConfigMsg != NULL) 00272 { 00273 // merge contents of the old command into the new one, then delete it 00274 PhyControlInfo *pOld = check_and_cast<PhyControlInfo *>(pendingRadioConfigMsg->getControlInfo()); 00275 PhyControlInfo *pNew = check_and_cast<PhyControlInfo *>(msg->getControlInfo()); 00276 if (pNew->getChannelNumber()==-1 && pOld->getChannelNumber()!=-1) 00277 pNew->setChannelNumber(pOld->getChannelNumber()); 00278 if (pNew->getBitrate()==-1 && pOld->getBitrate()!=-1) 00279 pNew->setBitrate(pOld->getBitrate()); 00280 delete pendingRadioConfigMsg; 00281 pendingRadioConfigMsg = NULL; 00282 } 00283 00284 if (fsm.getState() == IDLE || fsm.getState() == DEFER || fsm.getState() == BACKOFF) 00285 { 00286 EV << "Sending it down immediately\n"; 00287 sendDown(msg); 00288 } 00289 else 00290 { 00291 EV << "Delaying " << msg->getName() << " until next IDLE or DEFER state\n"; 00292 pendingRadioConfigMsg = msg; 00293 } 00294 } 00295 else 00296 { 00297 error("Unrecognized command from mgmt layer: (%s)%s msgkind=%d", msg->getClassName(), msg->getName(), msg->getKind()); 00298 } 00299 }
void Ieee80211Mac::handleSelfMsg | ( | cMessage * | msg | ) | [protected, virtual] |
Handle timer self messages.
Implements WirelessMacBase.
00228 { 00229 EV << "received self message: " << msg << endl; 00230 00231 if (msg == endReserve) 00232 nav = false; 00233 00234 handleWithFSM(msg); 00235 }
void Ieee80211Mac::handleUpperMsg | ( | cPacket * | msg | ) | [protected, virtual] |
Handle messages from upper layer.
Implements WirelessMacBase.
00238 { 00239 // check for queue overflow 00240 if (maxQueueSize && (int)transmissionQueue.size() == maxQueueSize) 00241 { 00242 EV << "message " << msg << " received from higher layer but MAC queue is full, dropping message\n"; 00243 delete msg; 00244 return; 00245 } 00246 00247 // must be a Ieee80211DataOrMgmtFrame, within the max size because we don't support fragmentation 00248 Ieee80211DataOrMgmtFrame *frame = check_and_cast<Ieee80211DataOrMgmtFrame *>(msg); 00249 if (frame->getByteLength() > fragmentationThreshold) 00250 error("message from higher layer (%s)%s is too long for 802.11b, %d bytes (fragmentation is not supported yet)", 00251 msg->getClassName(), msg->getName(), msg->getByteLength()); 00252 EV << "frame " << frame << " received from higher layer, receiver = " << frame->getReceiverAddress() << endl; 00253 00254 ASSERT(!frame->getReceiverAddress().isUnspecified()); 00255 00256 // fill in missing fields (receiver address, seq number), and insert into the queue 00257 frame->setTransmitterAddress(address); 00258 frame->setSequenceNumber(sequenceNumber); 00259 sequenceNumber = (sequenceNumber+1) % 4096; //XXX seqNum must be checked upon reception of frames! 00260 00261 transmissionQueue.push_back(frame); 00262 00263 handleWithFSM(frame); 00264 }
void Ieee80211Mac::handleLowerMsg | ( | cPacket * | msg | ) | [protected, virtual] |
Handle messages from lower (physical) layer.
Implements WirelessMacBase.
00302 { 00303 EV << "received message from lower layer: " << msg << endl; 00304 00305 Ieee80211Frame *frame = dynamic_cast<Ieee80211Frame *>(msg); 00306 if (!frame) 00307 error("message from physical layer (%s)%s is not a subclass of Ieee80211Frame", 00308 msg->getClassName(), msg->getName()); 00309 00310 EV << "Self address: " << address 00311 << ", receiver address: " << frame->getReceiverAddress() 00312 << ", received frame is for us: " << isForUs(frame) << endl; 00313 00314 Ieee80211TwoAddressFrame *twoAddressFrame = dynamic_cast<Ieee80211TwoAddressFrame *>(msg); 00315 ASSERT(!twoAddressFrame || twoAddressFrame->getTransmitterAddress() != address); 00316 00317 handleWithFSM(msg); 00318 00319 // if we are the owner then we did not send this message up 00320 if (msg->getOwner() == this) 00321 delete msg; 00322 }
void Ieee80211Mac::handleWithFSM | ( | cMessage * | msg | ) | [protected, virtual] |
Handle all kinds of messages and notifications with the state machine.
Msg can be upper, lower, self or NULL (when radio state changes)
Referenced by handleLowerMsg(), handleSelfMsg(), handleUpperMsg(), and receiveChangeNotification().
00347 { 00348 // skip those cases where there's nothing to do, so the switch looks simpler 00349 if (isUpperMsg(msg) && fsm.getState() != IDLE) 00350 { 00351 EV << "deferring upper message transmission in " << fsm.getStateName() << " state\n"; 00352 return; 00353 } 00354 00355 Ieee80211Frame *frame = dynamic_cast<Ieee80211Frame*>(msg); 00356 int frameType = frame ? frame->getType() : -1; 00357 int msgKind = msg->getKind(); 00358 logState(); 00359 stateVector.record(fsm.getState()); 00360 00361 if (frame && isLowerMsg(frame)) 00362 { 00363 lastReceiveFailed =(msgKind == COLLISION || msgKind == BITERROR); 00364 scheduleReservePeriod(frame); 00365 } 00366 00367 // TODO: fix bug according to the message: [omnetpp] A possible bug in the Ieee80211's FSM. 00368 FSMA_Switch(fsm) 00369 { 00370 FSMA_State(IDLE) 00371 { 00372 FSMA_Enter(sendDownPendingRadioConfigMsg()); 00373 FSMA_Event_Transition(Data-Ready, 00374 isUpperMsg(msg), 00375 DEFER, 00376 ASSERT(isInvalidBackoffPeriod() || backoffPeriod == 0); 00377 invalidateBackoffPeriod(); 00378 ); 00379 FSMA_No_Event_Transition(Immediate-Data-Ready, 00380 !transmissionQueue.empty(), 00381 DEFER, 00382 invalidateBackoffPeriod(); 00383 ); 00384 FSMA_Event_Transition(Receive, 00385 isLowerMsg(msg), 00386 RECEIVE, 00387 ); 00388 } 00389 FSMA_State(DEFER) 00390 { 00391 FSMA_Enter(sendDownPendingRadioConfigMsg()); 00392 FSMA_Event_Transition(Wait-DIFS, 00393 isMediumStateChange(msg) && isMediumFree(), 00394 WAITDIFS, 00395 ;); 00396 FSMA_No_Event_Transition(Immediate-Wait-DIFS, 00397 isMediumFree() || !backoff, 00398 WAITDIFS, 00399 ;); 00400 FSMA_Event_Transition(Receive, 00401 isLowerMsg(msg), 00402 RECEIVE, 00403 ;); 00404 } 00405 FSMA_State(WAITDIFS) 00406 { 00407 FSMA_Enter(scheduleDIFSPeriod()); 00408 FSMA_Event_Transition(Immediate-Transmit-RTS, 00409 msg == endDIFS && !isBroadcast(getCurrentTransmission()) 00410 && getCurrentTransmission()->getByteLength() >= rtsThreshold && !backoff, 00411 WAITCTS, 00412 sendRTSFrame(getCurrentTransmission()); 00413 cancelDIFSPeriod(); 00414 ); 00415 FSMA_Event_Transition(Immediate-Transmit-Broadcast, 00416 msg == endDIFS && isBroadcast(getCurrentTransmission()) && !backoff, 00417 WAITBROADCAST, 00418 sendBroadcastFrame(getCurrentTransmission()); 00419 cancelDIFSPeriod(); 00420 ); 00421 FSMA_Event_Transition(Immediate-Transmit-Data, 00422 msg == endDIFS && !isBroadcast(getCurrentTransmission()) && !backoff, 00423 WAITACK, 00424 sendDataFrame(getCurrentTransmission()); 00425 cancelDIFSPeriod(); 00426 ); 00427 FSMA_Event_Transition(DIFS-Over, 00428 msg == endDIFS, 00429 BACKOFF, 00430 ASSERT(backoff); 00431 if (isInvalidBackoffPeriod()) 00432 generateBackoffPeriod(); 00433 ); 00434 FSMA_Event_Transition(Busy, 00435 isMediumStateChange(msg) && !isMediumFree(), 00436 DEFER, 00437 backoff = true; 00438 cancelDIFSPeriod(); 00439 ); 00440 FSMA_No_Event_Transition(Immediate-Busy, 00441 !isMediumFree(), 00442 DEFER, 00443 backoff = true; 00444 cancelDIFSPeriod(); 00445 ); 00446 // radio state changes before we actually get the message, so this must be here 00447 FSMA_Event_Transition(Receive, 00448 isLowerMsg(msg), 00449 RECEIVE, 00450 cancelDIFSPeriod(); 00451 ;); 00452 } 00453 FSMA_State(BACKOFF) 00454 { 00455 FSMA_Enter(scheduleBackoffPeriod()); 00456 FSMA_Event_Transition(Transmit-RTS, 00457 msg == endBackoff && !isBroadcast(getCurrentTransmission()) 00458 && getCurrentTransmission()->getByteLength() >= rtsThreshold, 00459 WAITCTS, 00460 sendRTSFrame(getCurrentTransmission()); 00461 ); 00462 FSMA_Event_Transition(Transmit-Broadcast, 00463 msg == endBackoff && isBroadcast(getCurrentTransmission()), 00464 WAITBROADCAST, 00465 sendBroadcastFrame(getCurrentTransmission()); 00466 ); 00467 FSMA_Event_Transition(Transmit-Data, 00468 msg == endBackoff && !isBroadcast(getCurrentTransmission()), 00469 WAITACK, 00470 sendDataFrame(getCurrentTransmission()); 00471 ); 00472 FSMA_Event_Transition(Backoff-Busy, 00473 isMediumStateChange(msg) && !isMediumFree(), 00474 DEFER, 00475 cancelBackoffPeriod(); 00476 decreaseBackoffPeriod(); 00477 ); 00478 } 00479 FSMA_State(WAITACK) 00480 { 00481 FSMA_Enter(scheduleDataTimeoutPeriod(getCurrentTransmission())); 00482 FSMA_Event_Transition(Receive-ACK, 00483 isLowerMsg(msg) && isForUs(frame) && frameType == ST_ACK, 00484 IDLE, 00485 if (retryCounter == 0) numSentWithoutRetry++; 00486 numSent++; 00487 cancelTimeoutPeriod(); 00488 finishCurrentTransmission(); 00489 ); 00490 FSMA_Event_Transition(Transmit-Data-Failed, 00491 msg == endTimeout && retryCounter == transmissionLimit - 1, 00492 IDLE, 00493 giveUpCurrentTransmission(); 00494 ); 00495 FSMA_Event_Transition(Receive-ACK-Timeout, 00496 msg == endTimeout, 00497 DEFER, 00498 retryCurrentTransmission(); 00499 ); 00500 } 00501 // wait until broadcast is sent 00502 FSMA_State(WAITBROADCAST) 00503 { 00504 FSMA_Enter(scheduleBroadcastTimeoutPeriod(getCurrentTransmission())); 00505 FSMA_Event_Transition(Transmit-Broadcast, 00506 msg == endTimeout, 00507 IDLE, 00508 finishCurrentTransmission(); 00509 numSentBroadcast++; 00510 ); 00511 } 00512 // accoriding to 9.2.5.7 CTS procedure 00513 FSMA_State(WAITCTS) 00514 { 00515 FSMA_Enter(scheduleCTSTimeoutPeriod()); 00516 FSMA_Event_Transition(Receive-CTS, 00517 isLowerMsg(msg) && isForUs(frame) && frameType == ST_CTS, 00518 WAITSIFS, 00519 cancelTimeoutPeriod(); 00520 ); 00521 FSMA_Event_Transition(Transmit-RTS-Failed, 00522 msg == endTimeout && retryCounter == transmissionLimit - 1, 00523 IDLE, 00524 giveUpCurrentTransmission(); 00525 ); 00526 FSMA_Event_Transition(Receive-CTS-Timeout, 00527 msg == endTimeout, 00528 DEFER, 00529 retryCurrentTransmission(); 00530 ); 00531 } 00532 FSMA_State(WAITSIFS) 00533 { 00534 FSMA_Enter(scheduleSIFSPeriod(frame)); 00535 FSMA_Event_Transition(Transmit-CTS, 00536 msg == endSIFS && getFrameReceivedBeforeSIFS()->getType() == ST_RTS, 00537 IDLE, 00538 sendCTSFrameOnEndSIFS(); 00539 resetStateVariables(); 00540 ); 00541 FSMA_Event_Transition(Transmit-DATA, 00542 msg == endSIFS && getFrameReceivedBeforeSIFS()->getType() == ST_CTS, 00543 WAITACK, 00544 sendDataFrameOnEndSIFS(getCurrentTransmission()); 00545 ); 00546 FSMA_Event_Transition(Transmit-ACK, 00547 msg == endSIFS && isDataOrMgmtFrame(getFrameReceivedBeforeSIFS()), 00548 IDLE, 00549 sendACKFrameOnEndSIFS(); 00550 resetStateVariables(); 00551 ); 00552 } 00553 // this is not a real state 00554 FSMA_State(RECEIVE) 00555 { 00556 FSMA_No_Event_Transition(Immediate-Receive-Error, 00557 isLowerMsg(msg) && (msgKind == COLLISION || msgKind == BITERROR), 00558 IDLE, 00559 EV << "received frame contains bit errors or collision, next wait period is EIFS\n"; 00560 numCollision++; 00561 resetStateVariables(); 00562 ); 00563 FSMA_No_Event_Transition(Immediate-Receive-Broadcast, 00564 isLowerMsg(msg) && isBroadcast(frame) && isDataOrMgmtFrame(frame), 00565 IDLE, 00566 sendUp(frame); 00567 numReceivedBroadcast++; 00568 resetStateVariables(); 00569 ); 00570 FSMA_No_Event_Transition(Immediate-Receive-Data, 00571 isLowerMsg(msg) && isForUs(frame) && isDataOrMgmtFrame(frame), 00572 WAITSIFS, 00573 sendUp(frame); 00574 numReceived++; 00575 ); 00576 FSMA_No_Event_Transition(Immediate-Receive-RTS, 00577 isLowerMsg(msg) && isForUs(frame) && frameType == ST_RTS, 00578 WAITSIFS, 00579 ); 00580 FSMA_No_Event_Transition(Immediate-Receive-Other, 00581 isLowerMsg(msg), 00582 IDLE, 00583 resetStateVariables(); 00584 ); 00585 } 00586 } 00587 00588 logState(); 00589 stateVector.record(fsm.getState()); 00590 }
simtime_t Ieee80211Mac::getSIFS | ( | ) | [protected, virtual] |
Referenced by buildACKFrame(), buildCTSFrame(), buildDataFrame(), buildRTSFrame(), getDIFS(), getEIFS(), getPIFS(), scheduleCTSTimeoutPeriod(), scheduleDataTimeoutPeriod(), and scheduleSIFSPeriod().
00596 { 00597 // TODO: return aRxRFDelay() + aRxPLCPDelay() + aMACProcessingDelay() + aRxTxTurnaroundTime(); 00598 return SIFS; 00599 }
simtime_t Ieee80211Mac::getSlotTime | ( | ) | [protected, virtual] |
Referenced by computeBackoffPeriod(), decreaseBackoffPeriod(), getDIFS(), and getPIFS().
00602 { 00603 // TODO: return aCCATime() + aRxTxTurnaroundTime + aAirPropagationTime() + aMACProcessingDelay(); 00604 return ST; 00605 }
simtime_t Ieee80211Mac::getDIFS | ( | ) | [protected, virtual] |
Referenced by getEIFS(), and scheduleDIFSPeriod().
00613 { 00614 return getSIFS() + 2 * getSlotTime(); 00615 }
simtime_t Ieee80211Mac::getEIFS | ( | ) | [protected, virtual] |
Referenced by scheduleDIFSPeriod().
00618 { 00619 // FIXME: return getSIFS() + getDIFS() + (8 * ACKSize + aPreambleLength + aPLCPHeaderLength) / lowestDatarate; 00620 return getSIFS() + getDIFS() + (8 * LENGTH_ACK + PHY_HEADER_LENGTH) / 1E+6; 00621 }
simtime_t Ieee80211Mac::getPIFS | ( | ) | [protected, virtual] |
simtime_t Ieee80211Mac::computeBackoffPeriod | ( | Ieee80211Frame * | msg, | |
int | r | |||
) | [protected, virtual] |
Referenced by generateBackoffPeriod().
00624 { 00625 int cw; 00626 00627 EV << "generating backoff slot number for retry: " << r << endl; 00628 00629 if (isBroadcast(msg)) 00630 cw = cwMinBroadcast; 00631 else 00632 { 00633 ASSERT(0 <= r && r < transmissionLimit); 00634 00635 cw = (cwMinData + 1) * (1 << r) - 1; 00636 00637 if (cw > CW_MAX) 00638 cw = CW_MAX; 00639 } 00640 00641 int c = intrand(cw + 1); 00642 00643 EV << "generated backoff slot number: " << c << " , cw: " << cw << endl; 00644 00645 return ((double)c) * getSlotTime(); 00646 }
void Ieee80211Mac::scheduleSIFSPeriod | ( | Ieee80211Frame * | frame | ) | [protected, virtual] |
Referenced by handleWithFSM().
00652 { 00653 EV << "scheduling SIFS period\n"; 00654 endSIFS->setContextPointer(frame->dup()); 00655 scheduleAt(simTime() + getSIFS(), endSIFS); 00656 }
void Ieee80211Mac::scheduleDIFSPeriod | ( | ) | [protected, virtual] |
Referenced by handleWithFSM().
00659 { 00660 if (lastReceiveFailed) 00661 { 00662 EV << "receiption of last frame failed, scheduling EIFS period\n"; 00663 scheduleAt(simTime() + getEIFS(), endDIFS); 00664 } 00665 else 00666 { 00667 EV << "scheduling DIFS period\n"; 00668 scheduleAt(simTime() + getDIFS(), endDIFS); 00669 } 00670 }
void Ieee80211Mac::cancelDIFSPeriod | ( | ) | [protected, virtual] |
void Ieee80211Mac::scheduleDataTimeoutPeriod | ( | Ieee80211DataOrMgmtFrame * | frame | ) | [protected, virtual] |
Referenced by handleWithFSM().
00679 { 00680 EV << "scheduling data timeout period\n"; 00681 scheduleAt(simTime() + computeFrameDuration(frameToSend) + getSIFS() + computeFrameDuration(LENGTH_ACK, basicBitrate) + MAX_PROPAGATION_DELAY * 2, endTimeout); 00682 }
void Ieee80211Mac::scheduleBroadcastTimeoutPeriod | ( | Ieee80211DataOrMgmtFrame * | frame | ) | [protected, virtual] |
Referenced by handleWithFSM().
00685 { 00686 EV << "scheduling broadcast timeout period\n"; 00687 scheduleAt(simTime() + computeFrameDuration(frameToSend), endTimeout); 00688 }
void Ieee80211Mac::cancelTimeoutPeriod | ( | ) | [protected, virtual] |
Referenced by handleWithFSM().
00691 { 00692 EV << "cancelling timeout period\n"; 00693 cancelEvent(endTimeout); 00694 }
void Ieee80211Mac::scheduleCTSTimeoutPeriod | ( | ) | [protected, virtual] |
Referenced by handleWithFSM().
00697 { 00698 scheduleAt(simTime() + computeFrameDuration(LENGTH_RTS, basicBitrate) + getSIFS() + computeFrameDuration(LENGTH_CTS, basicBitrate) + MAX_PROPAGATION_DELAY * 2, endTimeout); 00699 }
void Ieee80211Mac::scheduleReservePeriod | ( | Ieee80211Frame * | frame | ) | [protected, virtual] |
Schedule network allocation period according to 9.2.5.4.
Referenced by handleWithFSM().
00702 { 00703 simtime_t reserve = frame->getDuration(); 00704 00705 // see spec. 7.1.3.2 00706 if (!isForUs(frame) && reserve != 0 && reserve < 32768) 00707 { 00708 if (endReserve->isScheduled()) { 00709 simtime_t oldReserve = endReserve->getArrivalTime() - simTime(); 00710 00711 if (oldReserve > reserve) 00712 return; 00713 00714 reserve = std::max(reserve, oldReserve); 00715 cancelEvent(endReserve); 00716 } 00717 else if (radioState == RadioState::IDLE) 00718 { 00719 // NAV: the channel just became virtually busy according to the spec 00720 scheduleAt(simTime(), mediumStateChange); 00721 } 00722 00723 EV << "scheduling reserve period for: " << reserve << endl; 00724 00725 ASSERT(reserve > 0); 00726 00727 nav = true; 00728 scheduleAt(simTime() + reserve, endReserve); 00729 } 00730 }
void Ieee80211Mac::invalidateBackoffPeriod | ( | ) | [protected, virtual] |
Generates a new backoff period based on the contention window.
Referenced by handleWithFSM().
00733 { 00734 backoffPeriod = -1; 00735 }
bool Ieee80211Mac::isInvalidBackoffPeriod | ( | ) | [protected, virtual] |
void Ieee80211Mac::generateBackoffPeriod | ( | ) | [protected, virtual] |
Referenced by handleWithFSM(), and retryCurrentTransmission().
00743 { 00744 backoffPeriod = computeBackoffPeriod(getCurrentTransmission(), retryCounter); 00745 ASSERT(backoffPeriod >= 0); 00746 EV << "backoff period set to " << backoffPeriod << endl; 00747 }
void Ieee80211Mac::decreaseBackoffPeriod | ( | ) | [protected, virtual] |
Referenced by handleWithFSM().
00750 { 00751 // see spec 9.2.5.2 00752 simtime_t elapsedBackoffTime = simTime() - endBackoff->getSendingTime(); 00753 backoffPeriod -= ((int)(elapsedBackoffTime / getSlotTime())) * getSlotTime(); 00754 ASSERT(backoffPeriod >= 0); 00755 EV << "backoff period decreased to " << backoffPeriod << endl; 00756 }
void Ieee80211Mac::scheduleBackoffPeriod | ( | ) | [protected, virtual] |
Referenced by handleWithFSM().
00759 { 00760 EV << "scheduling backoff period\n"; 00761 scheduleAt(simTime() + backoffPeriod, endBackoff); 00762 }
void Ieee80211Mac::cancelBackoffPeriod | ( | ) | [protected, virtual] |
Referenced by handleWithFSM().
00765 { 00766 EV << "cancelling Backoff period\n"; 00767 cancelEvent(endBackoff); 00768 }
void Ieee80211Mac::sendACKFrameOnEndSIFS | ( | ) | [protected, virtual] |
Referenced by handleWithFSM().
00774 { 00775 Ieee80211Frame *frameToACK = (Ieee80211Frame *)endSIFS->getContextPointer(); 00776 endSIFS->setContextPointer(NULL); 00777 sendACKFrame(check_and_cast<Ieee80211DataOrMgmtFrame*>(frameToACK)); 00778 delete frameToACK; 00779 }
void Ieee80211Mac::sendACKFrame | ( | Ieee80211DataOrMgmtFrame * | frame | ) | [protected, virtual] |
Referenced by sendACKFrameOnEndSIFS().
00782 { 00783 EV << "sending ACK frame\n"; 00784 sendDown(setBasicBitrate(buildACKFrame(frameToACK))); 00785 }
void Ieee80211Mac::sendRTSFrame | ( | Ieee80211DataOrMgmtFrame * | frameToSend | ) | [protected, virtual] |
Referenced by handleWithFSM().
00808 { 00809 EV << "sending RTS frame\n"; 00810 sendDown(setBasicBitrate(buildRTSFrame(frameToSend))); 00811 }
void Ieee80211Mac::sendCTSFrameOnEndSIFS | ( | ) | [protected, virtual] |
Referenced by handleWithFSM().
00814 { 00815 Ieee80211Frame *rtsFrame = (Ieee80211Frame *)endSIFS->getContextPointer(); 00816 endSIFS->setContextPointer(NULL); 00817 sendCTSFrame(check_and_cast<Ieee80211RTSFrame*>(rtsFrame)); 00818 delete rtsFrame; 00819 }
void Ieee80211Mac::sendCTSFrame | ( | Ieee80211RTSFrame * | rtsFrame | ) | [protected, virtual] |
Referenced by sendCTSFrameOnEndSIFS().
00822 { 00823 EV << "sending CTS frame\n"; 00824 sendDown(setBasicBitrate(buildCTSFrame(rtsFrame))); 00825 }
void Ieee80211Mac::sendDataFrameOnEndSIFS | ( | Ieee80211DataOrMgmtFrame * | frameToSend | ) | [protected, virtual] |
Referenced by handleWithFSM().
00788 { 00789 Ieee80211Frame *ctsFrame = (Ieee80211Frame *)endSIFS->getContextPointer(); 00790 endSIFS->setContextPointer(NULL); 00791 sendDataFrame(frameToSend); 00792 delete ctsFrame; 00793 }
void Ieee80211Mac::sendDataFrame | ( | Ieee80211DataOrMgmtFrame * | frameToSend | ) | [protected, virtual] |
Referenced by handleWithFSM(), and sendDataFrameOnEndSIFS().
00796 { 00797 EV << "sending Data frame\n"; 00798 sendDown(buildDataFrame(frameToSend)); 00799 }
void Ieee80211Mac::sendBroadcastFrame | ( | Ieee80211DataOrMgmtFrame * | frameToSend | ) | [protected, virtual] |
Referenced by handleWithFSM().
00802 { 00803 EV << "sending Broadcast frame\n"; 00804 sendDown(buildBroadcastFrame(frameToSend)); 00805 }
Ieee80211DataOrMgmtFrame * Ieee80211Mac::buildDataFrame | ( | Ieee80211DataOrMgmtFrame * | frameToSend | ) | [protected, virtual] |
Referenced by sendDataFrame().
00831 { 00832 Ieee80211DataOrMgmtFrame *frame = (Ieee80211DataOrMgmtFrame *)frameToSend->dup(); 00833 00834 if (isBroadcast(frameToSend)) 00835 frame->setDuration(0); 00836 else if (!frameToSend->getMoreFragments()) 00837 frame->setDuration(getSIFS() + computeFrameDuration(LENGTH_ACK, basicBitrate)); 00838 else 00839 // FIXME: shouldn't we use the next frame to be sent? 00840 frame->setDuration(3 * getSIFS() + 2 * computeFrameDuration(LENGTH_ACK, basicBitrate) + computeFrameDuration(frameToSend)); 00841 00842 return frame; 00843 }
Ieee80211ACKFrame * Ieee80211Mac::buildACKFrame | ( | Ieee80211DataOrMgmtFrame * | frameToACK | ) | [protected, virtual] |
Referenced by sendACKFrame().
00846 { 00847 Ieee80211ACKFrame *frame = new Ieee80211ACKFrame("wlan-ack"); 00848 frame->setReceiverAddress(frameToACK->getTransmitterAddress()); 00849 00850 if (!frameToACK->getMoreFragments()) 00851 frame->setDuration(0); 00852 else 00853 frame->setDuration(frameToACK->getDuration() - getSIFS() - computeFrameDuration(LENGTH_ACK, basicBitrate)); 00854 00855 return frame; 00856 }
Ieee80211RTSFrame * Ieee80211Mac::buildRTSFrame | ( | Ieee80211DataOrMgmtFrame * | frameToSend | ) | [protected, virtual] |
Referenced by sendRTSFrame().
00859 { 00860 Ieee80211RTSFrame *frame = new Ieee80211RTSFrame("wlan-rts"); 00861 frame->setTransmitterAddress(address); 00862 frame->setReceiverAddress(frameToSend->getReceiverAddress()); 00863 frame->setDuration(3 * getSIFS() + computeFrameDuration(LENGTH_CTS, basicBitrate) + 00864 computeFrameDuration(frameToSend) + 00865 computeFrameDuration(LENGTH_ACK, basicBitrate)); 00866 00867 return frame; 00868 }
Ieee80211CTSFrame * Ieee80211Mac::buildCTSFrame | ( | Ieee80211RTSFrame * | rtsFrame | ) | [protected, virtual] |
Referenced by sendCTSFrame().
00871 { 00872 Ieee80211CTSFrame *frame = new Ieee80211CTSFrame("wlan-cts"); 00873 frame->setReceiverAddress(rtsFrame->getTransmitterAddress()); 00874 frame->setDuration(rtsFrame->getDuration() - getSIFS() - computeFrameDuration(LENGTH_CTS, basicBitrate)); 00875 00876 return frame; 00877 }
Ieee80211DataOrMgmtFrame * Ieee80211Mac::buildBroadcastFrame | ( | Ieee80211DataOrMgmtFrame * | frameToSend | ) | [protected, virtual] |
Referenced by sendBroadcastFrame().
00880 { 00881 Ieee80211DataOrMgmtFrame *frame = (Ieee80211DataOrMgmtFrame *)frameToSend->dup(); 00882 frame->setDuration(0); 00883 return frame; 00884 }
Ieee80211Frame * Ieee80211Mac::setBasicBitrate | ( | Ieee80211Frame * | frame | ) | [protected, virtual] |
Attaches a PhyControlInfo to the frame which will cause it to be sent at basicBitrate not bitrate (e.g. 2Mbps instead of 11Mbps). Used with ACK, CTS, RTS.
Referenced by sendACKFrame(), sendCTSFrame(), and sendRTSFrame().
00887 { 00888 ASSERT(frame->getControlInfo()==NULL); 00889 PhyControlInfo *ctrl = new PhyControlInfo(); 00890 ctrl->setBitrate(basicBitrate); 00891 frame->setControlInfo(ctrl); 00892 return frame; 00893 }
void Ieee80211Mac::finishCurrentTransmission | ( | ) | [protected, virtual] |
Referenced by handleWithFSM().
00899 { 00900 popTransmissionQueue(); 00901 resetStateVariables(); 00902 }
void Ieee80211Mac::giveUpCurrentTransmission | ( | ) | [protected, virtual] |
Referenced by handleWithFSM().
00905 { 00906 popTransmissionQueue(); 00907 resetStateVariables(); 00908 numGivenUp++; 00909 }
void Ieee80211Mac::retryCurrentTransmission | ( | ) | [protected, virtual] |
Referenced by handleWithFSM().
00912 { 00913 ASSERT(retryCounter < transmissionLimit - 1); 00914 getCurrentTransmission()->setRetry(true); 00915 retryCounter++; 00916 numRetry++; 00917 backoff = true; 00918 generateBackoffPeriod(); 00919 }
void Ieee80211Mac::sendDownPendingRadioConfigMsg | ( | ) | [protected, virtual] |
Send down the change channel message to the physical layer if there is any.
Referenced by handleWithFSM().
00927 { 00928 if (pendingRadioConfigMsg != NULL) 00929 { 00930 sendDown(pendingRadioConfigMsg); 00931 pendingRadioConfigMsg = NULL; 00932 } 00933 }
void Ieee80211Mac::setMode | ( | Mode | mode | ) | [protected, virtual] |
Ieee80211DataOrMgmtFrame * Ieee80211Mac::getCurrentTransmission | ( | ) | [protected, virtual] |
Returns the current frame being transmitted.
Referenced by generateBackoffPeriod(), handleWithFSM(), resetStateVariables(), and retryCurrentTransmission().
00922 { 00923 return (Ieee80211DataOrMgmtFrame *)transmissionQueue.front(); 00924 }
void Ieee80211Mac::resetStateVariables | ( | ) | [protected, virtual] |
Reset backoff, backoffPeriod and retryCounter for IDLE state.
Referenced by finishCurrentTransmission(), giveUpCurrentTransmission(), and handleWithFSM().
00944 { 00945 backoffPeriod = 0; 00946 retryCounter = 0; 00947 00948 if (!transmissionQueue.empty()) { 00949 backoff = true; 00950 getCurrentTransmission()->setRetry(false); 00951 } 00952 else { 00953 backoff = false; 00954 } 00955 }
bool Ieee80211Mac::isMediumStateChange | ( | cMessage * | msg | ) | [protected, virtual] |
Used by the state machine to identify medium state change events. This message is currently optimized away and not sent through the kernel.
Referenced by handleWithFSM().
00958 { 00959 return msg == mediumStateChange || (msg == endReserve && radioState == RadioState::IDLE); 00960 }
bool Ieee80211Mac::isMediumFree | ( | ) | [protected, virtual] |
Tells if the medium is free according to the physical and virtual carrier sense algorithm.
Referenced by handleWithFSM().
00963 { 00964 return radioState == RadioState::IDLE && !endReserve->isScheduled(); 00965 }
bool Ieee80211Mac::isBroadcast | ( | Ieee80211Frame * | msg | ) | [protected, virtual] |
Returns true if message is a broadcast message.
Referenced by buildDataFrame(), computeBackoffPeriod(), and handleWithFSM().
bool Ieee80211Mac::isForUs | ( | Ieee80211Frame * | msg | ) | [protected, virtual] |
Returns true if message destination address is ours.
Referenced by handleLowerMsg(), handleWithFSM(), and scheduleReservePeriod().
00973 { 00974 return frame && frame->getReceiverAddress() == address; 00975 }
bool Ieee80211Mac::isDataOrMgmtFrame | ( | Ieee80211Frame * | frame | ) | [protected, virtual] |
Ieee80211Frame * Ieee80211Mac::getFrameReceivedBeforeSIFS | ( | ) | [protected, virtual] |
Returns the last frame received before the SIFS period.
Referenced by handleWithFSM().
00983 { 00984 return (Ieee80211Frame *)endSIFS->getContextPointer(); 00985 }
void Ieee80211Mac::popTransmissionQueue | ( | ) | [protected, virtual] |
Deletes frame at the front of queue.
Referenced by finishCurrentTransmission(), and giveUpCurrentTransmission().
00988 { 00989 EV << "dropping frame from transmission queue\n"; 00990 Ieee80211Frame *temp = transmissionQueue.front(); 00991 transmissionQueue.pop_front(); 00992 delete temp; 00993 00994 if (queueModule) 00995 { 00996 // tell queue module that we've become idle 00997 EV << "requesting another frame from queue module\n"; 00998 queueModule->requestPacket(); 00999 } 01000 }
double Ieee80211Mac::computeFrameDuration | ( | Ieee80211Frame * | msg | ) | [protected, virtual] |
Computes the duration (in seconds) of the transmission of a frame over the physical channel. 'bits' should be the total length of the MAC frame in bits, but excluding the physical layer framing (preamble etc.).
Referenced by buildACKFrame(), buildCTSFrame(), buildDataFrame(), buildRTSFrame(), scheduleBroadcastTimeoutPeriod(), scheduleCTSTimeoutPeriod(), and scheduleDataTimeoutPeriod().
01003 { 01004 return computeFrameDuration(msg->getBitLength(), bitrate); 01005 }
double Ieee80211Mac::computeFrameDuration | ( | int | bits, | |
double | bitrate | |||
) | [protected, virtual] |
void Ieee80211Mac::logState | ( | ) | [protected, virtual] |
Logs all state information.
Referenced by handleWithFSM().
01013 { 01014 EV << "state information: mode = " << modeName(mode) << ", state = " << fsm.getStateName() 01015 << ", backoff = " << backoff << ", backoffPeriod = " << backoffPeriod 01016 << ", retryCounter = " << retryCounter << ", radioState = " << radioState 01017 << ", nav = " << nav << endl; 01018 }
const char * Ieee80211Mac::modeName | ( | int | mode | ) | [protected] |
MACAddress Ieee80211Mac::address [protected] |
MAC address
Referenced by buildRTSFrame(), handleLowerMsg(), handleUpperMsg(), initialize(), isForUs(), and registerInterface().
double Ieee80211Mac::bitrate [protected] |
The bitrate is used to send data and mgmt frames; be sure to use a valid 802.11 bitrate
Referenced by computeFrameDuration(), and initialize().
double Ieee80211Mac::basicBitrate [protected] |
The basic bitrate (1 or 2 Mbps) is used to transmit control frames
Referenced by buildACKFrame(), buildCTSFrame(), buildDataFrame(), buildRTSFrame(), initialize(), scheduleCTSTimeoutPeriod(), scheduleDataTimeoutPeriod(), and setBasicBitrate().
int Ieee80211Mac::maxQueueSize [protected] |
Maximum number of frames in the queue; should be set in the omnetpp.ini
Referenced by handleUpperMsg(), and initialize().
int Ieee80211Mac::rtsThreshold [protected] |
The minimum length of MPDU to use RTS/CTS mechanism. 0 means always, extremely large value means never. See spec 9.2.6 and 361.
Referenced by handleWithFSM(), and initialize().
int Ieee80211Mac::transmissionLimit [protected] |
Maximum number of transmissions for a message. This includes the initial transmission and all subsequent retransmissions. Thus a value 0 is invalid and a value 1 means no retransmissions. See: dot11ShortRetryLimit on page 484. 'This attribute shall indicate the maximum number of transmission attempts of a frame, the length of which is less than or equal to dot11RTSThreshold, that shall be made before a failure condition is indicated. The default value of this attribute shall be 7'
Referenced by computeBackoffPeriod(), handleWithFSM(), initialize(), and retryCurrentTransmission().
int Ieee80211Mac::cwMinData [protected] |
Minimum contention window.
Referenced by computeBackoffPeriod(), and initialize().
int Ieee80211Mac::cwMinBroadcast [protected] |
Contention window size for broadcast messages.
Referenced by computeBackoffPeriod(), and initialize().
const int Ieee80211Mac::fragmentationThreshold = 2346 [static, protected] |
Messages longer than this threshold will be sent in multiple fragments. see spec 361
Referenced by handleUpperMsg().
cFSM Ieee80211Mac::fsm [protected] |
Referenced by handleCommand(), handleWithFSM(), initialize(), and logState().
Mode Ieee80211Mac::mode [protected] |
Referenced by initialize(), and logState().
int Ieee80211Mac::sequenceNumber [protected] |
Sequence number to be assigned to the next frame
Referenced by handleUpperMsg(), and initialize().
bool Ieee80211Mac::lastReceiveFailed [protected] |
Indicates that the last frame received had bit errors in it or there was a collision during receiving the frame. If this flag is set, then the MAC will wait EIFS instead of DIFS period of time in WAITDIFS state.
Referenced by handleWithFSM(), initialize(), and scheduleDIFSPeriod().
bool Ieee80211Mac::backoff [protected] |
True if backoff is enabled
Referenced by handleWithFSM(), initialize(), logState(), resetStateVariables(), and retryCurrentTransmission().
bool Ieee80211Mac::nav [protected] |
True during network allocation period. This flag is present to be able to watch this state.
Referenced by handleSelfMsg(), initialize(), logState(), and scheduleReservePeriod().
simtime_t Ieee80211Mac::backoffPeriod [protected] |
Remaining backoff period in seconds
Referenced by decreaseBackoffPeriod(), generateBackoffPeriod(), handleWithFSM(), initialize(), invalidateBackoffPeriod(), isInvalidBackoffPeriod(), logState(), resetStateVariables(), and scheduleBackoffPeriod().
int Ieee80211Mac::retryCounter [protected] |
Number of frame retransmission attempts, this is a simpification of SLRC and SSRC, see 9.2.4 in the spec
Referenced by generateBackoffPeriod(), handleWithFSM(), initialize(), logState(), resetStateVariables(), and retryCurrentTransmission().
RadioState::State Ieee80211Mac::radioState [protected] |
Physical radio (medium) state copied from physical layer
Referenced by initialize(), isMediumFree(), isMediumStateChange(), logState(), receiveChangeNotification(), and scheduleReservePeriod().
Messages received from upper layer and to be transmitted later
Referenced by getCurrentTransmission(), handleUpperMsg(), handleWithFSM(), popTransmissionQueue(), and resetStateVariables().
Ieee80211ASFTupleList Ieee80211Mac::asfTuplesList [protected] |
A list of last sender, sequence and fragment number tuples to identify duplicates, see spec 9.2.9. TODO: this is not yet used
IPassiveQueue* Ieee80211Mac::queueModule [protected] |
Passive queue module to request messages from
Referenced by initializeQueueModule(), and popTransmissionQueue().
cMessage* Ieee80211Mac::pendingRadioConfigMsg [protected] |
The last change channel message received and not yet sent to the physical layer, or NULL. The message will be sent down when the state goes to IDLE or DEFER next time.
Referenced by handleCommand(), Ieee80211Mac(), sendDownPendingRadioConfigMsg(), and ~Ieee80211Mac().
cMessage* Ieee80211Mac::endSIFS [protected] |
End of the Short Inter-Frame Time period
Referenced by getFrameReceivedBeforeSIFS(), handleWithFSM(), Ieee80211Mac(), initialize(), scheduleSIFSPeriod(), sendACKFrameOnEndSIFS(), sendCTSFrameOnEndSIFS(), sendDataFrameOnEndSIFS(), and ~Ieee80211Mac().
cMessage* Ieee80211Mac::endDIFS [protected] |
End of the Data Inter-Frame Time period
Referenced by cancelDIFSPeriod(), handleWithFSM(), Ieee80211Mac(), initialize(), scheduleDIFSPeriod(), and ~Ieee80211Mac().
cMessage* Ieee80211Mac::endBackoff [protected] |
End of the backoff period
Referenced by cancelBackoffPeriod(), decreaseBackoffPeriod(), handleWithFSM(), Ieee80211Mac(), initialize(), scheduleBackoffPeriod(), and ~Ieee80211Mac().
cMessage* Ieee80211Mac::endTimeout [protected] |
Timeout after the transmission of an RTS, a CTS, or a DATA frame
Referenced by cancelTimeoutPeriod(), handleWithFSM(), Ieee80211Mac(), initialize(), scheduleBroadcastTimeoutPeriod(), scheduleCTSTimeoutPeriod(), scheduleDataTimeoutPeriod(), and ~Ieee80211Mac().
cMessage* Ieee80211Mac::endReserve [protected] |
End of medium reserve period (NAV) when two other nodes were communicating on the channel
Referenced by handleSelfMsg(), Ieee80211Mac(), initialize(), isMediumFree(), isMediumStateChange(), scheduleReservePeriod(), and ~Ieee80211Mac().
cMessage* Ieee80211Mac::mediumStateChange [protected] |
Radio state change self message. Currently this is optimized away and sent directly
Referenced by Ieee80211Mac(), initialize(), isMediumStateChange(), receiveChangeNotification(), scheduleReservePeriod(), and ~Ieee80211Mac().
long Ieee80211Mac::numRetry [protected] |
Referenced by initialize(), and retryCurrentTransmission().
long Ieee80211Mac::numSentWithoutRetry [protected] |
Referenced by handleWithFSM(), and initialize().
long Ieee80211Mac::numGivenUp [protected] |
Referenced by giveUpCurrentTransmission(), and initialize().
long Ieee80211Mac::numCollision [protected] |
Referenced by handleWithFSM(), and initialize().
long Ieee80211Mac::numSent [protected] |
Referenced by handleWithFSM(), and initialize().
long Ieee80211Mac::numReceived [protected] |
Referenced by handleWithFSM(), and initialize().
long Ieee80211Mac::numSentBroadcast [protected] |
Referenced by handleWithFSM(), and initialize().
long Ieee80211Mac::numReceivedBroadcast [protected] |
Referenced by handleWithFSM(), and initialize().
cOutVector Ieee80211Mac::stateVector [protected] |
Referenced by handleWithFSM(), and initialize().
cOutVector Ieee80211Mac::radioStateVector [protected] |
Referenced by initialize(), and receiveChangeNotification().