NS2 fix
Fixes for the Network Simulator 2.26 Sources
This page presents a patch that corrects an invalid behavior of NS
(version 2.26) 802.11 implementation.
Background
The IEEE 802.11 standard defines station (STA) short retry count
(SSRC), STA long retry count (SLRC), short retry counter for MSDU and
long retry counter for MSDU. The values for a STA retry count and a
retry counter for MSDU are increased every time sending MPDU fails. The
values are reset when sending succeeds.
CW is reset to CWmin, when
- transmit was successful,
- SLRC reaches long retry limit, or
- SSRC reaches short retry limit
Problem
NS uses only one value for SSRC and short retry counter for MSDU. The
same goes for SLRC and long retry counter for MSDU. The SSRC and SLRC
should not be set to 0 when transmitting a new MPDU, but this is what
is done. As a result, CWis set to aCWMin when transmitting fails (due
to too many retries). While the difference between the behavior defined
in the standard and the results obtained with NS are negligible in most
cases, the difference becomes apparent with a large number of active
stations.
Solution
A short retry counter for MSDU and a long retry counter for MSDU are
introduced. The patch for the NS source code follows. The patch is
extracted with diff program and can be applied to sources with patch
program. The patch has been sent to the NS developers with online bug
report form on December 10, 2003.
diff -urN ns-2.26_org/mac/mac-802_11.cc
ns-2.26/mac/mac-802_11.cc
--- ns-2.26_org/mac/mac-802_11.cc 2003-02-27 00:08:56.000000000 +0200
+++ ns-2.26/mac/mac-802_11.cc 2003-12-04 07:35:17.000000000 +0200
@@ -160,6 +160,7 @@
cw_ = phymib_->CWMin;
ssrc_ = slrc_ = 0;
+ msrc_ = mlrc_ = 0;
sifs_ = phymib_->SIFSTime;
pifs_ = sifs_ + phymib_->SlotTime;
@@ -927,8 +928,11 @@
macmib_->RTSFailureCount++;
ssrc_ += 1; // STA Short Retry Count
+ msrc_ += 1;
-if(ssrc_ >= macmib_->ShortRetryLimit) {
+ inc_cw();
+
+ if(msrc_ >= macmib_->ShortRetryLimit) {
discard(pktRTS_, DROP_MAC_RETRY_COUNT_EXCEEDED); pktRTS_ = 0;
/* tell the callback the send operation failed
before discarding the packet */
@@ -946,15 +950,16 @@
}
//printf("(%d)....discarding RTS:%x\n",index_,pktRTS_);
discard(pktTx_, DROP_MAC_RETRY_COUNT_EXCEEDED); pktTx_ = 0;
-ssrc_ = 0;
-rst_cw();
+ msrc_ = 0;
+ if(ssrc_ == macmib_>ShortRetryLimit) {
+ rst_cw();
+ }
} else {
//printf("(%d)...retxing RTS:%x\n",index_,pktRTS_);
struct rts_frame *rf;
rf = (struct rts_frame*)pktRTS_->access(hdr_mac::offset_);
rf->rf_fc.fc_retry = 1;
-inc_cw();
mhBackoff_.start(cw_, is_idle());
}
}
@@ -964,7 +969,7 @@
{
struct hdr_cmn *ch;
struct hdr_mac802_11 *mh;
-u_int32_t *rcount, *thresh;
+ u_int32_t *rcount, *mcount, *thresh;
assert(mhBackoff_.busy() == 0);
@@ -994,16 +999,21 @@
if((u_int32_t) ch->size() <= macmib_->RTSThreshold) {
rcount = &ssrc_;
+ mcount = &msrc_;
thresh = &macmib_->ShortRetryLimit;
}
else {
rcount = &slrc_;
+ mcount = &msrc_;
thresh = &macmib_->LongRetryLimit;
}
(*rcount)++;
+ (*mcount)++;
+
+ inc_cw();
-if(*rcount > *thresh) {
+ if(*mcount >= *thresh) {
macmib_->FailedCount++;
/* tell the callback the send operation failed
before discarding the packet */
@@ -1018,7 +1028,9 @@
discard(pktTx_, DROP_MAC_RETRY_COUNT_EXCEEDED); pktTx_ = 0;
//printf("(%d)DATA discarded: count exceeded\n",index_);
*rcount = 0;
-rst_cw();
+ if(*rcount == *thresh) {
+ rst_cw();
+ }
}
else {
struct hdr_mac802_11 *dh;
@@ -1027,7 +1039,7 @@
sendRTS(ETHER_ADDR(mh->dh_da));
//printf("(%d)retxing data:%x..sendRTS..\n",index_,pktTx_);
-inc_cw();
+
mhBackoff_.start(cw_, is_idle());
}
}
@@ -1359,7 +1371,7 @@
* that our RTS was successful. Hence, we can reset
* the Short Retry Count and the CW.
*/
-//ssrc_ = 0;
+ ssrc_ = 0;
//rst_cw();
tx_resume();
@@ -1487,10 +1499,13 @@
* that our DATA transmission was successful. Hence,
* we can reset the Short/Long Retry Count and the CW.
*/
-if((u_int32_t) ch->size() <= macmib_->RTSThreshold)
+ if((u_int32_t) ch->size() <= macmib_->RTSThreshold) {
ssrc_ = 0;
-else
+ msrc_ = 0;
+ } else {
slrc_ = 0;
+ mlrc_ = 0;
+ }
/*
* Backoff before sending again.
diff -urN ns-2.26_org/mac/mac-802_11.h ns-2.26/mac/mac-802_11.h
--- ns-2.26_org/mac/mac-802_11.h 2003-02-27 00:08:56.000000000 +0200
+++ ns-2.26/mac/mac-802_11.h 2003-12-04 07:22:31.000000000 +0200
@@ -361,6 +361,8 @@
u_int32_t cw_; // Contention Window
u_int32_t ssrc_; // STA Short Retry Count
u_int32_t slrc_; // STA Long Retry Count
+ u_int32_t msrc_; // MSDU Short Retry Count
+ u_int32_t mlrc_; // MSDU Long Retry Count
double sifs_; // Short Interface Space
double pifs_; // PCF Interframe Space
double difs_; // DCF Interframe Space