Mac80211.cc

00001 /***************************************************************************
00002  * file:        Mac80211.cc
00003  *
00004  * author:      David Raguin / Marc L�bbers / Andreas Koepke
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 "MacToPhyControlInfo.h"
00023 #include <MacToNetwControlInfo.h>
00024 #include <PhyToMacControlInfo.h>
00025 #include <NetwToMacControlInfo.h>
00026 #include "SimpleAddress.h"
00027 #include <FWMath.h>
00028 #include <Decider80211.h>
00029 #include <DeciderResult80211.h>
00030 #include <BaseConnectionManager.h>
00031 
00032 Define_Module(Mac80211);
00033 
00034 
00035 void Mac80211::initialize(int stage)
00036 {
00037     BaseMacLayer::initialize(stage);
00038 
00039     if (stage == 0)
00040     {
00041         debugEV << "Initializing stage 0\n";
00042 
00043         switching = false;
00044         fsc = intrand(0x7FFFFFFF);
00045         if(fsc == 0) fsc = 1;
00046         debugEV << " fsc: " << fsc << "\n";
00047 
00048         queueLength = hasPar("queueLength") ? par("queueLength").longValue() : 10;
00049 
00050         // timers
00051         timeout = new cMessage("timeout", TIMEOUT);
00052         nav = new cMessage("NAV", NAV);
00053         contention = new ChannelSenseRequest("contention", MacToPhyInterface::CHANNEL_SENSE_REQUEST);
00054         contention->setSenseMode(UNTIL_BUSY);
00055         endSifs = new ChannelSenseRequest("end SIFS", MacToPhyInterface::CHANNEL_SENSE_REQUEST);
00056         endSifs->setSenseMode(UNTIL_BUSY);
00057         endSifs->setSenseTimeout(SIFS);
00058 
00059         state = IDLE;
00060         longRetryCounter = 0;
00061         shortRetryCounter = 0;
00062         rtsCtsThreshold = hasPar("rtsCtsThreshold") ? par("rtsCtsThreshold").longValue() : 1;
00063         currentIFS = EIFS;
00064 
00065         autoBitrate = hasPar("autoBitrate") ? par("autoBitrate").boolValue() : false;
00066 
00067         txPower = hasPar("txPower") ? par("txPower").doubleValue() : 110.11;
00068 
00069 
00070         delta = 1E-9;
00071 
00072         debugEV << "SIFS: " << SIFS << " DIFS: " << DIFS << " EIFS: " << EIFS << endl;
00073     }
00074     else if(stage == 1) {
00075       BaseConnectionManager* cc = getConnectionManager();
00076 
00077       if(cc->hasPar("pMax") && txPower > cc->par("pMax").doubleValue())
00078             opp_error("TranmitterPower can't be bigger than pMax in ConnectionManager! "
00079                     "Please adjust your omnetpp.ini file accordingly.");
00080 
00081       int channel = phy->getCurrentRadioChannel();
00082       if(!(1<=channel && channel<=14)) {
00083         opp_error("Radio set to invalid channel %d. Please make sure the"
00084               " phy modules parameter \"initialRadioChannel\" is set to"
00085               " a valid 802.11 channel (1 to 14)!", channel);
00086       }
00087       centerFreq = CENTER_FREQUENCIES[channel];
00088 
00089         bool found = false;
00090         bitrate = hasPar("bitrate") ? par("bitrate").doubleValue() : BITRATES_80211[0];
00091         for(int i = 0; i < 4; i++) {
00092             if(bitrate == BITRATES_80211[i]) {
00093                 found = true;
00094                 break;
00095             }
00096         }
00097         if(!found) bitrate = BITRATES_80211[0];
00098         defaultBitrate = bitrate;
00099 
00100         snrThresholds.push_back(hasPar("snr2Mbit") ? par("snr2Mbit").doubleValue() : 100);
00101         snrThresholds.push_back(hasPar("snr5Mbit") ? par("snr5Mbit").doubleValue() : 100);
00102         snrThresholds.push_back(hasPar("snr11Mbit") ? par("snr11Mbit").doubleValue() : 100);
00103         snrThresholds.push_back(111111111); // sentinel
00104 
00105         neighborhoodCacheSize = hasPar("neighborhoodCacheSize") ? par("neighborhoodCacheSize").longValue() : 0;
00106         neighborhoodCacheMaxAge = hasPar("neighborhoodCacheMaxAge") ? par("neighborhoodCacheMaxAge").longValue() : 10000;
00107 
00108         debugEV << " MAC Address: " << myMacAddr
00109            << " rtsCtsThreshold: " << rtsCtsThreshold
00110            << " bitrate: " << bitrate
00111            << " channel: " << channel
00112            << " autoBitrate: " << autoBitrate
00113            << " 2MBit: " << snrThresholds[0]
00114            << " 5.5MBit: " <<snrThresholds[1]
00115            << " 11MBit: " << snrThresholds[2]
00116            << " neighborhoodCacheSize " << neighborhoodCacheSize
00117            << " neighborhoodCacheMaxAge " << neighborhoodCacheMaxAge
00118            << endl;
00119 
00120         for(int i = 0; i < 3; i++) {
00121             snrThresholds[i] = FWMath::dBm2mW(snrThresholds[i]);
00122         }
00123 
00124         remainingBackoff = backoff();
00125         senseChannelWhileIdle(remainingBackoff + currentIFS);
00126     }
00127 }
00128 
00129 void Mac80211::senseChannelWhileIdle(simtime_t duration) {
00130   if(contention->isScheduled()) {
00131     error("Cannot start a new channel sense request because already sensing the channel!");
00132   }
00133 
00134   chSenseStart = simTime();
00135   contention->setSenseTimeout(duration);
00136 
00137   sendControlDown(contention);
00138 }
00139 
00144 void Mac80211::handleUpperMsg(cMessage *msg)
00145 {
00146   cPacket* pkt = static_cast<cPacket*>(msg);
00147 
00148   debugEV << "Mac80211::handleUpperMsg " << msg->getName() << "\n";
00149     if (pkt->getBitLength() > 18496){
00150         error("packet from higher layer (%s)%s is too long for 802.11b, %d bytes (fragmentation is not supported yet)",
00151               pkt->getClassName(), pkt->getName(), pkt->getByteLength());
00152     }
00153 
00154     if(fromUpperLayer.size() == queueLength) {
00155     //TODO: CSMAMacLayer does create a new mac packet and sends it up. Maybe settle on a consistent solution here
00156         msg->setName("MAC ERROR");
00157         msg->setKind(PACKET_DROPPED);
00158         sendControlUp(msg);
00159         debugEV << "packet " << msg << " received from higher layer but MAC queue is full, signalling error\n";
00160         return;
00161     }
00162 
00163     Mac80211Pkt *mac = encapsMsg(pkt);
00164     debugEV << "packet " << pkt << " received from higher layer, dest=" << mac->getDestAddr() << ", encapsulated\n";
00165 
00166     fromUpperLayer.push_back(mac);
00167     // If the MAC is in the IDLE state, then start a new contention period
00168     if (state == IDLE && !endSifs->isScheduled()) {
00169         beginNewCycle();
00170     }
00171     else
00172     {
00173       debugEV << "enqueued, will be transmitted later\n";
00174     }
00175 }
00176 
00181 Mac80211Pkt *Mac80211::encapsMsg(cPacket * netw)
00182 {
00183 
00184     Mac80211Pkt *pkt = new Mac80211Pkt(netw->getName());
00185     // headerLength, including final CRC-field AND the phy header length!
00186     pkt->setBitLength(MAC80211_HEADER_LENGTH);
00187     pkt->setRetry(false);                 // this is not a retry
00188     pkt->setSequenceControl(fsc++);       // add a unique fsc to it
00189     if(fsc <= 0) fsc = 1;
00190 
00191     // copy dest address from the Control Info attached to the network
00192     // mesage by the network layer
00193     NetwToMacControlInfo* cInfo = static_cast<NetwToMacControlInfo*>(netw->removeControlInfo());
00194 
00195     debugEV <<"CInfo removed, mac addr="<< cInfo->getNextHopMac()<<endl;
00196     pkt->setDestAddr(cInfo->getNextHopMac());
00197 
00198     //delete the control info
00199     delete cInfo;
00200 
00201     //set the src address to own mac address (nic module id())
00202     pkt->setSrcAddr(myMacAddr);
00203 
00204     //encapsulate the network packet
00205     pkt->encapsulate(netw);
00206     debugEV <<"pkt encapsulated, length: " << pkt->getBitLength() << "\n";
00207 
00208     return pkt;
00209 }
00210 
00211 //TODO: See if we can use the BaseMacLayers decapsMsg-method here
00212 cMessage *Mac80211::decapsMsg(Mac80211Pkt *frame) {
00213     cMessage *m = frame->decapsulate();
00214     m->setControlInfo(new MacToNetwControlInfo(frame->getSrcAddr(), 0));
00215     debugEV << " message decapsulated " << endl;
00216     return m;
00217 }
00218 
00225 void Mac80211::handleLowerMsg(cMessage *msg)
00226 {
00227     Mac80211Pkt *af = static_cast<Mac80211Pkt *>(msg);
00228     int radioState = phy->getRadioState();
00229     if(radioState == Radio::RX) {
00230         // end of the reception
00231       debugEV << " handleLowerMsg frame " << af << " received\n";
00232         addNeighbor(af);
00233         if (contention->isScheduled()) {
00234             error("Gaack! I am changing the IFS on an ongoing contention");
00235         }
00236         currentIFS = DIFS;
00237         if(af->getDestAddr() == myMacAddr) {
00238             handleMsgForMe(af);
00239         }
00240         else if(af->getDestAddr() == L2BROADCAST) {
00241             handleBroadcastMsg(af);
00242         }
00243         else {
00244             handleMsgNotForMe(af, af->getDuration());
00245         }
00246     }
00247     else {
00248       debugEV << " handleLowerMsg frame " << af << " deleted, strange race condition\n";
00249         delete af;
00250     }
00251 }
00252 
00253 void Mac80211::handleLowerControl(cMessage *msg)
00254 {
00255   debugEV << simTime() << " handleLowerControl " << msg->getName() << "\n";
00256     switch(msg->getKind()) {
00257     case MacToPhyInterface::CHANNEL_SENSE_REQUEST:
00258       if(msg == contention) {
00259         handleEndContentionTimer();
00260       } else if(msg == endSifs) {
00261         handleEndSifsTimer();   // noch zu betrachten
00262       } else {
00263         error("Unknown ChannelSenseRequest returned!");
00264       }
00265         break;
00266 
00267     case Decider80211::COLLISION:
00268     case Decider80211::BITERROR:
00269     {
00270       int radioState = phy->getRadioState();
00271         if(radioState == Radio::RX) {
00272             if (contention->isScheduled()) {
00273                 error("Gaack! I am changing the IFS on an ongoing contention");
00274             }
00275             currentIFS = EIFS;
00276             handleMsgNotForMe(msg, 0);
00277         }
00278         else {
00279           debugEV << " frame " << msg->getName() << " deleted, strange race condition\n";
00280             delete msg;
00281         }
00282         break;
00283     }
00284     case MacToPhyInterface::TX_OVER:
00285       debugEV << "PHY indicated transmission over" << endl;
00286         phy->setRadioState(Radio::RX);
00287         handleEndTransmission();
00288         delete msg;
00289         break;
00290 
00291     case MacToPhyInterface::RADIO_SWITCHING_OVER:
00292       //TODO: handle this correctly (by now we assume switch times are zero)
00293       delete msg;
00294       break;
00295 
00296     default:
00297       ev << "Unhandled control message from physical layer: " << msg << endl;
00298       delete msg;
00299     }
00300 }
00301 
00302 
00306 void Mac80211::handleSelfMsg(cMessage * msg)
00307 {
00308   debugEV << simTime() << " handleSelfMsg " << msg->getName() << "\n";
00309     switch (msg->getKind())
00310     {
00311         // the MAC was waiting for a CTS, a DATA, or an ACK packet but the timer has expired.
00312     case TIMEOUT:
00313         handleTimeoutTimer();   // noch zu betrachten..
00314         break;
00315 
00316         // the MAC was waiting because an other communication had won the channel. This communication is now over
00317     case NAV:
00318         handleNavTimer();       // noch zu betrachten...
00319         break;
00320 
00321     default:
00322         error("unknown timer type");
00323     }
00324 }
00325 
00326 
00336 void Mac80211::handleMsgNotForMe(cMessage *af, simtime_t duration)
00337 {
00338   debugEV << "handle msg not for me " << af->getName() << "\n";
00339 
00340     // if the duration of the packet is null, then do nothing (to avoid
00341     // the unuseful scheduling of a self message)
00342     if(duration != 0) {
00343         // the node is already deferring
00344         if (state == QUIET)
00345         {
00346             // the current value of the NAV is not sufficient
00347             if (nav->getArrivalTime() < simTime() + duration)
00348             {
00349                 cancelEvent(nav);
00350                 scheduleAt(simTime() + duration, nav);
00351                 debugEV << "NAV timer started for: " << duration << " State QUIET\n";
00352             }
00353         }
00354         // other states
00355         else
00356         {
00357             // if the MAC wait for another frame, it can delete its time out
00358             // (exchange is aborted)
00359             if (timeout->isScheduled()) {
00360                 cancelEvent(timeout);
00361                 if(state == WFACK) {
00362                     fromUpperLayer.front()->setRetry(true);
00363                 }
00364                 if((state == WFACK) || (state == WFCTS)) {
00365                     if(rtsCts(fromUpperLayer.front())) {
00366                         longRetryCounter++;
00367                     }
00368                     else {
00369                         shortRetryCounter++;
00370                     }
00371                 }
00372             }
00373             // the node must defer for the time of the transmission
00374             scheduleAt(simTime() + duration, nav);
00375             debugEV << "NAV timer started, not QUIET: " << duration << endl;
00376 
00377             assert(!contention->isScheduled());
00378             //suspendContention();
00379 
00380             setState(QUIET);
00381         }
00382     }
00383 
00384     if((af->getKind() == Decider80211::BITERROR) || (af->getKind() == Decider80211::COLLISION)) {
00385 
00386       assert(!contention->isScheduled());
00387         //suspendContention();
00388         //if (contention->isScheduled()) {
00389         //    error("Gaack! I am changing the IFS on an ongoing contention");
00390         //}
00391 
00392       //handle broken cts and ACK frames
00393       if(state == WFCTS) {
00394         assert(timeout->isScheduled());
00395         cancelEvent(timeout);
00396         rtsTransmissionFailed();
00397       }
00398       else if(state == WFACK) {
00399         assert(timeout->isScheduled());
00400       cancelEvent(timeout);
00401         dataTransmissionFailed();
00402       }
00403 
00404         currentIFS = EIFS;
00405     }
00406 
00407     beginNewCycle();
00408     delete af;
00409 }
00410 
00411 
00418 void Mac80211::handleMsgForMe(Mac80211Pkt *af)
00419 {
00420   debugEV << "handle msg for me " << af->getName() << " in " <<  stateName(state) << "\n";
00421 
00422     switch (state)
00423     {
00424     case IDLE:     // waiting for the end of the contention period
00425     case CONTEND:  // or waiting for RTS
00426 
00427         // RTS or DATA accepted
00428         if (af->getKind() == RTS) {
00429           assert(!contention->isScheduled());
00430       //suspendContention();
00431 
00432             handleRTSframe(af);
00433         }
00434         else if (af->getKind() == DATA) {
00435           assert(!contention->isScheduled());
00436           //suspendContention();
00437 
00438             handleDATAframe(af);
00439         }
00440         else {
00441             error("in handleMsgForMe() IDLE/CONTEND, strange message %s", af->getName());
00442         }
00443         break;
00444 
00445     case WFDATA:  // waiting for DATA
00446         if (af->getKind() == DATA) {
00447             handleDATAframe(af);
00448         }
00449         else {
00450           EV << "unexpected message -- probably a collision of RTSs\n";
00451             delete af;
00452         }
00453         break;
00454 
00455     case WFACK:  // waiting for ACK
00456         if (af->getKind() == ACK) {
00457             handleACKframe(af);
00458         }
00459         else {
00460             error("in handleMsgForMe() WFACK, strange message %s", af->getName());
00461         }
00462         delete af;
00463         break;
00464 
00465     case WFCTS:  // The MAC is waiting for CTS
00466         if (af->getKind() == CTS) {
00467             handleCTSframe(af);
00468         }
00469         else {
00470             EV << "unexpected msg -- deleted \n";
00471             delete af;
00472         }
00473         break;
00474     case QUIET: // the node is currently deferring.
00475 
00476         // cannot handle any packet with its MAC adress
00477         delete af;
00478         break;
00479 
00480     case BUSY: // currently transmitting an ACK or a BROADCAST packet
00481         if(switching) {
00482             EV << "message received during radio state switchover\n";
00483             delete af;
00484         }
00485         else {
00486             error("logic error: node is currently transmitting, can not receive "
00487                   "(does the physical layer do its job correctly?)");
00488         }
00489         break;
00490     default:
00491         error("unknown state %d", state);
00492     }
00493 }
00494 
00499 void Mac80211::handleRTSframe(Mac80211Pkt * af)
00500 {
00501     if(endSifs->isScheduled()) error("Mac80211::handleRTSframe when SIFS scheduled");
00502     // wait a short interframe space
00503     endSifs->setContextPointer(af);
00504 
00505     sendControlDown(endSifs);
00506     //scheduleAt(simTime() + SIFS, endSifs);
00507 }
00508 
00509 
00514 void Mac80211::handleDATAframe(Mac80211Pkt * af)
00515 {
00516     NeighborList::iterator it;
00517     if (rtsCts(af)) cancelEvent(timeout);  // cancel time-out event
00518     it = findNeighbor(af->getSrcAddr());
00519     if(it == neighbors.end()) error("Mac80211::handleDATAframe: neighbor not registered");
00520     if(af->getRetry() && (it->fsc == af->getSequenceControl())) {
00521       debugEV << "Mac80211::handleDATAframe suppressed duplicate message " << af
00522            << " fsc: " << it->fsc << "\n";
00523     }
00524     else {
00525         it->fsc = af->getSequenceControl();
00526         // pass the packet to the upper layer
00527         sendUp(decapsMsg(af));
00528     }
00529     // wait a short interframe space
00530     if(endSifs->isScheduled()) error("Mac80211::handleDATAframe when SIFS scheduled");
00531     endSifs->setContextPointer(af);
00532 
00533     sendControlDown(endSifs);
00534     //scheduleAt(simTime() + SIFS, endSifs);
00535 }
00536 
00537 
00541 void Mac80211::handleACKframe(Mac80211Pkt * af)
00542 {
00543     // cancel time-out event
00544     cancelEvent(timeout);
00545 
00546     // the transmission is acknowledged : initialize long_retry_counter
00547     longRetryCounter = 0;
00548     shortRetryCounter = 0;
00549     // post transmit backoff
00550     remainingBackoff = backoff();
00551     // removes the acknowledged packet from the queue
00552     Mac80211Pkt *temp = fromUpperLayer.front();
00553     fromUpperLayer.pop_front();
00554     delete temp;
00555 
00556     // if thre's a packet to send and if the channel is free then start a new contention period
00557     beginNewCycle();
00558 }
00559 
00560 
00564 void Mac80211::handleCTSframe(Mac80211Pkt * af)
00565 {
00566     // cancel time-out event
00567     cancelEvent(timeout);
00568     shortRetryCounter = 0;
00569     // wait a short interframe space
00570     if(endSifs->isScheduled()) error("Mac80211::handleCTSframe when SIFS scheduled");
00571     endSifs->setContextPointer(af);
00572 
00573     sendControlDown(endSifs);
00574     //scheduleAt(simTime() + SIFS, endSifs);
00575 }
00576 
00577 
00583 void Mac80211::handleBroadcastMsg(Mac80211Pkt *af)
00584 {
00585   debugEV << "handle broadcast\n";
00586     if((state == BUSY) && (!switching)) {
00587         error("logic error: node is currently transmitting, can not receive "
00588               "(does the physical layer do its job correctly?)");
00589     }
00590     sendUp(decapsMsg(af));
00591     delete af;
00592     if (state == CONTEND) {
00593       assert(!contention->isScheduled());
00594     //suspendContention();
00595 
00596         beginNewCycle();
00597     }
00598 }
00599 
00600 
00606 void Mac80211::handleEndContentionTimer()
00607 {
00608   if(!contention->getResult().isIdle()) {
00609     suspendContention();
00610     return;
00611   }
00612 
00613     if(state == IDLE) {
00614         remainingBackoff = 0;
00615     }
00616     else if(state == CONTEND) {
00617         // the node has won the channel, the backoff window is deleted and
00618         // will be new calculated in the next contention period
00619         remainingBackoff = 0;
00620         // unicast packet
00621         phy->setRadioState(Radio::TX);
00622         if (!nextIsBroadcast)
00623         {
00624             if(rtsCts(fromUpperLayer.front())) {
00625                 // send a RTS
00626                 sendRTSframe();
00627             }
00628             else {
00629                 sendDATAframe(0);
00630             }
00631         }// broadcast packet
00632         else {
00633             sendBROADCASTframe();
00634             // removes the packet from the queue without waiting for an acknowledgement
00635             Mac80211Pkt *temp = fromUpperLayer.front();
00636             fromUpperLayer.pop_front();
00637             delete(temp);
00638         }
00639     }
00640     else {
00641         error("logic error: expiration of the contention timer outside of CONTEND/IDLE state, should not happen");
00642     }
00643 }
00644 
00649 void Mac80211::handleNavTimer()
00650 {
00651     if (state != QUIET)
00652         error("logic error: expiration of the NAV timer outside of the state QUIET, should not happen");
00653 
00654     // if there's a packet to send and if the channel is free, then start a new contention period
00655 
00656     // lmf - Potential race condition: If nav expires at same time
00657     // medium becomes IDLE (usual case), but the navTimeout comes
00658     // before the mediumIndication, then the medium is still BUSY when
00659     // beginNewCycle() is called, so the backoff doesn't resume.
00660     // Usually it doesn't matter, since there is also an arriving
00661     // frame and so beginNewCycle() will be called again by the
00662     // handleMsgXXX.  But if there is no frame (mobility, exposed
00663     // terminal, etc) there's a potential problem.
00664 
00665     beginNewCycle();
00666 }
00667 
00668 
00669 
00670 void Mac80211::dataTransmissionFailed()
00671 {
00672   bool rtscts = rtsCts(fromUpperLayer.front());
00673     if(rtscts){
00674         longRetryCounter++;
00675     }else{
00676         shortRetryCounter++;
00677     }
00678     fromUpperLayer.front()->setRetry(true);
00679     remainingBackoff = backoff(rtscts);
00680 }
00681 
00682 
00683 void Mac80211::rtsTransmissionFailed()
00684 {
00685     longRetryCounter++;
00686     remainingBackoff = backoff();
00687 }
00688 
00692 void Mac80211::handleTimeoutTimer()
00693 {
00694     debugEV << simTime() << " handleTimeoutTimer " << stateName(state) << "\n";
00695     if(state == WFCTS) {
00696       rtsTransmissionFailed();
00697     }
00698     else if(state == WFACK) {
00699       dataTransmissionFailed();
00700     }
00701 
00702     // if there's a packet to send and if the channel is free then
00703     // start a new contention period
00704     if (state != QUIET)
00705         beginNewCycle();
00706 }
00707 
00708 
00713 void Mac80211::handleEndSifsTimer()
00714 {
00715   if(!endSifs->getResult().isIdle()){
00716     // delete the previously received frame
00717     delete static_cast<Mac80211Pkt *>(endSifs->getContextPointer());
00718 
00719     // state in now IDLE or CONTEND
00720     if (fromUpperLayer.empty())
00721       setState(IDLE);
00722     else
00723       setState(CONTEND);
00724 
00725     return;
00726   }
00727 
00728     Mac80211Pkt *frame = static_cast<Mac80211Pkt *>(endSifs->getContextPointer());
00729     phy->setRadioState(Radio::TX);
00730     switch (frame->getKind())
00731     {
00732     case RTS:
00733         sendCTSframe(frame);
00734         break;
00735     case CTS:
00736         sendDATAframe(frame);
00737         break;
00738     case DATA:
00739         sendACKframe(frame);
00740         break;
00741     default:
00742         error("logic error: end sifs timer when previously received packet is not RTS/CTS/DATA");
00743     }
00744 
00745     // don't need previous frame any more
00746     delete frame;
00747 }
00748 
00754 void Mac80211::handleEndTransmission()
00755 {
00756   debugEV << "transmission of packet is over\n";
00757     if(state == BUSY) {
00758         if(nextIsBroadcast) {
00759             shortRetryCounter = 0;
00760             longRetryCounter = 0;
00761             remainingBackoff = backoff();
00762         }
00763         beginNewCycle();
00764     }
00765     else if(state == WFDATA) {
00766       beginNewCycle();
00767     }
00768 }
00769 
00774 void Mac80211::sendDATAframe(Mac80211Pkt *af)
00775 {
00776     Mac80211Pkt *frame = static_cast<Mac80211Pkt *>(fromUpperLayer.front()->dup());
00777     double br;
00778 
00779     if(af) {
00780       PhyToMacControlInfo* tmp = static_cast<PhyToMacControlInfo*>(af->removeControlInfo());
00781 
00782         br = static_cast<const DeciderResult80211*>(tmp->getDeciderResult())->getBitrate();
00783 
00784         delete tmp;
00785     }
00786     else {
00787        br  = retrieveBitrate(frame->getDestAddr());
00788 
00789        if(shortRetryCounter) frame->setRetry(true);
00790     }
00791     simtime_t duration = packetDuration(frame->getBitLength(), br);
00792     Signal* signal = createSignal(simTime(), duration, txPower, br);
00793     MacToPhyControlInfo *pco = new MacToPhyControlInfo(signal);
00794     // build a copy of the frame in front of the queue'
00795     frame->setControlInfo(pco);
00796     frame->setSrcAddr(myMacAddr);
00797     frame->setKind(DATA);
00798     frame->setDuration(SIFS + packetDuration(LENGTH_ACK, br));
00799 
00800     // schedule time out
00801     scheduleAt(simTime() + timeOut(DATA, br), timeout);
00802     debugEV << "sending DATA  to " << frame->getDestAddr() << " with bitrate " << br << endl;
00803     // send DATA frame
00804     sendDown(frame);
00805 
00806     // update state and display
00807     setState(WFACK);
00808 }
00809 
00810 
00814 void Mac80211::sendACKframe(Mac80211Pkt * af)
00815 {
00816     Mac80211Pkt *frame = new Mac80211Pkt("wlan-ack");
00817 
00818     PhyToMacControlInfo* phyCtrlInfo = static_cast<PhyToMacControlInfo*>(af->removeControlInfo());
00819     double br = static_cast<const DeciderResult80211*>(phyCtrlInfo->getDeciderResult())->getBitrate();
00820     delete phyCtrlInfo;
00821     phyCtrlInfo = 0;
00822 
00823     Signal* signal = createSignal(simTime(),
00824                   packetDuration(LENGTH_ACK, br),
00825                   txPower, br);
00826 
00827     MacToPhyControlInfo *pco = new MacToPhyControlInfo(signal);
00828 
00829     frame->setControlInfo(pco);
00830     frame->setKind(ACK);
00831     frame->setBitLength((int)LENGTH_ACK);
00832 
00833     // the dest address must be the src adress of the RTS or the DATA
00834     // packet received. The src adress is the adress of the node
00835     frame->setSrcAddr(myMacAddr);
00836     frame->setDestAddr(af->getSrcAddr());
00837     frame->setDuration(0);
00838 
00839     sendDown(frame);
00840     debugEV << "sent ACK frame!\n";
00841 
00842     // update state and display
00843     setState(BUSY);
00844 }
00845 
00846 
00850 void Mac80211::sendRTSframe()
00851 {
00852     Mac80211Pkt *frame = new Mac80211Pkt("wlan-rts");
00853 
00854     const Mac80211Pkt* frameToSend = fromUpperLayer.front();
00855     double br = retrieveBitrate(frameToSend->getDestAddr());
00856 
00857     Signal* signal = createSignal(simTime(),
00858                   packetDuration(LENGTH_RTS, br),
00859                   txPower, br);
00860 
00861     MacToPhyControlInfo *pco = new MacToPhyControlInfo(signal);
00862 
00863     frame->setControlInfo(pco);
00864     frame->setKind(RTS);
00865     frame->setBitLength((int)LENGTH_RTS);
00866 
00867     // the src adress and dest address are copied in the frame in the queue (frame to be sent)
00868     frame->setSrcAddr(frameToSend->getSrcAddr());
00869     frame->setDestAddr(frameToSend->getDestAddr());
00870 
00871     double packetSize = frameToSend->getBitLength();
00872     frame->setDuration(3 * SIFS + packetDuration(LENGTH_CTS, br) +
00873                        packetDuration(packetSize, br) +
00874                        packetDuration(LENGTH_ACK, br));
00875 
00876     debugEV << " Mac80211::sendRTSframe duration: " <<  packetDuration(LENGTH_RTS, br) << " br: " << br << "\n";
00877 
00878     // schedule time-out
00879     scheduleAt(simTime() + timeOut(RTS, br), timeout);
00880 
00881     // send RTS frame
00882     sendDown(frame);
00883 
00884     // update state and display
00885     setState(WFCTS);
00886 }
00887 
00888 
00892 void Mac80211::sendCTSframe(Mac80211Pkt * af)
00893 {
00894     Mac80211Pkt *frame = new Mac80211Pkt("wlan-cts");
00895 
00896     PhyToMacControlInfo* phyCtrlInfo = static_cast<PhyToMacControlInfo*>(af->removeControlInfo());
00897   double br = static_cast<const DeciderResult80211*>(phyCtrlInfo->getDeciderResult())->getBitrate();
00898   delete phyCtrlInfo;
00899   phyCtrlInfo = 0;
00900 
00901   Signal* signal = createSignal(simTime(),
00902                   packetDuration(LENGTH_CTS, br),
00903                   txPower, br);
00904 
00905     MacToPhyControlInfo *pco = new MacToPhyControlInfo(signal);
00906     frame->setControlInfo(pco);
00907     frame->setKind(CTS);
00908     frame->setBitLength((int)LENGTH_CTS);
00909 
00910     // the dest adress must be the src adress of the RTS received. The
00911     // src adress is the adress of the node
00912     frame->setSrcAddr(myMacAddr);
00913     frame->setDestAddr(af->getSrcAddr());
00914 
00915     frame->setDuration(af->getDuration() - SIFS - packetDuration(LENGTH_CTS, br));
00916 
00917     //scheduleAt(simTime() + af->getDuration() - packetDuration(LENGTH_ACK, br) - 2 * SIFS + delta, timeout);
00918     debugEV << " Mac80211::sendCTSframe duration: " <<  packetDuration(LENGTH_CTS, br) << " br: " << br << "\n";
00919     // send CTS frame
00920     sendDown(frame);
00921 
00922     // update state and display
00923     setState(WFDATA);
00924 }
00925 
00929 void Mac80211::sendBROADCASTframe()
00930 {
00931     // send a copy of the frame in front of the queue
00932     Mac80211Pkt *frame = static_cast<Mac80211Pkt *>(fromUpperLayer.front()->dup());
00933 
00934     double br = retrieveBitrate(frame->getDestAddr());
00935 
00936     simtime_t duration = packetDuration(frame->getBitLength(), br);
00937     Signal* signal = createSignal(simTime(), duration, txPower, br);
00938 
00939     MacToPhyControlInfo *pco = new MacToPhyControlInfo(signal);
00940 
00941     frame->setControlInfo(pco);
00942     frame->setKind(BROADCAST);
00943 
00944     sendDown(frame);
00945     // update state and display
00946     setState(BUSY);
00947 }
00948 
00956 void Mac80211::beginNewCycle()
00957 {
00958     // before trying to send one more time a packet, test if the
00959     // maximum retry limit is reached. If it is the case, then
00960     // delete the packet and send the next packet.
00961     testMaxAttempts();
00962 
00963     if (nav->isScheduled()) {
00964       debugEV << "cannot beginNewCycle until NAV expires at t " << nav->getArrivalTime() << endl;
00965         return;
00966     }
00967 
00968     /*
00969     if(timeout->isScheduled()) {
00970       cancelEvent(timeout);
00971     }
00972     */
00973 
00974     if (!fromUpperLayer.empty()) {
00975 
00976         // look if the next packet is unicast or broadcast
00977         nextIsBroadcast = (fromUpperLayer.front()->getDestAddr() == L2BROADCAST);
00978 
00979         setState(CONTEND);
00980         if(!contention->isScheduled()) {
00981           ChannelState channel = phy->getChannelState();
00982           debugEV << simTime() << " do contention: medium = " << channel.info() << ", backoff = "
00983                <<  remainingBackoff << endl;
00984 
00985             if(channel.isIdle()) {
00986               senseChannelWhileIdle(currentIFS + remainingBackoff);
00987                 //scheduleAt(simTime() + currentIFS + remainingBackoff, contention);
00988             }
00989         }
00990     }
00991     else {
00992         // post-xmit backoff (minor nit: if random backoff=0, we punt)
00993 
00994         if(remainingBackoff > 0 && !contention->isScheduled()) {
00995           ChannelState channel = phy->getChannelState();
00996           debugEV << simTime() << " do contention: medium = " << channel.info() << ", backoff = "
00997                <<  remainingBackoff << endl;
00998 
00999             if(channel.isIdle()) {
01000               senseChannelWhileIdle(currentIFS + remainingBackoff);
01001                 //scheduleAt(simTime() + currentIFS + remainingBackoff, contention);
01002             }
01003         }
01004         setState(IDLE);
01005     }
01006 }
01007 
01011 simtime_t Mac80211::backoff(bool rtscts) {
01012     unsigned rc = (rtscts) ?  longRetryCounter : shortRetryCounter;
01013     unsigned cw = ((CW_MIN + 1) << rc) - 1;
01014     if(cw > CW_MAX) cw = CW_MAX;
01015 
01016     simtime_t value = ((double) intrand(cw + 1)) * ST;
01017     debugEV << simTime() << " random backoff = " << value << endl;
01018 
01019     return value;
01020 }
01021 
01026 void Mac80211::testMaxAttempts()
01027 {
01028     if ((longRetryCounter >= LONG_RETRY_LIMIT) || (shortRetryCounter >= SHORT_RETRY_LIMIT)) {
01029       debugEV << "retry limit reached src: "<< shortRetryCounter << " lrc: " << longRetryCounter << endl;
01030         // initialize counter
01031         longRetryCounter = 0;
01032         shortRetryCounter = 0;
01033         // delete the frame to transmit
01034         Mac80211Pkt *temp = fromUpperLayer.front();
01035         fromUpperLayer.pop_front();
01036         temp->setName("MAC ERROR");
01037         temp->setKind(PACKET_DROPPED);
01038         sendControlUp(temp);
01039     }
01040 }
01041 
01042 Signal* Mac80211::createSignal( simtime_t start, simtime_t length,
01043                 double power, double bitrate)
01044 {
01045   simtime_t end = start + length;
01046   //create signal with start at current simtime and passed length
01047   Signal* s = new Signal(start, length);
01048 
01049   //create and set tx power mapping
01050   ConstMapping* txPowerMapping
01051       = createSingleFrequencyMapping( start, end,
01052                       centerFreq, 11.0e6,
01053                       power);
01054   s->setTransmissionPower(txPowerMapping);
01055 
01056   //create and set bitrate mapping
01057 
01058   //create mapping over time
01059   Mapping* bitrateMapping
01060       = MappingUtils::createMapping(DimensionSet::timeDomain,
01061                       Mapping::STEPS);
01062 
01063   Argument pos(start);
01064   bitrateMapping->setValue(pos, BITRATE_HEADER);
01065 
01066   pos.setTime(PHY_HEADER_LENGTH / BITRATE_HEADER);
01067   bitrateMapping->setValue(pos, bitrate);
01068 
01069   s->setBitrate(bitrateMapping);
01070 
01071   return s;
01072 }
01073 
01078 //TODO: port bbitem handling
01079 /*
01080 void Mac80211::receiveBBItem(int category, const BBItem *details, int scopeModuleId)
01081 {
01082     Enter_Method_Silent();
01083     BasicLayer::receiveBBItem(category, details, scopeModuleId);
01084 
01085     EV << simTime() << " receiveBBItem " << details->info() << endl;
01086     if(category == catRadioState) {
01087         radioState = static_cast<const RadioState *>(details)->getState();
01088         switch(radioState)
01089         {
01090         case RadioState::SWITCH_TO_SLEEP:
01091         case RadioState::SWITCH_TO_RECV:
01092         case RadioState::SWITCH_TO_SEND:
01093             switching = true;
01094             break;
01095         case RadioState::SLEEP:
01096         case RadioState::RECV:
01097         case RadioState::SEND:
01098             switching = false;
01099             break;
01100         default:
01101             error("Mac80211::receiveBBItem unknown radio state");
01102             break;
01103         }
01104     }
01105 }
01106 */
01107 
01108 
01113 simtime_t Mac80211::timeOut(Mac80211MessageKinds type, double br)
01114 {
01115     simtime_t time_out = 0;
01116 
01117     switch (type)
01118     {
01119     case RTS:
01120         time_out = SIFS + packetDuration(LENGTH_RTS, br) + ST + packetDuration(LENGTH_CTS, br) + delta;
01121         debugEV << " Mac80211::timeOut RTS " << time_out << "\n";
01122         break;
01123     case DATA:
01124         time_out = SIFS + packetDuration(fromUpperLayer.front()->getBitLength(), br) + ST + packetDuration(LENGTH_ACK, br) + delta;
01125         debugEV << " Mac80211::timeOut DATA " << time_out << "\n";
01126         break;
01127     default:
01128         EV << "Unused frame type was given when calling timeOut(), this should not happen!\n";
01129     }
01130     return time_out;
01131 }
01132 
01138 simtime_t Mac80211::packetDuration(double bits, double br)
01139 {
01140     return bits / br + phyHeaderLength / BITRATE_HEADER;
01141 }
01142 
01143 const char *Mac80211::stateName(State state)
01144 {
01145 #define CASE(x) case x: s=#x; break
01146     const char *s = "???";
01147     switch (state)
01148     {
01149         CASE(WFDATA);
01150         CASE(QUIET);
01151         CASE(IDLE);
01152         CASE(CONTEND);
01153         CASE(WFCTS);
01154         CASE(WFACK);
01155         CASE(BUSY);
01156     }
01157     return s;
01158 #undef CASE
01159 }
01160 
01161 void Mac80211::setState(State newState)
01162 {
01163     if (state==newState)
01164       debugEV << "staying in state " << stateName(state) << "\n";
01165     else
01166       debugEV << "state " << stateName(state) << " --> " << stateName(newState) << "\n";
01167     state = newState;
01168 }
01169 
01170 void Mac80211::suspendContention()  {
01171   assert(!contention->isScheduled());
01172     // if there's a contention period
01173 
01174     //if(requestReturned || chSenseRequest->isScheduled()) {
01175         // update the backoff window in order to give higher priority in
01176         // the next battle
01177 
01178       simtime_t quietTime = simTime() - chSenseStart;
01179 
01180       debugEV << simTime() << " suspend contention: "
01181        << "began " << chSenseStart
01182        << ", ends " << chSenseStart + contention->getSenseTimeout()
01183        << ", ifs " << currentIFS
01184        << ", quiet time " << quietTime
01185        << endl;
01186 
01187         if(quietTime < currentIFS) {
01188           debugEV << "suspended during D/EIFS (no backoff)" << endl;
01189         }
01190         else {
01191             double remainingSlots;
01192             remainingSlots = (contention->getSenseTimeout() - quietTime).dbl()/ST;
01193 
01194             // Distinguish between (if) case where contention is
01195             // suspended after an integer number of slots and we
01196             // _round_ to integer to avoid fp error, and (else) case
01197             // where contention is suspended mid-slot (e.g. hidden
01198             // terminal xmits) and we _ceil_ to repeat the partial
01199             // slot.  Arbitrary value 0.0001 * ST is used to
01200             // distinguish the two cases, which may a problem if clock
01201             // skew between nic's is ever implemented.
01202 
01203             if (fabs(ceil(remainingSlots) - remainingSlots) < 0.0001 * ST ||
01204                 fabs(floor(remainingSlots) - remainingSlots) < 0.0001 * ST) {
01205                 remainingBackoff = floor(remainingSlots + 0.5) * ST;
01206             }
01207             else {
01208                 remainingBackoff = ceil(remainingSlots) * ST;
01209             }
01210 
01211             debugEV << "backoff was " << ((contention->getSenseTimeout() - currentIFS))/ST
01212                << " slots, now " << remainingSlots << " slots remain" << endl;
01213         }
01214 
01215         debugEV << "suspended backoff timer, remaining backoff time: "
01216            << remainingBackoff << endl;
01217 
01218     //}
01219 }
01220 
01221 double Mac80211::retrieveBitrate(int destAddress) {
01222     double bitrate = defaultBitrate;
01223     NeighborList::iterator it;
01224     if(autoBitrate && (destAddress != L2BROADCAST) &&
01225        (longRetryCounter == 0) && (shortRetryCounter == 0)) {
01226         it = findNeighbor(destAddress);
01227         if((it != neighbors.end()) && (it->age > (simTime() - neighborhoodCacheMaxAge))) {
01228             bitrate = it->bitrate;
01229         }
01230     }
01231     return bitrate;
01232 }
01233 
01234 void Mac80211::addNeighbor(Mac80211Pkt *af) {
01235     int srcAddress = af->getSrcAddr();
01236     NeighborList::iterator it = findNeighbor(srcAddress);
01237     const DeciderResult80211* result = static_cast<const DeciderResult80211*>(
01238                       static_cast<PhyToMacControlInfo *>(
01239                         af->getControlInfo())->getDeciderResult());
01240     double snr = result->getSnr();
01241 
01242     double bitrate = BITRATES_80211[0];
01243     NeighborEntry entry;
01244 
01245     if(snr > snrThresholds[0]) bitrate = BITRATES_80211[1];
01246     if(snr > snrThresholds[1]) bitrate = BITRATES_80211[2];
01247     if(snr > snrThresholds[2]) bitrate = BITRATES_80211[3];
01248 
01249     if(it != neighbors.end()) {
01250         it->age = simTime();
01251         it->bitrate = bitrate;
01252     }
01253     else {
01254         if(neighbors.size() < neighborhoodCacheSize) {
01255             entry.address = srcAddress;
01256             entry.age = simTime();
01257             entry.bitrate = bitrate;
01258             entry.fsc = 0;
01259             neighbors.push_back(entry);
01260         }
01261         else {
01262             it = findOldestNeighbor();
01263             if(it != neighbors.end()) {
01264                 it->age = simTime();
01265                 it->bitrate = bitrate;
01266                 it->address = srcAddress;
01267                 it->fsc = 0;
01268             }
01269         }
01270     }
01271     debugEV << "updated information for neighbor: " << srcAddress
01272        << " snr: " << snr << " bitrate: " << bitrate << endl;
01273 }
01274 
01275 Mac80211::~Mac80211() {
01276   cancelAndDelete(timeout);
01277   cancelAndDelete(nav);
01278   if(!contention->isScheduled())
01279     delete contention;
01280   if(!endSifs->isScheduled())
01281     delete endSifs;
01282 
01283   MacPktList::iterator it;
01284   for(it = fromUpperLayer.begin(); it != fromUpperLayer.end(); ++it) {
01285         delete (*it);
01286     }
01287     fromUpperLayer.clear();
01288 }
01289 
01290 void Mac80211::finish() {
01291     BaseMacLayer::finish();
01292 }
01293