#include <Mac80211.h>
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. | |
virtual void | registerInterface () |
Register the interface in IInterfaceTable. | |
virtual void | receiveChangeNotification (int category, const 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 (cPacket *) |
Handle packets from upper layer. | |
virtual void | handleCommand (cMessage *) |
Handle commands from upper layer. | |
virtual void | handleLowerMsg (cPacket *) |
Handle packets from lower layer. | |
virtual void | handleEndContentionTimer () |
handle end of contention | |
virtual void | handleMsgNotForMe (Mac80211Pkt *) |
handle a message that is not for me or errornous | |
virtual void | handleMsgForMe (Mac80211Pkt *) |
handle a message that was meant for me | |
virtual void | handleBroadcastMsg (Mac80211Pkt *) |
virtual void | handleEndTransmissionTimer () |
handle the end of a transmission... | |
virtual void | handleEndSifsTimer () |
handle end of SIFS | |
virtual void | handleTimeoutTimer () |
handle time out | |
virtual void | handleNavTimer () |
NAV timer expired, the exchange of messages of other stations is done. | |
virtual void | handleRTSframe (Mac80211Pkt *) |
virtual void | handleDATAframe (Mac80211Pkt *) |
virtual void | handleACKframe (Mac80211Pkt *) |
virtual void | handleCTSframe (Mac80211Pkt *) |
virtual void | sendDATAframe () |
send data frame | |
virtual void | sendACKframe (Mac80211Pkt *) |
send Acknoledgement | |
virtual void | sendCTSframe (Mac80211Pkt *) |
send CTS frame | |
virtual void | sendRTSframe () |
send RTS frame | |
virtual void | sendBROADCASTframe () |
send broadcast frame | |
virtual Mac80211Pkt * | encapsMsg (cPacket *netw) |
encapsulate packet | |
virtual void | decapsulateAndSendUp (Mac80211Pkt *frame) |
decapsulate packet and send to higher layer | |
virtual Mac80211Pkt * | buildDATAframe () |
build a data frame | |
virtual Mac80211Pkt * | buildACKframe (Mac80211Pkt *) |
build an ACK | |
virtual Mac80211Pkt * | buildCTSframe (Mac80211Pkt *) |
build a CTS frame | |
virtual Mac80211Pkt * | buildRTSframe () |
build an RTS frame | |
virtual Mac80211Pkt * | buildBROADCASTframe () |
build a broadcast frame | |
virtual void | beginNewCycle () |
start a new contention period | |
virtual simtime_t | computeBackoff () |
Compute a backoff value. | |
virtual int | computeContentionWindow () |
Compute a new contention window. | |
virtual void | testMaxAttempts () |
Test if maximum number of retries to transmit is exceeded. | |
virtual simtime_t | computeTimeout (_802_11frameType type, simtime_t last_frame_duration) |
return a timeOut value for a certain type of frame | |
virtual simtime_t | computePacketDuration (int bits) |
computes the duration of a transmission over the physical channel | |
virtual void | setState (State state) |
Sets the state, and produces a log message in between. | |
Static Protected Member Functions | |
static const char * | stateName (State state) |
Produce a readable name of the given state. | |
static const char * | timerTypeName (int type) |
Produce a readable name of the given timer type. | |
static const char * | pktTypeName (int type) |
Produce a readable name of the given packet type. | |
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. | |
simtime_t | EIFS |
extended interframe space | |
simtime_t | 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 | |
simtime_t | 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 | |
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 * > | MacPktList |
typedef std::list<Mac80211Pkt*> Mac80211::MacPktList [private] |
enum Mac80211::timerType [private] |
Definition of the timer types
00045 { 00046 TIMEOUT, 00047 NAV, 00048 CONTENTION, 00049 END_TRANSMISSION, 00050 END_SIFS 00051 };
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 };
Mac80211::Mac80211 | ( | ) |
Mac80211::~Mac80211 | ( | ) | [virtual] |
00037 { 00038 cancelAndDelete(timeout); 00039 cancelAndDelete(nav); 00040 cancelAndDelete(contention); 00041 cancelAndDelete(endTransmission); 00042 cancelAndDelete(endSifs); 00043 }
virtual int Mac80211::numInitStages | ( | ) | const [inline, protected, virtual] |
void Mac80211::initialize | ( | int | stage | ) | [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 + computePacketDuration(LENGTH_ACK); 00075 EV << "SIFS: " << SIFS << " DIFS: " << DIFS << " EIFS: " << EIFS << endl; 00076 00077 // get registered in IInterfaceTable 00078 registerInterface(); 00079 00080 WATCH(state); 00081 WATCH(radioState); 00082 } 00083 }
void Mac80211::registerInterface | ( | ) | [protected, virtual] |
Register the interface in IInterfaceTable.
Referenced by initialize().
00087 { 00088 InterfaceEntry *e = new InterfaceEntry(); 00089 00090 // interface name: NetworkInterface module's name without special characters ([]) 00091 char *interfaceName = new char[strlen(getParentModule()->getFullName()) + 1]; 00092 char *d = interfaceName; 00093 for (const char *s = getParentModule()->getFullName(); *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(par("mtu")); // FIXME 00121 00122 // capabilities 00123 e->setBroadcast(true); 00124 e->setMulticast(true); 00125 e->setPointToPoint(false); 00126 00127 // add 00128 IInterfaceTable *ift = InterfaceTableAccess().get(); 00129 ift->addInterface(e, this); 00130 }
void Mac80211::receiveChangeNotification | ( | int | category, | |
const 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.
00915 { 00916 Enter_Method("receiveChangeNotification(%s, %s)", notificationCategoryName(category), 00917 details?details->info().c_str() : "n/a"); 00918 printNotificationBanner(category, details); 00919 00920 if (category == NF_RADIOSTATE_CHANGED) 00921 { 00922 // update the local copy of the radio state 00923 radioState = check_and_cast<RadioState *>(details)->getState(); 00924 00925 // NOTE: we may be invoked during INIT STAGE 1 too, when SnrEval notifies us 00926 // about the initial radio state. This function has to work correctly 00927 // even when called during initialization phase! 00928 00929 EV << "** Radio state update in " << getClassName() << ": " << details->info() 00930 << " (at T=" << simTime() << ")\n"; 00931 00932 // beginning of a reception 00933 if (radioState == RadioState::RECV) 00934 { 00935 // if there's a contention period 00936 if (contention->isScheduled()) 00937 { 00938 // update the backoff window in order to give higher priority in 00939 // the next battle 00940 if (simTime() - contention->getSendingTime() >= DIFS) 00941 { 00942 BW = contention->getArrivalTime() - simTime(); 00943 EV << "Backoff window made smaller, new BW: " << BW << endl; 00944 } 00945 cancelEvent(contention); 00946 } 00947 00948 // if there's a SIFS period 00949 if (endSifs->isScheduled()) 00950 { 00951 // delete the previously received frame 00952 delete (Mac80211Pkt *)endSifs->getContextPointer(); 00953 00954 // cancel the next transmission 00955 cancelEvent(endSifs); 00956 00957 // state in now IDLE or CONTEND 00958 if (fromUpperLayer.empty()) 00959 setState(IDLE); 00960 else 00961 setState(CONTEND); 00962 } 00963 } 00964 } 00965 }
void Mac80211::handleSelfMsg | ( | cMessage * | msg | ) | [protected, virtual] |
Handle self messages such as timer...
handle timers
Implements WirelessMacBase.
00243 { 00244 EV << "processing self message with type = " << timerTypeName(msg->getKind()) << endl; 00245 00246 switch (msg->getKind()) 00247 { 00248 case END_SIFS: 00249 handleEndSifsTimer(); // noch zu betrachten 00250 break; 00251 00252 case END_TRANSMISSION: 00253 handleEndTransmissionTimer(); // noch zu betrachten 00254 break; 00255 00256 case CONTENTION: 00257 handleEndContentionTimer(); 00258 break; 00259 00260 // the MAC was waiting for a CTS, a DATA, or an ACK packet but the timer has expired. 00261 case TIMEOUT: 00262 handleTimeoutTimer(); // noch zu betrachten.. 00263 break; 00264 00265 // the MAC was waiting because an other communication had won the channel. This communication is now over 00266 case NAV: 00267 handleNavTimer(); // noch zu betrachten... 00268 break; 00269 00270 default: 00271 error("unknown timer type"); 00272 } 00273 }
void Mac80211::handleUpperMsg | ( | cPacket * | msg | ) | [protected, virtual] |
Handle packets from upper layer.
This implementation does not support fragmentation, so it is tested if the maximum length of the MPDU is exceeded.
Implements WirelessMacBase.
00143 { 00144 if (msg->getByteLength() > 2312) 00145 error("packet from higher layer (%s)%s is too long for 802.11b, %d bytes (fragmentation is not supported yet)", 00146 msg->getClassName(), msg->getName(), msg->getByteLength()); 00147 00148 if (maxQueueSize && (int)fromUpperLayer.size() == maxQueueSize) 00149 { 00150 EV << "packet " << msg << " received from higher layer but MAC queue is full, deleting\n"; 00151 delete msg; 00152 return; 00153 } 00154 00155 Mac80211Pkt *mac = encapsMsg(msg); 00156 EV << "packet " << msg << " received from higher layer, dest=" << mac->getDestAddr() << ", encapsulated\n"; 00157 00158 fromUpperLayer.push_back(mac); 00159 // If the MAC is in the IDLE state, then start a new contention period 00160 if (state == IDLE && !endSifs->isScheduled()) 00161 { 00162 tryWithoutBackoff = true; 00163 beginNewCycle(); 00164 } 00165 else 00166 { 00167 EV << "enqueued, will be transmitted later\n"; 00168 } 00169 }
void Mac80211::handleCommand | ( | cMessage * | msg | ) | [protected, virtual] |
Handle commands from upper layer.
Implements WirelessMacBase.
00133 { 00134 // no commands supported by Mac80211 00135 error("Non-packet message arrived from higher layer: (%s)%s", msg->getClassName(), msg->getName()); 00136 }
void Mac80211::handleLowerMsg | ( | cPacket * | msg | ) | [protected, virtual] |
Handle packets 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.
00209 { 00210 Mac80211Pkt *af = check_and_cast<Mac80211Pkt *>(msg); 00211 00212 // end of the reception 00213 EV << "frame " << af << " received, kind = " << pktTypeName(af->getKind()) << "\n"; 00214 00215 switch (af->getKind()) 00216 { 00217 case COLLISION: // packet lost or bit error 00218 delete af; 00219 if (state == CONTEND) 00220 beginNewCycle(); 00221 break; 00222 00223 case BITERROR: 00224 handleMsgNotForMe(af); 00225 break; 00226 00227 case BROADCAST: // broadcast packet 00228 handleBroadcastMsg(af); 00229 break; 00230 00231 default: // other packet 00232 if (af->getDestAddr() == myMacAddr) // FIXME verify broadcast dest addr works! 00233 handleMsgForMe(af); 00234 else 00235 handleMsgNotForMe(af); 00236 } 00237 }
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
Referenced by handleSelfMsg().
00507 { 00508 EV << "end contention period\n"; 00509 00510 if (state != CONTEND) 00511 error("logic error: expiration of the contention timer outside of CONTEND state, should not happen"); 00512 00513 // the node has won the channel, the backoff window is deleted and 00514 // will be new calculated in the next contention period 00515 BW = 0; 00516 // unicast packet 00517 if (!nextIsBroadcast) 00518 { 00519 if (rtsCts) 00520 { 00521 // send a RTS 00522 sendRTSframe(); 00523 setState(WFCTS); 00524 } 00525 else 00526 { 00527 sendDATAframe(); 00528 setState(WFACK); 00529 } 00530 00531 // broadcast packet 00532 } 00533 else 00534 { 00535 sendBROADCASTframe(); 00536 00537 // removes the packet from the queue without waiting for an acknowledgement 00538 Mac80211Pkt *temp = fromUpperLayer.front(); 00539 fromUpperLayer.pop_front(); 00540 delete(temp); 00541 } 00542 }
void Mac80211::handleMsgNotForMe | ( | Mac80211Pkt * | af | ) | [protected, virtual] |
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()
Referenced by handleLowerMsg().
00286 { 00287 EV << "handle msg not for me\n"; 00288 00289 // if this packet can not be correctly read 00290 if (af->getKind() == BITERROR) 00291 af->setDuration(EIFS); 00292 00293 // if the duration of the packet is null, then do nothing (to avoid 00294 // the unuseful scheduling of a self message) 00295 if (af->getDuration() != 0) 00296 { 00297 00298 // the node is already deferring 00299 if (state == QUIET) 00300 { 00301 // the current value of the NAV is not sufficient 00302 if (nav->getArrivalTime() < simTime() + af->getDuration()) 00303 { 00304 cancelEvent(nav); 00305 scheduleAt(simTime() + af->getDuration(), nav); 00306 EV << "NAV timer started for: " << af->getDuration() << " State QUIET\n"; 00307 } 00308 } 00309 00310 // other states 00311 else 00312 { 00313 // if the MAC wait for another frame, it can delete its time out 00314 // (exchange is aborted) 00315 if (timeout->isScheduled()) 00316 cancelEvent(timeout); 00317 00318 // is state == WFCTS or WFACK, the data transfer has failed ... 00319 00320 // the node must defer for the time of the transmission 00321 scheduleAt(simTime() + af->getDuration(), nav); 00322 EV << "NAV timer started, not QUIET: " << af->getDuration() << endl; 00323 setState(QUIET); 00324 00325 } 00326 } 00327 if (!rtsCts) 00328 { // todo: Nachgucken: was passiert bei Error ohne rtsCts! 00329 if (state == CONTEND) 00330 { 00331 if (af->getKind() == BITERROR) 00332 { 00333 if (contention->isScheduled()) 00334 cancelEvent(contention); 00335 scheduleAt(simTime() + computeBackoff() + EIFS, contention); 00336 } 00337 else 00338 beginNewCycle(); 00339 } 00340 } 00341 delete af; 00342 }
void Mac80211::handleMsgForMe | ( | Mac80211Pkt * | af | ) | [protected, virtual] |
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()
Referenced by handleLowerMsg().
00352 { 00353 EV << "handle msg for me in state = " << stateName(state) << " with type = " << pktTypeName(af->getKind()) << "\n"; 00354 00355 switch (state) 00356 { 00357 case IDLE: // waiting for the end of the contention period 00358 case CONTEND: // or waiting for RTS 00359 00360 // RTS or DATA accepted 00361 if (af->getKind() == RTS) 00362 handleRTSframe(af); 00363 else if (af->getKind() == DATA) 00364 handleDATAframe(af); 00365 else 00366 // TODO: what if a late ACK has arrived? 00367 EV << "in handleMsgForMe() IDLE/CONTEND, strange message, darf das?\n"; 00368 break; 00369 00370 case WFDATA: // waiting for DATA 00371 00372 if (af->getKind() == DATA) 00373 handleDATAframe(af); 00374 else 00375 EV << "in handleMsgForMe() WFDATA, strange message, darf das?\n"; 00376 break; 00377 00378 case WFACK: // waiting for ACK 00379 00380 if (af->getKind() == ACK) 00381 handleACKframe(af); 00382 else 00383 EV << "in handleMsgForMe() WFACK, strange message, darf das?\n"; 00384 delete af; 00385 break; 00386 00387 case WFCTS: // The MAC is waiting for CTS 00388 00389 if (af->getKind() == CTS) 00390 handleCTSframe(af); 00391 else 00392 EV << "in handleMsgForMe() WFCTS, strange message, darf das?\n"; 00393 break; 00394 00395 00396 case QUIET: // the node is currently deferring. 00397 00398 // cannot handle any packet with its MAC adress 00399 delete af; 00400 break; 00401 00402 case BUSY: // currently transmitting an ACK or a BROADCAST packet 00403 error("logic error: node is currently transmitting, can not receive " 00404 "(does the physical layer do its job correctly?)"); 00405 break; 00406 00407 default: 00408 error("unknown state %d", state); 00409 } 00410 }
void Mac80211::handleBroadcastMsg | ( | Mac80211Pkt * | af | ) | [protected, virtual] |
Handle a broadcast packet. This packet is simply passed to the upper layer. No acknowledgement is needed. Called by handleLowerMsg(Mac80211Pkt *af)
Referenced by handleLowerMsg().
00489 { 00490 EV << "handle broadcast\n"; 00491 if (state == BUSY) 00492 error("logic error: node is currently transmitting, can not receive " 00493 "(does the physical layer do its job correctly?)"); 00494 00495 decapsulateAndSendUp(af); 00496 if (state == CONTEND) 00497 beginNewCycle(); 00498 }
void Mac80211::handleEndTransmissionTimer | ( | ) | [protected, virtual] |
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)
Referenced by handleSelfMsg().
00605 { 00606 EV << "transmission of ACK/BROADCAST is over\n"; 00607 if (state != BUSY) 00608 error("logic error: expiration of the end transmission timer outside the BUSY state, should not happen"); 00609 00610 // if there's a packet to send and if the channel is free, then start a new contention period 00611 beginNewCycle(); 00612 }
void Mac80211::handleEndSifsTimer | ( | ) | [protected, virtual] |
handle end of SIFS
Handle the end sifs timer. Then sends a CTS, a DATA, or an ACK frame
Referenced by handleSelfMsg().
00577 { 00578 Mac80211Pkt *frame = (Mac80211Pkt *) endSifs->getContextPointer(); 00579 00580 switch (frame->getKind()) 00581 { 00582 case RTS: 00583 sendCTSframe(frame); 00584 break; 00585 case CTS: 00586 sendDATAframe(); 00587 break; 00588 case DATA: 00589 sendACKframe(frame); 00590 break; 00591 default: 00592 error("logic error: end sifs timer when previously received packet is not RTS/CTS/DATA"); 00593 } 00594 00595 // don't need previous frame any more 00596 delete frame; 00597 }
void Mac80211::handleTimeoutTimer | ( | ) | [protected, virtual] |
handle time out
Handle the time out timer. Called by handleTimer(cMessage* msg)
Referenced by handleSelfMsg().
00562 { 00563 // if (state == WFCTS || state == WFACK)testMaxAttempts(); 00564 00565 // if there's a packet to send and if the channel is free then 00566 // start a new contention period 00567 if (state != QUIET) 00568 beginNewCycle(); 00569 }
void Mac80211::handleNavTimer | ( | ) | [protected, virtual] |
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)
Referenced by handleSelfMsg().
00549 { 00550 if (state != QUIET) 00551 error("logic error: expiration of the NAV timer outside of the state QUIET, should not happen"); 00552 00553 // if there's a packet to send and if the channel is free, then start a new contention period 00554 beginNewCycle(); 00555 }
void Mac80211::handleRTSframe | ( | Mac80211Pkt * | af | ) | [protected, virtual] |
Handle aframe wich is expected to be an RTS. Called by HandleMsgForMe()
Referenced by handleMsgForMe().
00417 { 00418 // wait a short interframe space 00419 endSifs->setContextPointer(af); 00420 scheduleAt(simTime() + SIFS, endSifs); 00421 }
void Mac80211::handleDATAframe | ( | Mac80211Pkt * | af | ) | [protected, virtual] |
Handle a frame which expected to be a DATA frame. Called by HandleMsgForMe()
Referenced by handleMsgForMe().
00429 { 00430 if (rtsCts) 00431 cancelEvent(timeout); // cancel time-out event 00432 00433 // make a copy 00434 Mac80211Pkt *copy = (Mac80211Pkt *) af->dup(); 00435 00436 // pass the packet to the upper layer 00437 decapsulateAndSendUp(af); 00438 00439 // wait a short interframe space 00440 endSifs->setContextPointer(copy); 00441 scheduleAt(simTime() + SIFS, endSifs); 00442 }
void Mac80211::handleACKframe | ( | Mac80211Pkt * | af | ) | [protected, virtual] |
Handle a frame which is expected to be an ACK.Called by HandleMsgForMe(MAcawFrame* af)
Referenced by handleMsgForMe().
00450 { 00451 EV << "handling Ack frame\n"; 00452 00453 // cancel time-out event 00454 cancelEvent(timeout); 00455 00456 // the transmission is acknowledged : initialize long_retry_counter 00457 retryCounter = 1; 00458 00459 // removes the acknowledged packet from the queue 00460 Mac80211Pkt *temp = fromUpperLayer.front(); 00461 fromUpperLayer.pop_front(); 00462 delete temp; 00463 00464 // if thre's a packet to send and if the channel is free then start a new contention period 00465 beginNewCycle(); 00466 }
void Mac80211::handleCTSframe | ( | Mac80211Pkt * | af | ) | [protected, virtual] |
Handle a CTS frame. Called by HandleMsgForMe(Mac80211Pkt* af)
Referenced by handleMsgForMe().
00473 { 00474 // cancel time-out event 00475 cancelEvent(timeout); 00476 00477 // wait a short interframe space 00478 endSifs->setContextPointer(af); 00479 scheduleAt(simTime() + SIFS, endSifs); 00480 }
void Mac80211::sendDATAframe | ( | ) | [protected, virtual] |
send data frame
Send a DATA frame. Called by HandleEndSifsTimer() or handleEndContentionTimer()
Referenced by handleEndContentionTimer(), and handleEndSifsTimer().
00620 { 00621 EV << "sending data frame\n"; 00622 00623 // schedule time out 00624 scheduleAt(simTime() + computeTimeout(DATA, 0), timeout); 00625 00626 if (!rtsCts) 00627 // retryCounter incremented 00628 retryCounter++; 00629 00630 // send DATA frame 00631 sendDown(buildDATAframe()); 00632 00633 // update state and display 00634 setState(WFACK); 00635 }
void Mac80211::sendACKframe | ( | Mac80211Pkt * | af | ) | [protected, virtual] |
send Acknoledgement
Send an ACK frame.Called by HandleEndSifsTimer()
Referenced by handleEndSifsTimer().
00642 { 00643 // the MAC must wait the end of the transmission before beginning an 00644 // other contention period 00645 scheduleAt(simTime() + computePacketDuration(LENGTH_ACK) + delta, endTransmission); 00646 00647 // send ACK frame 00648 sendDown(buildACKframe(af)); 00649 EV << "sent ACK frame!\n"; 00650 00651 // update state and display 00652 setState(BUSY); 00653 }
void Mac80211::sendCTSframe | ( | Mac80211Pkt * | af | ) | [protected, virtual] |
send CTS frame
Send a CTS frame.Called by HandleEndSifsTimer()
Referenced by handleEndSifsTimer().
00679 { 00680 // schedule time-out 00681 scheduleAt(simTime() + computeTimeout(CTS, af->getDuration()), timeout); 00682 00683 // send CTS frame 00684 sendDown(buildCTSframe(af)); 00685 00686 // update state and display 00687 setState(WFDATA); 00688 }
void Mac80211::sendRTSframe | ( | ) | [protected, virtual] |
send RTS frame
Send a RTS frame.Called by handleContentionTimer()
Referenced by handleEndContentionTimer().
00660 { 00661 // schedule time-out 00662 scheduleAt(simTime() + computeTimeout(RTS, 0), timeout); 00663 00664 // long_retry_counter incremented 00665 retryCounter++; 00666 00667 // send RTS frame 00668 sendDown(buildRTSframe()); 00669 00670 // update state and display 00671 setState(WFCTS); 00672 }
void Mac80211::sendBROADCASTframe | ( | ) | [protected, virtual] |
send broadcast frame
Send a BROADCAST frame.Called by handleContentionTimer()
Referenced by handleEndContentionTimer().
00694 { 00695 // the MAC must wait the end of the transmission before beginning any 00696 // other contention period 00697 scheduleAt(simTime() + computePacketDuration(fromUpperLayer.front()->getBitLength()), endTransmission); 00698 // send ACK frame 00699 sendDown(buildBROADCASTframe()); 00700 00701 // update state and display 00702 setState(BUSY); 00703 }
Mac80211Pkt * Mac80211::encapsMsg | ( | cPacket * | netw | ) | [protected, virtual] |
encapsulate packet
Encapsulates the received network-layer packet into a MacPkt and set all needed header fields.
Referenced by handleUpperMsg().
00176 { 00177 Mac80211Pkt *pkt = new Mac80211Pkt(netw->getName()); 00178 pkt->setBitLength(272); // headerLength, including final CRC-field 00179 00180 // copy dest address from the control info 00181 Ieee802Ctrl *ctrl = check_and_cast<Ieee802Ctrl *>(netw->removeControlInfo()); 00182 pkt->setDestAddr(ctrl->getDest()); 00183 delete ctrl; 00184 00185 // set the src address to own mac address (nic module getId()) 00186 pkt->setSrcAddr(myMacAddr); 00187 00188 // encapsulate the network packet 00189 pkt->encapsulate(netw); 00190 00191 return pkt; 00192 }
void Mac80211::decapsulateAndSendUp | ( | Mac80211Pkt * | frame | ) | [protected, virtual] |
decapsulate packet and send to higher layer
Referenced by handleBroadcastMsg(), and handleDATAframe().
00195 { 00196 cPacket *msg = frame->decapsulate(); 00197 // FIXME TBD set control info 00198 delete frame; 00199 sendUp(msg); 00200 }
Mac80211Pkt * Mac80211::buildDATAframe | ( | ) | [protected, virtual] |
build a data frame
Build a DATA frame. Called by sendDATAframe()
Referenced by sendDATAframe().
00710 { 00711 // build a copy of the frame in front of the queue 00712 Mac80211Pkt *frame = (Mac80211Pkt *) (fromUpperLayer.front())->dup(); 00713 frame->setSrcAddr(myMacAddr); 00714 frame->setKind(DATA); 00715 if (rtsCts) 00716 frame->setDuration(SIFS + computePacketDuration(LENGTH_ACK)); 00717 else 00718 frame->setDuration(0); 00719 00720 return frame; 00721 }
Mac80211Pkt * Mac80211::buildACKframe | ( | Mac80211Pkt * | af | ) | [protected, virtual] |
build an ACK
Build an ACK frame. Called by sendACKframe()
Referenced by sendACKframe().
00728 { 00729 Mac80211Pkt *frame = new Mac80211Pkt("wlan-ack"); 00730 frame->setKind(ACK); 00731 frame->setBitLength(LENGTH_ACK); 00732 00733 // the dest address must be the src adress of the RTS or the DATA 00734 // packet received. The src adress is the adress of the node 00735 frame->setSrcAddr(myMacAddr); 00736 frame->setDestAddr(af->getSrcAddr()); 00737 frame->setDuration(0); 00738 00739 return frame; 00740 }
Mac80211Pkt * Mac80211::buildCTSframe | ( | Mac80211Pkt * | af | ) | [protected, virtual] |
build a CTS frame
Build a CTS frame. Called by sendCTSframe()
Referenced by sendCTSframe().
00766 { 00767 Mac80211Pkt *frame = new Mac80211Pkt("wlan-cts"); 00768 frame->setKind(CTS); 00769 frame->setBitLength(LENGTH_CTS); 00770 00771 // the dest adress must be the src adress of the RTS received. The 00772 // src adress is the adress of the node 00773 frame->setSrcAddr(myMacAddr); 00774 frame->setDestAddr(af->getSrcAddr()); 00775 frame->setDuration(af->getDuration() - SIFS - computePacketDuration(LENGTH_CTS)); 00776 00777 return frame; 00778 }
Mac80211Pkt * Mac80211::buildRTSframe | ( | ) | [protected, virtual] |
build an RTS frame
Build a RTS frame. Called by sendRTSframe()
Referenced by sendRTSframe().
00747 { 00748 Mac80211Pkt *frame = new Mac80211Pkt("wlan-rts"); 00749 frame->setKind(RTS); 00750 frame->setBitLength(LENGTH_RTS); 00751 00752 // the src adress and dest address are copied in the frame in the queue (frame to be sent) 00753 frame->setSrcAddr(((Mac80211Pkt *) fromUpperLayer.front())->getSrcAddr()); 00754 frame->setDestAddr(((Mac80211Pkt *) fromUpperLayer.front())->getDestAddr()); 00755 frame->setDuration(3 * SIFS + computePacketDuration(LENGTH_CTS) + 00756 computePacketDuration(fromUpperLayer.front()->getBitLength()) + 00757 computePacketDuration(LENGTH_ACK)); 00758 00759 return frame; 00760 }
Mac80211Pkt * Mac80211::buildBROADCASTframe | ( | ) | [protected, virtual] |
build a broadcast frame
Build a BROADCAST frame. Called sendBROADCASTframe()
Referenced by sendBROADCASTframe().
00784 { 00785 // send a copy of the frame in front of the queue 00786 Mac80211Pkt *frame = (Mac80211Pkt *) (fromUpperLayer.front())->dup(); 00787 frame->setKind(BROADCAST); 00788 return frame; 00789 }
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().
Referenced by handleACKframe(), handleBroadcastMsg(), handleEndTransmissionTimer(), handleLowerMsg(), handleMsgNotForMe(), handleNavTimer(), handleTimeoutTimer(), and handleUpperMsg().
00800 { 00801 EV << "beginning new contention cycle\n"; 00802 00803 // before trying to send one more time a packet, test if the 00804 // maximum retry limit is reached. If it is the case, then 00805 // delete the packet and send the next packet. 00806 testMaxAttempts(); 00807 00808 if (!fromUpperLayer.empty()) 00809 { 00810 00811 // look if the next packet is unicast or broadcast 00812 nextIsBroadcast = (((Mac80211Pkt *) fromUpperLayer.front())->getDestAddr().isBroadcast()); 00813 00814 // print("next is broadcast = "<<nextIsBroadcast); 00815 00816 // if the channel is free then wait a random time and transmit 00817 if (radioState == RadioState::IDLE) 00818 { 00819 // if channel is idle AND I was not the last one that transmitted 00820 // data: no backoff 00821 if (tryWithoutBackoff) 00822 { 00823 EV << "trying to send without backoff...\n"; 00824 scheduleAt(simTime() + DIFS, contention); 00825 } 00826 else 00827 { 00828 // backoff! 00829 scheduleAt(simTime() + computeBackoff() + DIFS, contention); 00830 } 00831 } 00832 tryWithoutBackoff = false; 00833 00834 // else wait until the channel gets free; the state is now contend 00835 setState(CONTEND); 00836 } 00837 else 00838 { 00839 tryWithoutBackoff = false; 00840 setState(IDLE); 00841 } 00842 }
simtime_t Mac80211::computeBackoff | ( | ) | [protected, virtual] |
Compute a backoff value.
Compute the backoff value.
Referenced by beginNewCycle(), and handleMsgNotForMe().
00848 { 00849 // the MAC has won the previous contention. We have to compute a new 00850 // backoff window 00851 if (BW == 0) { 00852 int CW = computeContentionWindow(); 00853 EV << "generating backoff for CW: " << CW << endl; 00854 BW = intrand(CW + 1) * ST; 00855 } 00856 // CW is the contention window (see the function). ST is the 00857 // slot time. else we take the old value of BW, in order to give a 00858 // bigger priority to a node which has lost a previous contention 00859 // period. 00860 EV << "backing off for: " << BW + DIFS << endl; 00861 return BW; 00862 }
int Mac80211::computeContentionWindow | ( | ) | [protected, virtual] |
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 computeBackoff()
Referenced by computeBackoff().
00872 { 00873 // the next packet is an unicast packet 00874 if (!nextIsBroadcast) 00875 { 00876 int cw = (CW_MIN + 1) * (1 << (retryCounter - 1)) - 1; 00877 // return the calculated value or CWmax if the maximal value is reached 00878 if (cw <= CW_MAX) 00879 return cw; 00880 else 00881 return CW_MAX; 00882 } 00883 00884 // the next packet is broadcast : the contention window must be maximal 00885 else 00886 return broadcastBackoff; 00887 }
void Mac80211::testMaxAttempts | ( | ) | [protected, virtual] |
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.
Referenced by beginNewCycle().
00896 { 00897 if (retryCounter > RETRY_LIMIT) 00898 { 00899 // initialize counter 00900 retryCounter = 1; 00901 // reportLost(fromUpperLayer.front()); 00902 00903 // delete the frame to transmit 00904 Mac80211Pkt *temp = fromUpperLayer.front(); 00905 fromUpperLayer.pop_front(); 00906 delete(temp); 00907 } 00908 }
simtime_t Mac80211::computeTimeout | ( | _802_11frameType | type, | |
simtime_t | last_frame_duration | |||
) | [protected, virtual] |
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.
Referenced by sendCTSframe(), sendDATAframe(), and sendRTSframe().
00973 { 00974 simtime_t time_out = 0; 00975 switch (type) 00976 { 00977 case RTS: 00978 time_out = SIFS + computePacketDuration(LENGTH_RTS) + computePacketDuration(LENGTH_CTS) + delta; 00979 break; 00980 case CTS: 00981 time_out = last_frame_duration - computePacketDuration(LENGTH_ACK) - 2 * SIFS + delta; 00982 break; 00983 case DATA: 00984 time_out = 00985 SIFS + computePacketDuration(fromUpperLayer.front()->getBitLength()) + computePacketDuration(LENGTH_ACK) + 00986 delta + 0.1; 00987 //XXX: I have added some time here, because propagation delay of AirFrames caused problems 00988 // the timeout periods should be carefully revised with special care for the deltas?! --Levy 00989 break; 00990 default: 00991 EV << "Unused frame type was given when calling computeTimeout(), this should not happen!\n"; 00992 } 00993 return time_out; 00994 }
simtime_t Mac80211::computePacketDuration | ( | int | bits | ) | [protected, virtual] |
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.
Referenced by buildCTSframe(), buildDATAframe(), buildRTSframe(), computeTimeout(), initialize(), sendACKframe(), and sendBROADCASTframe().
01002 { 01003 return bits / bitrate + PHY_HEADER_LENGTH / BITRATE_HEADER; 01004 }
const char * Mac80211::stateName | ( | State | state | ) | [static, protected] |
Produce a readable name of the given state.
Referenced by handleMsgForMe(), and setState().
01007 { 01008 #define CASE(x) case x: s=#x; break 01009 const char *s = "???"; 01010 switch (state) 01011 { 01012 CASE(WFDATA); 01013 CASE(QUIET); 01014 CASE(IDLE); 01015 CASE(CONTEND); 01016 CASE(WFCTS); 01017 CASE(WFACK); 01018 CASE(BUSY); 01019 } 01020 return s; 01021 #undef CASE 01022 }
const char * Mac80211::timerTypeName | ( | int | type | ) | [static, protected] |
Produce a readable name of the given timer type.
Referenced by handleSelfMsg().
01025 { 01026 #define CASE(x) case x: s=#x; break 01027 const char *s = "???"; 01028 switch (type) 01029 { 01030 CASE(TIMEOUT); 01031 CASE(NAV); 01032 CASE(CONTENTION); 01033 CASE(END_TRANSMISSION); 01034 CASE(END_SIFS); 01035 } 01036 return s; 01037 #undef CASE 01038 }
const char * Mac80211::pktTypeName | ( | int | type | ) | [static, protected] |
Produce a readable name of the given packet type.
Referenced by handleLowerMsg(), and handleMsgForMe().
01041 { 01042 #define CASE(x) case x: s=#x; break 01043 const char *s = "???"; 01044 switch (type) 01045 { 01046 CASE(TIMEOUT); 01047 CASE(DATA); 01048 CASE(BROADCAST); 01049 CASE(RTS); 01050 CASE(CTS); 01051 CASE(ACK); 01052 CASE(ACKRTS); 01053 CASE(BEGIN_RECEPTION); 01054 CASE(BITERROR); 01055 CASE(COLLISION); 01056 } 01057 return s; 01058 #undef CASE 01059 }
void Mac80211::setState | ( | State | state | ) | [protected, virtual] |
Sets the state, and produces a log message in between.
Referenced by beginNewCycle(), handleEndContentionTimer(), handleMsgNotForMe(), receiveChangeNotification(), sendACKframe(), sendBROADCASTframe(), sendCTSframe(), sendDATAframe(), and sendRTSframe().
01062 { 01063 if (state==newState) 01064 EV << "staying in state " << stateName(state) << "\n"; 01065 else 01066 EV << "state " << stateName(state) << " --> " << stateName(newState) << "\n"; 01067 state = newState; 01068 }
MACAddress Mac80211::myMacAddr [protected] |
mac address
Referenced by buildACKframe(), buildCTSframe(), buildDATAframe(), encapsMsg(), handleLowerMsg(), and registerInterface().
cMessage* Mac80211::timeout [protected] |
Timer used for time-outs after the transmission of a RTS, a CTS, or a DATA packet.
Referenced by handleACKframe(), handleCTSframe(), handleDATAframe(), handleMsgNotForMe(), initialize(), Mac80211(), sendCTSframe(), sendDATAframe(), sendRTSframe(), and ~Mac80211().
cMessage* Mac80211::nav [protected] |
Timer used for the defer time of a node. Also called NAV : networks allocation vector.
Referenced by handleMsgNotForMe(), initialize(), Mac80211(), and ~Mac80211().
cMessage* Mac80211::contention [protected] |
Timer used for contention periods.
Referenced by beginNewCycle(), handleMsgNotForMe(), initialize(), Mac80211(), receiveChangeNotification(), and ~Mac80211().
cMessage* Mac80211::endTransmission [protected] |
Timer used to indicate the end of the transmission of an ACK or a BROADCAST packet.
Referenced by initialize(), Mac80211(), sendACKframe(), sendBROADCASTframe(), and ~Mac80211().
cMessage* Mac80211::endSifs [protected] |
Timer used to indicate the end of a SIFS.
Referenced by handleCTSframe(), handleDATAframe(), handleEndSifsTimer(), handleRTSframe(), handleUpperMsg(), initialize(), Mac80211(), receiveChangeNotification(), and ~Mac80211().
simtime_t Mac80211::EIFS [protected] |
simtime_t Mac80211::BW [protected] |
Variable to store the current backoff value.
Referenced by computeBackoff(), handleEndContentionTimer(), initialize(), and receiveChangeNotification().
State Mac80211::state [protected] |
Current state of the MAC.
Referenced by handleBroadcastMsg(), handleEndContentionTimer(), handleEndTransmissionTimer(), handleLowerMsg(), handleMsgForMe(), handleMsgNotForMe(), handleNavTimer(), handleTimeoutTimer(), handleUpperMsg(), initialize(), and setState().
RadioState::State Mac80211::radioState [protected] |
Current state of the radio (kept updated by receiveChangeNotification()).
Referenced by beginNewCycle(), initialize(), and receiveChangeNotification().
int Mac80211::maxQueueSize [protected] |
Maximal number of packets in the queue; should be set in the omnetpp.ini.
Referenced by handleUpperMsg(), and initialize().
bool Mac80211::nextIsBroadcast [protected] |
Boolean used to know if the next packet is a broadcast packet.
Referenced by beginNewCycle(), computeContentionWindow(), and handleEndContentionTimer().
MacPktList Mac80211::fromUpperLayer [protected] |
Buffering of messages from upper layer.
Referenced by beginNewCycle(), buildBROADCASTframe(), buildDATAframe(), buildRTSframe(), computeTimeout(), handleACKframe(), handleEndContentionTimer(), handleUpperMsg(), receiveChangeNotification(), sendBROADCASTframe(), and testMaxAttempts().
int Mac80211::retryCounter [protected] |
Number of frame transmission attempt.
Referenced by computeContentionWindow(), handleACKframe(), initialize(), sendDATAframe(), sendRTSframe(), and testMaxAttempts().
bool Mac80211::tryWithoutBackoff [protected] |
If there's a new packet to send and the channel is free, no backoff is needed.
Referenced by beginNewCycle(), and handleUpperMsg().
bool Mac80211::rtsCts [protected] |
true if Rts/Cts is used, false if not; can be set in omnetpp.ini
Referenced by buildDATAframe(), handleDATAframe(), handleEndContentionTimer(), handleMsgNotForMe(), initialize(), and sendDATAframe().
simtime_t Mac80211::delta [protected] |
Very small value used in timer scheduling in order to avoid multiple changements of state in the same simulation time.
Referenced by computeTimeout(), initialize(), and sendACKframe().
double Mac80211::bitrate [protected] |
The bitrate should be set in omnetpp.ini; be sure to use a valid 802.11 bitrate.
Referenced by computePacketDuration(), and initialize().
int Mac80211::broadcastBackoff [protected] |