NS2中的多速率MAC

来源:互联网 发布:淘宝新品打造爆款 编辑:程序博客网 时间:2024/06/05 11:22

转载地址:http://www.winlab.rutgers.edu/~zhibinwu/html/multirate_ns_mac.htm

Introduction

First, an introduction on "how ns-2 handle the 802.11 rate":

There is a file ns-mac.tcl in ./tcl/lib directory, in this file the MAC/802-11 set datarate_ as 1Mb, and basicRate_ as 1Mb. change these two values could change rate.

We have to consider following questions:

Atomic operations:

  1. The sender determine the rate (how??). calculate NAV, assuming ACK use the same rate( or basic rate??). Send DATA
  2. How to let the receiver know the rate? We have to use PLCP header. The SIGNAL field in PLCP header is used for this purpose.
  3. Why the receiver needs to know the rate? because it wants to correct receive it and might send ACK with same rate.
  4. Using Short PLCP? Two major changes, PLCP preamble is 72 instead of 144 bits (still sent with 1Mbps) The PLCP header is sent with 2Mbps.

Control & Feedback for auto-rate

  1. Receiver-based Autorate (RBAR). RTS/CTS is necessary, RTS send with lowest rate (1Mbps), the receiver put something in the CTS to tell the sender use which rate (CTS is still sent with lowest rate)
  2. ARF (auto-rate fallback), for every 2nd ACK miss( transmission failure) following good transmission, fallback to lower rate and set a timer. Whenever the consecutive 10  good transmission or timer expired, upgrade to higher rate. Then, if miss ACK, fallback to lower rate.
  3. Fixed Rate. Assume every node is not moving, the benefits of adaptive autorate is very small. So, for every node pair, we set a fixed rate to follow, either 1,2,5.5,11

Rate .vs. Range

  1. Each rate corresponding to a different transmission range. This is to be reflected.
  2. Carrier-Sense threshold does not change for different rate. So this is a fixed vaue.

Implementation

  1. set rate
  2. short preamble
  3. receive threshold
  4. AutoRate Scheme 1: ARF

baisc multirate codes (only Implement Feature 1 & 2) (download zip file)
And also, there is 8db SNR difference from the 1Mbps and 11Mbps rate. It means that the 1Mbps frames will be decoded in a distance more than 250 meters. 
it is a baisc multirate setting with rate info attached as Pxtinfo txinfo
there is no auto rate selection.

Advanced multirate code: 
Implement Feature 1,2 3

Auto multi-rate codes:  (Implement Feature 1,2 3 and a feasible Autorate Scheme)
in addition to basic multirate, auto rate and channel access estimation.
The design is integrated with a new cross-layer MAC design entity which a new structure of Node_Info is involved. (Link to Design of Cross-layer MAC).

For both versions, 6 files need to modified:

in ~/mac directoty:

  • mac-802_11.h
  • mac-802-11.cc
  • wireless-phy.cc.
  • wireless-phy.h

in ~/common directory

  • mobilenode.cc   .allow node to change its rate. It should has its will to stay in a lower rate as wish.
  • packet-stamp.h  This is a HACK! The receiver cannot know the rate before decoding the PLCP header, but here we put rate as same as SNR.

Note that whenever switch from versions of multi-rate to non-mulitrate ns codes, make clean & make due to problems with packet-stamp.h otherwise, "segmentation fault" occurs.
Based on the feature, Modifications are described in detail

Set Rate in TCL for each node:

rate is given in tcl code, and no matter what happens, the node has to use this rate as a fixed value. No matter a received DATA is another rate or not, datarate_ does not change. Only if an auto-rate scheme is in effect.............
in mac-802.11.cc 
getTxrate helps to get the rate info and calculate the timeouts,
setTxrate is only used for autorate..............

in mobilenode.cc:

       #include "wireless-phy.h"#include "mac-802_11.h"     Mac802_11* macptr;                ......                //Zhibin - To have an access to change rate! else if (strcmp(argv[1], "change_rate") == 0) {                       macptr = (Mac802_11*) ifhead_.lh_first->uptarget();                       if (macptr) {                               // Keep attention: supposes only 1                               // interface present!                               macptr->setRate(atoi(argv[2]));                               fprintf(stderr, "Rate changed to: %d\n\n",\                                               atoi(argv[2]));                               return TCL_OK;                       } else {                               fprintf(stderr, "Error.. Mac not found..\n");                               return(TCL_ERROR);                       };                       return TCL_OK;}                 ............                          
Actually, this change might not useful if u don't set it dynamically from tcl file.

in mac-802_11.h

//zhibin-multirate inline double   setRate(double newvalue){ return dataRate_ = newvalue;};        //-----------------

Short Preamble header & different rate for ACK/RTS/CTS/DATA


in mac-802_11.h

       // Zhibin- To introduce the short preamble, variables will be bind from ns-default.tcl        u_int32_t       ShortPreambleLength;        double          ShortPLCPDataRate;double          ShortPLCPHeaderThreshold;  // we keep this parameter as part of MIB       inline double getEIFS(double r) {                // see (802.11-1999, 9.2.10)               return(SIFSTime + getDIFS()                       + (8 *  getACKlen(r))/PLCPDataRate);       }      inline double  getShortPLCPHeaderThreshold() {   return ShortPLCPHeaderThreshold ;       }                                                        inline u_int32_t getShortPreambleLength() { return(ShortPreambleLength); }       inline double getShortPLCPDataRate() { return(ShortPLCPDataRate); }       inline u_int32_t getPLCPHeaderLength() { return(PLCPHeaderLength); }      inline u_int32_t getPLCPhdrLen(double r) {      return       ((r>ShortPLCPHeaderThreshold )                         ?((ShortPreambleLength >> 3)+(PLCPHeaderLength >> 3))                        :((PreambleLength >> 3)+(PLCPHeaderLength >> 3)));}       inline u_int32_t getHdrLen11(double r) {                           return(getPLCPhdrLen(r) + sizeof(struct hdr_mac802_11)                       + ETHER_FCS_LEN);       }               inline u_int32_t getRTSlen(double r) {             return(getPLCPhdrLen(r) + sizeof(struct rts_frame));       }       inline u_int32_t getCTSlen(double r) {               return(getPLCPhdrLen(r) + sizeof(struct cts_frame));      }       inline u_int32_t getACKlen(double r) {               return(getPLCPhdrLen(r) + sizeof(struct ack_frame));       }                    
in ns-default.tcl
        Mac/802_11 set ShortPreambleLength_      72  ;#  DataRate of Short PLCP Header. PLCP preample is always sent at DSSS_PLCPDataRateMac/802_11 set ShortPLCPDataRate_          2.0e6  ;#-------zhibinwu ----------------Mac/802_11 set ShortPLCPHeaderThreshold_ 1.0e6;
in mac-802_11.cc
       parent->bind("ShortPreambleLength_", &ShortPreambleLength);       parent->bind("ShortPLCPHeaderThreshold_", &ShortPLCPHeaderThreshold);       parent->bind_bw("ShortPLCPDataRate_", &ShortPLCPDataRate);
Has to assume all ACK and RTS/CTS are in basic rate. Thus, probablay 1mbps,
Change :

 getCTSlen() ----> getRTSlen(basicRate_); 
 getRTSlen() ----> getCTSlen(basicRate_);
 getACKlen() ----> getACKlen(basicRate_); 
 getEIFS ----> getEIFS(basicRate_);
 getHdrlen11()  ----->getHdrlen11(p->txinfo_.getTxRate()) 
doubleMac802_11::txtime(double psz, double drt){// change wrt Mike's code//double dsz = psz - PLCP_HDR_LEN;//int plcp_hdr = PLCP_HDR_LEN << 3;//double dsz = psz - phymib_.getPLCPhdrLen();//       int plcp_hdr = phymib_.getPLCPhdrLen() << 3;        double dsz = psz - phymib_.getPLCPhdrLen(drt);       int plcp_hdr = phymib_.getPLCPhdrLen(drt) << 3;int datalen = (int)dsz << 3;// change wrt Mike's code//double t = (((double)plcp_hdr)/phymib_->PLCPDataRate) + (((double)datalen)/drt);//double t = (((double)plcp_hdr)/phymib_.getPLCPDataRate())//                                       + (((double)datalen)/drt);      double t = 0;               if ( drt >phymib_.getShortPLCPHeaderThreshold() ) {               /* Zhibin - In this case the are sent at 1 Mbps while                * ShortPLCPHeader at 2Mbps and the rest at dataRate_                */           t = (((double)phymib_.getShortPreambleLength())/(phymib_.getPLCPDataRate())) +                (((double)phymib_.getPLCPHeaderLength())/(phymib_.getShortPLCPDataRate())) +                (((double)datalen)/drt);       } else {           t = (((double)plcp_hdr)/phymib_.getPLCPDataRate()) + (((double)datalen)/drt);       };return(t);}

Attach and Read Rate information with DATA frame


in packet-stamp.h
 inline double getTxRate() {return txRate;} inline void   setTxRate(double r) {txRate = r;}
in 802.11.cc

voidMac802_11::sendDATA(Packet *p){....if((u_int32_t)ETHER_ADDR(dh->dh_ra) != MAC_BROADCAST) {         p->txinfo_.setTxRate(dataRate_);                                      if((u_int32_t)ETHER_ADDR(dh->dh_ra) != MAC_BROADCAST) {                ch->size() += phymib_.getHdrLen11(dataRate_);        }else{                // GgX - Broadcast packets are always sent at basicRate_                ch->size() += phymib_.getHdrLen11(basicRate_);        };                                                                        .....}   

SNR of different Rates ( Drop packets of higher rate if SNR is low)



In  wireless-phy.cc


IN sendup fucntion, first get the rate information of the packet. ( The default rate is 1M,if unset in MAC layer)

    double rate = p->txinfo_.getTxRate();    int rate_index;//zhibinwu, find the rate index in rate tablefor ( int rate_index=0; rate_index< NUM_RATE_80211b; i++){  if ( rate == RXRate_[rate_index]) break;}        if (rate_index==4) printf ("ERROR! RATE NOT FOUND!\N");if (Pr < RXThresh_[rate_index]) {/* * We can detect, but not successfully receive * this packet. */hdr_cmn *hdr = HDR_CMN(p);hdr->error() = 1;#if DEBUG > 3printf("SM %f.9 _%d_ drop pkt from %d low POWER %e/%e\n",       Scheduler::instance().clock(), node()->index(),       p->txinfo_.getNode()->index(),       Pr,RXThresh_[rate_index]);#endif}
And
RXRate_[0]= 1000000;RXrate_[1]= 2000000; RxRate_[2]= 5500000;RxRate_[3]= 11000000;RXThresh_[0] = 0.1;     // receive power threshold (W) for each rateRXThresh_[1] = 0.2;     // receive power threshold (W) for each rateRXThresh_[2] = 0.3;     // receive power threshold (W) for each rateRXThresh_[3] = 0.4;     // receive power threshold (W) for each rate
in wireless-phy.h 

#define NUM_RATE_80211b 4;double RXRate_[NUM_RATE_80211b];double RXThresh_[NUM_RATE_80211b];     // receive power threshold (W) for each rate

ARF

ARF relies on MAC retransmission (set retry limit as 7 will be good)
  1. Define rate array in MAC;
  2. set a varible in MAC to flag miss ACK event.
  3. Set a conunter to counter consecutive transmissions
  4. In retransmit data, downgrade-rate, reset ch->size() and ch->txtime();
  5. In recvACK, prepare upgrade-rate
In mac-802_11.cc
   //zhibinwu        optRate_[0] = 1000000;        optRate_[1] = 2000000;        optRate_[2] = 5500000;        optRate_[3] = 11000000;missACK = false;ACKcounter = 0;voidMac802_11::recvACK(Packet *p){       //zhibinwu ----------ARF----        missACK_ = false;        ACKcounter_++;        if ( ACKcounter_ >10 )        {           //upgrade datarate           int m;           for (m=0;m<4;m++)           {               if ( optRate_[m] == dataRate_ && m!=3)               {                  dataRate_ = optRate_[m+1];                  break;               }           }           //printf(" the new datarate is %f\n", dataRate_);           ACKcounter_ = 0;        }        //-------------------------------
   }voidMac802_11::RetransmitDATA(){     //zhibinwu's code to do ARF (AutoRate Fallback)       ACKcounter_ = 0;  // no successive ACKs       if (missACK_ == false))              missACK_ =  true; //first missed ACK does not trigger fallback               else if ( dataRate_ == basicRate_)       {           //already fallback to lowest       }       else       {             //previous rate is datarate_ as same as getTxRate             ch->size() -= phymib_.getHdrLen11(pktTx_->txinfo_.getTxRate());               // assert pktTx and change size     int m;     for (m=0;m<4;m++)     {         if ( optRate_[m] == dataRate_ && m!=0)  {      dataRate_ = optRate_[m-1];          }                 }                   //calculate new size                 ch->size() += phymib_.getHdrLen11(dataRate_);                     ch->txtime() = txtime(ch->size(), dataRate_);                    pktTx_->txinfo_.setTxRate(dataRate_);                                                        }               // =============ARF---end=========

Appendix: PHY Model

In ns-2, the model is TwoRayground. It is for long range. Basically it means the attenuation factor 4 is used instead of 2.

Pr =   PtGtGrht2hr2 / (Ld4)

The original setting is:

Tx Power0.2818W  (24.5dbm) CSThreshold1.559e-11 W (-102.5db)  550mRxThreshold3.652e-10 W (-91.1db)250m((3.652/1.559)*10)^0.25 =2.2
2.2*250 = 550


Modified model for 802.11b
TxPower0.031622777 W (15dbm)RatedistanceCST -100dbm (1e-13 W) 1124mRxThreshold[0]-94dbm    3.9811e-13 W 1Mbps796RxThreshold[1]-91dbm   7.9433e-13W2Mbps669RxThreshold[2]-87dbm   1.9953e-12  W5.5Mbps532mRxThreshold[3]-82dbm   6.3096e-12  W11Mbps399m
原创粉丝点击