?? mac80211.cc
字號:
/*************************************************************************** * file: Mac80211.cc * * author: David Raguin / Marc L鯾bers * * copyright: (C) 2004 Telecommunication Networks Group (TKN) at * Technische Universitaet Berlin, Germany. * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later * version. * For further information see file COPYING * in the top level directory *************************************************************************** * part of: framework implementation developed by tkn * description: MAC layer for 802.11b * *************************************************************************** * changelog: $Revision$ * last modified: $Date: 2005-01-15 21:52:51 +0100 (Sat, 15 Jan 2005) $ * by: $Author: koepke $ **************************************************************************/#include "Mac80211.h"#include "RadioState.h"#define EV (ev.disabled()||!debug) ? (std::ostream&)ev : ev << logName() << "::Mac80211: "Define_Module( Mac80211 );/** * First we have to initialize the module from which we derived ours, * in this case BasicMacLayer. Besides some parameters are set or read * in from omnetpp.ini * * **/void Mac80211::initialize(int stage){ BasicMacLayer::initialize(stage); if(stage==0){ txEnergy=(double)par("txEnergy"); rxEnergy=(double)par("rxEnergy"); idleEnergy=(double)par("idleEnergy"); energyConsumption=0; reCounter=0; WATCH(reCounter); idleTimeStamp=simTime(); retryLimit=(int)par("retryLimit"); // MAX RETRY TIMES EV <<"Initializing stage 0\n"; headerLength=272;//has to be 272, including final CRC-field; this //makes sure it is! maxQueueSize=par("maxQueueSize"); //timers timeout = new cMessage( "timeout", TIMEOUT); nav = new cMessage("NAV", NAV); contension = new cMessage("contension", CONTENSION); endTransmission = new cMessage ("transmission", END_TRANSMISSION); endSifs = new cMessage("end SIFS", END_SIFS); BW = 0; state = IDLE; retryCounter = 1; //retry counter WATCH(retryCounter); broadcastBackoff=par("broadcastBackoff"); rtsCts=par("rtsCts"); bitrate=par("bitrate"); delta = 1E-9; WATCH_PTRLIST(fromUpperLayer);// revised by Yupeng EIFS = SIFS + DIFS + packetDuration(LENGTH_ACK); EV <<"SIFS: "<<SIFS<<" DIFS: "<<DIFS<<" EIFS: "<<EIFS<<endl; } else{ EV <<"initializing stage 1\n"; //subscribe for the information of the carrier sense bbRs=blackboard()->subscribe( this, "RadioState"); }}/** * This implementation does not support fragmentation, so it is tested * if the maximum length of the MPDU is exceeded. **/void Mac80211::handleUpperMsg(MacPkt *ma){ Mac80211Pkt *mac = static_cast<Mac80211Pkt *>(ma); if(mac->encapsulatedMsg()->length()>18496) error("Network Packet is too long for 802.11b! Fragmentation is not supported yet!!"); EV <<"Got upper msg! STATE:"<<state<<endl; if ((int)fromUpperLayer.size() < maxQueueSize){ fromUpperLayer.push_back(mac); //If the MAC is in the IDLE state, then start a new contension period if ( state == IDLE && !endSifs->isScheduled() ) { tryWithoutBackoff=true; beginNewCycle(); } } else{ delete mac; EV <<"Mac Queue is full; packet was deleted!\n"; }}/*** Handle all messages from lower layer. Checks the destination MAC* adress of the packet. Then calls one of the three functions :* handleMsgNotForMe(MacawFrame *af), handleBroadcastMsg(MacawFrame* *af), or handleMsgForMe(MacawFrame *af). Called by* handleMessage(cMessage* msg).**/void Mac80211::handleLowerMsg(MacPkt *mac){ Mac80211Pkt *af = static_cast<Mac80211Pkt *>(mac); //end of the reception phy_receiving=false;//<- probably not needed anymore... EV <<"frame received\n"; switch ( af->kind() ){ //packet lost or bit error case COLLISION: delete af; if (state == CONTEND) beginNewCycle(); break; case BITERROR: handleMsgNotForMe(af); break; //broadcast packet! case BROADCAST: handleBroadcastMsg(af); break; //other packets default: if (af->getDestAddr() != myMacAddr() ) handleMsgNotForMe(af); else handleMsgForMe(af); }}/** handle Timer*/void Mac80211::handleSelfMsg(cMessage *msg){ switch (msg->kind()) { case END_SIFS: handleEndSifsTimer();//noch zu betrachten break; case END_TRANSMISSION: handleEndTransmissionTimer();//noch zu betrachten break; case CONTENSION: handleEndContensionTimer(); break; //the MAC was waiting for a CTS, a DATA, or an ACK packet but the timer has expired. case TIMEOUT: handleTimeOutTimer();//noch zu betrachten.. break; //the MAC was waiting because an other communication had won the channel. This communication is now over case NAV: handleNavTimer();//noch zu betrachten... break; default: error("unknown timer type"); } }/*** Handle all ACKs,RTS, CTS, or DATA not for the node. If RTS/CTS* is used the node must stay quiet until the current handshake* between the two communicating nodes is over. This is done by* scheduling the timer message nav (Network Allocation Vector).* Without RTS/CTS a new contension is started. If an error* occured the node must defer for EIFS. Called by* handleLowerMsg(MacPkt *af)**/void Mac80211::handleMsgNotForMe(Mac80211Pkt *af){ EV <<"handle msg not for me\n"; //if this packet can not be correctly read if (af->kind() == BITERROR) af->setDuration( EIFS ); //if the duration of the packet is null, then do nothing (to avoid //the unuseful scheduling of a self message) if (af->getDuration() != 0) { //the node is already deferring if (state == QUIET){ //the current value of the NAV is not sufficient if (nav->arrivalTime() < simTime() + af->getDuration() ){ cancelEvent( nav); scheduleAt(simTime() + af->getDuration(), nav); energyConsumption += idleEnergy*af->getDuration(); // revised by Yupeng EV <<"NAV timer started for: "<<af->getDuration()<<" State QUIET\n"; } } //other states else{ //if the MAC wait for another frame, it can delete its time out //(exchange is aborted) if (timeout->isScheduled() ) cancelEvent(timeout); //is state == WFCTS or WFACK, the data transfer has failed ... //the node must defer for the time of the transmission scheduleAt(simTime() + af->getDuration(), nav); energyConsumption += idleEnergy*af->getDuration(); // revised by Yupeng EV <<"NAV timerStartetd, not QUIET: "<<af->getDuration()<<endl; state = QUIET; } } if(!rtsCts){ //todo: Nachgucken: was passiert bei Error ohne rtsCts! if(state==CONTEND){ if(af->kind()==BITERROR){ if(contension->isScheduled()) cancelEvent(contension); scheduleAt(simTime()+backoff()+EIFS,contension); energyConsumption += idleEnergy*(backoff()+EIFS); }else beginNewCycle(); } } delete af;}/*** Handle a packet for the node. The result of this reception is* a function of the type of the received message (RTS,CTS,DATA,* or ACK), and of the current state of the MAC (WFDATA, CONTEND,* IDLE, WFCTS, or WFACK). Called by handleLowerMsg(MacawFrame* *af)**/void Mac80211::handleMsgForMe(Mac80211Pkt *af){ EV <<"handle msg for me\n"; switch (state){ //the MAC layer is in CONTEND or IDLE state:waiting for a RTS or //for the end of the constension period case IDLE: case CONTEND: //if the message is an RTS or DATA if (af->kind() == RTS) handleRTSframe(af); else if(af->kind() == DATA) handleDATAframe(af); else EV <<"in handleMsgForMe() IDLE/CONTED, strange message, darf das?\n"; break; //the mac layer is waiting for DATA case WFDATA: //if the frame is a data frame if (af->kind() == DATA) handleDATAframe(af); else EV <<"in handleMsgForMe() WFDATA, strange message, darf das?\n"; break; //the MAC layer is waiting for an ACK case WFACK: //if the frame is an ACK if (af->kind() == ACK) handleACKframe(af); else EV <<"in handleMsgForMe() WFACK, strange message, darf das?\n"; delete af; break; //The MAC is waiting for an CTS case WFCTS: //if the frame is a CTS if (af->kind()==CTS) handleCTSframe(af); else EV <<"in handleMsgForMe() WFCTS, strange message, darf das?\n"; break; //the node is currently deferring. Can not handle any packet with //its MAC adress case QUIET: delete af; break; //node currently transmitting an ACK or a BROADCAST packet case BUSY: EV <<"ERROR: user error shown in window, myId:"<<parentModule()->id()<<endl; error("node currently transmitting ... can not receive ... does the physical layer correctly its job?..in handleMsgForMe case BUSY!"); break; default: error("unkown state in the mac layer"); }}/*** Handle aframe wich is expected to be an RTS. Called by* HandleMsgForMe(MacawFrame* af)**/void Mac80211::handleRTSframe(Mac80211Pkt* af){ findHost()->displayString().setTagArg("i",1,"green"); energyConsumption += idleEnergy*(simTime()-idleTimeStamp); // idle time for waiting RTS //wait a short interframe space endSifs->setContextPointer(af); scheduleAt(simTime() + SIFS, endSifs); energyConsumption += rxEnergy*af->length()/(double)par("bitrate"); energyConsumption += idleEnergy*SIFS;}/*** Handle a frame which expected to be a DATA frame. Called by* HandleMsgForMe(MAcawFrame* af)**/void Mac80211::handleDATAframe(Mac80211Pkt* af){ if(rtsCts) //cancel time-out event cancelEvent( timeout ); //make a copy Mac80211Pkt* copy = (Mac80211Pkt*) af->dup(); //pass the packet to the upper layer sendUp(af); energyConsumption += rxEnergy*af->length()/(double)par("bitrate"); //wait a short interframe space endSifs->setContextPointer(copy); scheduleAt(simTime() + SIFS, endSifs); energyConsumption += idleEnergy*SIFS;}/*** Handle a frame which is expected to be an ACK.Called by* HandleMsgForMe(MAcawFrame* af)**/void Mac80211::handleACKframe(Mac80211Pkt* af){ //cancel time-out event cancelEvent( timeout ); //the the transmission is acknowledged : initialize long_retry_counter retryCounter = 1; //removes the acknowledged packet from the queue Mac80211Pkt* temp = fromUpperLayer.front(); fromUpperLayer.pop_front(); delete temp; //if thre's a packet to send and if the channel is free then start a new contension period beginNewCycle();}/*** Handle a CTS frame. Called by HandleMsgForMe(Mac80211Pkt* af)**/void Mac80211::handleCTSframe(Mac80211Pkt* af){ //cancel time-out event cancelEvent( timeout ); //wait a short interframe space endSifs->setContextPointer(af); scheduleAt(simTime() + SIFS, endSifs); energyConsumption += rxEnergy*af->getDuration(); energyConsumption += idleEnergy*SIFS;}/** * Handle a broadcast packet. This packet is simply passed to the * upper layer. No acknowledgement is needed. Called by * handleLowerMsg(MacawFrame *af)**/void Mac80211::handleBroadcastMsg(Mac80211Pkt *af){ EV <<"handle broadcast\n"; if (state == BUSY) error("node currently transmitting ... can not receive ... does the physical layer correctly its job?,...in handleBroadcastMsg()"); else { sendUp( af ); energyConsumption += rxEnergy*af->length()/(double)par("bitrate"); if (state == CONTEND) beginNewCycle(); }}/** * The node has won the contension, and is now allowed to send an * RTS/DATA or Broadcast packet. The backoff value is deleted and * will be newly computed in the next contension period */void Mac80211::handleEndContensionTimer(){ if (state == CONTEND){ //the node has won the channell, the backof window is deleted and //will be new calculated in the next contension period BW = 0; //unicast packet if (!nextIsBroadcast){ if(rtsCts){ //send a RTS sendRTSframe(); state=WFCTS; //updateDisplay(WFCTS); }else{ sendDATAframe(); state=WFACK; } //broadcast packet }else{ sendBROADCASTframe(); //removes the packet from the queue without waiting for an acknowledgement Mac80211Pkt* temp = fromUpperLayer.front(); fromUpperLayer.pop_front(); delete(temp); } } else error("expiration of the contension timer outside of CONTEND state... should not happen"); } /*** Handle the NAV timer (end of a defering period). Called by* HandleTimer(cMessage* msg)**/void Mac80211::handleNavTimer(){ if (state == QUIET) //if there's a packet to send and if the channel is free then //start a new contension period beginNewCycle(); else error("expiration of the NAV timer outside of the state QUIET ...should not happen");}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -