INET Framework for OMNeT++/OMNEST
Mac80211.cc
Go to the documentation of this file.
00001 /***************************************************************************
00002  * file:        Mac80211.cc
00003  *
00004  * author:      David Raguin / Marc L�bbers
00005  *
00006  * copyright:   (C) 2004 Telecommunication Networks Group (TKN) at
00007  *              Technische Universitaet Berlin, Germany.
00008  *
00009  *              This program is free software; you can redistribute it
00010  *              and/or modify it under the terms of the GNU General Public
00011  *              License as published by the Free Software Foundation; either
00012  *              version 2 of the License, or (at your option) any later
00013  *              version.
00014  *              For further information see file COPYING
00015  *              in the top level directory
00016  ***************************************************************************
00017  * part of:     framework implementation developed by tkn
00018  **************************************************************************/
00019 
00020 
00021 #include "Mac80211.h"
00022 #include "Ieee802Ctrl_m.h"
00023 #include "RadioState.h"
00024 #include "IInterfaceTable.h"
00025 #include "InterfaceTableAccess.h"
00026 
00027 
00028 Define_Module(Mac80211);
00029 
00030 
00031 Mac80211::Mac80211()
00032 {
00033     timeout = nav = contention = endTransmission = endSifs = NULL;
00034 }
00035 
00036 Mac80211::~Mac80211()
00037 {
00038     cancelAndDelete(timeout);
00039     cancelAndDelete(nav);
00040     cancelAndDelete(contention);
00041     cancelAndDelete(endTransmission);
00042     cancelAndDelete(endSifs);
00043 }
00044 
00045 void Mac80211::initialize(int stage)
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 }
00084 
00085 
00086 void Mac80211::registerInterface()
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 }
00131 
00132 void Mac80211::handleCommand(cMessage *msg)
00133 {
00134     // no commands supported by Mac80211
00135     error("Non-packet message arrived from higher layer: (%s)%s", msg->getClassName(), msg->getName());
00136 }
00137 
00142 void Mac80211::handleUpperMsg(cPacket *msg)
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(), (int)(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 }
00170 
00175 Mac80211Pkt *Mac80211::encapsMsg(cPacket *netw)
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 }
00193 
00194 void Mac80211::decapsulateAndSendUp(Mac80211Pkt *frame)
00195 {
00196     cPacket *msg = frame->decapsulate();
00197     // FIXME TBD set control info
00198     delete frame;
00199     sendUp(msg);
00200 }
00201 
00208 void Mac80211::handleLowerMsg(cPacket *msg)
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 }
00238 
00242 void Mac80211::handleSelfMsg(cMessage * msg)
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 }
00274 
00275 
00285 void Mac80211::handleMsgNotForMe(Mac80211Pkt *af)
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 }
00343 
00344 
00351 void Mac80211::handleMsgForMe(Mac80211Pkt *af)
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 }
00411 
00416 void Mac80211::handleRTSframe(Mac80211Pkt * af)
00417 {
00418     // wait a short interframe space
00419     endSifs->setContextPointer(af);
00420     scheduleAt(simTime() + SIFS, endSifs);
00421 }
00422 
00423 
00428 void Mac80211::handleDATAframe(Mac80211Pkt * af)
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 }
00443 
00444 
00449 void Mac80211::handleACKframe(Mac80211Pkt * af)
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 }
00467 
00468 
00472 void Mac80211::handleCTSframe(Mac80211Pkt * af)
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 }
00481 
00482 
00488 void Mac80211::handleBroadcastMsg(Mac80211Pkt *af)
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 }
00499 
00500 
00506 void Mac80211::handleEndContentionTimer()
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 }
00543 
00548 void Mac80211::handleNavTimer()
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 }
00556 
00557 
00561 void Mac80211::handleTimeoutTimer()
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 }
00570 
00571 
00576 void Mac80211::handleEndSifsTimer()
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 }
00598 
00604 void Mac80211::handleEndTransmissionTimer()
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 }
00613 
00614 
00619 void Mac80211::sendDATAframe()
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 }
00636 
00637 
00641 void Mac80211::sendACKframe(Mac80211Pkt * af)
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 }
00654 
00655 
00659 void Mac80211::sendRTSframe()
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 }
00673 
00674 
00678 void Mac80211::sendCTSframe(Mac80211Pkt * af)
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 }
00689 
00693 void Mac80211::sendBROADCASTframe()
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 }
00704 
00705 
00709 Mac80211Pkt *Mac80211::buildDATAframe()
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 }
00722 
00723 
00727 Mac80211Pkt *Mac80211::buildACKframe(Mac80211Pkt * af)
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 }
00741 
00742 
00746 Mac80211Pkt *Mac80211::buildRTSframe()
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 }
00761 
00765 Mac80211Pkt *Mac80211::buildCTSframe(Mac80211Pkt * af)
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 }
00779 
00783 Mac80211Pkt *Mac80211::buildBROADCASTframe()
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 }
00790 
00791 
00799 void Mac80211::beginNewCycle()
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 }
00843 
00847 simtime_t Mac80211::computeBackoff()
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 }
00863 
00871 int Mac80211::computeContentionWindow()
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 }
00888 
00889 
00890 
00895 void Mac80211::testMaxAttempts()
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 }
00909 
00914 void Mac80211::receiveChangeNotification(int category, const cPolymorphic *details)
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 }
00966 
00967 
00972 simtime_t Mac80211::computeTimeout(_802_11frameType type, simtime_t last_frame_duration)
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 }
00995 
01001 simtime_t Mac80211::computePacketDuration(int bits)
01002 {
01003     return bits / bitrate + PHY_HEADER_LENGTH / BITRATE_HEADER;
01004 }
01005 
01006 const char *Mac80211::stateName(State state)
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 }
01023 
01024 const char *Mac80211::timerTypeName(int type)
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 }
01039 
01040 const char *Mac80211::pktTypeName(int type)
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 }
01060 
01061 void Mac80211::setState(State newState)
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 }
01069 
01070