Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

Mac80211 Class Reference

#include <Mac80211.h>

Inheritance diagram for Mac80211:

WirelessMacBase INotifiable List of all members.

Detailed Description

An implementation of the 802.11b MAC.

For more info, see the NED file.

Author:
David Raguin


Public Member Functions

 Mac80211 ()
virtual ~Mac80211 ()

Protected Member Functions

virtual int numInitStages () const
 Initialization of the module and some variables.
virtual void initialize (int)
 Initialization of the module and some variables.
void registerInterface ()
 Register the interface in InterfaceTable.
virtual void receiveChangeNotification (int category, cPolymorphic *details)
 Called by the NotificationBoard whenever a change occurs we're interested in.
virtual void handleSelfMsg (cMessage *)
 Handle self messages such as timer...
virtual void handleUpperMsg (cMessage *)
 Handle messages from upper layer.
virtual void handleLowerMsg (cMessage *)
 Handle messages from lower layer.
virtual void handleEndContentionTimer ()
 handle end of contention
void handleMsgNotForMe (Mac80211Pkt *)
 handle a message that is not for me or errornous
void handleMsgForMe (Mac80211Pkt *)
 handle a message that was meant for me
void handleBroadcastMsg (Mac80211Pkt *)
void handleEndTransmissionTimer ()
 handle the end of a transmission...
void handleEndSifsTimer ()
 handle end of SIFS
void handleTimeoutTimer ()
 handle time out
void handleNavTimer ()
 NAV timer expired, the exchange of messages of other stations is done.
void handleRTSframe (Mac80211Pkt *)
void handleDATAframe (Mac80211Pkt *)
void handleACKframe (Mac80211Pkt *)
void handleCTSframe (Mac80211Pkt *)
virtual void sendDATAframe ()
 send data frame
void sendACKframe (Mac80211Pkt *)
 send Acknoledgement
void sendCTSframe (Mac80211Pkt *)
 send CTS frame
virtual void sendRTSframe ()
 send RTS frame
void sendBROADCASTframe ()
 send broadcast frame
Mac80211Pkt * encapsMsg (cMessage *netw)
 encapsulate packet
void decapsulateAndSendUp (Mac80211Pkt *frame)
 decapsulate packet and send to higher layer
virtual Mac80211Pkt * buildDATAframe ()
 build a data frame
Mac80211Pkt * buildACKframe (Mac80211Pkt *)
 build an ACK
Mac80211Pkt * buildCTSframe (Mac80211Pkt *)
 build a CTS frame
virtual Mac80211Pkt * buildRTSframe ()
 build an RTS frame
Mac80211Pkt * buildBROADCASTframe ()
 build a broadcast frame
virtual void beginNewCycle ()
 start a new contention period
double backoff ()
 Compute a backoff value.
int contentionWindow ()
 Compute a new contention window.
void testMaxAttempts ()
 Test if maximum number of retries to transmit is exceeded.
double timeOut (_802_11frameType type, double last_frame_duration)
 return a timeOut value for a certain type of frame
double packetDuration (int bits)
 computes the duration of a transmission over the physical channel
const char * stateName (State state)
 Produce a readable name of the given state.
void setState (State state)
 Sets the state, and produces a log message in between.

Protected Attributes

MACAddress myMacAddr
 mac address
cMessage * timeout
 Timer used for time-outs after the transmission of a RTS, a CTS, or a DATA packet.
cMessage * nav
 Timer used for the defer time of a node. Also called NAV : networks allocation vector.
cMessage * contention
 Timer used for contention periods.
cMessage * endTransmission
 Timer used to indicate the end of the transmission of an ACK or a BROADCAST packet.
cMessage * endSifs
 Timer used to indicate the end of a SIFS.
double EIFS
 extended interframe space
double BW
 Variable to store the current backoff value.
State state
 Current state of the MAC.
RadioState::States radioState
 Current state of the radio (kept updated by receiveChangeNotification()).
int maxQueueSize
 Maximal number of packets in the queue; should be set in the omnetpp.ini.
bool nextIsBroadcast
 Boolean used to know if the next packet is a broadcast packet.
MacPktList fromUpperLayer
 Buffering of messages from upper layer.
int retryCounter
 Number of frame transmission attempt.
bool tryWithoutBackoff
 If there's a new packet to send and the channel is free, no backoff is needed.
bool rtsCts
 true if Rts/Cts is used, false if not; can be set in omnetpp.ini
double delta
 Very small value used in timer scheduling in order to avoid multiple changements of state in the same simulation time.
double bitrate
 The bitrate should be set in omnetpp.ini; be sure to use a valid 802.11 bitrate.
int broadcastBackoff
 Should be set in the omnetpp.ini.

Private Types

typedef std::list< Mac80211Pkt * > MacPktList
enum  timerType {
  TIMEOUT, NAV, CONTENTION, END_TRANSMISSION,
  END_SIFS
}
enum  State {
  WFDATA = 0, QUIET = 1, IDLE = 2, CONTEND = 3,
  WFCTS = 4, WFACK = 5, BUSY = 6
}


Member Typedef Documentation

typedef std::list<Mac80211Pkt*> Mac80211::MacPktList [private]
 


Member Enumeration Documentation

enum Mac80211::State [private]
 

Definition of the states

Enumeration values:
WFDATA 
QUIET 
IDLE 
CONTEND 
WFCTS 
WFACK 
BUSY 
00054                {
00055       WFDATA = 0, // waiting for data packet
00056       QUIET = 1,  // waiting for the communication between two other nodes to end
00057       IDLE = 2,   // no packet to send, no packet receiving
00058       CONTEND = 3,// contention state (battle for the channel)
00059       WFCTS = 4,  // RTS sent, waiting for CTS
00060       WFACK = 5,  // DATA packet sent, waiting for ACK
00061       BUSY = 6    // during transmission of an ACK or a BROADCAST packet
00062     };

enum Mac80211::timerType [private]
 

Definition of the timer types

Enumeration values:
TIMEOUT 
NAV 
CONTENTION 
END_TRANSMISSION 
END_SIFS 
00045                    {
00046       TIMEOUT,
00047       NAV,
00048       CONTENTION,
00049       END_TRANSMISSION,
00050       END_SIFS
00051     };


Constructor & Destructor Documentation

Mac80211::Mac80211  ) 
 

00032 {
00033     timeout = nav = contention = endTransmission = endSifs = NULL;
00034 }

Mac80211::~Mac80211  )  [virtual]
 

00037 {
00038     cancelAndDelete(timeout);
00039     cancelAndDelete(nav);
00040     cancelAndDelete(contention);
00041     cancelAndDelete(endTransmission);
00042     cancelAndDelete(endSifs);
00043 }


Member Function Documentation

double Mac80211::backoff  )  [protected]
 

Compute a backoff value.

Compute the backoff value.

00829 {
00830     // the MAC has won the previous contention. We have to compute a new
00831     // backoff window
00832     if (BW == 0)
00833         BW = ((double) intrand(contentionWindow() + 1)) * ST;
00834     // CW is the contention window (see the function). ST is the
00835     // slot time.  else we take the old value of BW, in order to give a
00836     // bigger priority to a node which has lost a previous contention
00837     // period.
00838     EV << "backing off for: " << BW + DIFS << endl;
00839     return BW;
00840 }

void Mac80211::beginNewCycle  )  [protected, virtual]
 

start a new contention period

Start a new contention period if the channel is free and if there's a packet to send. Called at the end of a deferring period, a busy period, or after a failure. Called by the HandleMsgForMe(), HandleTimer() HandleUpperMsg(), and, without RTS/CTS, by handleMsgNotForMe().

00783 {
00784     // before trying to send one more time a packet, test if the
00785     // maximum retry limit is reached. If it is the case, then
00786     // delete the packet and send the next packet.
00787     testMaxAttempts();
00788 
00789     if (!fromUpperLayer.empty())
00790     {
00791 
00792         // look if the next packet is unicast or broadcast
00793         nextIsBroadcast = (((Mac80211Pkt *) fromUpperLayer.front())->getDestAddr().isBroadcast());
00794 
00795         // print("next is broadcast = "<<nextIsBroadcast);
00796 
00797         // if the channel is free then wait a random time and transmit
00798         if (radioState == RadioState::IDLE)
00799         {
00800             // if channel is idle AND I was not the last one that transmitted
00801             // data: no backoff
00802             if (tryWithoutBackoff)
00803             {
00804                 EV << "trying to send without backoff...\n";
00805                 scheduleAt(simTime() + DIFS, contention);
00806             }
00807             else
00808             {
00809                 // backoff!
00810                 scheduleAt(simTime() + backoff() + DIFS, contention);
00811             }
00812         }
00813         tryWithoutBackoff = false;
00814 
00815         // else wait until the channel gets free; the state is now contend
00816         setState(CONTEND);
00817     }
00818     else
00819     {
00820         tryWithoutBackoff = false;
00821         setState(IDLE);
00822     }
00823 }

Mac80211Pkt * Mac80211::buildACKframe Mac80211Pkt *  af  )  [protected]
 

build an ACK

Build an ACK frame. Called by sendACKframe()

00711 {
00712     Mac80211Pkt *frame = new Mac80211Pkt("wlan-ack");
00713     frame->setKind(ACK);
00714     frame->setLength(LENGTH_ACK);
00715 
00716     // the dest address must be the src adress of the RTS or the DATA
00717     // packet received. The src adress is the adress of the node
00718     frame->setSrcAddr(myMacAddr);
00719     frame->setDestAddr(af->getSrcAddr());
00720     frame->setDuration(0);
00721 
00722     return frame;
00723 }

Mac80211Pkt * Mac80211::buildBROADCASTframe  )  [protected]
 

build a broadcast frame

Build a BROADCAST frame. Called sendBROADCASTframe()

00767 {
00768     // send a copy of the frame in front of the queue
00769     Mac80211Pkt *frame = (Mac80211Pkt *) (fromUpperLayer.front())->dup();
00770     frame->setKind(BROADCAST);
00771     return frame;
00772 }

Mac80211Pkt * Mac80211::buildCTSframe Mac80211Pkt *  af  )  [protected]
 

build a CTS frame

Build a CTS frame. Called by sendCTSframe()

00749 {
00750     Mac80211Pkt *frame = new Mac80211Pkt("wlan-cts");
00751     frame->setKind(CTS);
00752     frame->setLength(LENGTH_CTS);
00753 
00754     // the dest adress must be the src adress of the RTS received. The
00755     // src adress is the adress of the node
00756     frame->setSrcAddr(myMacAddr);
00757     frame->setDestAddr(af->getSrcAddr());
00758     frame->setDuration(af->getDuration() - SIFS - packetDuration(LENGTH_CTS));
00759 
00760     return frame;
00761 }

Mac80211Pkt * Mac80211::buildDATAframe  )  [protected, virtual]
 

build a data frame

Build a DATA frame. Called by sendDATAframe()

00693 {
00694     // build a copy of the frame in front of the queue
00695     Mac80211Pkt *frame = (Mac80211Pkt *) (fromUpperLayer.front())->dup();
00696     frame->setSrcAddr(myMacAddr);
00697     frame->setKind(DATA);
00698     if (rtsCts)
00699         frame->setDuration(SIFS + packetDuration(LENGTH_ACK));
00700     else
00701         frame->setDuration(0);
00702 
00703     return frame;
00704 }

Mac80211Pkt * Mac80211::buildRTSframe  )  [protected, virtual]
 

build an RTS frame

Build a RTS frame. Called by sendRTSframe()

00730 {
00731     Mac80211Pkt *frame = new Mac80211Pkt("wlan-rts");
00732     frame->setKind(RTS);
00733     frame->setLength(LENGTH_RTS);
00734 
00735     // the src adress and dest address are copied in the frame in the queue (frame to be sent)
00736     frame->setSrcAddr(((Mac80211Pkt *) fromUpperLayer.front())->getSrcAddr());
00737     frame->setDestAddr(((Mac80211Pkt *) fromUpperLayer.front())->getDestAddr());
00738     frame->setDuration(3 * SIFS + packetDuration(LENGTH_CTS) +
00739                        packetDuration(fromUpperLayer.front()->length()) +
00740                        packetDuration(LENGTH_ACK));
00741 
00742     return frame;
00743 }

int Mac80211::contentionWindow  )  [protected]
 

Compute a new contention window.

Compute the contention window with the binary backoff algorithm. Use the variable counter (attempts to transmit packet), the constant values CWmax (contention window maximum) and m (parameter for the initial backoff window, usally m=7). Called by backoff()

00850 {
00851     // the next packet is an unicast packet
00852     if (!nextIsBroadcast)
00853     {
00854         int cw;
00855         cw = (CW_MIN + 1) * (unsigned int) pow(2.0, (int) retryCounter - 1) - 1;
00856         // return the calculated value or CWmax if the maximal value is reached
00857         if (cw <= CW_MAX)
00858             return cw;
00859         else
00860             return CW_MAX;
00861     }
00862 
00863     // the next packet is broadcast : the contention window must be maximal
00864     else
00865         return broadcastBackoff;
00866 }

void Mac80211::decapsulateAndSendUp Mac80211Pkt *  frame  )  [protected]
 

decapsulate packet and send to higher layer

00187 {
00188     cMessage *msg = frame->decapsulate();
00189     // FIXME TBD set control info
00190     delete frame;
00191     sendUp(msg);
00192 }

Mac80211Pkt * Mac80211::encapsMsg cMessage *  netw  )  [protected]
 

encapsulate packet

Encapsulates the received network-layer packet into a MacPkt and set all needed header fields.

00168 {
00169     Mac80211Pkt *pkt = new Mac80211Pkt(netw->name());
00170     pkt->setLength(272);        // headerLength, including final CRC-field
00171 
00172     // copy dest address from the control info
00173     Ieee802Ctrl *ctrl = check_and_cast<Ieee802Ctrl *>(netw->removeControlInfo());
00174     pkt->setDestAddr(ctrl->getDest());
00175     delete ctrl;
00176 
00177     // set the src address to own mac address (nic module id())
00178     pkt->setSrcAddr(myMacAddr);
00179 
00180     // encapsulate the network packet
00181     pkt->encapsulate(netw);
00182 
00183     return pkt;
00184 }

void Mac80211::handleACKframe Mac80211Pkt *  af  )  [protected]
 

Handle a frame which is expected to be an ACK.Called by HandleMsgForMe(MAcawFrame* af)

00439 {
00440     // cancel time-out event
00441     cancelEvent(timeout);
00442 
00443     // the the transmission is acknowledged : initialize long_retry_counter
00444     retryCounter = 1;
00445 
00446     // removes the acknowledged packet from the queue
00447     Mac80211Pkt *temp = fromUpperLayer.front();
00448     fromUpperLayer.pop_front();
00449     delete temp;
00450 
00451     // if thre's a packet to send and if the channel is free then start a new contention period
00452     beginNewCycle();
00453 }

void Mac80211::handleBroadcastMsg Mac80211Pkt *  af  )  [protected]
 

Handle a broadcast packet. This packet is simply passed to the upper layer. No acknowledgement is needed. Called by handleLowerMsg(Mac80211Pkt *af)

00476 {
00477     EV << "handle broadcast\n";
00478     if (state == BUSY)
00479         error("logic error: node is currently transmitting, can not receive "
00480               "(does the physical layer do its job correctly?)");
00481 
00482     decapsulateAndSendUp(af);
00483     if (state == CONTEND)
00484         beginNewCycle();
00485 }

void Mac80211::handleCTSframe Mac80211Pkt *  af  )  [protected]
 

Handle a CTS frame. Called by HandleMsgForMe(Mac80211Pkt* af)

00460 {
00461     // cancel time-out event
00462     cancelEvent(timeout);
00463 
00464     // wait a short interframe space
00465     endSifs->setContextPointer(af);
00466     scheduleAt(simTime() + SIFS, endSifs);
00467 }

void Mac80211::handleDATAframe Mac80211Pkt *  af  )  [protected]
 

Handle a frame which expected to be a DATA frame. Called by HandleMsgForMe()

00418 {
00419     if (rtsCts)
00420         cancelEvent(timeout);  // cancel time-out event
00421 
00422     // make a copy
00423     Mac80211Pkt *copy = (Mac80211Pkt *) af->dup();
00424 
00425     // pass the packet to the upper layer
00426     decapsulateAndSendUp(af);
00427 
00428     // wait a short interframe space
00429     endSifs->setContextPointer(copy);
00430     scheduleAt(simTime() + SIFS, endSifs);
00431 }

void Mac80211::handleEndContentionTimer  )  [protected, virtual]
 

handle end of contention

The node has won the contention, and is now allowed to send an RTS/DATA or Broadcast packet. The backoff value is deleted and will be newly computed in the next contention period

00494 {
00495     if (state != CONTEND)
00496         error("logic error: expiration of the contention timer outside of CONTEND state, should not happen");
00497 
00498     // the node has won the channel, the backoff window is deleted and
00499     // will be new calculated in the next contention period
00500     BW = 0;
00501     // unicast packet
00502     if (!nextIsBroadcast)
00503     {
00504         if (rtsCts)
00505         {
00506             // send a RTS
00507             sendRTSframe();
00508             setState(WFCTS);
00509         }
00510         else
00511         {
00512             sendDATAframe();
00513             setState(WFACK);
00514         }
00515 
00516         // broadcast packet
00517     }
00518     else
00519     {
00520         sendBROADCASTframe();
00521 
00522         // removes the packet from the queue without waiting for an acknowledgement
00523         Mac80211Pkt *temp = fromUpperLayer.front();
00524         fromUpperLayer.pop_front();
00525         delete(temp);
00526     }
00527 }

void Mac80211::handleEndSifsTimer  )  [protected]
 

handle end of SIFS

Handle the end sifs timer. Then sends a CTS, a DATA, or an ACK frame

00562 {
00563     Mac80211Pkt *frame = (Mac80211Pkt *) endSifs->contextPointer();
00564 
00565     switch (frame->kind())
00566     {
00567     case RTS:
00568         sendCTSframe(frame);
00569         break;
00570     case CTS:
00571         sendDATAframe();
00572         break;
00573     case DATA:
00574         sendACKframe(frame);
00575         break;
00576     default:
00577         error("logic error: end sifs timer when previously received packet is not RTS/CTS/DATA");
00578     }
00579 
00580     // don't need previous frame any more
00581     delete frame;
00582 }

void Mac80211::handleEndTransmissionTimer  )  [protected]
 

handle the end of a transmission...

Handle the end of transmission timer (end of the transmission of an ACK or a broadcast packet). Called by HandleTimer(cMessage* msg)

00590 {
00591     EV << "transmission of ACK/BROADCAST is over\n";
00592     if (state != BUSY)
00593         error("logic error: expiration of the end transmission timer outside the BUSY state, should not happen");
00594 
00595     // if there's a packet to send and if the channel is free, then start a new contention period
00596     beginNewCycle();
00597 }

void Mac80211::handleLowerMsg cMessage *  msg  )  [protected, virtual]
 

Handle messages from lower layer.

Handle all messages from lower layer. Checks the destination MAC adress of the packet. Then calls one of the three functions : handleMsgNotForMe(), handleBroadcastMsg(), or handleMsgForMe(). Called by handleMessage().

Implements WirelessMacBase.

00201 {
00202     Mac80211Pkt *af = check_and_cast<Mac80211Pkt *>(msg);
00203 
00204     // end of the reception
00205     EV << "frame " << af << " received\n";
00206 
00207     switch (af->kind())
00208     {
00209     case COLLISION: // packet lost or bit error
00210         delete af;
00211         if (state == CONTEND)
00212             beginNewCycle();
00213         break;
00214 
00215     case BITERROR:
00216         handleMsgNotForMe(af);
00217         break;
00218 
00219     case BROADCAST: // broadcast packet
00220         handleBroadcastMsg(af);
00221         break;
00222 
00223     default: // other packet
00224         if (af->getDestAddr() == myMacAddr)  // FIXME verify broadcast dest addr works!
00225             handleMsgForMe(af);
00226         else
00227             handleMsgNotForMe(af);
00228     }
00229 }

void Mac80211::handleMsgForMe Mac80211Pkt *  af  )  [protected]
 

handle a message that was meant for me

Handle a packet for the node. The result of this reception is a function of the type of the received message (RTS,CTS,DATA, or ACK), and of the current state of the MAC (WFDATA, CONTEND, IDLE, WFCTS, or WFACK). Called by handleLowerMsg()

00342 {
00343     EV << "handle msg for me\n";
00344 
00345     switch (state)
00346     {
00347     case IDLE:     // waiting for the end of the contention period
00348     case CONTEND:  // or waiting for RTS
00349 
00350         // RTS or DATA accepted
00351         if (af->kind() == RTS)
00352             handleRTSframe(af);
00353         else if (af->kind() == DATA)
00354             handleDATAframe(af);
00355         else
00356             EV << "in handleMsgForMe() IDLE/CONTEND, strange message, darf das?\n";
00357         break;
00358 
00359     case WFDATA:  // waiting for DATA
00360 
00361         if (af->kind() == DATA)
00362             handleDATAframe(af);
00363         else
00364             EV << "in handleMsgForMe() WFDATA, strange message, darf das?\n";
00365         break;
00366 
00367     case WFACK:  // waiting for ACK
00368 
00369         if (af->kind() == ACK)
00370             handleACKframe(af);
00371         else
00372             EV << "in handleMsgForMe() WFACK, strange message, darf das?\n";
00373         delete af;
00374         break;
00375 
00376     case WFCTS:  // The MAC is waiting for CTS
00377 
00378         if (af->kind() == CTS)
00379             handleCTSframe(af);
00380         else
00381             EV << "in handleMsgForMe() WFCTS, strange message, darf das?\n";
00382         break;
00383 
00384 
00385     case QUIET: // the node is currently deferring.
00386 
00387         // cannot handle any packet with its MAC adress
00388         delete af;
00389         break;
00390 
00391     case BUSY: // currently transmitting an ACK or a BROADCAST packet
00392         error("logic error: node is currently transmitting, can not receive "
00393               "(does the physical layer do its job correctly?)");
00394         break;
00395 
00396     default:
00397         error("unknown state %d", state);
00398     }
00399 }

void Mac80211::handleMsgNotForMe Mac80211Pkt *  af  )  [protected]
 

handle a message that is not for me or errornous

Handle all ACKs,RTS, CTS, or DATA not for the node. If RTS/CTS is used the node must stay quiet until the current handshake between the two communicating nodes is over. This is done by scheduling the timer message nav (Network Allocation Vector). Without RTS/CTS a new contention is started. If an error occured the node must defer for EIFS. Called by handleLowerMsg()

00276 {
00277     EV << "handle msg not for me\n";
00278 
00279     // if this packet  can not be correctly read
00280     if (af->kind() == BITERROR)
00281         af->setDuration(EIFS);
00282 
00283     // if the duration of the packet is null, then do nothing (to avoid
00284     // the unuseful scheduling of a self message)
00285     if (af->getDuration() != 0)
00286     {
00287 
00288         // the node is already deferring
00289         if (state == QUIET)
00290         {
00291             // the current value of the NAV is not sufficient
00292             if (nav->arrivalTime() < simTime() + af->getDuration())
00293             {
00294                 cancelEvent(nav);
00295                 scheduleAt(simTime() + af->getDuration(), nav);
00296                 EV << "NAV timer started for: " << af->getDuration() << " State QUIET\n";
00297             }
00298         }
00299 
00300         // other states
00301         else
00302         {
00303             // if the MAC wait for another frame, it can delete its time out
00304             // (exchange is aborted)
00305             if (timeout->isScheduled())
00306                 cancelEvent(timeout);
00307 
00308             // is state == WFCTS or WFACK, the data transfer has failed ...
00309 
00310             // the node must defer for the time of the transmission
00311             scheduleAt(simTime() + af->getDuration(), nav);
00312             EV << "NAV timer started, not QUIET: " << af->getDuration() << endl;
00313             setState(QUIET);
00314 
00315         }
00316     }
00317     if (!rtsCts)
00318     {                           // todo: Nachgucken: was passiert bei Error ohne rtsCts!
00319         if (state == CONTEND)
00320         {
00321             if (af->kind() == BITERROR)
00322             {
00323                 if (contention->isScheduled())
00324                     cancelEvent(contention);
00325                 scheduleAt(simTime() + backoff() + EIFS, contention);
00326             }
00327             else
00328                 beginNewCycle();
00329         }
00330     }
00331     delete af;
00332 }

void Mac80211::handleNavTimer  )  [protected]
 

NAV timer expired, the exchange of messages of other stations is done.

Handle the NAV timer (end of a defering period). Called by HandleTimer(cMessage* msg)

00534 {
00535     if (state != QUIET)
00536         error("logic error: expiration of the NAV timer outside of the state QUIET, should not happen");
00537 
00538     // if there's a packet to send and if the channel is free, then start a new contention period
00539     beginNewCycle();
00540 }

void Mac80211::handleRTSframe Mac80211Pkt *  af  )  [protected]
 

Handle aframe wich is expected to be an RTS. Called by HandleMsgForMe()

00406 {
00407     // wait a short interframe space
00408     endSifs->setContextPointer(af);
00409     scheduleAt(simTime() + SIFS, endSifs);
00410 }

void Mac80211::handleSelfMsg cMessage *  msg  )  [protected, virtual]
 

Handle self messages such as timer...

handle timers

Implements WirelessMacBase.

00235 {
00236     switch (msg->kind())
00237     {
00238     case END_SIFS:
00239         handleEndSifsTimer();   // noch zu betrachten
00240         break;
00241 
00242     case END_TRANSMISSION:
00243         handleEndTransmissionTimer();   // noch zu betrachten
00244         break;
00245 
00246     case CONTENTION:
00247         handleEndContentionTimer();
00248         break;
00249 
00250         // the MAC was waiting for a CTS, a DATA, or an ACK packet but the timer has expired.
00251     case TIMEOUT:
00252         handleTimeoutTimer();   // noch zu betrachten..
00253         break;
00254 
00255         // the MAC was waiting because an other communication had won the channel. This communication is now over
00256     case NAV:
00257         handleNavTimer();       // noch zu betrachten...
00258         break;
00259 
00260     default:
00261         error("unknown timer type");
00262     }
00263 }

void Mac80211::handleTimeoutTimer  )  [protected]
 

handle time out

Handle the time out timer. Called by handleTimer(cMessage* msg)

00547 {
00548     // if (state == WFCTS || state == WFACK)testMaxAttempts();
00549 
00550     // if there's a packet to send and if the channel is free then
00551     // start a new contention period
00552     if (state != QUIET)
00553         beginNewCycle();
00554 }

void Mac80211::handleUpperMsg cMessage *  msg  )  [protected, virtual]
 

Handle messages from upper layer.

This implementation does not support fragmentation, so it is tested if the maximum length of the MPDU is exceeded.

Implements WirelessMacBase.

00135 {
00136     if (msg->byteLength() > 2312)
00137         error("packet from higher layer (%s)%s is too long for 802.11b, %d bytes (fragmentation is not supported yet)",
00138               msg->className(), msg->name(), msg->byteLength());
00139 
00140     if (maxQueueSize && fromUpperLayer.size() == maxQueueSize)
00141     {
00142         EV << "packet " << msg << " received from higher layer but MAC queue is full, deleting\n";
00143         delete msg;
00144         return;
00145     }
00146 
00147     Mac80211Pkt *mac = encapsMsg(msg);
00148     EV << "packet " << msg << " received from higher layer, dest=" << mac->getDestAddr() << ", encapsulated\n";
00149 
00150     fromUpperLayer.push_back(mac);
00151     // If the MAC is in the IDLE state, then start a new contention period
00152     if (state == IDLE && !endSifs->isScheduled())
00153     {
00154         tryWithoutBackoff = true;
00155         beginNewCycle();
00156     }
00157     else
00158     {
00159         EV << "enqueued, will be transmitted later\n";
00160     }
00161 }

void Mac80211::initialize int   )  [protected, virtual]
 

Initialization of the module and some variables.

Reimplemented from WirelessMacBase.

00046 {
00047     WirelessMacBase::initialize(stage);
00048 
00049     if (stage == 0)
00050     {
00051         EV << "Initializing stage 0\n";
00052         maxQueueSize = par("maxQueueSize");
00053 
00054         // subscribe for the information of the carrier sense
00055         nb->subscribe(this, NF_RADIOSTATE_CHANGED);
00056 
00057         // timers
00058         timeout = new cMessage("timeout", TIMEOUT);
00059         nav = new cMessage("NAV", NAV);
00060         contention = new cMessage("contention", CONTENTION);
00061         endTransmission = new cMessage("transmission", END_TRANSMISSION);
00062         endSifs = new cMessage("end SIFS", END_SIFS);
00063 
00064         BW = 0;
00065         state = IDLE;
00066         retryCounter = 1;
00067         broadcastBackoff = par("broadcastBackoff");
00068         rtsCts = par("rtsCts");
00069         bitrate = par("bitrate");
00070         delta = 1E-9;
00071 
00072         radioState = RadioState::IDLE; // until 1st receiveChangeNotification()
00073 
00074         EIFS = SIFS + DIFS + packetDuration(LENGTH_ACK);
00075         EV << "SIFS: " << SIFS << " DIFS: " << DIFS << " EIFS: " << EIFS << endl;
00076 
00077         // get registered in InterfaceTable
00078         registerInterface();
00079     }
00080 }

virtual int Mac80211::numInitStages  )  const [inline, protected, virtual]
 

Initialization of the module and some variables.

00070 {return 2;}

double Mac80211::packetDuration int  bits  )  [protected]
 

computes the duration of a transmission over the physical channel

Computes the duration of the transmission of a frame over the physical channel. 'bits' should be the total length of the MAC packet in bits.

00978 {
00979     return bits / bitrate + PHY_HEADER_LENGTH / BITRATE_HEADER;
00980 }

void Mac80211::receiveChangeNotification int  category,
cPolymorphic *  details
[protected, virtual]
 

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

Handle change nofitications. In this layer it is usually information about the radio channel, i.e. if it is IDLE etc.

Implements INotifiable.

00894 {
00895     Enter_Method("receiveChangeNotification(%s, %s)", notificationCategoryName(category),
00896                  details?details->info().c_str() : "n/a");
00897 
00898     if (category == NF_RADIOSTATE_CHANGED)
00899     {
00900         // update the local copy of the radio state
00901         radioState = check_and_cast<RadioState *>(details)->getState();
00902 
00903         // NOTE: we may be invoked during INIT STAGE 1 too, when SnrEval notifies us
00904         // about the initial radio state. This function has to work correctly
00905         // even when called during initialization phase!
00906 
00907         EV << "** Radio state update in " << className() << ": " << details->info()
00908            << " (at T=" << simtimeToStr(simTime()) << ")\n";
00909 
00910         // beginning of a reception
00911         if (radioState == RadioState::RECV)
00912         {
00913             // if there's a contention period
00914             if (contention->isScheduled())
00915             {
00916                 // update the backoff window in order to give higher priority in
00917                 // the next battle
00918                 if (simTime() - contention->sendingTime() >= DIFS)
00919                 {
00920                     BW = contention->arrivalTime() - simTime();
00921                     EV << "Backoff window made smaller, new BW: " << BW << endl;
00922                 }
00923                 cancelEvent(contention);
00924             }
00925 
00926             // if there's a SIFS period
00927             if (endSifs->isScheduled())
00928             {
00929                 // delete the previously received frame
00930                 delete (Mac80211Pkt *)endSifs->contextPointer();
00931 
00932                 // cancel the next transmission
00933                 cancelEvent(endSifs);
00934 
00935                 // state in now IDLE or CONTEND
00936                 if (fromUpperLayer.empty())
00937                     setState(IDLE);
00938                 else
00939                     setState(CONTEND);
00940             }
00941         }
00942     }
00943 }

void Mac80211::registerInterface  )  [protected]
 

Register the interface in InterfaceTable.

00084 {
00085     InterfaceEntry *e = new InterfaceEntry();
00086 
00087     // interface name: NetworkInterface module's name without special characters ([])
00088     char *interfaceName = new char[strlen(parentModule()->fullName()) + 1];
00089     char *d = interfaceName;
00090     for (const char *s = parentModule()->fullName(); *s; s++)
00091         if (isalnum(*s))
00092             *d++ = *s;
00093     *d = '\0';
00094 
00095     e->setName(interfaceName);
00096     delete [] interfaceName;
00097 
00098     const char *addrstr = par("address");
00099     if (!strcmp(addrstr, "auto"))
00100     {
00101         // assign automatic address
00102         myMacAddr = MACAddress::generateAutoAddress();
00103 
00104         // change module parameter from "auto" to concrete address
00105         par("address").setStringValue(myMacAddr.str().c_str());
00106     }
00107     else
00108     {
00109         myMacAddr.setAddress(addrstr);
00110     }
00111     e->setMACAddress(myMacAddr);
00112 
00113     // generate interface identifier for IPv6
00114     e->setInterfaceToken(myMacAddr.formInterfaceIdentifier());
00115 
00116     // MTU on 802.11 = ?
00117     e->setMtu(1500);            // FIXME
00118 
00119     // capabilities
00120     e->setBroadcast(true);
00121     e->setMulticast(true);
00122     e->setPointToPoint(false);
00123 
00124     // add
00125     InterfaceTable *ift = InterfaceTableAccess().get();
00126     ift->addInterface(e, this);
00127 }

void Mac80211::sendACKframe Mac80211Pkt *  af  )  [protected]
 

send Acknoledgement

Send an ACK frame.Called by HandleEndSifsTimer()

00625 {
00626     // the MAC must wait the end of the transmission before beginning an
00627     // other contention period
00628     scheduleAt(simTime() + packetDuration(LENGTH_ACK) + delta, endTransmission);
00629 
00630     // send ACK frame
00631     sendDown(buildACKframe(af));
00632     EV << "sent ACK frame!\n";
00633 
00634     // update state and display
00635     setState(BUSY);
00636 }

void Mac80211::sendBROADCASTframe  )  [protected]
 

send broadcast frame

Send a BROADCAST frame.Called by handleContentionTimer()

00677 {
00678     // the MAC must wait the end of the transmission before beginning any
00679     // other contention period
00680     scheduleAt(simTime() + packetDuration(fromUpperLayer.front()->length()), endTransmission);
00681     // send ACK frame
00682     sendDown(buildBROADCASTframe());
00683 
00684     // update state and display
00685     setState(BUSY);
00686 }

void Mac80211::sendCTSframe Mac80211Pkt *  af  )  [protected]
 

send CTS frame

Send a CTS frame.Called by HandleEndSifsTimer()

00662 {
00663     // schedule time-out
00664     scheduleAt(simTime() + timeOut(CTS, af->getDuration()), timeout);
00665 
00666     // send CTS frame
00667     sendDown(buildCTSframe(af));
00668 
00669     // update state and display
00670     setState(WFDATA);
00671 }

void Mac80211::sendDATAframe  )  [protected, virtual]
 

send data frame

Send a DATA frame. Called by HandleEndSifsTimer() or handleEndContentionTimer()

00605 {
00606     // schedule time out
00607     scheduleAt(simTime() + timeOut(DATA, 0), timeout);
00608 
00609     if (!rtsCts)
00610         // retryCounter incremented
00611         retryCounter++;
00612 
00613     // send DATA frame
00614     sendDown(buildDATAframe());
00615 
00616     // update state and display
00617     setState(WFACK);
00618 }

void Mac80211::sendRTSframe  )  [protected, virtual]
 

send RTS frame

Send a RTS frame.Called by handleContentionTimer()

00643 {
00644     // schedule time-out
00645     scheduleAt(simTime() + timeOut(RTS, 0), timeout);
00646 
00647     // long_retry_counter incremented
00648     retryCounter++;
00649 
00650     // send RTS frame
00651     sendDown(buildRTSframe());
00652 
00653     // update state and display
00654     setState(WFCTS);
00655 }

void Mac80211::setState State  state  )  [protected]
 

Sets the state, and produces a log message in between.

01001 {
01002     if (state==newState)
01003         EV << "staying in state " << stateName(state) << "\n";
01004     else
01005         EV << "state " << stateName(state) << " --> " << stateName(newState) << "\n";
01006     state = newState;
01007 }

const char * Mac80211::stateName State  state  )  [protected]
 

Produce a readable name of the given state.

00983 {
00984 #define CASE(x) case x: s=#x; break
00985     const char *s = "???";
00986     switch (state)
00987     {
00988         CASE(WFDATA);
00989         CASE(QUIET);
00990         CASE(IDLE);
00991         CASE(CONTEND);
00992         CASE(WFCTS);
00993         CASE(WFACK);
00994         CASE(BUSY);
00995     }
00996     return s;
00997 #undef CASE
00998 }

void Mac80211::testMaxAttempts  )  [protected]
 

Test if maximum number of retries to transmit is exceeded.

Test if the maximal retry limit is reached, and delete the frame to send in this case.

00875 {
00876     if (retryCounter > RETRY_LIMIT)
00877     {
00878         // initialize counter
00879         retryCounter = 1;
00880         // reportLost(fromUpperLayer.front());
00881 
00882         // delete the frame to transmit
00883         Mac80211Pkt *temp = fromUpperLayer.front();
00884         fromUpperLayer.pop_front();
00885         delete(temp);
00886     }
00887 }

double Mac80211::timeOut _802_11frameType  type,
double  last_frame_duration
[protected]
 

return a timeOut value for a certain type of frame

Return a time-out value for a type of frame. Called by SendRTSframe, sendCTSframe, etc.

00951 {
00952     double time_out = 0;
00953     switch (type)
00954     {
00955     case RTS:
00956         time_out = SIFS + packetDuration(LENGTH_RTS) + packetDuration(LENGTH_CTS) + delta;
00957         break;
00958     case CTS:
00959         time_out = last_frame_duration - packetDuration(LENGTH_ACK) - 2 * SIFS + delta;
00960         break;
00961     case DATA:
00962         time_out =
00963             SIFS + packetDuration(fromUpperLayer.front()->length()) + packetDuration(LENGTH_ACK) +
00964             delta;
00965         break;
00966     default:
00967         EV << "Unused frame type was given when calling timeOut(), this should not happen!\n";
00968     }
00969     return time_out;
00970 }


Member Data Documentation

double Mac80211::bitrate [protected]
 

The bitrate should be set in omnetpp.ini; be sure to use a valid 802.11 bitrate.

int Mac80211::broadcastBackoff [protected]
 

Should be set in the omnetpp.ini.

double Mac80211::BW [protected]
 

Variable to store the current backoff value.

cMessage* Mac80211::contention [protected]
 

Timer used for contention periods.

double Mac80211::delta [protected]
 

Very small value used in timer scheduling in order to avoid multiple changements of state in the same simulation time.

double Mac80211::EIFS [protected]
 

extended interframe space

cMessage* Mac80211::endSifs [protected]
 

Timer used to indicate the end of a SIFS.

cMessage* Mac80211::endTransmission [protected]
 

Timer used to indicate the end of the transmission of an ACK or a BROADCAST packet.

MacPktList Mac80211::fromUpperLayer [protected]
 

Buffering of messages from upper layer.

int Mac80211::maxQueueSize [protected]
 

Maximal number of packets in the queue; should be set in the omnetpp.ini.

MACAddress Mac80211::myMacAddr [protected]
 

mac address

cMessage* Mac80211::nav [protected]
 

Timer used for the defer time of a node. Also called NAV : networks allocation vector.

bool Mac80211::nextIsBroadcast [protected]
 

Boolean used to know if the next packet is a broadcast packet.

RadioState::States Mac80211::radioState [protected]
 

Current state of the radio (kept updated by receiveChangeNotification()).

int Mac80211::retryCounter [protected]
 

Number of frame transmission attempt.

bool Mac80211::rtsCts [protected]
 

true if Rts/Cts is used, false if not; can be set in omnetpp.ini

State Mac80211::state [protected]
 

Current state of the MAC.

cMessage* Mac80211::timeout [protected]
 

Timer used for time-outs after the transmission of a RTS, a CTS, or a DATA packet.

bool Mac80211::tryWithoutBackoff [protected]
 

If there's a new packet to send and the channel is free, no backoff is needed.


The documentation for this class was generated from the following files:
Generated on Sat Apr 1 20:52:23 2006 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.1