#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.
|