|
INET Framework for OMNeT++/OMNEST
|
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