--- a/src/devices/wifi/edca-txop-n.cc Wed Feb 03 20:34:51 2010 +0100
+++ b/src/devices/wifi/edca-txop-n.cc Wed Feb 03 20:34:52 2010 +0100
@@ -87,6 +87,9 @@
virtual void GotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address source) {
m_txop->GotBlockAck (blockAck, source);
}
+ virtual void MissedBlockAck (void) {
+ m_txop->MissedBlockAck ();
+ }
virtual void StartNext (void) {
m_txop->StartNext ();
}
@@ -507,6 +510,20 @@
RestartAccessIfNeeded ();
}
+void
+EdcaTxopN::MissedBlockAck (void)
+{
+ NS_LOG_FUNCTION (this);
+ MY_DEBUG ("missed block ack");
+
+ MY_DEBUG ("Retransmit block ack request");
+ m_currentHdr.SetRetry ();
+ m_dcf->UpdateFailedCw ();
+
+ m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
+ RestartAccessIfNeeded ();
+}
+
Ptr<MsduAggregator>
EdcaTxopN::GetMsduAggregator (void) const
{
--- a/src/devices/wifi/edca-txop-n.h Wed Feb 03 20:34:51 2010 +0100
+++ b/src/devices/wifi/edca-txop-n.h Wed Feb 03 20:34:52 2010 +0100
@@ -114,6 +114,7 @@
void MissedCts (void);
void GotAck (double snr, WifiMode txMode);
void GotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address recipient);
+ void MissedBlockAck (void);
void GotAddBaResponse (const MgtAddBaResponseHeader *respHdr, Mac48Address recipient);
void MissedAck (void);
void StartNext (void);
--- a/src/devices/wifi/mac-low.cc Wed Feb 03 20:34:51 2010 +0100
+++ b/src/devices/wifi/mac-low.cc Wed Feb 03 20:34:52 2010 +0100
@@ -117,6 +117,9 @@
MacLowTransmissionListener::GotBlockAck (const CtrlBAckResponseHeader *blockAck,
Mac48Address source)
{}
+void
+MacLowTransmissionListener::MissedBlockAck (void)
+{}
MacLowDcfListener::MacLowDcfListener ()
{}
MacLowDcfListener::~MacLowDcfListener ()
@@ -319,6 +322,7 @@
m_fastAckTimeoutEvent (),
m_superFastAckTimeoutEvent (),
m_fastAckFailedTimeoutEvent (),
+ m_blockAckTimeoutEvent (),
m_ctsTimeoutEvent (),
m_sendCtsEvent (),
m_sendAckEvent (),
@@ -353,6 +357,7 @@
m_fastAckTimeoutEvent.Cancel ();
m_superFastAckTimeoutEvent.Cancel ();
m_fastAckFailedTimeoutEvent.Cancel ();
+ m_blockAckTimeoutEvent.Cancel ();
m_ctsTimeoutEvent.Cancel ();
m_sendCtsEvent.Cancel ();
m_sendAckEvent.Cancel ();
@@ -389,6 +394,11 @@
m_fastAckFailedTimeoutEvent.Cancel ();
oneRunning = true;
}
+ if (m_blockAckTimeoutEvent.IsRunning ())
+ {
+ m_blockAckTimeoutEvent.Cancel ();
+ oneRunning = true;
+ }
if (m_ctsTimeoutEvent.IsRunning ())
{
m_ctsTimeoutEvent.Cancel ();
@@ -445,6 +455,16 @@
{
m_ackTimeout = ackTimeout;
}
+void
+MacLow::SetBasicBlockAckTimeout (Time blockAckTimeout)
+{
+ m_basicBlockAckTimeout = blockAckTimeout;
+}
+void
+MacLow::SetCompressedBlockAckTimeout (Time blockAckTimeout)
+{
+ m_compressedBlockAckTimeout = blockAckTimeout;
+}
void
MacLow::SetCtsTimeout (Time ctsTimeout)
{
@@ -480,6 +500,16 @@
{
return m_ackTimeout;
}
+Time
+MacLow::GetBasicBlockAckTimeout () const
+{
+ return m_basicBlockAckTimeout;
+}
+Time
+MacLow::GetCompressedBlockAckTimeout () const
+{
+ return m_compressedBlockAckTimeout;
+}
Time
MacLow::GetCtsTimeout (void) const
{
@@ -696,13 +726,13 @@
}
}
else if (hdr.IsBlockAck () && hdr.GetAddr1 () == m_self &&
- (m_txParams.MustWaitBasicBlockAck () || m_txParams.MustWaitCompressedBlockAck ()))
- //m_blockAckTimeoutEvent.IsRunning ())
+ (m_txParams.MustWaitBasicBlockAck () || m_txParams.MustWaitCompressedBlockAck ()) &&
+ m_blockAckTimeoutEvent.IsRunning ())
{
NS_LOG_DEBUG ("got block ack from "<<hdr.GetAddr2 ());
CtrlBAckResponseHeader blockAck;
packet->RemoveHeader (blockAck);
- //m_blockAckTimeoutEvent.Cancel ();
+ m_blockAckTimeoutEvent.Cancel ();
m_listener->GotBlockAck (&blockAck, hdr.GetAddr2 ());
}
else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () == m_self)
@@ -868,7 +898,14 @@
Time
MacLow::GetBlockAckDuration (Mac48Address to, WifiMode blockAckReqTxMode, enum BlockAckType type) const
{
- //WifiMode blockAckMode = GetBlockAckTxModeForBlockAckReq (to, blockAckReqTxMode);
+ /*
+ * For immediate BlockAck we should transmit the frame with the same WifiMode
+ * as the BlockAckReq.
+ *
+ * from section 9.6 in IEEE802.11e:
+ * The BlockAck control frame shall be sent at the same rate and modulation class as
+ * the BlockAckReq frame if it is sent in response to a BlockAckReq frame.
+ */
return m_phy->CalculateTxDuration (GetBlockAckSize (type), blockAckReqTxMode, WIFI_PREAMBLE_LONG);
}
Time
@@ -1129,6 +1166,18 @@
}
}
void
+MacLow::BlockAckTimeout (void)
+{
+ NS_LOG_FUNCTION (this);
+ NS_LOG_DEBUG ("block ack timeout");
+
+ WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
+ station->ReportDataFailed ();
+ MacLowTransmissionListener *listener = m_listener;
+ m_listener = 0;
+ listener->MissedBlockAck ();
+}
+void
MacLow::SuperFastAckTimeout ()
{
NS_LOG_FUNCTION (this);
@@ -1221,7 +1270,19 @@
NotifyAckTimeoutStartNow (timerDelay);
m_superFastAckTimeoutEvent = Simulator::Schedule (timerDelay,
&MacLow::SuperFastAckTimeout, this);
- }
+ }
+ else if (m_txParams.MustWaitBasicBlockAck ())
+ {
+ Time timerDelay = txDuration + GetBasicBlockAckTimeout ();
+ NS_ASSERT (m_blockAckTimeoutEvent.IsExpired ());
+ m_blockAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::BlockAckTimeout, this);
+ }
+ else if (m_txParams.MustWaitCompressedBlockAck ())
+ {
+ Time timerDelay = txDuration + GetCompressedBlockAckTimeout ();
+ NS_ASSERT (m_blockAckTimeoutEvent.IsExpired ());
+ m_blockAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::BlockAckTimeout, this);
+ }
else if (m_txParams.HasNextPacket ())
{
Time delay = txDuration + GetSifs ();
@@ -1573,9 +1634,6 @@
{
m_txParams.DisableAck ();
duration -= GetSifs ();
- /* from section 9.6 in IEEE802.11e:
- The BlockAck control frame shall be sent at the same rate and modulation class as
- the BlockAckReq frame if it is sent in response to a BlockAckReq frame.*/
if (blockAck->IsBasic ())
{
duration -= GetBlockAckDuration (originator, blockAckReqTxMode, BASIC_BLOCK_ACK);
--- a/src/devices/wifi/mac-low.h Wed Feb 03 20:34:51 2010 +0100
+++ b/src/devices/wifi/mac-low.h Wed Feb 03 20:34:52 2010 +0100
@@ -95,6 +95,16 @@
*/
virtual void GotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address source);
/**
+ * ns3::MacLow did not receive an expected BLOCK_ACK within
+ * BlockAckTimeout. This method is used only for immediate
+ * block ack variant. With delayed block ack, the MissedAck method will be
+ * called instead: upon receipt of a block ack request, the rx station will
+ * reply with a normal ack frame. Later, when the rx station gets a txop, it
+ * will send the block ack back to the tx station which will reply with a
+ * normal ack to the rx station.
+ */
+ virtual void MissedBlockAck (void);
+ /**
* Invoked when ns3::MacLow wants to start a new transmission
* as configured by MacLowTransmissionParameters::EnableNextData.
* The listener is expected to call again MacLow::StartTransmission
@@ -338,6 +348,8 @@
void SetAddress (Mac48Address ad);
void SetAckTimeout (Time ackTimeout);
+ void SetBasicBlockAckTimeout (Time blockAckTimeout);
+ void SetCompressedBlockAckTimeout (Time blockAckTimeout);
void SetCtsTimeout (Time ctsTimeout);
void SetSifs (Time sifs);
void SetSlotTime (Time slotTime);
@@ -345,6 +357,8 @@
void SetBssid (Mac48Address ad);
Mac48Address GetAddress (void) const;
Time GetAckTimeout (void) const;
+ Time GetBasicBlockAckTimeout () const;
+ Time GetCompressedBlockAckTimeout () const;
Time GetCtsTimeout (void) const;
Time GetSifs (void) const;
Time GetSlotTime (void) const;
@@ -474,6 +488,7 @@
void FastAckTimeout (void);
void SuperFastAckTimeout (void);
void FastAckFailedTimeout (void);
+ void BlockAckTimeout (void);
void CtsTimeout (void);
void SendCtsAfterRts (Mac48Address source, Time duration, WifiMode txMode, double rtsSnr);
void SendAckAfterData (Mac48Address source, Time duration, WifiMode txMode, double rtsSnr);
@@ -539,6 +554,7 @@
EventId m_fastAckTimeoutEvent;
EventId m_superFastAckTimeoutEvent;
EventId m_fastAckFailedTimeoutEvent;
+ EventId m_blockAckTimeoutEvent;
EventId m_ctsTimeoutEvent;
EventId m_sendCtsEvent;
EventId m_sendAckEvent;
@@ -553,6 +569,8 @@
Mac48Address m_self;
Mac48Address m_bssid;
Time m_ackTimeout;
+ Time m_basicBlockAckTimeout;
+ Time m_compressedBlockAckTimeout;
Time m_ctsTimeout;
Time m_sifs;
Time m_slotTime;
--- a/src/devices/wifi/qadhoc-wifi-mac.cc Wed Feb 03 20:34:51 2010 +0100
+++ b/src/devices/wifi/qadhoc-wifi-mac.cc Wed Feb 03 20:34:52 2010 +0100
@@ -147,6 +147,18 @@
m_low->SetAckTimeout (ackTimeout);
}
+void
+QadhocWifiMac::SetBasicBlockAckTimeout (Time blockAckTimeout)
+{
+ m_low->SetBasicBlockAckTimeout (blockAckTimeout);
+}
+
+void
+QadhocWifiMac::SetCompressedBlockAckTimeout (Time blockAckTimeout)
+{
+ m_low->SetCompressedBlockAckTimeout (blockAckTimeout);
+}
+
void
QadhocWifiMac::SetCtsTimeout (Time ctsTimeout)
{
@@ -183,6 +195,18 @@
return m_low->GetAckTimeout ();
}
+Time
+QadhocWifiMac::GetBasicBlockAckTimeout (void) const
+{
+ return m_low->GetBasicBlockAckTimeout ();
+}
+
+Time
+QadhocWifiMac::GetCompressedBlockAckTimeout (void) const
+{
+ return m_low->GetCompressedBlockAckTimeout ();
+}
+
Time
QadhocWifiMac::GetCtsTimeout (void) const
{
--- a/src/devices/wifi/qadhoc-wifi-mac.h Wed Feb 03 20:34:51 2010 +0100
+++ b/src/devices/wifi/qadhoc-wifi-mac.h Wed Feb 03 20:34:52 2010 +0100
@@ -74,6 +74,10 @@
virtual void SetAddress (Mac48Address address);
virtual void SetSsid (Ssid ssid);
virtual Mac48Address GetBssid (void) const;
+ virtual void SetBasicBlockAckTimeout (Time blockAckTimeout);
+ virtual void SetCompressedBlockAckTimeout (Time blockAckTimeout);
+ virtual Time GetBasicBlockAckTimeout (void) const;
+ virtual Time GetCompressedBlockAckTimeout (void) const;
private:
--- a/src/devices/wifi/qap-wifi-mac.cc Wed Feb 03 20:34:51 2010 +0100
+++ b/src/devices/wifi/qap-wifi-mac.cc Wed Feb 03 20:34:52 2010 +0100
@@ -198,6 +198,18 @@
}
void
+QapWifiMac::SetBasicBlockAckTimeout (Time blockAckTimeout)
+{
+ m_low->SetBasicBlockAckTimeout (blockAckTimeout);
+}
+
+void
+QapWifiMac::SetCompressedBlockAckTimeout (Time blockAckTimeout)
+{
+ m_low->SetCompressedBlockAckTimeout (blockAckTimeout);
+}
+
+void
QapWifiMac::SetCtsTimeout (Time ctsTimeout)
{
m_low->SetCtsTimeout (ctsTimeout);
@@ -234,6 +246,18 @@
}
Time
+QapWifiMac::GetBasicBlockAckTimeout () const
+{
+ return m_low->GetBasicBlockAckTimeout ();
+}
+
+Time
+QapWifiMac::GetCompressedBlockAckTimeout () const
+{
+ return m_low->GetCompressedBlockAckTimeout ();
+}
+
+Time
QapWifiMac::GetCtsTimeout (void) const
{
return m_low->GetCtsTimeout ();
--- a/src/devices/wifi/qap-wifi-mac.h Wed Feb 03 20:34:51 2010 +0100
+++ b/src/devices/wifi/qap-wifi-mac.h Wed Feb 03 20:34:52 2010 +0100
@@ -82,6 +82,10 @@
virtual void SetAddress (Mac48Address address);
virtual void SetSsid (Ssid ssid);
virtual Mac48Address GetBssid (void) const;
+ virtual void SetBasicBlockAckTimeout (Time blockAckTimeout);
+ virtual void SetCompressedBlockAckTimeout (Time blockAckTimeout);
+ virtual Time GetBasicBlockAckTimeout (void) const;
+ virtual Time GetCompressedBlockAckTimeout (void) const;
void SetBeaconInterval (Time interval);
Time GetBeaconInterval (void) const;
--- a/src/devices/wifi/qsta-wifi-mac.cc Wed Feb 03 20:34:51 2010 +0100
+++ b/src/devices/wifi/qsta-wifi-mac.cc Wed Feb 03 20:34:52 2010 +0100
@@ -169,6 +169,18 @@
m_low->SetAckTimeout (ackTimeout);
}
+void
+QstaWifiMac::SetBasicBlockAckTimeout (Time blockAckTimeout)
+{
+ m_low->SetBasicBlockAckTimeout (blockAckTimeout);
+}
+
+void
+QstaWifiMac::SetCompressedBlockAckTimeout (Time blockAckTimeout)
+{
+ m_low->SetCompressedBlockAckTimeout (blockAckTimeout);
+}
+
void
QstaWifiMac::SetCtsTimeout (Time ctsTimeout)
{
@@ -205,6 +217,18 @@
return m_low->GetAckTimeout ();
}
+Time
+QstaWifiMac::GetBasicBlockAckTimeout (void) const
+{
+ return m_low->GetBasicBlockAckTimeout ();
+}
+
+Time
+QstaWifiMac::GetCompressedBlockAckTimeout (void) const
+{
+ return m_low->GetCompressedBlockAckTimeout ();
+}
+
Time
QstaWifiMac::GetCtsTimeout (void) const
{
--- a/src/devices/wifi/qsta-wifi-mac.h Wed Feb 03 20:34:51 2010 +0100
+++ b/src/devices/wifi/qsta-wifi-mac.h Wed Feb 03 20:34:52 2010 +0100
@@ -81,6 +81,10 @@
virtual void SetAddress (Mac48Address address);
virtual void SetSsid (Ssid ssid);
virtual Mac48Address GetBssid (void) const;
+ virtual void SetBasicBlockAckTimeout (Time blockAckTimeout);
+ virtual void SetCompressedBlockAckTimeout (Time blockAckTimeout);
+ virtual Time GetBasicBlockAckTimeout (void) const;
+ virtual Time GetCompressedBlockAckTimeout (void) const;
void SetMaxMissedBeacons (uint32_t missed);
void SetProbeRequestTimeout (Time timeout);
--- a/src/devices/wifi/wifi-mac.cc Wed Feb 03 20:34:51 2010 +0100
+++ b/src/devices/wifi/wifi-mac.cc Wed Feb 03 20:34:52 2010 +0100
@@ -69,6 +69,63 @@
return ctsTimeout;
}
+Time
+WifiMac::GetDefaultBasicBlockAckDelay (void)
+{
+ // This value must be rivisited
+ return MicroSeconds (250);
+}
+Time
+WifiMac::GetDefaultCompressedBlockAckDelay (void)
+{
+ // This value must be rivisited
+ return MicroSeconds (68);
+}
+Time
+WifiMac::GetDefaultBasicBlockAckTimeout (void)
+{
+ Time blockAckTimeout = GetDefaultSifs ();
+ blockAckTimeout += GetDefaultBasicBlockAckDelay ();
+ blockAckTimeout += MicroSeconds (GetDefaultMaxPropagationDelay ().GetMicroSeconds () * 2);
+ blockAckTimeout += GetDefaultSlot ();
+ return blockAckTimeout;
+}
+Time
+WifiMac::GetDefaultCompressedBlockAckTimeout (void)
+{
+ Time blockAckTimeout = GetDefaultSifs ();
+ blockAckTimeout += GetDefaultCompressedBlockAckDelay ();
+ blockAckTimeout += MicroSeconds (GetDefaultMaxPropagationDelay ().GetMicroSeconds () * 2);
+ blockAckTimeout += GetDefaultSlot ();
+ return blockAckTimeout;
+}
+
+void
+WifiMac::SetBasicBlockAckTimeout (Time blockAckTimeout)
+{
+ //this method must be implemented by QoS WifiMacs
+}
+
+Time
+WifiMac::GetBasicBlockAckTimeout (void) const
+{
+ //this method must be implemented by QoS WifiMacs
+ return MicroSeconds (0);
+}
+
+void
+WifiMac::SetCompressedBlockAckTimeout (Time blockAckTimeout)
+{
+ //this methos must be implemented by QoS WifiMacs
+}
+
+Time
+WifiMac::GetCompressedBlockAckTimeout (void) const
+{
+ //this method must be implemented by QoS WifiMacs
+ return MicroSeconds (0);
+}
+
TypeId
WifiMac::GetTypeId (void)
{
@@ -84,6 +141,16 @@
MakeTimeAccessor (&WifiMac::GetAckTimeout,
&WifiMac::SetAckTimeout),
MakeTimeChecker ())
+ .AddAttribute ("BasicBlockAckTimeout", "When this timeout expires, the BASIC_BLOCK_ACK_REQ/BASIC_BLOCK_ACK handshake has failed.",
+ TimeValue (GetDefaultBasicBlockAckTimeout ()),
+ MakeTimeAccessor (&WifiMac::GetBasicBlockAckTimeout,
+ &WifiMac::SetBasicBlockAckTimeout),
+ MakeTimeChecker ())
+ .AddAttribute ("CompressedBlockAckTimeout", "When this timeout expires, the COMPRESSED_BLOCK_ACK_REQ/COMPRESSED_BLOCK_ACK handshake has failed.",
+ TimeValue (GetDefaultCompressedBlockAckTimeout ()),
+ MakeTimeAccessor (&WifiMac::GetCompressedBlockAckTimeout,
+ &WifiMac::SetCompressedBlockAckTimeout),
+ MakeTimeChecker ())
.AddAttribute ("Sifs", "The value of the SIFS constant.",
TimeValue (GetDefaultSifs ()),
MakeTimeAccessor (&WifiMac::SetSifs,
--- a/src/devices/wifi/wifi-mac.h Wed Feb 03 20:34:51 2010 +0100
+++ b/src/devices/wifi/wifi-mac.h Wed Feb 03 20:34:52 2010 +0100
@@ -179,6 +179,13 @@
* \param linkDown the callback to invoke when the link becomes down.
*/
virtual void SetLinkDownCallback (Callback<void> linkDown) = 0;
+ /* Next functions are not pure vitual so non Qos WifiMacs are not
+ * forced to implement them.
+ */
+ virtual void SetBasicBlockAckTimeout (Time blockAckTimeout);
+ virtual Time GetBasicBlockAckTimeout (void) const;
+ virtual void SetCompressedBlockAckTimeout (Time blockAckTimeout);
+ virtual Time GetCompressedBlockAckTimeout (void) const;
/**
* Public method used to fire a MacTx trace. Implemented for encapsulation
@@ -224,6 +231,10 @@
static Time GetDefaultEifsNoDifs (void);
static Time GetDefaultCtsAckDelay (void);
static Time GetDefaultCtsAckTimeout (void);
+ static Time GetDefaultBasicBlockAckDelay (void);
+ static Time GetDefaultBasicBlockAckTimeout (void);
+ static Time GetDefaultCompressedBlockAckDelay (void);
+ static Time GetDefaultCompressedBlockAckTimeout (void);
/**
* \param standard the phy standard to be used
*