diff --git a/CHANGES.html b/CHANGES.html index b99bbf114..f78fbb808 100644 --- a/CHANGES.html +++ b/CHANGES.html @@ -58,6 +58,7 @@ us a note on ns-developers mailing list.

  • A new attribute WifiPhy::PostReceptionErrorModel has been added to force specific packet drops.
  • +
  • A new attribute WifiPhy::PreambleDetectionModel has been added to decide whether PHY preambles are successfully detected.
  • New attributes QosTxop::AddBaResponseTimeout and QosTxop::FailedAddBaTimeout have been added to set the timeout to wait for an ADDBA response after the ACK to the ADDBA request is received and to set the timeout after a failed BA agreement, respectively.
  • diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 4927b8468..bfd5857af 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -23,6 +23,7 @@ requirements (Note: not all features available on all platforms): New user-visible features ------------------------- +- (wifi) Preamble detection can now be modelled Bugs fixed ---------- diff --git a/src/mesh/test/dot11s/hwmp-proactive-regression-test-0-1.pcap b/src/mesh/test/dot11s/hwmp-proactive-regression-test-0-1.pcap index 01a3809b5..50ff54e2d 100644 Binary files a/src/mesh/test/dot11s/hwmp-proactive-regression-test-0-1.pcap and b/src/mesh/test/dot11s/hwmp-proactive-regression-test-0-1.pcap differ diff --git a/src/mesh/test/dot11s/hwmp-proactive-regression-test-1-1.pcap b/src/mesh/test/dot11s/hwmp-proactive-regression-test-1-1.pcap index 752e3175f..54714b633 100644 Binary files a/src/mesh/test/dot11s/hwmp-proactive-regression-test-1-1.pcap and b/src/mesh/test/dot11s/hwmp-proactive-regression-test-1-1.pcap differ diff --git a/src/mesh/test/dot11s/hwmp-proactive-regression-test-2-1.pcap b/src/mesh/test/dot11s/hwmp-proactive-regression-test-2-1.pcap index e59c83ecc..156033813 100644 Binary files a/src/mesh/test/dot11s/hwmp-proactive-regression-test-2-1.pcap and b/src/mesh/test/dot11s/hwmp-proactive-regression-test-2-1.pcap differ diff --git a/src/mesh/test/dot11s/hwmp-proactive-regression-test-3-1.pcap b/src/mesh/test/dot11s/hwmp-proactive-regression-test-3-1.pcap index 182a460e9..662f6d4a2 100644 Binary files a/src/mesh/test/dot11s/hwmp-proactive-regression-test-3-1.pcap and b/src/mesh/test/dot11s/hwmp-proactive-regression-test-3-1.pcap differ diff --git a/src/mesh/test/dot11s/hwmp-proactive-regression-test-4-1.pcap b/src/mesh/test/dot11s/hwmp-proactive-regression-test-4-1.pcap index 9f3eb8abb..261ffdac8 100644 Binary files a/src/mesh/test/dot11s/hwmp-proactive-regression-test-4-1.pcap and b/src/mesh/test/dot11s/hwmp-proactive-regression-test-4-1.pcap differ diff --git a/src/mesh/test/dot11s/hwmp-reactive-regression-test-0-1.pcap b/src/mesh/test/dot11s/hwmp-reactive-regression-test-0-1.pcap index b07cceab6..207252f5a 100644 Binary files a/src/mesh/test/dot11s/hwmp-reactive-regression-test-0-1.pcap and b/src/mesh/test/dot11s/hwmp-reactive-regression-test-0-1.pcap differ diff --git a/src/mesh/test/dot11s/hwmp-reactive-regression-test-1-1.pcap b/src/mesh/test/dot11s/hwmp-reactive-regression-test-1-1.pcap index 943faa860..edf8f243a 100644 Binary files a/src/mesh/test/dot11s/hwmp-reactive-regression-test-1-1.pcap and b/src/mesh/test/dot11s/hwmp-reactive-regression-test-1-1.pcap differ diff --git a/src/mesh/test/dot11s/hwmp-reactive-regression-test-2-1.pcap b/src/mesh/test/dot11s/hwmp-reactive-regression-test-2-1.pcap index 5f02ba69d..6b623819c 100644 Binary files a/src/mesh/test/dot11s/hwmp-reactive-regression-test-2-1.pcap and b/src/mesh/test/dot11s/hwmp-reactive-regression-test-2-1.pcap differ diff --git a/src/mesh/test/dot11s/hwmp-reactive-regression-test-3-1.pcap b/src/mesh/test/dot11s/hwmp-reactive-regression-test-3-1.pcap index 20f9e87a8..69132f05c 100644 Binary files a/src/mesh/test/dot11s/hwmp-reactive-regression-test-3-1.pcap and b/src/mesh/test/dot11s/hwmp-reactive-regression-test-3-1.pcap differ diff --git a/src/mesh/test/dot11s/hwmp-reactive-regression-test-4-1.pcap b/src/mesh/test/dot11s/hwmp-reactive-regression-test-4-1.pcap index 3ce66df2b..ce0efa629 100644 Binary files a/src/mesh/test/dot11s/hwmp-reactive-regression-test-4-1.pcap and b/src/mesh/test/dot11s/hwmp-reactive-regression-test-4-1.pcap differ diff --git a/src/mesh/test/dot11s/hwmp-reactive-regression-test-5-1.pcap b/src/mesh/test/dot11s/hwmp-reactive-regression-test-5-1.pcap index 1e515a1ab..a9a2d8af6 100644 Binary files a/src/mesh/test/dot11s/hwmp-reactive-regression-test-5-1.pcap and b/src/mesh/test/dot11s/hwmp-reactive-regression-test-5-1.pcap differ diff --git a/src/wifi/doc/source/wifi-design.rst b/src/wifi/doc/source/wifi-design.rst index 0171c2e49..e6cc85ddf 100644 --- a/src/wifi/doc/source/wifi-design.rst +++ b/src/wifi/doc/source/wifi-design.rst @@ -175,7 +175,6 @@ The following details pertain to the physical layer and channel models: * 802.11 PCF implementation currently assumes a DTIM interval equal to the beacon interval * Authentication and encryption are missing * Processing delays are not modeled -* PLCP preamble reception is not modeled * PHY_RXSTART is not supported * The current implementation assumes that secondary channels are always higher than primary channels * Cases where RTS/CTS and ACK are transmitted using HT/VHT/HE formats are not supported @@ -297,9 +296,9 @@ In the standard, there is also what is called the "minimum modulation and coding rate sensitivity" in section 18.3.10.6 CCA requirements. This is analogous to the RxSensitivity attribute in ``YansWifiPhy``. CCA busy state is not raised in this model when this threshold is exceeded -but instead RX state is immediately reached, since it is assumed that PLCP -sync always succeeds in this model. Even if the PLCP header reception fails, the -channel state is still held in RX until YansWifiPhy::EndReceive(). +but instead RX state is immediately reachedif PHY preamble detection is successful. +Even if the PHY header reception fails, the channel state is still held +in RX until YansWifiPhy::EndReceive(). In ns-3, the values of these attributes are -101 dBm for RxSensitivity and -62 dBm for CcaEdThreshold. @@ -311,10 +310,15 @@ calculated from the transmission power and adjusted based on the Tx gain of the transmitter, Rx gain of the receiver, and any path loss propagation model in effect. -The packet reception occurs in two stages. First, an event is scheduled -for when the PLCP header has been received. PLCP header is often transmitted +The packet reception occurs in three stages. First, an event is scheduled +for when PHY preamble has been detected. This decides whether the preamble +can be detected, by calling a preamble detection model. In case there is no +preamble detection model attached to the PHY, it assumes preamble is always detected. +Currently, there is only a simple threshold-based preamble detection model in ns-3, +called ``ThresholdPreambleDetectionModel``. If PHY preamble has been successfully detected, +it schedules a second event for when PHY header has been received. PHY header is often transmitted at a lower modulation rate than is the payload. The portion of the packet -corresponding to the PLCP header is evaluated for probability of error +corresponding to the PHY header is evaluated for probability of error based on the observed SNR. The InterferenceHelper object returns a value for "probability of error (PER)" for this header based on the SNR that has been tracked by the InterferenceHelper. The ``YansWifiPhy`` then draws diff --git a/src/wifi/model/interference-helper.cc b/src/wifi/model/interference-helper.cc index f9346e669..5bba2bf91 100644 --- a/src/wifi/model/interference-helper.cc +++ b/src/wifi/model/interference-helper.cc @@ -25,6 +25,7 @@ #include "interference-helper.h" #include "wifi-phy.h" #include "error-rate-model.h" +#include "wifi-utils.h" namespace ns3 { @@ -229,26 +230,36 @@ InterferenceHelper::CalculateSnr (double signal, double noiseInterference, uint1 double noiseFloor = m_noiseFigure * Nt; double noise = noiseFloor + noiseInterference; double snr = signal / noise; //linear scale - NS_LOG_DEBUG ("bandwidth(MHz)=" << channelWidth << ", signal(W)= " << signal << ", noise(W)=" << noiseFloor << ", interference(W)=" << noiseInterference << ", snr(linear)=" << snr); + NS_LOG_DEBUG ("bandwidth(MHz)=" << channelWidth << ", signal(W)= " << signal << ", noise(W)=" << noiseFloor << ", interference(W)=" << noiseInterference << ", snr=" << RatioToDb(snr) << "dB"); return snr; } double InterferenceHelper::CalculateNoiseInterferenceW (Ptr event, NiChanges *ni) const { - double noiseInterference = m_firstPower; + double noiseInterferenceW = m_firstPower; auto it = m_niChanges.find (event->GetStartTime ()); - for (; it != m_niChanges.end () && it->second.GetEvent () != event; ++it) + for (; it != m_niChanges.end (); ++it) { - noiseInterference = it->second.GetPower (); + if (it->second.GetEvent () == event) + { + continue; + } + if (it->first > Simulator::Now ()) + { + break; + } + noiseInterferenceW = it->second.GetPower () - event->GetRxPowerW (); } + it = m_niChanges.find (event->GetStartTime ()); + for (; it != m_niChanges.end () && it->second.GetEvent () != event; ++it); ni->emplace (event->GetStartTime (), NiChange (0, event)); while (++it != m_niChanges.end () && it->second.GetEvent () != event) { ni->insert (*it); } ni->emplace (event->GetEndTime (), NiChange (0, event)); - return noiseInterference; + return noiseInterferenceW; } double diff --git a/src/wifi/model/preamble-detection-model.cc b/src/wifi/model/preamble-detection-model.cc new file mode 100644 index 000000000..d956807ae --- /dev/null +++ b/src/wifi/model/preamble-detection-model.cc @@ -0,0 +1,36 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2018 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Sébastien Deronne + */ + +#include "preamble-detection-model.h" + +namespace ns3 { + +NS_OBJECT_ENSURE_REGISTERED (PreambleDetectionModel); + +TypeId PreambleDetectionModel::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::PreambleDetectionModel") + .SetParent () + .SetGroupName ("Wifi") + ; + return tid; +} + +} //namespace ns3 diff --git a/src/wifi/model/preamble-detection-model.h b/src/wifi/model/preamble-detection-model.h new file mode 100644 index 000000000..195f01023 --- /dev/null +++ b/src/wifi/model/preamble-detection-model.h @@ -0,0 +1,58 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2018 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Sébastien Deronne + */ + +#ifndef PREAMBLE_DETECTION_MODEL_H +#define PREAMBLE_DETECTION_MODEL_H + +#include "ns3/object.h" + +namespace ns3 { + +/** + * \ingroup wifi + * \brief the interface for Wifi's preamble detection models + * + */ +class PreambleDetectionModel : public Object +{ +public: + /** + * \brief Get the type ID. + * \return the object TypeId + */ + static TypeId GetTypeId (void); + + /** + * A pure virtual method that must be implemented in the subclass. + * This method returns whether the preamble detection was successful. + * + * \param snr the SNR of the received signal. + * \param channelWidth the channel width of the received signal in MHz. + * + * \return true if the preamble has been detected, + * false otherwise + */ + virtual bool IsPreambleDetected (double snr, double channelWidth) const = 0; +}; + +} //namespace ns3 + +#endif /* PREAMBLE_DETECTION_MODEL_H */ + diff --git a/src/wifi/model/spectrum-wifi-phy.cc b/src/wifi/model/spectrum-wifi-phy.cc index 7fc52a25a..5abc5897b 100644 --- a/src/wifi/model/spectrum-wifi-phy.cc +++ b/src/wifi/model/spectrum-wifi-phy.cc @@ -240,7 +240,7 @@ SpectrumWifiPhy::StartRx (Ptr rxParams) NS_LOG_INFO ("Received Wi-Fi signal"); Ptr packet = wifiRxParams->packet->Copy (); - StartReceivePreambleAndHeader (packet, rxPowerW, rxDuration); + StartReceivePreamble (packet, rxPowerW, rxDuration); } Ptr diff --git a/src/wifi/model/threshold-preamble-detection-model.cc b/src/wifi/model/threshold-preamble-detection-model.cc new file mode 100644 index 000000000..8772d404f --- /dev/null +++ b/src/wifi/model/threshold-preamble-detection-model.cc @@ -0,0 +1,65 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2018 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Sébastien Deronne + */ + +#include "ns3/log.h" +#include "ns3/double.h" +#include "threshold-preamble-detection-model.h" +#include "wifi-utils.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("ThresholdPreambleDetectionModel"); + +NS_OBJECT_ENSURE_REGISTERED (ThresholdPreambleDetectionModel); + +TypeId +ThresholdPreambleDetectionModel::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::ThresholdPreambleDetectionModel") + .SetParent () + .SetGroupName ("Wifi") + .AddConstructor () + .AddAttribute ("Threshold", + "Preamble is successfully detection if the SNR is at or above this value (expressed in dB).", + DoubleValue (2), + MakeDoubleAccessor (&ThresholdPreambleDetectionModel::m_threshold), + MakeDoubleChecker ()) + ; + return tid; +} + +ThresholdPreambleDetectionModel::ThresholdPreambleDetectionModel () +{ + NS_LOG_FUNCTION (this); +} + +ThresholdPreambleDetectionModel::~ThresholdPreambleDetectionModel () +{ + NS_LOG_FUNCTION (this); +} + +bool +ThresholdPreambleDetectionModel::IsPreambleDetected (double snr, double channelWidth) const +{ + NS_LOG_FUNCTION (this); + return (RatioToDb (snr) >= m_threshold); +} + +} //namespace ns3 diff --git a/src/wifi/model/threshold-preamble-detection-model.h b/src/wifi/model/threshold-preamble-detection-model.h new file mode 100644 index 000000000..dbc56fc96 --- /dev/null +++ b/src/wifi/model/threshold-preamble-detection-model.h @@ -0,0 +1,63 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2018 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Sébastien Deronne + */ + +#ifndef THRESHOLD_PREAMBLE_DETECTION_MODEL_H +#define THRESHOLD_PREAMBLE_DETECTION_MODEL_H + +#include "preamble-detection-model.h" + +namespace ns3 { +/** + * \ingroup wifi + * + * A threshold-based model for detecting PHY preamble. + * This model assumes that a preamble is successfully detected if SNR is at or above a given threshold. By default, this threshold is set to 2 dB. + */ +class ThresholdPreambleDetectionModel : public PreambleDetectionModel +{ +public: + /** + * \brief Get the type ID. + * \return the object TypeId + */ + static TypeId GetTypeId (void); + + ThresholdPreambleDetectionModel (); + ~ThresholdPreambleDetectionModel (); + + /** + * This method returns whether the preamble detection was successful. + * + * \param snr the SNR ratio (not dB) of the received signal. + * \param channelWidth the channel width of the received signal in MHz. + * + * \return true if the preamble has been detected, + * false otherwise + */ + bool IsPreambleDetected (double snr, double channelWidth) const; + + +private: + double m_threshold; ///< SNR threshold in dB used to decide whether a preamble is successfully received +}; + +} //namespace ns3 + +#endif /* THRESHOLD_PREAMBLE_DETECTION_MODEL_H */ diff --git a/src/wifi/model/wifi-phy.cc b/src/wifi/model/wifi-phy.cc index f37b620c3..673dae01f 100644 --- a/src/wifi/model/wifi-phy.cc +++ b/src/wifi/model/wifi-phy.cc @@ -30,6 +30,7 @@ #include "ampdu-tag.h" #include "wifi-utils.h" #include "frame-capture-model.h" +#include "preamble-detection-model.h" #include "wifi-radio-energy-model.h" #include "error-rate-model.h" #include "wifi-net-device.h" @@ -308,6 +309,11 @@ WifiPhy::GetTypeId (void) PointerValue (), MakePointerAccessor (&WifiPhy::m_frameCaptureModel), MakePointerChecker ()) + .AddAttribute ("PreambleDetectionModel", + "Ptr to an object that implements the preamble detection model", + PointerValue (), + MakePointerAccessor (&WifiPhy::m_preambleDetectionModel), + MakePointerChecker ()) .AddAttribute ("PostReceptionErrorModel", "An optional packet error model can be added to the receive " "packet process after any propagation-based (SNR-based) error " @@ -372,6 +378,7 @@ WifiPhy::WifiPhy () m_rxMpduReferenceNumber (0xffffffff), m_endRxEvent (), m_endPlcpRxEvent (), + m_endPreambleDetectionEvent (), m_standard (WIFI_PHY_STANDARD_UNSPECIFIED), m_isConstructed (false), m_channelCenterFrequency (0), @@ -401,6 +408,9 @@ void WifiPhy::DoDispose (void) { NS_LOG_FUNCTION (this); + m_endRxEvent.Cancel (); + m_endPlcpRxEvent.Cancel (); + m_endPreambleDetectionEvent.Cancel (); m_device = 0; m_mobility = 0; m_state = 0; @@ -762,6 +772,12 @@ WifiPhy::SetFrameCaptureModel (const Ptr model) m_frameCaptureModel = model; } +void +WifiPhy::SetPreambleDetectionModel (const Ptr model) +{ + m_preambleDetectionModel = model; +} + void WifiPhy::SetWifiRadioEnergyModel (const Ptr wifiRadioEnergyModel) { @@ -1506,6 +1522,7 @@ WifiPhy::DoChannelSwitch (uint8_t nch) NS_LOG_DEBUG ("drop packet because of channel switching while reception"); m_endPlcpRxEvent.Cancel (); m_endRxEvent.Cancel (); + m_endPreambleDetectionEvent.Cancel (); goto switchChannel; break; case WifiPhyState::TX: @@ -1514,6 +1531,11 @@ WifiPhy::DoChannelSwitch (uint8_t nch) break; case WifiPhyState::CCA_BUSY: case WifiPhyState::IDLE: + if (m_endPreambleDetectionEvent.IsRunning ()) + { + m_endPreambleDetectionEvent.Cancel (); + m_endRxEvent.Cancel (); + } goto switchChannel; break; case WifiPhyState::SLEEP: @@ -1558,6 +1580,7 @@ WifiPhy::DoFrequencySwitch (uint16_t frequency) NS_LOG_DEBUG ("drop packet because of channel/frequency switching while reception"); m_endPlcpRxEvent.Cancel (); m_endRxEvent.Cancel (); + m_endPreambleDetectionEvent.Cancel (); goto switchFrequency; break; case WifiPhyState::TX: @@ -1566,6 +1589,11 @@ WifiPhy::DoFrequencySwitch (uint16_t frequency) break; case WifiPhyState::CCA_BUSY: case WifiPhyState::IDLE: + if (m_endPreambleDetectionEvent.IsRunning ()) + { + m_endPreambleDetectionEvent.Cancel (); + m_endRxEvent.Cancel (); + } goto switchFrequency; break; case WifiPhyState::SLEEP: @@ -1629,22 +1657,10 @@ void WifiPhy::SetOffMode (void) { NS_LOG_FUNCTION (this); - switch (m_state->GetState ()) - { - case WifiPhyState::RX: - m_endPlcpRxEvent.Cancel (); - m_endRxEvent.Cancel (); - case WifiPhyState::TX: - case WifiPhyState::SWITCHING: - case WifiPhyState::CCA_BUSY: - case WifiPhyState::IDLE: - case WifiPhyState::SLEEP: - m_state->SwitchToOff (); - break; - default: - NS_ASSERT (false); - break; - } + m_endPlcpRxEvent.Cancel (); + m_endRxEvent.Cancel (); + m_endPreambleDetectionEvent.Cancel (); + m_state->SwitchToOff (); } void @@ -1726,6 +1742,12 @@ WifiPhy::GetHePlcpHeaderMode () return WifiPhy::GetHeMcs0 (); } +Time +WifiPhy::GetPreambleDetectionDuration (void) +{ + return MicroSeconds (4); +} + Time WifiPhy::GetPlcpTrainingSymbolDuration (WifiTxVector txVector) { @@ -2389,12 +2411,23 @@ WifiPhy::SendPacket (Ptr packet, WifiTxVector txVector, MpduType m Time txDuration = CalculateTxDuration (packet->GetSize (), txVector, GetFrequency (), mpdutype, 1); NS_ASSERT (txDuration.IsStrictlyPositive ()); - if (m_state->IsStateRx ()) + if (m_endPreambleDetectionEvent.IsRunning ()) + { + m_endPreambleDetectionEvent.Cancel (); + } + if (m_endPlcpRxEvent.IsRunning ()) { m_endPlcpRxEvent.Cancel (); + } + if (m_endRxEvent.IsRunning ()) + { m_endRxEvent.Cancel (); + } + if (m_state->IsStateRx ()) + { m_interference.NotifyRxEnd (); } + NotifyTxBegin (packet); if ((mpdutype == MPDU_IN_AGGREGATE) && (txVector.GetPreambleType () != WIFI_PREAMBLE_NONE)) { @@ -2427,7 +2460,39 @@ WifiPhy::SendPacket (Ptr packet, WifiTxVector txVector, MpduType m } void -WifiPhy::StartReceivePreambleAndHeader (Ptr packet, double rxPowerW, Time rxDuration) +WifiPhy::StartReceiveHeader (Ptr packet, WifiTxVector txVector, MpduType mpdutype, Ptr event, Time rxDuration) +{ + NS_LOG_FUNCTION (this << packet << txVector.GetMode () << txVector.GetPreambleType () << +mpdutype); + NS_ASSERT (!IsStateRx ()); + NS_ASSERT (m_endPlcpRxEvent.IsExpired ()); + + InterferenceHelper::SnrPer snrPer = m_interference.CalculatePlcpHeaderSnrPer (event); + double snr = snrPer.snr; + NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per); + + if (!m_preambleDetectionModel || (m_preambleDetectionModel->IsPreambleDetected (snr, m_channelWidth))) + { + m_state->SwitchToRx (rxDuration); + NotifyRxBegin (packet); + + Time remainingPreambleHeaderDuration = CalculatePlcpPreambleAndHeaderDuration (txVector) - GetPreambleDetectionDuration (); + m_endPlcpRxEvent = Simulator::Schedule (remainingPreambleHeaderDuration, &WifiPhy::StartReceivePacket, this, + packet, txVector, mpdutype, event); + + NS_ASSERT (m_endRxEvent.IsExpired ()); + m_endRxEvent = Simulator::Schedule (rxDuration, &WifiPhy::EndReceive, this, + packet, txVector.GetPreambleType (), mpdutype, event); + } + else + { + NS_LOG_DEBUG ("Packet reception could not be started because PHY preamble detection failed"); + m_plcpSuccess = false; + m_interference.NotifyRxEnd (); + } +} + +void +WifiPhy::StartReceivePreamble (Ptr packet, double rxPowerW, Time rxDuration) { WifiPhyTag tag; bool found = packet->RemovePacketTag (tag); @@ -2456,8 +2521,7 @@ WifiPhy::StartReceivePreambleAndHeader (Ptr packet, double rxPowerW, Tim if (tag.GetFrameComplete () == 0) { - NS_LOG_DEBUG ("drop packet because of incomplete frame"); - NotifyRxDrop (packet); + NS_LOG_DEBUG ("Packet reception stopped because transmitter has been switched off"); m_plcpSuccess = false; return; } @@ -2471,8 +2535,7 @@ WifiPhy::StartReceivePreambleAndHeader (Ptr packet, double rxPowerW, Tim Time endRx = Simulator::Now () + rxDuration; if (txVector.GetNss () > GetMaxSupportedRxSpatialStreams ()) { - NS_LOG_DEBUG ("drop packet because not enough RX antennas"); - NotifyRxDrop (packet); + NS_LOG_DEBUG ("Packet reception could not be started because not enough RX antennas"); m_plcpSuccess = false; if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ()) { @@ -2585,8 +2648,6 @@ WifiPhy::StartReceivePacket (Ptr packet, InterferenceHelper::SnrPer snrPer; snrPer = m_interference.CalculatePlcpHeaderSnrPer (event); - NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per); - if (m_random->GetValue () > snrPer.per) //plcp reception succeeded { if (IsModeSupported (txMode) || IsMcsSupported (txMode)) @@ -2603,7 +2664,7 @@ WifiPhy::StartReceivePacket (Ptr packet, } else //plcp reception failed { - NS_LOG_DEBUG ("drop packet because plcp preamble/header reception failed"); + NS_LOG_DEBUG ("drop packet because PHY header reception failed"); NotifyRxDrop (packet); m_plcpSuccess = false; } @@ -3679,6 +3740,10 @@ void WifiPhy::AbortCurrentReception () { NS_LOG_FUNCTION (this); + if (m_endPreambleDetectionEvent.IsRunning ()) + { + m_endPreambleDetectionEvent.Cancel (); + } if (m_endPlcpRxEvent.IsRunning ()) { m_endPlcpRxEvent.Cancel (); @@ -3741,22 +3806,31 @@ WifiPhy::StartRx (Ptr packet, WifiTxVector txVector, MpduType mpdutype, NS_LOG_DEBUG ("sync to signal (power=" << rxPowerW << "W)"); m_currentEvent = event; - m_state->SwitchToRx (rxDuration); - NS_ASSERT (m_endPlcpRxEvent.IsExpired ()); - NotifyRxBegin (packet); - m_interference.NotifyRxStart (); - - if (preamble != WIFI_PREAMBLE_NONE) + m_interference.NotifyRxStart (); //We need to notify it now so that it starts recording events + if (preamble == WIFI_PREAMBLE_NONE) { - NS_ASSERT (m_endPlcpRxEvent.IsExpired ()); - Time preambleAndHeaderDuration = CalculatePlcpPreambleAndHeaderDuration (txVector); - m_endPlcpRxEvent = Simulator::Schedule (preambleAndHeaderDuration, &WifiPhy::StartReceivePacket, this, - packet, txVector, mpdutype, event); - } + m_state->SwitchToRx (rxDuration); + NotifyRxBegin (packet); + m_interference.NotifyRxStart (); - NS_ASSERT (m_endRxEvent.IsExpired ()); - m_endRxEvent = Simulator::Schedule (rxDuration, &WifiPhy::EndReceive, this, - packet, preamble, mpdutype, event); + NS_ASSERT (m_endRxEvent.IsExpired ()); + m_endRxEvent = Simulator::Schedule (rxDuration, &WifiPhy::EndReceive, this, + packet, txVector.GetPreambleType (), mpdutype, event); + } + else + { + if (!m_endPreambleDetectionEvent.IsRunning ()) + { + Time startOfPreambleDuration = GetPreambleDetectionDuration (); + Time remainingRxDuration = rxDuration - startOfPreambleDuration; + m_endPreambleDetectionEvent = Simulator::Schedule (startOfPreambleDuration, &WifiPhy::StartReceiveHeader, this, + packet, txVector, mpdutype, event, remainingRxDuration); + } + else + { + NS_LOG_DEBUG ("Ignore packet because RX is already decoding preamble"); + } + } } int64_t diff --git a/src/wifi/model/wifi-phy.h b/src/wifi/model/wifi-phy.h index 3131e38fd..ffaa194db 100644 --- a/src/wifi/model/wifi-phy.h +++ b/src/wifi/model/wifi-phy.h @@ -41,6 +41,7 @@ class NetDevice; class MobilityModel; class WifiPhyStateHelper; class FrameCaptureModel; +class PreambleDetectionModel; class WifiRadioEnergyModel; class UniformRandomVariable; @@ -114,15 +115,29 @@ public: void SetCapabilitiesChangedCallback (Callback callback); /** - * Starting receiving the plcp of a packet (i.e. the first bit of the preamble has arrived). + * Starting receiving the PHY preamble of a packet (i.e. the first bit of the preamble has arrived). * * \param packet the arriving packet * \param rxPowerW the receive power in W * \param rxDuration the duration needed for the reception of the packet */ - void StartReceivePreambleAndHeader (Ptr packet, - double rxPowerW, - Time rxDuration); + void StartReceivePreamble (Ptr packet, + double rxPowerW, + Time rxDuration); + + /** + * Starting receiving the PHY header of a packet (i.e. after the end of receiving the preamble). + * + * \param packet the arriving packet + * \param txVector the TXVECTOR of the arriving packet + * \param mpdutype the type of the MPDU as defined in WifiPhy::MpduType. + * \param event the corresponding event of the first time the packet arrives + */ + void StartReceiveHeader (Ptr packet, + WifiTxVector txVector, + MpduType mpdutype, + Ptr event, + Time rxDuration); /** * Starting receiving the payload of a packet (i.e. the first bit of the packet has arrived). @@ -252,6 +267,12 @@ public: */ static Time CalculatePlcpPreambleAndHeaderDuration (WifiTxVector txVector); + /** + * + * \return the preamble detection duration, which is the time correletion needs to detect the start of an incoming frame. + */ + Time GetPreambleDetectionDuration (void); + /** * \param txVector the transmission parameters used for this packet * @@ -1446,6 +1467,12 @@ public: * \param frameCaptureModel the frame capture model */ void SetFrameCaptureModel (const Ptr frameCaptureModel); + /** + * Sets the preamble detection model. + * + * \param preambleDetectionModel the preamble detection model + */ + void SetPreambleDetectionModel (const Ptr preambleDetectionModel); /** * Sets the wifi radio energy model. * @@ -1524,8 +1551,9 @@ protected: uint32_t m_txMpduReferenceNumber; //!< A-MPDU reference number to identify all transmitted subframes belonging to the same received A-MPDU uint32_t m_rxMpduReferenceNumber; //!< A-MPDU reference number to identify all received subframes belonging to the same received A-MPDU - EventId m_endRxEvent; //!< the end reeive event - EventId m_endPlcpRxEvent; //!< the end PLCP receive event + EventId m_endRxEvent; //!< the end of receive event + EventId m_endPlcpRxEvent; //!< the end of PLCP receive event + EventId m_endPreambleDetectionEvent; //!< the end of preamble detection event private: /** @@ -1807,6 +1835,7 @@ private: Ptr m_currentEvent; //!< Hold the current event Ptr m_frameCaptureModel; //!< Frame capture model + Ptr m_preambleDetectionModel; //!< Preamble detection model Ptr m_wifiRadioEnergyModel; //!< Wifi radio energy model Ptr m_postReceptionErrorModel; //!< Error model for receive packet events diff --git a/src/wifi/model/yans-wifi-channel.cc b/src/wifi/model/yans-wifi-channel.cc index c967c22ae..016652868 100644 --- a/src/wifi/model/yans-wifi-channel.cc +++ b/src/wifi/model/yans-wifi-channel.cc @@ -132,7 +132,7 @@ YansWifiChannel::Receive (Ptr phy, Ptr packet, double rxPow NS_LOG_INFO ("Received signal too weak to process: " << rxPowerDbm << " dBm"); return; } - phy->StartReceivePreambleAndHeader (packet, DbmToW (rxPowerDbm + phy->GetRxGain ()), duration); + phy->StartReceivePreamble (packet, DbmToW (rxPowerDbm + phy->GetRxGain ()), duration); } std::size_t diff --git a/src/wifi/test/preamble-detection-test.cc b/src/wifi/test/preamble-detection-test.cc new file mode 100644 index 000000000..9210df85f --- /dev/null +++ b/src/wifi/test/preamble-detection-test.cc @@ -0,0 +1,254 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2018 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Sébastien Deronne + */ + +#include "ns3/log.h" +#include "ns3/test.h" +#include "ns3/pointer.h" +#include "ns3/spectrum-wifi-helper.h" +#include "ns3/wifi-spectrum-value-helper.h" +#include "ns3/spectrum-wifi-phy.h" +#include "ns3/nist-error-rate-model.h" +#include "ns3/wifi-mac-header.h" +#include "ns3/wifi-mac-trailer.h" +#include "ns3/wifi-phy-tag.h" +#include "ns3/wifi-spectrum-signal-parameters.h" +#include "ns3/wifi-utils.h" +#include "ns3/threshold-preamble-detection-model.h" + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("TestThresholdPreambleDetectionWithoutFrameCapture"); + +static const uint8_t CHANNEL_NUMBER = 36; +static const uint32_t FREQUENCY = 5180; // MHz +static const uint16_t CHANNEL_WIDTH = 20; // MHz +static const uint16_t GUARD_WIDTH = CHANNEL_WIDTH; // MHz (expanded to channel width to model spectrum mask) + +/** + * \ingroup wifi-test + * \ingroup tests + * + * \brief Wifi Preamble Detection Test + */ +class TestThresholdPreambleDetectionWithoutFrameCapture : public TestCase +{ +public: + TestThresholdPreambleDetectionWithoutFrameCapture (); + virtual ~TestThresholdPreambleDetectionWithoutFrameCapture (); + +protected: + virtual void DoSetup (void); + Ptr m_phy; ///< Phy + /** + * Send packet function + * \param txPowerDbm the transmit power in dBm + */ + void SendPacket (double txPowerDbm); + /** + * Spectrum wifi receive success function + * \param p the packet + * \param snr the SNR + * \param txVector the transmit vector + */ + void SpectrumWifiPhyRxSuccess (Ptr p, double snr, WifiTxVector txVector); + /** + * Spectrum wifi receive failure function + */ + void SpectrumWifiPhyRxFailure (void); + uint32_t m_countRxSuccess; ///< count RX success + uint32_t m_countRxFailure; ///< count RX failure + +private: + virtual void DoRun (void); + + /** + * Check the PHY state + * \param expectedState the expected PHY state + */ + void CheckPhyState (WifiPhyState expectedState); + /** + * Check the number of received packets + * \param expectedSuccessCount the number of successfully received packets + * \param expectedFailureCount the number of unsuccessfully received packets + */ + void CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount); +}; + +TestThresholdPreambleDetectionWithoutFrameCapture::TestThresholdPreambleDetectionWithoutFrameCapture () + : TestCase ("Threshold preamble detection model test when no frame capture model is applied"), + m_countRxSuccess (0), + m_countRxFailure (0) +{ +} + +void +TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket (double txPowerDbm) +{ + WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs11 (), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false, false); + MpduType mpdutype = NORMAL_MPDU; + + Ptr pkt = Create (1000); + WifiMacHeader hdr; + WifiMacTrailer trailer; + + hdr.SetType (WIFI_MAC_QOSDATA); + hdr.SetQosTid (0); + uint32_t size = pkt->GetSize () + hdr.GetSize () + trailer.GetSerializedSize (); + Time txDuration = m_phy->CalculateTxDuration (size, txVector, m_phy->GetFrequency (), mpdutype, 0); + hdr.SetDuration (txDuration); + + pkt->AddHeader (hdr); + pkt->AddTrailer (trailer); + WifiPhyTag tag (txVector, mpdutype, 1); + pkt->AddPacketTag (tag); + Ptr txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (FREQUENCY, CHANNEL_WIDTH, DbmToW (txPowerDbm), GUARD_WIDTH); + Ptr txParams = Create (); + txParams->psd = txPowerSpectrum; + txParams->txPhy = 0; + txParams->duration = txDuration; + txParams->packet = pkt; + + m_phy->StartRx (txParams); +} + +void +TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState (WifiPhyState expectedState) +{ + WifiPhyState currentState; + PointerValue ptr; + m_phy->GetAttribute ("State", ptr); + Ptr state = DynamicCast (ptr.Get ()); + currentState = state->GetState (); + NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ()); +} + +void +TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount (uint32_t expectedSuccessCount, uint32_t expectedFailureCount) +{ + NS_TEST_ASSERT_MSG_EQ (m_countRxSuccess, expectedSuccessCount, "Didn't receive right number of successful packets"); + NS_TEST_ASSERT_MSG_EQ (m_countRxFailure, expectedFailureCount, "Didn't receive right number of unsuccessful packets"); +} + +void +TestThresholdPreambleDetectionWithoutFrameCapture::SpectrumWifiPhyRxSuccess (Ptr p, double snr, WifiTxVector txVector) +{ + NS_LOG_FUNCTION (this << p << snr << txVector); + m_countRxSuccess++; +} + +void +TestThresholdPreambleDetectionWithoutFrameCapture::SpectrumWifiPhyRxFailure (void) +{ + NS_LOG_FUNCTION (this); + m_countRxFailure++; +} + +TestThresholdPreambleDetectionWithoutFrameCapture::~TestThresholdPreambleDetectionWithoutFrameCapture () +{ +} + +void +TestThresholdPreambleDetectionWithoutFrameCapture::DoSetup (void) +{ + m_phy = CreateObject (); + m_phy->ConfigureStandard (WIFI_PHY_STANDARD_80211ax_5GHZ); + Ptr error = CreateObject (); + m_phy->SetErrorRateModel (error); + m_phy->SetChannelNumber (CHANNEL_NUMBER); + m_phy->SetFrequency (FREQUENCY); + m_phy->SetReceiveOkCallback (MakeCallback (&TestThresholdPreambleDetectionWithoutFrameCapture::SpectrumWifiPhyRxSuccess, this)); + m_phy->SetReceiveErrorCallback (MakeCallback (&TestThresholdPreambleDetectionWithoutFrameCapture::SpectrumWifiPhyRxFailure, this)); + + Ptr preambleDetectionModel = CreateObject (); + m_phy->SetPreambleDetectionModel (preambleDetectionModel); +} + +// Test that the expected number of packet receptions occur. +void +TestThresholdPreambleDetectionWithoutFrameCapture::DoRun (void) +{ + double txPowerDbm = -30; + + //CASE 1: send one packet and check PHY state: packet reception should succeed + + Simulator::Schedule (Seconds (1.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, txPowerDbm); + // At 4us, STA PHY STATE should be IDLE + Simulator::Schedule (Seconds (1.0) + MicroSeconds (4.0), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState, this, WifiPhyState::IDLE); + // At 5us, STA PHY STATE should be RX + Simulator::Schedule (Seconds (1.0) + MicroSeconds (5.0), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState, this, WifiPhyState::RX); + // Packet should have been successfully received + Simulator::Schedule (Seconds (1.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0); + + //CASE 2: send two packets with same power within the 4us window and check PHY state: PHY preamble detection should fail + + Simulator::Schedule (Seconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, txPowerDbm); + Simulator::Schedule (Seconds (2.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, txPowerDbm); + Simulator::Schedule (Seconds (2.0) + MicroSeconds (4.0), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState, this, WifiPhyState::IDLE); + Simulator::Schedule (Seconds (2.0) + MicroSeconds (5.0), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState, this, WifiPhyState::IDLE); + // No more packet should have been successfully received, and since preamble detection did not pass the packet should not have been counted as a failure + Simulator::Schedule (Seconds (2.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 0); + + //CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY state: PHY preamble detection should succeed and packet reception should fail + + Simulator::Schedule (Seconds (3.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, txPowerDbm); + Simulator::Schedule (Seconds (3.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, txPowerDbm - 3); + Simulator::Schedule (Seconds (3.0) + MicroSeconds (4.0), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState, this, WifiPhyState::IDLE); + Simulator::Schedule (Seconds (3.0) + MicroSeconds (5.0), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState, this, WifiPhyState::RX); + // In this case, the first packet should be marked as a failure + Simulator::Schedule (Seconds (3.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 1); + + //CASE 4: send two packets with second one 3 dB higher within the 4us window and check PHY state: PHY preamble detection should fail and no packets should enter the reception stage + Simulator::Schedule (Seconds (4.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, txPowerDbm); + Simulator::Schedule (Seconds (4.0) + MicroSeconds (2.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, txPowerDbm + 3); + Simulator::Schedule (Seconds (4.0) + MicroSeconds (4.0), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState, this, WifiPhyState::IDLE); + Simulator::Schedule (Seconds (4.0) + MicroSeconds (5.0), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState, this, WifiPhyState::IDLE); + Simulator::Schedule (Seconds (4.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 1); + + //CASE 5: idem but send the second packet after the 4us window: PHY preamble detection should succeed and packet reception should fail + + Simulator::Schedule (Seconds (5.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, txPowerDbm); + Simulator::Schedule (Seconds (5.0) + MicroSeconds (6.0), &TestThresholdPreambleDetectionWithoutFrameCapture::SendPacket, this, txPowerDbm + 3); + Simulator::Schedule (Seconds (5.0) + MicroSeconds (4.0), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState, this, WifiPhyState::IDLE); + Simulator::Schedule (Seconds (5.0) + MicroSeconds (5.0), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckPhyState, this, WifiPhyState::RX); + Simulator::Schedule (Seconds (5.1), &TestThresholdPreambleDetectionWithoutFrameCapture::CheckRxPacketCount, this, 1, 2); + + Simulator::Run (); + Simulator::Destroy (); +} + +/** + * \ingroup wifi-test + * \ingroup tests + * + * \brief Preamble Detection Test Suite + */ +class PreambleDetectionTestSuite : public TestSuite +{ +public: + PreambleDetectionTestSuite (); +}; + +PreambleDetectionTestSuite::PreambleDetectionTestSuite () + : TestSuite ("wifi-preamble-detection", UNIT) +{ + AddTestCase (new TestThresholdPreambleDetectionWithoutFrameCapture, TestCase::QUICK); +} + +static PreambleDetectionTestSuite preambleDetectionTestSuite; ///< the test suite diff --git a/src/wifi/test/wifi-test.cc b/src/wifi/test/wifi-test.cc index 7b5428997..6f633bb75 100644 --- a/src/wifi/test/wifi-test.cc +++ b/src/wifi/test/wifi-test.cc @@ -1025,7 +1025,6 @@ SetChannelFrequencyTest::DoRun () } Simulator::Destroy (); - } //----------------------------------------------------------------------------- @@ -1656,6 +1655,9 @@ void StaWifiMacScanningTestCase::DoRun (void) { { + RngSeedManager::SetSeed (1); + RngSeedManager::SetRun (1); + NodeContainer nodes = Setup (false, false); Ptr nearestAp = nodes.Get (2); Mac48Address nearestApAddr = DynamicCast (nearestAp->GetDevice (0))->GetMac ()->GetAddress (); @@ -1670,6 +1672,9 @@ StaWifiMacScanningTestCase::DoRun (void) } m_associatedApBssid = Mac48Address (); { + RngSeedManager::SetSeed (1); + RngSeedManager::SetRun (1); + NodeContainer nodes = Setup (true, true); Ptr nearestAp = nodes.Get (2); Mac48Address nearestApAddr = DynamicCast (nearestAp->GetDevice (0))->GetMac ()->GetAddress (); @@ -1682,6 +1687,9 @@ StaWifiMacScanningTestCase::DoRun (void) } m_associatedApBssid = Mac48Address (); { + RngSeedManager::SetSeed (1); + RngSeedManager::SetRun (1); + NodeContainer nodes = Setup (true, false); Ptr nearestAp = nodes.Get (2); Mac48Address secondNearestApAddr = DynamicCast (nodes.Get (1)->GetDevice (0))->GetMac ()->GetAddress (); diff --git a/src/wifi/wscript b/src/wifi/wscript index d1b3e3767..4da5c7bdb 100644 --- a/src/wifi/wscript +++ b/src/wifi/wscript @@ -85,6 +85,8 @@ def build(bld): 'model/he-capabilities.cc', 'model/frame-capture-model.cc', 'model/simple-frame-capture-model.cc', + 'model/preamble-detection-model.cc', + 'model/threshold-preamble-detection-model.cc', 'model/he-operation.cc', 'model/he-configuration.cc', 'model/extended-capabilities.cc', @@ -112,6 +114,7 @@ def build(bld): 'test/wifi-error-rate-models-test.cc', 'test/wifi-transmit-mask-test.cc', 'test/wifi-phy-thresholds-test.cc', + 'test/preamble-detection-test.cc', ] headers = bld(features='ns3header') @@ -200,6 +203,8 @@ def build(bld): 'model/he-capabilities.h', 'model/frame-capture-model.h', 'model/simple-frame-capture-model.h', + 'model/preamble-detection-model.h', + 'model/threshold-preamble-detection-model.h', 'model/qos-blocked-destinations.h', 'model/he-operation.h', 'model/he-configuration.h',