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

📄 mac80211.cc

📁 基于omnet++开发的Mf框架下的802.11协议仿真。
💻 CC
📖 第 1 页 / 共 2 页
字号:
/***	Handle the time out timer. Called by HandleTimer(cMessage**	msg)**/void Mac80211::handleTimeOutTimer(){    //if (state == WFCTS || state == WFACK) retryCounter++;    //if there's a packet to send and if the channel is free then  //start a new contension period  if (state != QUIET) beginNewCycle();  }  /***	Handle the end sifs timer. Then sends a CTS, a DATA, or an ACK*	frame**/void Mac80211::handleEndSifsTimer(){  Mac80211Pkt* frame = (Mac80211Pkt*) endSifs->contextPointer();    switch (frame->kind()){  case RTS:    sendCTSframe(frame);    break;  case CTS:    sendDATAframe();    break;  case DATA:    sendACKframe(frame);    break;  default :    error ("end sifs timer with previous received packet != RTS, CTS, or DATA");  }    //don't need previous frame any more  delete frame;}/***	Handle the end of transmission timer (end of the transmission*	of an ACK or a broadcast packet). Called by*	HandleTimer(cMessage* msg)**/void Mac80211::handleEndTransmissionTimer(){  EV <<"transmission of ACK/BROADCAST is over\n";  if (state == BUSY)        //if thre's a packet to send and if the channel is free then start a new contension period    beginNewCycle();  else     error("expiration of the end_transmission timer outside the BUSY state ... should not happen");}/** *	Send a DATA frame. Called by HandleEndSifsTimer() or *	handleEndContensionTimer() **/void Mac80211::sendDATAframe(){  //schedule time out  scheduleAt(simTime() + timeOut(DATA, 0), timeout);     if(!rtsCts)    //retryCounter incremented    retryCounter++;    //send DATA frame    sendDown(buildDATAframe());  energyConsumption += txEnergy*(buildDATAframe())->length()/(double)par("bitrate");   //update state and display  state = WFACK;  //updateDisplay(WFACK);}/***	Send an ACK frame.Called by HandleEndSifsTimer()**/void Mac80211::sendACKframe( Mac80211Pkt* af ){  //the MAC must wait the end of the transmission before beginning an  //other contension period  scheduleAt(simTime() +packetDuration(LENGTH_ACK) + delta, endTransmission );    //send ACK frame  sendDown(buildACKframe(af));  energyConsumption += txEnergy*(buildACKframe(af))->length()/(double)par("bitrate");   EV <<"sent ACK frame!\n";  //update state and display  state = BUSY;  //  updateDisplay(BUSY);}/***	Send a RTS frame.Called by handleContentionTimer()**/void Mac80211::sendRTSframe(){      //schedule time-out  scheduleAt(simTime() + timeOut(RTS, 0), timeout);    //long_retry_counter incremented  retryCounter++;    //send RTS frame  sendDown(buildRTSframe());  energyConsumption += txEnergy*(buildRTSframe())->length()/(double)par("bitrate");   //update state and display  state = WFCTS;  //updateDisplay(WFCTS);??}/***	Send a CTS frame.Called by HandleEndSifsTimer()**/void Mac80211::sendCTSframe( Mac80211Pkt* af ){  //schedule time-out  scheduleAt(simTime() + timeOut(CTS, af->getDuration() ), timeout);    //send CTS frame  sendDown(buildCTSframe(af));  energyConsumption += txEnergy*(buildCTSframe(af))->length()/(double)par("bitrate");   //update state and display  state = WFDATA;  //  updateDisplay(WFDATA);}/***	Send a BROADCAST frame.Called by handleContentionTimer()**/void Mac80211::sendBROADCASTframe( ){  //the MAC must wait the end of the transmission before beginning any  //other contension period  scheduleAt(simTime() + packetDuration( fromUpperLayer.front()->length() ), endTransmission );  //send ACK frame  sendDown(buildBROADCASTframe());  energyConsumption += txEnergy*(buildBROADCASTframe())->length()/(double)par("bitrate");   //update state and display  state = BUSY;  //  updateDisplay(BUSY);}/***	Build a DATA frame. Called by sendDATAframe()**/Mac80211Pkt* Mac80211::buildDATAframe(){  //send a copy of the frame in front of the queue  Mac80211Pkt *frame = (Mac80211Pkt*)(fromUpperLayer.front() )->dup();  frame->setSrcAddr(myMacAddr());  frame->setKind(DATA);  frame->setName("DATA");  if(rtsCts)    frame->setDuration ( SIFS + packetDuration(LENGTH_ACK));  else    frame->setDuration(0);    return(frame);}/***	Build an ACK frame. Called by sendACKframe()**/Mac80211Pkt* Mac80211::buildACKframe( Mac80211Pkt* af ){  Mac80211Pkt* frame = static_cast<Mac80211Pkt *>(createCapsulePkt());  frame->setName("ACK");  frame->setKind(ACK);  frame->setLength(LENGTH_ACK);    //the dest address must be the src adress of the RTS or the DATA  //packet received. The src adress is the adress of the node  frame->setSrcAddr(myMacAddr());  frame->setDestAddr(af->getSrcAddr());  frame->setDuration(0);    return(frame);}/***	Build a RTS frame. Called by sendRTSframe()**/Mac80211Pkt* Mac80211:: buildRTSframe(){  Mac80211Pkt *frame  = new Mac80211Pkt;  frame->setName("RTS");  frame->setKind(RTS);  frame->setLength(LENGTH_RTS);    //the src adress and dest address are copied in the frame in the queue (frame to be sent)  frame->setSrcAddr( ( ( Mac80211Pkt*) fromUpperLayer.front() )->getSrcAddr());  frame->setDestAddr( ( (Mac80211Pkt*) fromUpperLayer.front() )->getDestAddr());  frame->setDuration ( 3*SIFS + packetDuration(LENGTH_CTS) + packetDuration( fromUpperLayer.front()->length() ) +packetDuration(LENGTH_ACK));    return(frame);}/***	Build a CTS frame. Called by sendCTSframe()**/Mac80211Pkt* Mac80211::buildCTSframe( Mac80211Pkt* af ){  Mac80211Pkt* frame = new Mac80211Pkt;  frame->setName("CTS");  frame->setKind(CTS);  frame->setLength(LENGTH_CTS);    //the dest adress must be the src adress of the RTS received. The  //src adress is the adress of the node  frame->setSrcAddr(myMacAddr());  frame->setDestAddr(af->getSrcAddr());  frame->setDuration (af->getDuration() - SIFS - packetDuration(LENGTH_CTS));    return(frame);}/***	Build a BROADCAST frame. Called sendBROADCASTframe()**/Mac80211Pkt* Mac80211:: buildBROADCASTframe( ){  //send a copy of the frame in front of the queue  Mac80211Pkt *frame = (Mac80211Pkt*)(fromUpperLayer.front())->dup();  frame->setKind(BROADCAST);  frame->setName("BROADCAST");    return(frame);}/***	Start a new contension period if the channel is free and if*	there's a packet to send.  Called at the end of a deferring*	period, a busy period, or after a failure. Called by the*	HandleMsgForMe(), HandleTimer() HandleUpperMsg(), and, without*	RTS/CTS, by handleMsgNotForMe().**/void Mac80211::beginNewCycle(){  //before trying to send one more time a packet, test if the  //maximum retry limit is reached. If it is the case, then  //delete the packet and send the next packet.    testMaxAttempts();    if (!fromUpperLayer.empty()) {        //look if the next packet is unicast or broadcast    nextIsBroadcast = ( ( (Mac80211Pkt*) fromUpperLayer.front() )->getDestAddr() == BROADCAST_ADDRESS);        //    print("next is broadcast = "<<nextIsBroadcast);        //if the channel is free then wait a random time and transmit    if((static_cast<const RadioState *>(bbRs->data()))->getState()==RadioState::IDLE){      //if channel is idle AND I was not the last one that transmitted      //data: no backoff      if(tryWithoutBackoff){		EV <<"trying to send without backoff...\n";		scheduleAt(simTime() + DIFS, contension);		energyConsumption += idleEnergy*DIFS;      }      else{   // backoff!		scheduleAt(simTime() + backoff() + DIFS, contension);		energyConsumption += idleEnergy*(backoff() + DIFS);      }    }    tryWithoutBackoff=false;        //else wait until the channel is free    //the state is now contend    state = CONTEND;    EV <<"Now in State: "<<state<<endl;    //updateDisplay(CONTEND);  }  else {    tryWithoutBackoff=false;    state = IDLE;    EV <<"Now in state: "<<state<<endl;    idleTimeStamp=simTime();    findHost()->displayString().setTagArg("i",1,"yellow");          }}/** *	Compute the backoff value. **/double Mac80211::backoff(){  //the MAC has won the previous contension. We have to compute a new  //backoff window  if (BW == 0)     BW = ((double)intrand(CW()+1)) * ST;  //CW is the contention window (see the function). ST is the  //slot time.  else we take the old value of BW, in order to give a  //bigger priority to a node which has lost a previous contension  //period.  EV <<"backing off for: "<<BW+DIFS<<endl;  return(BW);}/***	Compute the contention window with the binary backoff*	algorithm.  Use the variable counter (attempts to transmit*	packet), the constant values CWmax (contention window maximum)*	and m (parameter for the initial backoff window, usally m=7).*	Called by backoff()**/int Mac80211::CW(){  //the next packet is an unicast packet  if (!nextIsBroadcast){    int cw;    cw = (CW_MIN+1) * (unsigned int) pow(2.0, (int) retryCounter) - 1;    //return the calculated value or CWmax if the maximal value is reached    if (cw <= CW_MAX) return (cw);    else return (CW_MAX);  }    //the next packet is broadcast : the contension window must be maximal  else return (broadcastBackoff);}/*** 	Test if the maximal retry limit is reached, and delete the* 	frame to send in this case.**/void Mac80211::testMaxAttempts(){   //reCounter++;  if (retryCounter > retryLimit) {        //initialize counter        retryCounter = 1;    //reportLost(fromUpperLayer.front());    //\todo publish on Blackboard        //delete the frame to transmit    Mac80211Pkt* temp = fromUpperLayer.front();    fromUpperLayer.pop_front();    delete(temp);  }}/** * Handle messages from the blackboard. In this layer it is usally * information about the channel, i.e. if it is IDLE etc. **/bool Mac80211::blackboardItemChanged( BBItemRef bbItem){  Enter_Method("blackboardItemChanged(\"%s\")", bbItem->label());  // check whether item was already handled by parent module  if( BasicMacLayer::blackboardItemChanged( bbItem ) ){    EV <<"bbItem handled by parent class -> return\n";    return true;  }  if( bbRs == bbItem ){    EV <<"In blackboardItemChanged() I have to handle item!\n";    //beginning of a reception    if ((static_cast<const RadioState *>(bbRs->data()))->getState()==RadioState::RECV){            EV <<"Carrier Sense: receiving!\n";      phy_receiving = true; //is it needed?            //if there's a contention period      if (contension->isScheduled()){	//update the backoff window in order to give higher priority in	//the next battle	if(simTime()-contension->sendingTime()>=DIFS){	  BW = contension->arrivalTime() - simTime();	  EV <<"Backoff window made smaller, new BW: "<<BW<<endl;	}	cancelEvent( contension );      }            //if there's a SIFS period      if(endSifs->isScheduled() ){	//delete the previously received frame	delete ( (Mac80211Pkt*) endSifs->contextPointer());		//cancel the next transmission	cancelEvent(endSifs);		//state in now IDLE or CONTEND	if (fromUpperLayer.empty())	  state = IDLE;	else	  state = CONTEND;      }    }        EV <<"now state: "<<state<<endl;    // item was handeled -> return true    return true;  } // end if( bbRs == bbItem )  // item not interesting for me  EV <<"item "<<bbItem->label()<<" not for me, let derived module handle it\n";  return false;  }/***	Return a time-out value for a type of frame. Called by*	SendRTSframe, sendCTSframe, etc.**/double Mac80211::timeOut(_802_11frameType type, double last_frame_duration){  double time_out = 0;  switch (type){  case RTS :    time_out = SIFS + packetDuration(LENGTH_RTS) + packetDuration(LENGTH_CTS) + delta;    break;  case CTS :    time_out = last_frame_duration - packetDuration(LENGTH_ACK) - 2*SIFS + delta;    break;  case DATA :    time_out = SIFS + packetDuration( fromUpperLayer.front()->length() ) + packetDuration(LENGTH_ACK) + delta;    break;  default :    EV <<"Unused frame type was given when calling timeOut(), this should not happen!\n";  }  return(time_out);}/** * Computes the duration of the transmission of a frame over the * physical channel. 'bits' should be the total length of the MAC * packet in bits. */double Mac80211::packetDuration(int bits) {  return(bits/bitrate+PHY_HEADER_LENGTH/BITRATE_HEADER);}              /** * revised by Yupeng 2006-11-21 14:50 *  *  */ void Mac80211::finish(){	BasicMacLayer::finish();			FILE   *fp;     	fp   =   fopen("c:\\80211Energy.txt","a");     	fprintf(fp,   "%f\r\n",  energyConsumption);     	fclose(fp);  	ev << logName() << "::80211MacLayer: Total energy consumed: " << energyConsumption <<"(mW)" <<endl;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -