#include <Mac80211.h>
Inheritance diagram for Mac80211:
For more info, see the NED file.
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. | |
const char * | timerTypeName (int type) |
Produce a readable name of the given timer type. | |
const char * | pktTypeName (int type) |
Produce a readable name of the given packet type. | |
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::State | 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 |
TIMEOUT | |
NAV | |
CONTENTION | |
END_TRANSMISSION | |
END_SIFS | |
WFDATA = 0 | |
QUIET = 1 | |
IDLE = 2 | |
CONTEND = 3 | |
WFCTS = 4 | |
WFACK = 5 | |
BUSY = 6 | |
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 } |
typedef std::list<Mac80211Pkt*> Mac80211::MacPktList [private] |
enum Mac80211::State [private] |
Definition of the states
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
00045 { 00046 TIMEOUT, 00047 NAV, 00048 CONTENTION, 00049 END_TRANSMISSION, 00050 END_SIFS 00051 };
Mac80211::Mac80211 | ( | ) |
Mac80211::~Mac80211 | ( | ) | [virtual] |
00037 { 00038 cancelAndDelete(timeout); 00039 cancelAndDelete(nav); 00040 cancelAndDelete(contention); 00041 cancelAndDelete(endTransmission); 00042 cancelAndDelete(endSifs); 00043 }
double Mac80211::backoff | ( | ) | [protected] |
Compute a backoff value.
Compute the backoff value.
00843 { 00844 // the MAC has won the previous contention. We have to compute a new 00845 // backoff window 00846 if (BW == 0) { 00847 int CW = contentionWindow(); 00848 EV << "generating backoff for CW: " << CW << endl; 00849 BW = ((double) intrand(CW + 1)) * ST; 00850 } 00851 // CW is the contention window (see the function). ST is the 00852 // slot time. else we take the old value of BW, in order to give a 00853 // bigger priority to a node which has lost a previous contention 00854 // period. 00855 EV << "backing off for: " << BW + DIFS << endl; 00856 return BW; 00857 }
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().
00795 { 00796 EV << "beginning new contention cycle\n"; 00797 00798 // before trying to send one more time a packet, test if the 00799 // maximum retry limit is reached. If it is the case, then 00800 // delete the packet and send the next packet. 00801 testMaxAttempts(); 00802 00803 if (!fromUpperLayer.empty()) 00804 { 00805 00806 // look if the next packet is unicast or broadcast 00807 nextIsBroadcast = (((Mac80211Pkt *) fromUpperLayer.front())->getDestAddr().isBroadcast()); 00808 00809 // print("next is broadcast = "<<nextIsBroadcast); 00810 00811 // if the channel is free then wait a random time and transmit 00812 if (radioState == RadioState::IDLE) 00813 { 00814 // if channel is idle AND I was not the last one that transmitted 00815 // data: no backoff 00816 if (tryWithoutBackoff) 00817 { 00818 EV << "trying to send without backoff...\n"; 00819 scheduleAt(simTime() + DIFS, contention); 00820 } 00821 else 00822 { 00823 // backoff! 00824 scheduleAt(simTime() + backoff() + DIFS, contention); 00825 } 00826 } 00827 tryWithoutBackoff = false; 00828 00829 // else wait until the channel gets free; the state is now contend 00830 setState(CONTEND); 00831 } 00832 else 00833 { 00834 tryWithoutBackoff = false; 00835 setState(IDLE); 00836 } 00837 }
Mac80211Pkt * Mac80211::buildACKframe | ( | Mac80211Pkt * | af | ) | [protected] |
build an ACK
Build an ACK frame. Called by sendACKframe()
00723 { 00724 Mac80211Pkt *frame = new Mac80211Pkt("wlan-ack"); 00725 frame->setKind(ACK); 00726 frame->setLength(LENGTH_ACK); 00727 00728 // the dest address must be the src adress of the RTS or the DATA 00729 // packet received. The src adress is the adress of the node 00730 frame->setSrcAddr(myMacAddr); 00731 frame->setDestAddr(af->getSrcAddr()); 00732 frame->setDuration(0); 00733 00734 return frame; 00735 }
Mac80211Pkt * Mac80211::buildBROADCASTframe | ( | ) | [protected] |
build a broadcast frame
Build a BROADCAST frame. Called sendBROADCASTframe()
00779 { 00780 // send a copy of the frame in front of the queue 00781 Mac80211Pkt *frame = (Mac80211Pkt *) (fromUpperLayer.front())->dup(); 00782 frame->setKind(BROADCAST); 00783 return frame; 00784 }
Mac80211Pkt * Mac80211::buildCTSframe | ( | Mac80211Pkt * | af | ) | [protected] |
build a CTS frame
Build a CTS frame. Called by sendCTSframe()
00761 { 00762 Mac80211Pkt *frame = new Mac80211Pkt("wlan-cts"); 00763 frame->setKind(CTS); 00764 frame->setLength(LENGTH_CTS); 00765 00766 // the dest adress must be the src adress of the RTS received. The 00767 // src adress is the adress of the node 00768 frame->setSrcAddr(myMacAddr); 00769 frame->setDestAddr(af->getSrcAddr()); 00770 frame->setDuration(af->getDuration() - SIFS - packetDuration(LENGTH_CTS)); 00771 00772 return frame; 00773 }
Mac80211Pkt * Mac80211::buildDATAframe | ( | ) | [protected, virtual] |
build a data frame
Build a DATA frame. Called by sendDATAframe()
00705 { 00706 // build a copy of the frame in front of the queue 00707 Mac80211Pkt *frame = (Mac80211Pkt *) (fromUpperLayer.front())->dup(); 00708 frame->setSrcAddr(myMacAddr); 00709 frame->setKind(DATA); 00710 if (rtsCts) 00711 frame->setDuration(SIFS + packetDuration(LENGTH_ACK)); 00712 else 00713 frame->setDuration(0); 00714 00715 return frame; 00716 }
Mac80211Pkt * Mac80211::buildRTSframe | ( | ) | [protected, virtual] |
build an RTS frame
Build a RTS frame. Called by sendRTSframe()
00742 { 00743 Mac80211Pkt *frame = new Mac80211Pkt("wlan-rts"); 00744 frame->setKind(RTS); 00745 frame->setLength(LENGTH_RTS); 00746 00747 // the src adress and dest address are copied in the frame in the queue (frame to be sent) 00748 frame->setSrcAddr(((Mac80211Pkt *) fromUpperLayer.front())->getSrcAddr()); 00749 frame->setDestAddr(((Mac80211Pkt *) fromUpperLayer.front())->getDestAddr()); 00750 frame->setDuration(3 * SIFS + packetDuration(LENGTH_CTS) + 00751 packetDuration(fromUpperLayer.front()->length()) + 00752 packetDuration(LENGTH_ACK)); 00753 00754 return frame; 00755 }
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()
00867 { 00868 // the next packet is an unicast packet 00869 if (!nextIsBroadcast) 00870 { 00871 int cw = (CW_MIN + 1) * (1 << (retryCounter - 1)) - 1; 00872 // return the calculated value or CWmax if the maximal value is reached 00873 if (cw <= CW_MAX) 00874 return cw; 00875 else 00876 return CW_MAX; 00877 } 00878 00879 // the next packet is broadcast : the contention window must be maximal 00880 else 00881 return broadcastBackoff; 00882 }
void Mac80211::decapsulateAndSendUp | ( | Mac80211Pkt * | frame | ) | [protected] |
decapsulate packet and send to higher layer
00190 { 00191 cMessage *msg = frame->decapsulate(); 00192 // FIXME TBD set control info 00193 delete frame; 00194 sendUp(msg); 00195 }
Mac80211Pkt * Mac80211::encapsMsg | ( | cMessage * | netw | ) | [protected] |
encapsulate packet
Encapsulates the received network-layer packet into a MacPkt and set all needed header fields.
00171 { 00172 Mac80211Pkt *pkt = new Mac80211Pkt(netw->name()); 00173 pkt->setLength(272); // headerLength, including final CRC-field 00174 00175 // copy dest address from the control info 00176 Ieee802Ctrl *ctrl = check_and_cast<Ieee802Ctrl *>(netw->removeControlInfo()); 00177 pkt->setDestAddr(ctrl->getDest()); 00178 delete ctrl; 00179 00180 // set the src address to own mac address (nic module id()) 00181 pkt->setSrcAddr(myMacAddr); 00182 00183 // encapsulate the network packet 00184 pkt->encapsulate(netw); 00185 00186 return pkt; 00187 }
void Mac80211::handleACKframe | ( | Mac80211Pkt * | af | ) | [protected] |
Handle a frame which is expected to be an ACK.Called by HandleMsgForMe(MAcawFrame* af)
00445 { 00446 EV << "handling Ack frame\n"; 00447 00448 // cancel time-out event 00449 cancelEvent(timeout); 00450 00451 // the transmission is acknowledged : initialize long_retry_counter 00452 retryCounter = 1; 00453 00454 // removes the acknowledged packet from the queue 00455 Mac80211Pkt *temp = fromUpperLayer.front(); 00456 fromUpperLayer.pop_front(); 00457 delete temp; 00458 00459 // if thre's a packet to send and if the channel is free then start a new contention period 00460 beginNewCycle(); 00461 }
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)
00484 { 00485 EV << "handle broadcast\n"; 00486 if (state == BUSY) 00487 error("logic error: node is currently transmitting, can not receive " 00488 "(does the physical layer do its job correctly?)"); 00489 00490 decapsulateAndSendUp(af); 00491 if (state == CONTEND) 00492 beginNewCycle(); 00493 }
void Mac80211::handleCTSframe | ( | Mac80211Pkt * | af | ) | [protected] |
void Mac80211::handleDATAframe | ( | Mac80211Pkt * | af | ) | [protected] |
Handle a frame which expected to be a DATA frame. Called by HandleMsgForMe()
00424 { 00425 if (rtsCts) 00426 cancelEvent(timeout); // cancel time-out event 00427 00428 // make a copy 00429 Mac80211Pkt *copy = (Mac80211Pkt *) af->dup(); 00430 00431 // pass the packet to the upper layer 00432 decapsulateAndSendUp(af); 00433 00434 // wait a short interframe space 00435 endSifs->setContextPointer(copy); 00436 scheduleAt(simTime() + SIFS, endSifs); 00437 }
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
00502 { 00503 EV << "end contention period\n"; 00504 00505 if (state != CONTEND) 00506 error("logic error: expiration of the contention timer outside of CONTEND state, should not happen"); 00507 00508 // the node has won the channel, the backoff window is deleted and 00509 // will be new calculated in the next contention period 00510 BW = 0; 00511 // unicast packet 00512 if (!nextIsBroadcast) 00513 { 00514 if (rtsCts) 00515 { 00516 // send a RTS 00517 sendRTSframe(); 00518 setState(WFCTS); 00519 } 00520 else 00521 { 00522 sendDATAframe(); 00523 setState(WFACK); 00524 } 00525 00526 // broadcast packet 00527 } 00528 else 00529 { 00530 sendBROADCASTframe(); 00531 00532 // removes the packet from the queue without waiting for an acknowledgement 00533 Mac80211Pkt *temp = fromUpperLayer.front(); 00534 fromUpperLayer.pop_front(); 00535 delete(temp); 00536 } 00537 }
void Mac80211::handleEndSifsTimer | ( | ) | [protected] |
handle end of SIFS
Handle the end sifs timer. Then sends a CTS, a DATA, or an ACK frame
00572 { 00573 Mac80211Pkt *frame = (Mac80211Pkt *) endSifs->contextPointer(); 00574 00575 switch (frame->kind()) 00576 { 00577 case RTS: 00578 sendCTSframe(frame); 00579 break; 00580 case CTS: 00581 sendDATAframe(); 00582 break; 00583 case DATA: 00584 sendACKframe(frame); 00585 break; 00586 default: 00587 error("logic error: end sifs timer when previously received packet is not RTS/CTS/DATA"); 00588 } 00589 00590 // don't need previous frame any more 00591 delete frame; 00592 }
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)
00600 { 00601 EV << "transmission of ACK/BROADCAST is over\n"; 00602 if (state != BUSY) 00603 error("logic error: expiration of the end transmission timer outside the BUSY state, should not happen"); 00604 00605 // if there's a packet to send and if the channel is free, then start a new contention period 00606 beginNewCycle(); 00607 }
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.
00204 { 00205 Mac80211Pkt *af = check_and_cast<Mac80211Pkt *>(msg); 00206 00207 // end of the reception 00208 EV << "frame " << af << " received, kind = " << pktTypeName(af->kind()) << "\n"; 00209 00210 switch (af->kind()) 00211 { 00212 case COLLISION: // packet lost or bit error 00213 delete af; 00214 if (state == CONTEND) 00215 beginNewCycle(); 00216 break; 00217 00218 case BITERROR: 00219 handleMsgNotForMe(af); 00220 break; 00221 00222 case BROADCAST: // broadcast packet 00223 handleBroadcastMsg(af); 00224 break; 00225 00226 default: // other packet 00227 if (af->getDestAddr() == myMacAddr) // FIXME verify broadcast dest addr works! 00228 handleMsgForMe(af); 00229 else 00230 handleMsgNotForMe(af); 00231 } 00232 }
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()
00347 { 00348 EV << "handle msg for me in state = " << stateName(state) << " with type = " << pktTypeName(af->kind()) << "\n"; 00349 00350 switch (state) 00351 { 00352 case IDLE: // waiting for the end of the contention period 00353 case CONTEND: // or waiting for RTS 00354 00355 // RTS or DATA accepted 00356 if (af->kind() == RTS) 00357 handleRTSframe(af); 00358 else if (af->kind() == DATA) 00359 handleDATAframe(af); 00360 else 00361 // TODO: what if a late ACK has arrived? 00362 EV << "in handleMsgForMe() IDLE/CONTEND, strange message, darf das?\n"; 00363 break; 00364 00365 case WFDATA: // waiting for DATA 00366 00367 if (af->kind() == DATA) 00368 handleDATAframe(af); 00369 else 00370 EV << "in handleMsgForMe() WFDATA, strange message, darf das?\n"; 00371 break; 00372 00373 case WFACK: // waiting for ACK 00374 00375 if (af->kind() == ACK) 00376 handleACKframe(af); 00377 else 00378 EV << "in handleMsgForMe() WFACK, strange message, darf das?\n"; 00379 delete af; 00380 break; 00381 00382 case WFCTS: // The MAC is waiting for CTS 00383 00384 if (af->kind() == CTS) 00385 handleCTSframe(af); 00386 else 00387 EV << "in handleMsgForMe() WFCTS, strange message, darf das?\n"; 00388 break; 00389 00390 00391 case QUIET: // the node is currently deferring. 00392 00393 // cannot handle any packet with its MAC adress 00394 delete af; 00395 break; 00396 00397 case BUSY: // currently transmitting an ACK or a BROADCAST packet 00398 error("logic error: node is currently transmitting, can not receive " 00399 "(does the physical layer do its job correctly?)"); 00400 break; 00401 00402 default: 00403 error("unknown state %d", state); 00404 } 00405 }
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()
00281 { 00282 EV << "handle msg not for me\n"; 00283 00284 // if this packet can not be correctly read 00285 if (af->kind() == BITERROR) 00286 af->setDuration(EIFS); 00287 00288 // if the duration of the packet is null, then do nothing (to avoid 00289 // the unuseful scheduling of a self message) 00290 if (af->getDuration() != 0) 00291 { 00292 00293 // the node is already deferring 00294 if (state == QUIET) 00295 { 00296 // the current value of the NAV is not sufficient 00297 if (nav->arrivalTime() < simTime() + af->getDuration()) 00298 { 00299 cancelEvent(nav); 00300 scheduleAt(simTime() + af->getDuration(), nav); 00301 EV << "NAV timer started for: " << af->getDuration() << " State QUIET\n"; 00302 } 00303 } 00304 00305 // other states 00306 else 00307 { 00308 // if the MAC wait for another frame, it can delete its time out 00309 // (exchange is aborted) 00310 if (timeout->isScheduled()) 00311 cancelEvent(timeout); 00312 00313 // is state == WFCTS or WFACK, the data transfer has failed ... 00314 00315 // the node must defer for the time of the transmission 00316 scheduleAt(simTime() + af->getDuration(), nav); 00317 EV << "NAV timer started, not QUIET: " << af->getDuration() << endl; 00318 setState(QUIET); 00319 00320 } 00321 } 00322 if (!rtsCts) 00323 { // todo: Nachgucken: was passiert bei Error ohne rtsCts! 00324 if (state == CONTEND) 00325 { 00326 if (af->kind() == BITERROR) 00327 { 00328 if (contention->isScheduled()) 00329 cancelEvent(contention); 00330 scheduleAt(simTime() + backoff() + EIFS, contention); 00331 } 00332 else 00333 beginNewCycle(); 00334 } 00335 } 00336 delete af; 00337 }
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)
00544 { 00545 if (state != QUIET) 00546 error("logic error: expiration of the NAV timer outside of the state QUIET, should not happen"); 00547 00548 // if there's a packet to send and if the channel is free, then start a new contention period 00549 beginNewCycle(); 00550 }
void Mac80211::handleRTSframe | ( | Mac80211Pkt * | af | ) | [protected] |
void Mac80211::handleSelfMsg | ( | cMessage * | msg | ) | [protected, virtual] |
Handle self messages such as timer...
handle timers
Implements WirelessMacBase.
00238 { 00239 EV << "processing self message with type = " << timerTypeName(msg->kind()) << endl; 00240 00241 switch (msg->kind()) 00242 { 00243 case END_SIFS: 00244 handleEndSifsTimer(); // noch zu betrachten 00245 break; 00246 00247 case END_TRANSMISSION: 00248 handleEndTransmissionTimer(); // noch zu betrachten 00249 break; 00250 00251 case CONTENTION: 00252 handleEndContentionTimer(); 00253 break; 00254 00255 // the MAC was waiting for a CTS, a DATA, or an ACK packet but the timer has expired. 00256 case TIMEOUT: 00257 handleTimeoutTimer(); // noch zu betrachten.. 00258 break; 00259 00260 // the MAC was waiting because an other communication had won the channel. This communication is now over 00261 case NAV: 00262 handleNavTimer(); // noch zu betrachten... 00263 break; 00264 00265 default: 00266 error("unknown timer type"); 00267 } 00268 }
void Mac80211::handleTimeoutTimer | ( | ) | [protected] |
handle time out
Handle the time out timer. Called by handleTimer(cMessage* msg)
00557 { 00558 // if (state == WFCTS || state == WFACK)testMaxAttempts(); 00559 00560 // if there's a packet to send and if the channel is free then 00561 // start a new contention period 00562 if (state != QUIET) 00563 beginNewCycle(); 00564 }
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.
00138 { 00139 if (msg->byteLength() > 2312) 00140 error("packet from higher layer (%s)%s is too long for 802.11b, %d bytes (fragmentation is not supported yet)", 00141 msg->className(), msg->name(), msg->byteLength()); 00142 00143 if (maxQueueSize && fromUpperLayer.size() == maxQueueSize) 00144 { 00145 EV << "packet " << msg << " received from higher layer but MAC queue is full, deleting\n"; 00146 delete msg; 00147 return; 00148 } 00149 00150 Mac80211Pkt *mac = encapsMsg(msg); 00151 EV << "packet " << msg << " received from higher layer, dest=" << mac->getDestAddr() << ", encapsulated\n"; 00152 00153 fromUpperLayer.push_back(mac); 00154 // If the MAC is in the IDLE state, then start a new contention period 00155 if (state == IDLE && !endSifs->isScheduled()) 00156 { 00157 tryWithoutBackoff = true; 00158 beginNewCycle(); 00159 } 00160 else 00161 { 00162 EV << "enqueued, will be transmitted later\n"; 00163 } 00164 }
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; //XXX it's rather "epsilon", but this delta business looks a bit dodgy a solution anyway 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 WATCH(state); 00081 WATCH(radioState); 00082 } 00083 }
virtual int Mac80211::numInitStages | ( | ) | const [inline, protected, virtual] |
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.
00997 { 00998 return bits / bitrate + PHY_HEADER_LENGTH / BITRATE_HEADER; 00999 }
const char * Mac80211::pktTypeName | ( | int | type | ) | [protected] |
Produce a readable name of the given packet type.
01036 { 01037 #define CASE(x) case x: s=#x; break 01038 const char *s = "???"; 01039 switch (type) 01040 { 01041 CASE(TIMEOUT); 01042 CASE(DATA); 01043 CASE(BROADCAST); 01044 CASE(RTS); 01045 CASE(CTS); 01046 CASE(ACK); 01047 CASE(ACKRTS); 01048 CASE(BEGIN_RECEPTION); 01049 CASE(BITERROR); 01050 CASE(COLLISION); 01051 } 01052 return s; 01053 #undef CASE 01054 }
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.
00910 { 00911 Enter_Method("receiveChangeNotification(%s, %s)", notificationCategoryName(category), 00912 details?details->info().c_str() : "n/a"); 00913 printNotificationBanner(category, details); 00914 00915 if (category == NF_RADIOSTATE_CHANGED) 00916 { 00917 // update the local copy of the radio state 00918 radioState = check_and_cast<RadioState *>(details)->getState(); 00919 00920 // NOTE: we may be invoked during INIT STAGE 1 too, when SnrEval notifies us 00921 // about the initial radio state. This function has to work correctly 00922 // even when called during initialization phase! 00923 00924 EV << "** Radio state update in " << className() << ": " << details->info() 00925 << " (at T=" << simtimeToStr(simTime()) << ")\n"; 00926 00927 // beginning of a reception 00928 if (radioState == RadioState::RECV) 00929 { 00930 // if there's a contention period 00931 if (contention->isScheduled()) 00932 { 00933 // update the backoff window in order to give higher priority in 00934 // the next battle 00935 if (simTime() - contention->sendingTime() >= DIFS) 00936 { 00937 BW = contention->arrivalTime() - simTime(); 00938 EV << "Backoff window made smaller, new BW: " << BW << endl; 00939 } 00940 cancelEvent(contention); 00941 } 00942 00943 // if there's a SIFS period 00944 if (endSifs->isScheduled()) 00945 { 00946 // delete the previously received frame 00947 delete (Mac80211Pkt *)endSifs->contextPointer(); 00948 00949 // cancel the next transmission 00950 cancelEvent(endSifs); 00951 00952 // state in now IDLE or CONTEND 00953 if (fromUpperLayer.empty()) 00954 setState(IDLE); 00955 else 00956 setState(CONTEND); 00957 } 00958 } 00959 } 00960 }
void Mac80211::registerInterface | ( | ) | [protected] |
Register the interface in InterfaceTable.
00087 { 00088 InterfaceEntry *e = new InterfaceEntry(); 00089 00090 // interface name: NetworkInterface module's name without special characters ([]) 00091 char *interfaceName = new char[strlen(parentModule()->fullName()) + 1]; 00092 char *d = interfaceName; 00093 for (const char *s = parentModule()->fullName(); *s; s++) 00094 if (isalnum(*s)) 00095 *d++ = *s; 00096 *d = '\0'; 00097 00098 e->setName(interfaceName); 00099 delete [] interfaceName; 00100 00101 const char *addrstr = par("address"); 00102 if (!strcmp(addrstr, "auto")) 00103 { 00104 // assign automatic address 00105 myMacAddr = MACAddress::generateAutoAddress(); 00106 00107 // change module parameter from "auto" to concrete address 00108 par("address").setStringValue(myMacAddr.str().c_str()); 00109 } 00110 else 00111 { 00112 myMacAddr.setAddress(addrstr); 00113 } 00114 e->setMACAddress(myMacAddr); 00115 00116 // generate interface identifier for IPv6 00117 e->setInterfaceToken(myMacAddr.formInterfaceIdentifier()); 00118 00119 // MTU on 802.11 = ? 00120 e->setMtu(1500); // FIXME 00121 00122 // capabilities 00123 e->setBroadcast(true); 00124 e->setMulticast(true); 00125 e->setPointToPoint(false); 00126 00127 // add 00128 InterfaceTable *ift = InterfaceTableAccess().get(); 00129 ift->addInterface(e, this); 00130 }
void Mac80211::sendACKframe | ( | Mac80211Pkt * | af | ) | [protected] |
send Acknoledgement
Send an ACK frame.Called by HandleEndSifsTimer()
00637 { 00638 // the MAC must wait the end of the transmission before beginning an 00639 // other contention period 00640 scheduleAt(simTime() + packetDuration(LENGTH_ACK) + delta, endTransmission); 00641 00642 // send ACK frame 00643 sendDown(buildACKframe(af)); 00644 EV << "sent ACK frame!\n"; 00645 00646 // update state and display 00647 setState(BUSY); 00648 }
void Mac80211::sendBROADCASTframe | ( | ) | [protected] |
send broadcast frame
Send a BROADCAST frame.Called by handleContentionTimer()
00689 { 00690 // the MAC must wait the end of the transmission before beginning any 00691 // other contention period 00692 scheduleAt(simTime() + packetDuration(fromUpperLayer.front()->length()), endTransmission); 00693 // send ACK frame 00694 sendDown(buildBROADCASTframe()); 00695 00696 // update state and display 00697 setState(BUSY); 00698 }
void Mac80211::sendCTSframe | ( | Mac80211Pkt * | af | ) | [protected] |
send CTS frame
Send a CTS frame.Called by HandleEndSifsTimer()
00674 { 00675 // schedule time-out 00676 scheduleAt(simTime() + timeOut(CTS, af->getDuration()), timeout); 00677 00678 // send CTS frame 00679 sendDown(buildCTSframe(af)); 00680 00681 // update state and display 00682 setState(WFDATA); 00683 }
void Mac80211::sendDATAframe | ( | ) | [protected, virtual] |
send data frame
Send a DATA frame. Called by HandleEndSifsTimer() or handleEndContentionTimer()
00615 { 00616 EV << "sending data frame\n"; 00617 00618 // schedule time out 00619 scheduleAt(simTime() + timeOut(DATA, 0), timeout); 00620 00621 if (!rtsCts) 00622 // retryCounter incremented 00623 retryCounter++; 00624 00625 // send DATA frame 00626 sendDown(buildDATAframe()); 00627 00628 // update state and display 00629 setState(WFACK); 00630 }
void Mac80211::sendRTSframe | ( | ) | [protected, virtual] |
send RTS frame
Send a RTS frame.Called by handleContentionTimer()
00655 { 00656 // schedule time-out 00657 scheduleAt(simTime() + timeOut(RTS, 0), timeout); 00658 00659 // long_retry_counter incremented 00660 retryCounter++; 00661 00662 // send RTS frame 00663 sendDown(buildRTSframe()); 00664 00665 // update state and display 00666 setState(WFCTS); 00667 }
void Mac80211::setState | ( | State | state | ) | [protected] |
const char * Mac80211::stateName | ( | State | state | ) | [protected] |
Produce a readable name of the given state.
01002 { 01003 #define CASE(x) case x: s=#x; break 01004 const char *s = "???"; 01005 switch (state) 01006 { 01007 CASE(WFDATA); 01008 CASE(QUIET); 01009 CASE(IDLE); 01010 CASE(CONTEND); 01011 CASE(WFCTS); 01012 CASE(WFACK); 01013 CASE(BUSY); 01014 } 01015 return s; 01016 #undef CASE 01017 }
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.
00891 { 00892 if (retryCounter > RETRY_LIMIT) 00893 { 00894 // initialize counter 00895 retryCounter = 1; 00896 // reportLost(fromUpperLayer.front()); 00897 00898 // delete the frame to transmit 00899 Mac80211Pkt *temp = fromUpperLayer.front(); 00900 fromUpperLayer.pop_front(); 00901 delete(temp); 00902 } 00903 }
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.
00968 { 00969 double time_out = 0; 00970 switch (type) 00971 { 00972 case RTS: 00973 time_out = SIFS + packetDuration(LENGTH_RTS) + packetDuration(LENGTH_CTS) + delta; 00974 break; 00975 case CTS: 00976 time_out = last_frame_duration - packetDuration(LENGTH_ACK) - 2 * SIFS + delta; 00977 break; 00978 case DATA: 00979 time_out = 00980 SIFS + packetDuration(fromUpperLayer.front()->length()) + packetDuration(LENGTH_ACK) + 00981 delta + 0.1; 00982 //XXX: I have added some time here, because propagation delay of AirFrames caused problems 00983 // the timeout periods should be carefully revised with special care for the deltas?! --Levy 00984 break; 00985 default: 00986 EV << "Unused frame type was given when calling timeOut(), this should not happen!\n"; 00987 } 00988 return time_out; 00989 }
const char * Mac80211::timerTypeName | ( | int | type | ) | [protected] |
Produce a readable name of the given timer type.
01020 { 01021 #define CASE(x) case x: s=#x; break 01022 const char *s = "???"; 01023 switch (type) 01024 { 01025 CASE(TIMEOUT); 01026 CASE(NAV); 01027 CASE(CONTENTION); 01028 CASE(END_TRANSMISSION); 01029 CASE(END_SIFS); 01030 } 01031 return s; 01032 #undef CASE 01033 }
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::State 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.