⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mac80211.cc

📁 基于omnet++开发的Mf框架下的802.11协议仿真。
💻 CC
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************** * 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 + -