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:
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:
in ~/common directory
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
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:
Actually, this change might not useful if u don't set it dynamically from tcl file.
#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;
}
............
in mac-802_11.h
//zhibin-multirate
inline double setRate(double newvalue){ return dataRate_ = newvalue;};
//-----------------
// Zhibin- To introduce the short preamble, variables will be bind from ns-default.tclin 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 mac-802_11.cc
Mac/802_11 set ShortPreambleLength_ 72 ;
# DataRate of Short PLCP Header. PLCP preample is always sent at DSSS_PLCPDataRate
Mac/802_11 set ShortPLCPDataRate_ 2.0e6 ;
#-------zhibinwu ----------------
Mac/802_11 set ShortPLCPHeaderThreshold_ 1.0e6;
Has to assume all ACK and RTS/CTS are in basic rate. Thus, probablay 1mbps,
parent->bind("ShortPreambleLength_", &ShortPreambleLength);
parent->bind("ShortPLCPHeaderThreshold_", &ShortPLCPHeaderThreshold);
parent->bind_bw("ShortPLCPDataRate_", &ShortPLCPDataRate);
double
Mac802_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);
}
inline double getTxRate() {return txRate;}in 802.11.cc
inline void setTxRate(double r) {txRate = r;}
void
Mac802_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_);
};
.....
}
double rate = p->txinfo_.getTxRate();And
int rate_index;
//zhibinwu, find the rate index in rate table
for ( 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 > 3
printf("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
}
RXRate_[0]= 1000000;in wireless-phy.h
RXrate_[1]= 2000000;
RxRate_[2]= 5500000;
RxRate_[3]= 11000000;
RXThresh_[0] = 0.1; // receive power threshold (W) for each rate
RXThresh_[1] = 0.2; // receive power threshold (W) for each rate
RXThresh_[2] = 0.3; // receive power threshold (W) for each rate
RXThresh_[3] = 0.4; // receive power threshold (W) for each rate
#define NUM_RATE_80211b 4;
double RXRate_[NUM_RATE_80211b];
double RXThresh_[NUM_RATE_80211b]; // receive power threshold (W) for each rate
//zhibinwu
optRate_[0] = 1000000;
optRate_[1] = 2000000;
optRate_[2] = 5500000;
optRate_[3] = 11000000;
missACK = false;
ACKcounter = 0;
void
Mac802_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;
}
//-------------------------------
}
void
Mac802_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=========
}
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 Power |
0.2818W (24.5dbm) |
|
CSThreshold |
1.559e-11 W (-102.5db) |
550m |
RxThreshold |
3.652e-10 W (-91.1db) | 250m |
TxPower |
0.031622777 W (15dbm) | Rate |
distance |
CST |
-100dbm (1e-13 W) |
1124m |
|
RxThreshold[0] |
-94dbm
3.9811e-13 W |
1Mbps |
796 |
RxThreshold[1] | -91dbm 7.9433e-13W |
2Mbps |
669 |
RxThreshold[2] | -87dbm
1.9953e-12 W |
5.5Mbps |
532m |
RxThreshold[3] | -82dbm
6.3096e-12 W |
11Mbps |
399m |