?? mac80211.cc
字號:
/*** 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 + -