# HG changeset patch # User Mirko Banchi # Date 1265225692 -3600 # Node ID dd0accd82659766766984dd8383cfd89f06b241b # Parent dd5ece55acb963a44ca5629a766df9d9de7cf02b add block ack timeouts diff -r dd5ece55acb9 -r dd0accd82659 src/devices/wifi/edca-txop-n.cc --- 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 EdcaTxopN::GetMsduAggregator (void) const { diff -r dd5ece55acb9 -r dd0accd82659 src/devices/wifi/edca-txop-n.h --- 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); diff -r dd5ece55acb9 -r dd0accd82659 src/devices/wifi/mac-low.cc --- 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 "<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); diff -r dd5ece55acb9 -r dd0accd82659 src/devices/wifi/mac-low.h --- 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; diff -r dd5ece55acb9 -r dd0accd82659 src/devices/wifi/qadhoc-wifi-mac.cc --- 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 { diff -r dd5ece55acb9 -r dd0accd82659 src/devices/wifi/qadhoc-wifi-mac.h --- 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: diff -r dd5ece55acb9 -r dd0accd82659 src/devices/wifi/qap-wifi-mac.cc --- 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 (); diff -r dd5ece55acb9 -r dd0accd82659 src/devices/wifi/qap-wifi-mac.h --- 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; diff -r dd5ece55acb9 -r dd0accd82659 src/devices/wifi/qsta-wifi-mac.cc --- 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 { diff -r dd5ece55acb9 -r dd0accd82659 src/devices/wifi/qsta-wifi-mac.h --- 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); diff -r dd5ece55acb9 -r dd0accd82659 src/devices/wifi/wifi-mac.cc --- 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, diff -r dd5ece55acb9 -r dd0accd82659 src/devices/wifi/wifi-mac.h --- 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 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 *