Ieee80211Mac Class Reference

#include <Ieee80211Mac.h>

Inheritance diagram for Ieee80211Mac:

WirelessMacBase INotifiable

List of all members.


Detailed Description

IEEE 802.11b Media Access Control Layer.

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
IPassiveQueuequeueModule
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


Member Typedef Documentation

typedef std::list<Ieee80211DataOrMgmtFrame*> Ieee80211Mac::Ieee80211DataOrMgmtFrameList [private]


Member Enumeration Documentation

the 80211 MAC state machine

Enumerator:
IDLE 
DEFER 
WAITDIFS 
BACKOFF 
WAITACK 
WAITBROADCAST 
WAITCTS 
WAITSIFS 
RECEIVE 
00125                {
00126         IDLE,
00127         DEFER,
00128         WAITDIFS,
00129         BACKOFF,
00130         WAITACK,
00131         WAITBROADCAST,
00132         WAITCTS,
00133         WAITSIFS,
00134         RECEIVE,
00135     };

80211 MAC operation modes

Enumerator:
DCF  Distributed Coordination Function.
PCF  Point Coordination Function.
00141               {
00142         DCF,  
00143         PCF,  
00144     };


Constructor & Destructor Documentation

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 }


Member Function Documentation

virtual int Ieee80211Mac::numInitStages (  )  const [inline, protected, virtual]

Initialization of the module and its variables.

00248 {return 2;}

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]

00608 {
00609     return getSIFS() + getSlotTime();
00610 }

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]

Referenced by handleWithFSM().

00673 {
00674     EV << "cancelling DIFS period\n";
00675     cancelEvent(endDIFS);
00676 }

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]

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]

Referenced by handleWithFSM().

00738 {
00739     return backoffPeriod == -1;
00740 }

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]

Change the current MAC operation mode.

00936 {
00937     if (mode == PCF)
00938         error("PCF mode not yet supported");
00939 
00940     this->mode = mode;
00941 }

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().

00968 {
00969     return frame && frame->getReceiverAddress().isBroadcast();
00970 }

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]

Checks if the frame is a data or management frame.

Referenced by handleWithFSM().

00978 {
00979     return dynamic_cast<Ieee80211DataOrMgmtFrame*>(frame);
00980 }

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]

01008 {
01009     return bits / bitrate + PHY_HEADER_LENGTH / BITRATE_HEADER;
01010 }

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]

Produce a readable name of the given MAC operation mode.

Referenced by logState().

01021 {
01022 #define CASE(x) case x: s=#x; break
01023     const char *s = "???";
01024     switch (mode)
01025     {
01026         CASE(DCF);
01027         CASE(PCF);
01028     }
01029     return s;
01030 #undef CASE
01031 }


Member Data Documentation

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().

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().

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]

Mode Ieee80211Mac::mode [protected]

Referenced by initialize(), and logState().

Sequence number to be assigned to the next frame

Referenced by handleUpperMsg(), and initialize().

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]

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().

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().

A list of last sender, sequence and fragment number tuples to identify duplicates, see spec 9.2.9. TODO: this is not yet used

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]

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]

cMessage* Ieee80211Mac::endTimeout [protected]

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 handleWithFSM(), and initialize().

long Ieee80211Mac::numGivenUp [protected]

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().

Referenced by handleWithFSM(), and initialize().

Referenced by handleWithFSM(), and initialize().

cOutVector Ieee80211Mac::stateVector [protected]

Referenced by handleWithFSM(), and initialize().

cOutVector Ieee80211Mac::radioStateVector [protected]


The documentation for this class was generated from the following files:

Generated on Fri Mar 20 18:51:19 2009 for INET Framework for OMNeT++/OMNEST by  doxygen 1.5.5