#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. | |
| 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 } |
|
|
|
|
|
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 };
|
|
|
Definition of the timer types 00045 {
00046 TIMEOUT,
00047 NAV,
00048 CONTENTION,
00049 END_TRANSMISSION,
00050 END_SIFS
00051 };
|
|
|
00032 {
00033 timeout = nav = contention = endTransmission = endSifs = NULL;
00034 }
|
|
|
00037 {
00038 cancelAndDelete(timeout);
00039 cancelAndDelete(nav);
00040 cancelAndDelete(contention);
00041 cancelAndDelete(endTransmission);
00042 cancelAndDelete(endSifs);
00043 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
Initialization of the module and some variables.
00070 {return 2;}
|
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
|
The bitrate should be set in omnetpp.ini; be sure to use a valid 802.11 bitrate.
|
|
|
Should be set in the omnetpp.ini.
|
|
|
Variable to store the current backoff value.
|
|
|
Timer used for contention periods.
|
|
|
Very small value used in timer scheduling in order to avoid multiple changements of state in the same simulation time.
|
|
|
extended interframe space
|
|
|
Timer used to indicate the end of a SIFS.
|
|
|
Timer used to indicate the end of the transmission of an ACK or a BROADCAST packet.
|
|
|
Buffering of messages from upper layer.
|
|
|
Maximal number of packets in the queue; should be set in the omnetpp.ini.
|
|
|
mac address
|
|
|
Timer used for the defer time of a node. Also called NAV : networks allocation vector.
|
|
|
Boolean used to know if the next packet is a broadcast packet.
|
|
|
Current state of the radio (kept updated by receiveChangeNotification()).
|
|
|
Number of frame transmission attempt.
|
|
|
true if Rts/Cts is used, false if not; can be set in omnetpp.ini
|
|
|
Current state of the MAC.
|
|
|
Timer used for time-outs after the transmission of a RTS, a CTS, or a DATA packet.
|
|
|
If there's a new packet to send and the channel is free, no backoff is needed.
|
1.4.1