INET Framework for OMNeT++/OMNEST
Ieee80211Mac Class Reference

#include <Ieee80211Mac.h>

Inheritance diagram for Ieee80211Mac:
WirelessMacBase INotifiable

List of all members.

Classes

struct  Ieee80211ASFTuple

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

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

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

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.


Member Typedef Documentation

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

Member Enumeration Documentation

80211 MAC operation modes

Enumerator:
DCF 

Distributed Coordination Function.

PCF 

Point Coordination Function.

              {
        DCF,  
        PCF,  
    };

the 80211 MAC state machine

Enumerator:
IDLE 
DEFER 
WAITDIFS 
BACKOFF 
WAITACK 
WAITBROADCAST 
WAITCTS 
WAITSIFS 
RECEIVE 

Constructor & Destructor Documentation

Ieee80211Mac::Ieee80211Mac ( )
{
    endSIFS = NULL;
    endDIFS = NULL;
    endBackoff = NULL;
    endTimeout = NULL;
    endReserve = NULL;
    mediumStateChange = NULL;
    pendingRadioConfigMsg = NULL;
}
Ieee80211Mac::~Ieee80211Mac ( ) [virtual]
{
    cancelAndDelete(endSIFS);
    cancelAndDelete(endDIFS);
    cancelAndDelete(endBackoff);
    cancelAndDelete(endTimeout);
    cancelAndDelete(endReserve);
    cancelAndDelete(mediumStateChange);

    if (pendingRadioConfigMsg)
        delete pendingRadioConfigMsg;
}

Member Function Documentation

Ieee80211ACKFrame * Ieee80211Mac::buildACKFrame ( Ieee80211DataOrMgmtFrame *  frameToACK) [protected, virtual]

Referenced by sendACKFrame().

{
    Ieee80211ACKFrame *frame = new Ieee80211ACKFrame("wlan-ack");
    frame->setReceiverAddress(frameToACK->getTransmitterAddress());

    if (!frameToACK->getMoreFragments())
        frame->setDuration(0);
    else
        frame->setDuration(frameToACK->getDuration() - getSIFS() - computeFrameDuration(LENGTH_ACK, basicBitrate));

    return frame;
}
Ieee80211DataOrMgmtFrame * Ieee80211Mac::buildBroadcastFrame ( Ieee80211DataOrMgmtFrame *  frameToSend) [protected, virtual]

Referenced by sendBroadcastFrame().

{
    Ieee80211DataOrMgmtFrame *frame = (Ieee80211DataOrMgmtFrame *)frameToSend->dup();
    frame->setDuration(0);
    return frame;
}
Ieee80211CTSFrame * Ieee80211Mac::buildCTSFrame ( Ieee80211RTSFrame *  rtsFrame) [protected, virtual]

Referenced by sendCTSFrame().

{
    Ieee80211CTSFrame *frame = new Ieee80211CTSFrame("wlan-cts");
    frame->setReceiverAddress(rtsFrame->getTransmitterAddress());
    frame->setDuration(rtsFrame->getDuration() - getSIFS() - computeFrameDuration(LENGTH_CTS, basicBitrate));

    return frame;
}
Ieee80211DataOrMgmtFrame * Ieee80211Mac::buildDataFrame ( Ieee80211DataOrMgmtFrame *  frameToSend) [protected, virtual]

Referenced by sendDataFrame().

{
    Ieee80211DataOrMgmtFrame *frame = (Ieee80211DataOrMgmtFrame *)frameToSend->dup();

    if (isBroadcast(frameToSend))
        frame->setDuration(0);
    else if (!frameToSend->getMoreFragments())
        frame->setDuration(getSIFS() + computeFrameDuration(LENGTH_ACK, basicBitrate));
    else
        // FIXME: shouldn't we use the next frame to be sent?
        frame->setDuration(3 * getSIFS() + 2 * computeFrameDuration(LENGTH_ACK, basicBitrate) + computeFrameDuration(frameToSend));

    return frame;
}
Ieee80211RTSFrame * Ieee80211Mac::buildRTSFrame ( Ieee80211DataOrMgmtFrame *  frameToSend) [protected, virtual]

Referenced by sendRTSFrame().

{
    Ieee80211RTSFrame *frame = new Ieee80211RTSFrame("wlan-rts");
    frame->setTransmitterAddress(address);
    frame->setReceiverAddress(frameToSend->getReceiverAddress());
    frame->setDuration(3 * getSIFS() + computeFrameDuration(LENGTH_CTS, basicBitrate) +
                       computeFrameDuration(frameToSend) +
                       computeFrameDuration(LENGTH_ACK, basicBitrate));

    return frame;
}
void Ieee80211Mac::cancelBackoffPeriod ( ) [protected, virtual]

Referenced by handleWithFSM().

{
    EV << "cancelling Backoff period\n";
    cancelEvent(endBackoff);
}
void Ieee80211Mac::cancelDIFSPeriod ( ) [protected, virtual]

Referenced by handleWithFSM().

{
    EV << "cancelling DIFS period\n";
    cancelEvent(endDIFS);
}
void Ieee80211Mac::cancelTimeoutPeriod ( ) [protected, virtual]

Referenced by handleWithFSM().

{
    EV << "cancelling timeout period\n";
    cancelEvent(endTimeout);
}
simtime_t Ieee80211Mac::computeBackoffPeriod ( Ieee80211Frame *  msg,
int  r 
) [protected, virtual]

Referenced by generateBackoffPeriod().

{
    int cw;

    EV << "generating backoff slot number for retry: " << r << endl;

    if (isBroadcast(msg))
        cw = cwMinBroadcast;
    else
    {
        ASSERT(0 <= r && r < transmissionLimit);

        cw = (cwMinData + 1) * (1 << r) - 1;

        if (cw > CW_MAX)
            cw = CW_MAX;
    }

    int c = intrand(cw + 1);

    EV << "generated backoff slot number: " << c << " , cw: " << cw << endl;

    return ((double)c) * getSlotTime();
}
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().

{
    return computeFrameDuration(msg->getBitLength(), bitrate);
}
double Ieee80211Mac::computeFrameDuration ( int  bits,
double  bitrate 
) [protected, virtual]
{
    return bits / bitrate + PHY_HEADER_LENGTH / BITRATE_HEADER;
}
void Ieee80211Mac::decreaseBackoffPeriod ( ) [protected, virtual]

Referenced by handleWithFSM().

{
    // see spec 9.2.5.2
    simtime_t elapsedBackoffTime = simTime() - endBackoff->getSendingTime();
    backoffPeriod -= ((int)(elapsedBackoffTime / getSlotTime())) * getSlotTime();
    ASSERT(backoffPeriod >= 0);
    EV << "backoff period decreased to " << backoffPeriod << endl;
}
void Ieee80211Mac::finishCurrentTransmission ( ) [protected, virtual]
void Ieee80211Mac::generateBackoffPeriod ( ) [protected, virtual]

Referenced by handleWithFSM(), and retryCurrentTransmission().

{
    backoffPeriod = computeBackoffPeriod(getCurrentTransmission(), retryCounter);
    ASSERT(backoffPeriod >= 0);
    EV << "backoff period set to " << backoffPeriod << endl;
}
Ieee80211DataOrMgmtFrame * Ieee80211Mac::getCurrentTransmission ( ) [protected, virtual]

Returns the current frame being transmitted.

Referenced by generateBackoffPeriod(), handleWithFSM(), resetStateVariables(), and retryCurrentTransmission().

{
    return (Ieee80211DataOrMgmtFrame *)transmissionQueue.front();
}
simtime_t Ieee80211Mac::getDIFS ( ) [protected, virtual]

Referenced by getEIFS(), and scheduleDIFSPeriod().

{
    return getSIFS() + 2 * getSlotTime();
}
simtime_t Ieee80211Mac::getEIFS ( ) [protected, virtual]

Referenced by scheduleDIFSPeriod().

{
// FIXME:   return getSIFS() + getDIFS() + (8 * ACKSize + aPreambleLength + aPLCPHeaderLength) / lowestDatarate;
    return getSIFS() + getDIFS() + (8 * LENGTH_ACK + PHY_HEADER_LENGTH) / 1E+6;
}
Ieee80211Frame * Ieee80211Mac::getFrameReceivedBeforeSIFS ( ) [protected, virtual]

Returns the last frame received before the SIFS period.

Referenced by handleWithFSM().

{
    return (Ieee80211Frame *)endSIFS->getContextPointer();
}
simtime_t Ieee80211Mac::getPIFS ( ) [protected, virtual]
{
    return getSIFS() + getSlotTime();
}
simtime_t Ieee80211Mac::getSIFS ( ) [protected, virtual]

Referenced by buildACKFrame(), buildCTSFrame(), buildDataFrame(), buildRTSFrame(), getDIFS(), getEIFS(), getPIFS(), scheduleCTSTimeoutPeriod(), scheduleDataTimeoutPeriod(), and scheduleSIFSPeriod().

{
// TODO:   return aRxRFDelay() + aRxPLCPDelay() + aMACProcessingDelay() + aRxTxTurnaroundTime();
    return SIFS;
}
simtime_t Ieee80211Mac::getSlotTime ( ) [protected, virtual]

Referenced by computeBackoffPeriod(), decreaseBackoffPeriod(), getDIFS(), and getPIFS().

{
// TODO:   return aCCATime() + aRxTxTurnaroundTime + aAirPropagationTime() + aMACProcessingDelay();
    return ST;
}
void Ieee80211Mac::giveUpCurrentTransmission ( ) [protected, virtual]
void Ieee80211Mac::handleCommand ( cMessage *  msg) [protected, virtual]

Handle commands (msg kind+control info) coming from upper layers.

Implements WirelessMacBase.

{
    if (msg->getKind()==PHY_C_CONFIGURERADIO)
    {
        EV << "Passing on command " << msg->getName() << " to physical layer\n";
        if (pendingRadioConfigMsg != NULL)
        {
            // merge contents of the old command into the new one, then delete it
            PhyControlInfo *pOld = check_and_cast<PhyControlInfo *>(pendingRadioConfigMsg->getControlInfo());
            PhyControlInfo *pNew = check_and_cast<PhyControlInfo *>(msg->getControlInfo());
            if (pNew->getChannelNumber()==-1 && pOld->getChannelNumber()!=-1)
                pNew->setChannelNumber(pOld->getChannelNumber());
            if (pNew->getBitrate()==-1 && pOld->getBitrate()!=-1)
                pNew->setBitrate(pOld->getBitrate());
            delete pendingRadioConfigMsg;
            pendingRadioConfigMsg = NULL;
        }

        if (fsm.getState() == IDLE || fsm.getState() == DEFER || fsm.getState() == BACKOFF)
        {
            EV << "Sending it down immediately\n";
            sendDown(msg);
        }
        else
        {
            EV << "Delaying " << msg->getName() << " until next IDLE or DEFER state\n";
            pendingRadioConfigMsg = msg;
        }
    }
    else
    {
        error("Unrecognized command from mgmt layer: (%s)%s msgkind=%d", msg->getClassName(), msg->getName(), msg->getKind());
    }
}
void Ieee80211Mac::handleLowerMsg ( cPacket *  msg) [protected, virtual]

Handle messages from lower (physical) layer.

Implements WirelessMacBase.

{
    EV << "received message from lower layer: " << msg << endl;

    Ieee80211Frame *frame = dynamic_cast<Ieee80211Frame *>(msg);
    if (!frame)
        error("message from physical layer (%s)%s is not a subclass of Ieee80211Frame",
              msg->getClassName(), msg->getName());

    EV << "Self address: " << address
       << ", receiver address: " << frame->getReceiverAddress()
       << ", received frame is for us: " << isForUs(frame) << endl;

    Ieee80211TwoAddressFrame *twoAddressFrame = dynamic_cast<Ieee80211TwoAddressFrame *>(msg);
    ASSERT(!twoAddressFrame || twoAddressFrame->getTransmitterAddress() != address);

    handleWithFSM(msg);

    // if we are the owner then we did not send this message up
    if (msg->getOwner() == this)
        delete msg;
}
void Ieee80211Mac::handleSelfMsg ( cMessage *  msg) [protected, virtual]

Handle timer self messages.

Implements WirelessMacBase.

{
    EV << "received self message: " << msg << endl;

    if (msg == endReserve)
        nav = false;

    handleWithFSM(msg);
}
void Ieee80211Mac::handleUpperMsg ( cPacket *  msg) [protected, virtual]

Handle messages from upper layer.

Implements WirelessMacBase.

{
    // check for queue overflow
    if (maxQueueSize && (int)transmissionQueue.size() == maxQueueSize)
    {
        EV << "message " << msg << " received from higher layer but MAC queue is full, dropping message\n";
        delete msg;
        return;
    }

    // must be a Ieee80211DataOrMgmtFrame, within the max size because we don't support fragmentation
    Ieee80211DataOrMgmtFrame *frame = check_and_cast<Ieee80211DataOrMgmtFrame *>(msg);
    if (frame->getByteLength() > fragmentationThreshold)
        error("message from higher layer (%s)%s is too long for 802.11b, %d bytes (fragmentation is not supported yet)",
              msg->getClassName(), msg->getName(), (int)(msg->getByteLength()));
    EV << "frame " << frame << " received from higher layer, receiver = " << frame->getReceiverAddress() << endl;

    ASSERT(!frame->getReceiverAddress().isUnspecified());

    // fill in missing fields (receiver address, seq number), and insert into the queue
    frame->setTransmitterAddress(address);
    frame->setSequenceNumber(sequenceNumber);
    sequenceNumber = (sequenceNumber+1) % 4096;  //XXX seqNum must be checked upon reception of frames!

    transmissionQueue.push_back(frame);

    handleWithFSM(frame);
}
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().

{
    // skip those cases where there's nothing to do, so the switch looks simpler
    if (isUpperMsg(msg) && fsm.getState() != IDLE)
    {
        EV << "deferring upper message transmission in " << fsm.getStateName() << " state\n";
        return;
    }

    Ieee80211Frame *frame = dynamic_cast<Ieee80211Frame*>(msg);
    int frameType = frame ? frame->getType() : -1;
    int msgKind = msg->getKind();
    logState();
    stateVector.record(fsm.getState());

    if (frame && isLowerMsg(frame))
    {
        lastReceiveFailed =(msgKind == COLLISION || msgKind == BITERROR);
        scheduleReservePeriod(frame);
    }

    // TODO: fix bug according to the message: [omnetpp] A possible bug in the Ieee80211's FSM.
    FSMA_Switch(fsm)
    {
        FSMA_State(IDLE)
        {
            FSMA_Enter(sendDownPendingRadioConfigMsg());
            FSMA_Event_Transition(Data-Ready,
                                  isUpperMsg(msg),
                                  DEFER,
                ASSERT(isInvalidBackoffPeriod() || backoffPeriod == 0);
                invalidateBackoffPeriod();
            );
            FSMA_No_Event_Transition(Immediate-Data-Ready,
                                     !transmissionQueue.empty(),
                                     DEFER,
                invalidateBackoffPeriod();
            );
            FSMA_Event_Transition(Receive,
                                  isLowerMsg(msg),
                                  RECEIVE,
            );
        }
        FSMA_State(DEFER)
        {
            FSMA_Enter(sendDownPendingRadioConfigMsg());
            FSMA_Event_Transition(Wait-DIFS,
                                  isMediumStateChange(msg) && isMediumFree(),
                                  WAITDIFS,
            ;);
            FSMA_No_Event_Transition(Immediate-Wait-DIFS,
                                     isMediumFree() || !backoff,
                                     WAITDIFS,
            ;);
            FSMA_Event_Transition(Receive,
                                  isLowerMsg(msg),
                                  RECEIVE,
            ;);
        }
        FSMA_State(WAITDIFS)
        {
            FSMA_Enter(scheduleDIFSPeriod());
            FSMA_Event_Transition(Immediate-Transmit-RTS,
                                  msg == endDIFS && !isBroadcast(getCurrentTransmission())
                                  && getCurrentTransmission()->getByteLength() >= rtsThreshold && !backoff,
                                  WAITCTS,
                sendRTSFrame(getCurrentTransmission());
                cancelDIFSPeriod();
            );
            FSMA_Event_Transition(Immediate-Transmit-Broadcast,
                                  msg == endDIFS && isBroadcast(getCurrentTransmission()) && !backoff,
                                  WAITBROADCAST,
                sendBroadcastFrame(getCurrentTransmission());
                cancelDIFSPeriod();
            );
            FSMA_Event_Transition(Immediate-Transmit-Data,
                                  msg == endDIFS && !isBroadcast(getCurrentTransmission()) && !backoff,
                                  WAITACK,
                sendDataFrame(getCurrentTransmission());
                cancelDIFSPeriod();
            );
            FSMA_Event_Transition(DIFS-Over,
                                  msg == endDIFS,
                                  BACKOFF,
                ASSERT(backoff);
                if (isInvalidBackoffPeriod())
                    generateBackoffPeriod();
            );
            FSMA_Event_Transition(Busy,
                                  isMediumStateChange(msg) && !isMediumFree(),
                                  DEFER,
                backoff = true;
                cancelDIFSPeriod();
            );
            FSMA_No_Event_Transition(Immediate-Busy,
                                     !isMediumFree(),
                                     DEFER,
                backoff = true;
                cancelDIFSPeriod();
            );
            // radio state changes before we actually get the message, so this must be here
            FSMA_Event_Transition(Receive,
                                  isLowerMsg(msg),
                                  RECEIVE,
                cancelDIFSPeriod();
            ;);
        }
        FSMA_State(BACKOFF)
        {
            FSMA_Enter(scheduleBackoffPeriod());
            FSMA_Event_Transition(Transmit-RTS,
                                  msg == endBackoff && !isBroadcast(getCurrentTransmission())
                                  && getCurrentTransmission()->getByteLength() >= rtsThreshold,
                                  WAITCTS,
                sendRTSFrame(getCurrentTransmission());
            );
            FSMA_Event_Transition(Transmit-Broadcast,
                                  msg == endBackoff && isBroadcast(getCurrentTransmission()),
                                  WAITBROADCAST,
                sendBroadcastFrame(getCurrentTransmission());
            );
            FSMA_Event_Transition(Transmit-Data,
                                  msg == endBackoff && !isBroadcast(getCurrentTransmission()),
                                  WAITACK,
                sendDataFrame(getCurrentTransmission());
            );
            FSMA_Event_Transition(Backoff-Busy,
                                  isMediumStateChange(msg) && !isMediumFree(),
                                  DEFER,
                cancelBackoffPeriod();
                decreaseBackoffPeriod();
            );
        }
        FSMA_State(WAITACK)
        {
            FSMA_Enter(scheduleDataTimeoutPeriod(getCurrentTransmission()));
            FSMA_Event_Transition(Receive-ACK,
                                  isLowerMsg(msg) && isForUs(frame) && frameType == ST_ACK,
                                  IDLE,
                if (retryCounter == 0) numSentWithoutRetry++;
                numSent++;
                cancelTimeoutPeriod();
                finishCurrentTransmission();
            );
            FSMA_Event_Transition(Transmit-Data-Failed,
                                  msg == endTimeout && retryCounter == transmissionLimit - 1,
                                  IDLE,
                giveUpCurrentTransmission();
            );
            FSMA_Event_Transition(Receive-ACK-Timeout,
                                  msg == endTimeout,
                                  DEFER,
                retryCurrentTransmission();
            );
        }
        // wait until broadcast is sent
        FSMA_State(WAITBROADCAST)
        {
            FSMA_Enter(scheduleBroadcastTimeoutPeriod(getCurrentTransmission()));
            FSMA_Event_Transition(Transmit-Broadcast,
                                  msg == endTimeout,
                                  IDLE,
                finishCurrentTransmission();
                numSentBroadcast++;
            );
        }
        // accoriding to 9.2.5.7 CTS procedure
        FSMA_State(WAITCTS)
        {
            FSMA_Enter(scheduleCTSTimeoutPeriod());
            FSMA_Event_Transition(Receive-CTS,
                                  isLowerMsg(msg) && isForUs(frame) && frameType == ST_CTS,
                                  WAITSIFS,
                cancelTimeoutPeriod();
            );
            FSMA_Event_Transition(Transmit-RTS-Failed,
                                  msg == endTimeout && retryCounter == transmissionLimit - 1,
                                  IDLE,
                giveUpCurrentTransmission();
            );
            FSMA_Event_Transition(Receive-CTS-Timeout,
                                  msg == endTimeout,
                                  DEFER,
                retryCurrentTransmission();
            );
        }
        FSMA_State(WAITSIFS)
        {
            FSMA_Enter(scheduleSIFSPeriod(frame));
            FSMA_Event_Transition(Transmit-CTS,
                                  msg == endSIFS && getFrameReceivedBeforeSIFS()->getType() == ST_RTS,
                                  IDLE,
                sendCTSFrameOnEndSIFS();
                resetStateVariables();
            );
            FSMA_Event_Transition(Transmit-DATA,
                                  msg == endSIFS && getFrameReceivedBeforeSIFS()->getType() == ST_CTS,
                                  WAITACK,
                sendDataFrameOnEndSIFS(getCurrentTransmission());
            );
            FSMA_Event_Transition(Transmit-ACK,
                                  msg == endSIFS && isDataOrMgmtFrame(getFrameReceivedBeforeSIFS()),
                                  IDLE,
                sendACKFrameOnEndSIFS();
                resetStateVariables();
            );
        }
        // this is not a real state
        FSMA_State(RECEIVE)
        {
            FSMA_No_Event_Transition(Immediate-Receive-Error,
                                     isLowerMsg(msg) && (msgKind == COLLISION || msgKind == BITERROR),
                                     IDLE,
                EV << "received frame contains bit errors or collision, next wait period is EIFS\n";
                numCollision++;
                resetStateVariables();
            );
            FSMA_No_Event_Transition(Immediate-Receive-Broadcast,
                                     isLowerMsg(msg) && isBroadcast(frame) && isDataOrMgmtFrame(frame),
                                     IDLE,
                sendUp(frame);
                numReceivedBroadcast++;
                resetStateVariables();
            );
            FSMA_No_Event_Transition(Immediate-Receive-Data,
                                     isLowerMsg(msg) && isForUs(frame) && isDataOrMgmtFrame(frame),
                                     WAITSIFS,
                sendUp(frame);
                numReceived++;
            );
            FSMA_No_Event_Transition(Immediate-Receive-RTS,
                                     isLowerMsg(msg) && isForUs(frame) && frameType == ST_RTS,
                                     WAITSIFS,
            );
            FSMA_No_Event_Transition(Immediate-Receive-Other,
                                     isLowerMsg(msg),
                                     IDLE,
                resetStateVariables();
            );
        }
    }

    logState();
    stateVector.record(fsm.getState());
}
void Ieee80211Mac::initialize ( int  stage) [protected, virtual]

Initialization of the module and some variables.

Reimplemented from WirelessMacBase.

{
    WirelessMacBase::initialize(stage);

    if (stage == 0)
    {
        EV << "Initializing stage 0\n";

        // initialize parameters
        maxQueueSize = par("maxQueueSize");
        bitrate = par("bitrate");
        basicBitrate = 2e6; //FIXME make it parameter
        rtsThreshold = par("rtsThresholdBytes");

        // the variable is renamed due to a confusion in the standard
        // the name retry limit would be misleading, see the header file comment
        transmissionLimit = par("retryLimit");
        if (transmissionLimit == -1) transmissionLimit = 7;
        ASSERT(transmissionLimit > 0);

        cwMinData = par("cwMinData");
        if (cwMinData == -1) cwMinData = CW_MIN;
        ASSERT(cwMinData >= 0);

        cwMinBroadcast = par("cwMinBroadcast");
        if (cwMinBroadcast == -1) cwMinBroadcast = 31;
        ASSERT(cwMinBroadcast >= 0);

        const char *addressString = par("address");
        if (!strcmp(addressString, "auto")) {
            // assign automatic address
            address = MACAddress::generateAutoAddress();
            // change module parameter from "auto" to concrete address
            par("address").setStringValue(address.str().c_str());
        }
        else
            address.setAddress(addressString);

        // subscribe for the information of the carrier sense
        nb->subscribe(this, NF_RADIOSTATE_CHANGED);

        // initalize self messages
        endSIFS = new cMessage("SIFS");
        endDIFS = new cMessage("DIFS");
        endBackoff = new cMessage("Backoff");
        endTimeout = new cMessage("Timeout");
        endReserve = new cMessage("Reserve");
        mediumStateChange = new cMessage("MediumStateChange");

        // interface
        registerInterface();

        // obtain pointer to external queue
        initializeQueueModule();

        // state variables
        fsm.setName("Ieee80211Mac State Machine");
        mode = DCF;
        sequenceNumber = 0;
        radioState = RadioState::IDLE;
        retryCounter = 0;
        backoffPeriod = -1;
        backoff = false;
        lastReceiveFailed = false;
        nav = false;

        // statistics
        numRetry = 0;
        numSentWithoutRetry = 0;
        numGivenUp = 0;
        numCollision = 0;
        numSent = 0;
        numReceived = 0;
        numSentBroadcast = 0;
        numReceivedBroadcast = 0;
        stateVector.setName("State");
        stateVector.setEnum("Ieee80211Mac");
        radioStateVector.setName("RadioState");
        radioStateVector.setEnum("RadioState");

        // initialize watches
        WATCH(fsm);
        WATCH(radioState);
        WATCH(retryCounter);
        WATCH(backoff);
        WATCH(nav);

        WATCH(numRetry);
        WATCH(numSentWithoutRetry);
        WATCH(numGivenUp);
        WATCH(numCollision);
        WATCH(numSent);
        WATCH(numReceived);
        WATCH(numSentBroadcast);
        WATCH(numReceivedBroadcast);
    }
}
void Ieee80211Mac::initializeQueueModule ( ) [protected, virtual]

Referenced by initialize().

{
    // use of external queue module is optional -- find it if there's one specified
    if (par("queueModule").stringValue()[0])
    {
        cModule *module = getParentModule()->getSubmodule(par("queueModule").stringValue());
        queueModule = check_and_cast<IPassiveQueue *>(module);

        EV << "Requesting first two frames from queue module\n";
        queueModule->requestPacket();
        // needed for backoff: mandatory if next message is already present
        queueModule->requestPacket();
    }
}
void Ieee80211Mac::invalidateBackoffPeriod ( ) [protected, virtual]

Generates a new backoff period based on the contention window.

Referenced by handleWithFSM().

{
    backoffPeriod = -1;
}
bool Ieee80211Mac::isBroadcast ( Ieee80211Frame *  msg) [protected, virtual]

Returns true if message is a broadcast message.

Referenced by buildDataFrame(), computeBackoffPeriod(), and handleWithFSM().

{
    return frame && frame->getReceiverAddress().isBroadcast();
}
bool Ieee80211Mac::isDataOrMgmtFrame ( Ieee80211Frame *  frame) [protected, virtual]

Checks if the frame is a data or management frame.

Referenced by handleWithFSM().

{
    return dynamic_cast<Ieee80211DataOrMgmtFrame*>(frame);
}
bool Ieee80211Mac::isForUs ( Ieee80211Frame *  msg) [protected, virtual]

Returns true if message destination address is ours.

Referenced by handleLowerMsg(), handleWithFSM(), and scheduleReservePeriod().

{
    return frame && frame->getReceiverAddress() == address;
}
bool Ieee80211Mac::isInvalidBackoffPeriod ( ) [protected, virtual]

Referenced by handleWithFSM().

{
    return backoffPeriod == -1;
}
bool Ieee80211Mac::isMediumFree ( ) [protected, virtual]

Tells if the medium is free according to the physical and virtual carrier sense algorithm.

Referenced by handleWithFSM().

{
    return radioState == RadioState::IDLE && !endReserve->isScheduled();
}
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().

{
    return msg == mediumStateChange || (msg == endReserve && radioState == RadioState::IDLE);
}
void Ieee80211Mac::logState ( ) [protected, virtual]

Logs all state information.

Referenced by handleWithFSM().

{
    EV  << "state information: mode = " << modeName(mode) << ", state = " << fsm.getStateName()
        << ", backoff = " << backoff << ", backoffPeriod = " << backoffPeriod
        << ", retryCounter = " << retryCounter << ", radioState = " << radioState
        << ", nav = " << nav << endl;
}
const char * Ieee80211Mac::modeName ( int  mode) [protected]

Produce a readable name of the given MAC operation mode.

Referenced by logState().

{
#define CASE(x) case x: s=#x; break
    const char *s = "???";
    switch (mode)
    {
        CASE(DCF);
        CASE(PCF);
    }
    return s;
#undef CASE
}
virtual int Ieee80211Mac::numInitStages ( ) const [inline, protected, virtual]

Initialization of the module and its variables.

{return 2;}
void Ieee80211Mac::popTransmissionQueue ( ) [protected, virtual]

Deletes frame at the front of queue.

Referenced by finishCurrentTransmission(), and giveUpCurrentTransmission().

{
    EV << "dropping frame from transmission queue\n";
    Ieee80211Frame *temp = transmissionQueue.front();
    transmissionQueue.pop_front();
    delete temp;

    if (queueModule)
    {
        // tell queue module that we've become idle
        EV << "requesting another frame from queue module\n";
        queueModule->requestPacket();
    }
}
void Ieee80211Mac::receiveChangeNotification ( int  category,
const cPolymorphic *  details 
) [protected, virtual]

Called by the NotificationBoard whenever a change occurs we're interested in.

Implements INotifiable.

{
    Enter_Method_Silent();
    printNotificationBanner(category, details);

    if (category == NF_RADIOSTATE_CHANGED)
    {
        RadioState::State newRadioState = check_and_cast<RadioState *>(details)->getState();

        // FIXME: double recording, because there's no sample hold in the gui
        radioStateVector.record(radioState);
        radioStateVector.record(newRadioState);

        radioState = newRadioState;

        handleWithFSM(mediumStateChange);
    }
}
void Ieee80211Mac::registerInterface ( ) [protected, virtual]

Referenced by initialize().

{
    IInterfaceTable *ift = InterfaceTableAccess().getIfExists();
    if (!ift)
        return;

    InterfaceEntry *e = new InterfaceEntry();

    // interface name: NetworkInterface module's name without special characters ([])
    char *interfaceName = new char[strlen(getParentModule()->getFullName()) + 1];
    char *d = interfaceName;
    for (const char *s = getParentModule()->getFullName(); *s; s++)
        if (isalnum(*s))
            *d++ = *s;
    *d = '\0';

    e->setName(interfaceName);
    delete [] interfaceName;

    // address
    e->setMACAddress(address);
    e->setInterfaceToken(address.formInterfaceIdentifier());

    // FIXME: MTU on 802.11 = ?
    e->setMtu(par("mtu"));

    // capabilities
    e->setBroadcast(true);
    e->setMulticast(true);
    e->setPointToPoint(false);

    // add
    ift->addInterface(e, this);
}
void Ieee80211Mac::resetStateVariables ( ) [protected, virtual]

Reset backoff, backoffPeriod and retryCounter for IDLE state.

Referenced by finishCurrentTransmission(), giveUpCurrentTransmission(), and handleWithFSM().

{
    backoffPeriod = 0;
    retryCounter = 0;

    if (!transmissionQueue.empty()) {
        backoff = true;
        getCurrentTransmission()->setRetry(false);
    }
    else {
        backoff = false;
    }
}
void Ieee80211Mac::retryCurrentTransmission ( ) [protected, virtual]

Referenced by handleWithFSM().

void Ieee80211Mac::scheduleBackoffPeriod ( ) [protected, virtual]

Referenced by handleWithFSM().

{
    EV << "scheduling backoff period\n";
    scheduleAt(simTime() + backoffPeriod, endBackoff);
}
void Ieee80211Mac::scheduleBroadcastTimeoutPeriod ( Ieee80211DataOrMgmtFrame *  frame) [protected, virtual]

Referenced by handleWithFSM().

{
    EV << "scheduling broadcast timeout period\n";
    scheduleAt(simTime() + computeFrameDuration(frameToSend), endTimeout);
}
void Ieee80211Mac::scheduleCTSTimeoutPeriod ( ) [protected, virtual]
void Ieee80211Mac::scheduleDataTimeoutPeriod ( Ieee80211DataOrMgmtFrame *  frame) [protected, virtual]

Referenced by handleWithFSM().

{
    EV << "scheduling data timeout period\n";
    scheduleAt(simTime() + computeFrameDuration(frameToSend) + getSIFS() + computeFrameDuration(LENGTH_ACK, basicBitrate) + MAX_PROPAGATION_DELAY * 2, endTimeout);
}
void Ieee80211Mac::scheduleDIFSPeriod ( ) [protected, virtual]

Referenced by handleWithFSM().

{
    if (lastReceiveFailed)
    {
        EV << "receiption of last frame failed, scheduling EIFS period\n";
        scheduleAt(simTime() + getEIFS(), endDIFS);
    }
    else
    {
        EV << "scheduling DIFS period\n";
        scheduleAt(simTime() + getDIFS(), endDIFS);
    }
}
void Ieee80211Mac::scheduleReservePeriod ( Ieee80211Frame *  frame) [protected, virtual]

Schedule network allocation period according to 9.2.5.4.

Referenced by handleWithFSM().

{
    simtime_t reserve = frame->getDuration();

    // see spec. 7.1.3.2
    if (!isForUs(frame) && reserve != 0 && reserve < 32768)
    {
        if (endReserve->isScheduled()) {
            simtime_t oldReserve = endReserve->getArrivalTime() - simTime();

            if (oldReserve > reserve)
                return;

            reserve = std::max(reserve, oldReserve);
            cancelEvent(endReserve);
        }
        else if (radioState == RadioState::IDLE)
        {
            // NAV: the channel just became virtually busy according to the spec
            scheduleAt(simTime(), mediumStateChange);
        }

        EV << "scheduling reserve period for: " << reserve << endl;

        ASSERT(reserve > 0);

        nav = true;
        scheduleAt(simTime() + reserve, endReserve);
    }
}
void Ieee80211Mac::scheduleSIFSPeriod ( Ieee80211Frame *  frame) [protected, virtual]

Referenced by handleWithFSM().

{
    EV << "scheduling SIFS period\n";
    endSIFS->setContextPointer(frame->dup());
    scheduleAt(simTime() + getSIFS(), endSIFS);
}
void Ieee80211Mac::sendACKFrame ( Ieee80211DataOrMgmtFrame *  frame) [protected, virtual]

Referenced by sendACKFrameOnEndSIFS().

{
    EV << "sending ACK frame\n";
    sendDown(setBasicBitrate(buildACKFrame(frameToACK)));
}
void Ieee80211Mac::sendACKFrameOnEndSIFS ( ) [protected, virtual]

Referenced by handleWithFSM().

{
    Ieee80211Frame *frameToACK = (Ieee80211Frame *)endSIFS->getContextPointer();
    endSIFS->setContextPointer(NULL);
    sendACKFrame(check_and_cast<Ieee80211DataOrMgmtFrame*>(frameToACK));
    delete frameToACK;
}
void Ieee80211Mac::sendBroadcastFrame ( Ieee80211DataOrMgmtFrame *  frameToSend) [protected, virtual]

Referenced by handleWithFSM().

{
    EV << "sending Broadcast frame\n";
    sendDown(buildBroadcastFrame(frameToSend));
}
void Ieee80211Mac::sendCTSFrame ( Ieee80211RTSFrame *  rtsFrame) [protected, virtual]

Referenced by sendCTSFrameOnEndSIFS().

{
    EV << "sending CTS frame\n";
    sendDown(setBasicBitrate(buildCTSFrame(rtsFrame)));
}
void Ieee80211Mac::sendCTSFrameOnEndSIFS ( ) [protected, virtual]

Referenced by handleWithFSM().

{
    Ieee80211Frame *rtsFrame = (Ieee80211Frame *)endSIFS->getContextPointer();
    endSIFS->setContextPointer(NULL);
    sendCTSFrame(check_and_cast<Ieee80211RTSFrame*>(rtsFrame));
    delete rtsFrame;
}
void Ieee80211Mac::sendDataFrame ( Ieee80211DataOrMgmtFrame *  frameToSend) [protected, virtual]

Referenced by handleWithFSM(), and sendDataFrameOnEndSIFS().

{
    EV << "sending Data frame\n";
    sendDown(buildDataFrame(frameToSend));
}
void Ieee80211Mac::sendDataFrameOnEndSIFS ( Ieee80211DataOrMgmtFrame *  frameToSend) [protected, virtual]

Referenced by handleWithFSM().

{
    Ieee80211Frame *ctsFrame = (Ieee80211Frame *)endSIFS->getContextPointer();
    endSIFS->setContextPointer(NULL);
    sendDataFrame(frameToSend);
    delete ctsFrame;
}
void Ieee80211Mac::sendDownPendingRadioConfigMsg ( ) [protected, virtual]

Send down the change channel message to the physical layer if there is any.

Referenced by handleWithFSM().

void Ieee80211Mac::sendRTSFrame ( Ieee80211DataOrMgmtFrame *  frameToSend) [protected, virtual]

Referenced by handleWithFSM().

{
    EV << "sending RTS frame\n";
    sendDown(setBasicBitrate(buildRTSFrame(frameToSend)));
}
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().

{
    ASSERT(frame->getControlInfo()==NULL);
    PhyControlInfo *ctrl = new PhyControlInfo();
    ctrl->setBitrate(basicBitrate);
    frame->setControlInfo(ctrl);
    return frame;
}
void Ieee80211Mac::setMode ( Mode  mode) [protected, virtual]

Change the current MAC operation mode.

{
    if (mode == PCF)
        error("PCF mode not yet supported");

    this->mode = mode;
}

Member Data Documentation

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

bool Ieee80211Mac::backoff [protected]

True if backoff is enabled

Referenced by handleWithFSM(), initialize(), logState(), resetStateVariables(), and retryCurrentTransmission().

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

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

Contention window size for broadcast messages.

Referenced by computeBackoffPeriod(), and initialize().

int Ieee80211Mac::cwMinData [protected]

Minimum contention window.

Referenced by computeBackoffPeriod(), and initialize().

cMessage* Ieee80211Mac::endDIFS [protected]

End of the Data Inter-Frame Time period

Referenced by cancelDIFSPeriod(), handleWithFSM(), Ieee80211Mac(), initialize(), scheduleDIFSPeriod(), 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().

const int Ieee80211Mac::fragmentationThreshold = 2346 [static, protected]

Messages longer than this threshold will be sent in multiple fragments. see spec 361

Referenced by handleUpperMsg().

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

int Ieee80211Mac::maxQueueSize [protected]

Maximum number of frames in the queue; should be set in the omnetpp.ini

Referenced by handleUpperMsg(), and initialize().

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

Mode Ieee80211Mac::mode [protected]

Referenced by initialize(), logState(), and setMode().

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

long Ieee80211Mac::numCollision [protected]

Referenced by handleWithFSM(), and initialize().

long Ieee80211Mac::numReceived [protected]

Referenced by handleWithFSM(), and initialize().

Referenced by handleWithFSM(), and initialize().

long Ieee80211Mac::numRetry [protected]
long Ieee80211Mac::numSent [protected]

Referenced by handleWithFSM(), and initialize().

Referenced by handleWithFSM(), and initialize().

Referenced by handleWithFSM(), and initialize().

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

Passive queue module to request messages from

Referenced by initializeQueueModule(), and popTransmissionQueue().

Physical radio (medium) state copied from physical layer

Referenced by initialize(), isMediumFree(), isMediumStateChange(), logState(), receiveChangeNotification(), and scheduleReservePeriod().

cOutVector Ieee80211Mac::radioStateVector [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().

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

Sequence number to be assigned to the next frame

Referenced by handleUpperMsg(), and initialize().

cOutVector Ieee80211Mac::stateVector [protected]

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

Messages received from upper layer and to be transmitted later

Referenced by getCurrentTransmission(), handleUpperMsg(), handleWithFSM(), popTransmissionQueue(), and resetStateVariables().


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