diff --git a/src/wifi/helper/wifi-helper.cc b/src/wifi/helper/wifi-helper.cc index 67a3b0432..ef7790a1b 100644 --- a/src/wifi/helper/wifi-helper.cc +++ b/src/wifi/helper/wifi-helper.cc @@ -22,6 +22,10 @@ #include "wifi-helper.h" #include "ns3/wifi-net-device.h" #include "ns3/wifi-mac.h" +#include "ns3/regular-wifi-mac.h" +#include "ns3/dca-txop.h" +#include "ns3/edca-txop-n.h" +#include "ns3/minstrel-wifi-manager.h" #include "ns3/wifi-phy.h" #include "ns3/wifi-remote-station-manager.h" #include "ns3/wifi-channel.h" @@ -31,6 +35,7 @@ #include "ns3/mobility-model.h" #include "ns3/log.h" #include "ns3/config.h" +#include "ns3/pointer.h" #include "ns3/simulator.h" #include "ns3/names.h" @@ -163,4 +168,57 @@ WifiHelper::EnableLogComponents (void) LogComponentEnable ("YansWifiPhy", LOG_LEVEL_ALL); } +int64_t +WifiHelper::AssignStreams (NetDeviceContainer c, int64_t stream) +{ + int64_t currentStream = stream; + Ptr netDevice; + for (NetDeviceContainer::Iterator i = c.Begin (); i != c.End (); ++i) + { + netDevice = (*i); + Ptr wifi = DynamicCast (netDevice); + if (wifi) + { + // Handle any random numbers in the PHY objects. + currentStream += wifi->GetPhy ()->AssignStreams (currentStream); + + // Handle any random numbers in the station managers. + Ptr manager = wifi->GetRemoteStationManager (); + Ptr minstrel = DynamicCast (manager); + if (minstrel) + { + currentStream += minstrel->AssignStreams (currentStream); + } + + // Handle any random numbers in the MAC objects. + Ptr mac = wifi->GetMac (); + Ptr rmac = DynamicCast (mac); + if (rmac) + { + PointerValue ptr; + rmac->GetAttribute ("DcaTxop", ptr); + Ptr dcaTxop = ptr.Get (); + currentStream += dcaTxop->AssignStreams (currentStream); + + rmac->GetAttribute ("VO_EdcaTxopN", ptr); + Ptr vo_edcaTxopN = ptr.Get (); + currentStream += vo_edcaTxopN->AssignStreams (currentStream); + + rmac->GetAttribute ("VI_EdcaTxopN", ptr); + Ptr vi_edcaTxopN = ptr.Get (); + currentStream += vi_edcaTxopN->AssignStreams (currentStream); + + rmac->GetAttribute ("BE_EdcaTxopN", ptr); + Ptr be_edcaTxopN = ptr.Get (); + currentStream += be_edcaTxopN->AssignStreams (currentStream); + + rmac->GetAttribute ("BK_EdcaTxopN", ptr); + Ptr bk_edcaTxopN = ptr.Get (); + currentStream += bk_edcaTxopN->AssignStreams (currentStream); + } + } + } + return (currentStream - stream); +} + } // namespace ns3 diff --git a/src/wifi/helper/wifi-helper.h b/src/wifi/helper/wifi-helper.h index 29c7d0083..e992748c3 100644 --- a/src/wifi/helper/wifi-helper.h +++ b/src/wifi/helper/wifi-helper.h @@ -171,6 +171,19 @@ public: */ static void EnableLogComponents (void); + /** + * Assign a fixed random variable stream number to the random variables + * used by this model. Return the number of streams (possibly zero) that + * have been assigned. The Install() method should have previously been + * called by the user. + * + * \param c NetDeviceContainer of the set of net devices for which the + * WifiNetDevice should be modified to use a fixed stream + * \param stream first stream index to use + * \return the number of stream indices assigned by this helper + */ + int64_t AssignStreams (NetDeviceContainer c, int64_t stream); + private: ObjectFactory m_stationManager; enum WifiPhyStandard m_standard; diff --git a/src/wifi/helper/yans-wifi-helper.cc b/src/wifi/helper/yans-wifi-helper.cc index d59ad6835..80f007baf 100644 --- a/src/wifi/helper/yans-wifi-helper.cc +++ b/src/wifi/helper/yans-wifi-helper.cc @@ -536,4 +536,11 @@ YansWifiPhyHelper::EnableAsciiInternal ( Config::Connect (oss.str (), MakeBoundCallback (&AsciiPhyTransmitSinkWithContext, stream)); } +int64_t +YansWifiPhyHelper::AssignStreams (int64_t stream) +{ + NS_LOG_FUNCTION (this << stream); + return m_channel->AssignStreams (stream); +} + } // namespace ns3 diff --git a/src/wifi/helper/yans-wifi-helper.h b/src/wifi/helper/yans-wifi-helper.h index 05076a24b..5f045f6cc 100644 --- a/src/wifi/helper/yans-wifi-helper.h +++ b/src/wifi/helper/yans-wifi-helper.h @@ -230,6 +230,16 @@ public: */ void SetPcapDataLinkType (enum SupportedPcapDataLinkTypes dlt); + /** + * Assign a fixed random variable stream number to the random variables + * used by this model. Return the number of streams (possibly zero) that + * have been assigned. + * + * \param stream first stream index to use + * \return the number of stream indices assigned by this model + */ + int64_t AssignStreams (int64_t stream); + private: /** * \param node the node on which we wish to create a wifi PHY diff --git a/src/wifi/model/dca-txop.cc b/src/wifi/model/dca-txop.cc index 9ef37253b..57f14790d 100644 --- a/src/wifi/model/dca-txop.cc +++ b/src/wifi/model/dca-txop.cc @@ -242,6 +242,14 @@ DcaTxop::Queue (Ptr packet, const WifiMacHeader &hdr) StartAccessIfNeeded (); } +int64_t +DcaTxop::AssignStreams (int64_t stream) +{ + NS_LOG_FUNCTION (this << stream); + m_rng->AssignStreams (stream); + return 1; +} + void DcaTxop::RestartAccessIfNeeded (void) { diff --git a/src/wifi/model/dca-txop.h b/src/wifi/model/dca-txop.h index d3c9559a0..e40ee21bc 100644 --- a/src/wifi/model/dca-txop.h +++ b/src/wifi/model/dca-txop.h @@ -107,6 +107,16 @@ public: */ void Queue (Ptr packet, const WifiMacHeader &hdr); + /** + * Assign a fixed random variable stream number to the random variables + * used by this model. Return the number of streams (possibly zero) that + * have been assigned. + * + * \param stream first stream index to use + * \return the number of stream indices assigned by this model + */ + int64_t AssignStreams (int64_t stream); + private: class TransmissionListener; class NavListener; @@ -163,7 +173,6 @@ private: TransmissionListener *m_transmissionListener; RandomStream *m_rng; - bool m_accessOngoing; Ptr m_currentPacket; WifiMacHeader m_currentHdr; diff --git a/src/wifi/model/edca-txop-n.cc b/src/wifi/model/edca-txop-n.cc index 0d270b8d9..605ac2624 100644 --- a/src/wifi/model/edca-txop-n.cc +++ b/src/wifi/model/edca-txop-n.cc @@ -1104,6 +1104,15 @@ EdcaTxopN::SendDelbaFrame (Mac48Address addr, uint8_t tid, bool byOriginator) PushFront (packet, hdr); } + +int64_t +EdcaTxopN::AssignStreams (int64_t stream) +{ + NS_LOG_FUNCTION (this << stream); + m_rng->AssignStreams (stream); + return 1; +} + void EdcaTxopN::DoStart () { diff --git a/src/wifi/model/edca-txop-n.h b/src/wifi/model/edca-txop-n.h index 0cc5b2c05..c91ab3168 100644 --- a/src/wifi/model/edca-txop-n.h +++ b/src/wifi/model/edca-txop-n.h @@ -150,6 +150,16 @@ public: void SetBlockAckInactivityTimeout (uint16_t timeout); void SendDelbaFrame (Mac48Address addr, uint8_t tid, bool byOriginator); + /** + * Assign a fixed random variable stream number to the random variables + * used by this model. Return the number of streams (possibly zero) that + * have been assigned. + * + * \param stream first stream index to use + * \return the number of stream indices assigned by this model + */ + int64_t AssignStreams (int64_t stream); + private: void DoStart (); /** diff --git a/src/wifi/model/minstrel-wifi-manager.cc b/src/wifi/model/minstrel-wifi-manager.cc index 42071084d..c5b9d7748 100644 --- a/src/wifi/model/minstrel-wifi-manager.cc +++ b/src/wifi/model/minstrel-wifi-manager.cc @@ -30,7 +30,6 @@ #include "minstrel-wifi-manager.h" #include "wifi-phy.h" -#include "ns3/random-variable.h" #include "ns3/simulator.h" #include "ns3/log.h" #include "ns3/uinteger.h" @@ -121,6 +120,8 @@ MinstrelWifiManager::GetTypeId (void) MinstrelWifiManager::MinstrelWifiManager () { + m_uniformRandomVariable = CreateObject (); + m_nsupported = 0; } @@ -140,6 +141,14 @@ MinstrelWifiManager::SetupPhy (Ptr phy) WifiRemoteStationManager::SetupPhy (phy); } +int64_t +MinstrelWifiManager::AssignStreams (int64_t stream) +{ + NS_LOG_FUNCTION (this << stream); + m_uniformRandomVariable->SetStream (stream); + return 1; +} + Time MinstrelWifiManager::GetCalcTxTime (WifiMode mode) const { @@ -490,7 +499,7 @@ MinstrelWifiManager::FindRate (MinstrelWifiRemoteStation *station) uint32_t idx; /// for determining when to try a sample rate - UniformVariable coinFlip (0, 100); + int coinFlip = m_uniformRandomVariable->GetInteger (0, 100) % 2; /** * if we are below the target of look around rate percentage, look around @@ -498,7 +507,7 @@ MinstrelWifiManager::FindRate (MinstrelWifiRemoteStation *station) * all at once until it reaches the look around rate */ if ( (((100 * station->m_sampleCount) / (station->m_sampleCount + station->m_packetCount )) < m_lookAroundRate) - && ((int)coinFlip.GetValue ()) % 2 == 1 ) + && (coinFlip == 1) ) { /// now go through the table and find an index rate @@ -746,8 +755,8 @@ MinstrelWifiManager::InitSampleTable (MinstrelWifiRemoteStation *station) * The next two lines basically tries to generate a random number * between 0 and the number of available rates */ - UniformVariable uv (0, numSampleRates); - newIndex = (i + (uint32_t)uv.GetValue ()) % numSampleRates; + int uv = m_uniformRandomVariable->GetInteger (0, numSampleRates); + newIndex = (i + uv) % numSampleRates; /// this loop is used for filling in other uninitilized places while (m_sampleTable[newIndex][col] != 0) diff --git a/src/wifi/model/minstrel-wifi-manager.h b/src/wifi/model/minstrel-wifi-manager.h index 3346475da..84315e5c3 100644 --- a/src/wifi/model/minstrel-wifi-manager.h +++ b/src/wifi/model/minstrel-wifi-manager.h @@ -26,9 +26,7 @@ #include "wifi-remote-station-manager.h" #include "wifi-mode.h" #include "ns3/nstime.h" -#include - - +#include "ns3/random-variable-stream.h" namespace ns3 { @@ -96,6 +94,16 @@ public: virtual void SetupPhy (Ptr phy); + /** + * Assign a fixed random variable stream number to the random variables + * used by this model. Return the number of streams (possibly zero) that + * have been assigned. + * + * \param stream first stream index to use + * \return the number of stream indices assigned by this model + */ + int64_t AssignStreams (int64_t stream); + private: // overriden from base class virtual WifiRemoteStation * DoCreateStation (void) const; @@ -157,6 +165,9 @@ private: uint32_t m_sampleCol; ///< number of sample columns uint32_t m_pktLen; ///< packet length used for calculate mode TxTime uint32_t m_nsupported; ///< modes supported + + /// Provides uniform random variables. + Ptr m_uniformRandomVariable; }; } // namespace ns3 diff --git a/src/wifi/model/random-stream.cc b/src/wifi/model/random-stream.cc index 7f6f1828e..cc91adbfa 100644 --- a/src/wifi/model/random-stream.cc +++ b/src/wifi/model/random-stream.cc @@ -30,15 +30,22 @@ RandomStream::~RandomStream () RealRandomStream::RealRandomStream () - : m_stream (UniformVariable ()) { + m_stream = CreateObject (); } + uint32_t RealRandomStream::GetNext (uint32_t min, uint32_t max) { - return m_stream.GetInteger (min, max); + return m_stream->GetInteger (min, max); } +int64_t +RealRandomStream::AssignStreams (int64_t stream) +{ + m_stream->SetStream (stream); + return 1; +} void TestRandomStream::AddNext (uint32_t v) @@ -55,4 +62,10 @@ TestRandomStream::GetNext (uint32_t min, uint32_t max) return next; } +int64_t +TestRandomStream::AssignStreams (int64_t stream) +{ + return 0; +} + } // namespace ns3 diff --git a/src/wifi/model/random-stream.h b/src/wifi/model/random-stream.h index a9887081a..83857f9d7 100644 --- a/src/wifi/model/random-stream.h +++ b/src/wifi/model/random-stream.h @@ -22,7 +22,7 @@ #include #include -#include "ns3/random-variable.h" +#include "ns3/random-variable-stream.h" namespace ns3 { @@ -35,6 +35,16 @@ class RandomStream public: virtual ~RandomStream (); virtual uint32_t GetNext (uint32_t min, uint32_t max) = 0; + + /** + * Assign a fixed random variable stream number to the random variables + * used by this model. Return the number of streams (possibly zero) that + * have been assigned. + * + * \param stream first stream index to use + * \return the number of stream indices assigned by this model + */ + virtual int64_t AssignStreams (int64_t stream) = 0; }; class RealRandomStream : public RandomStream @@ -42,8 +52,20 @@ class RealRandomStream : public RandomStream public: RealRandomStream (); virtual uint32_t GetNext (uint32_t min, uint32_t max); + + /** + * Assign a fixed random variable stream number to the random variables + * used by this model. Return the number of streams (possibly zero) that + * have been assigned. + * + * \param stream first stream index to use + * \return the number of stream indices assigned by this model + */ + virtual int64_t AssignStreams (int64_t stream); + private: - UniformVariable m_stream; + /// Provides uniform random variables. + Ptr m_stream; }; class TestRandomStream : public RandomStream @@ -51,6 +73,17 @@ class TestRandomStream : public RandomStream public: void AddNext (uint32_t v); virtual uint32_t GetNext (uint32_t min, uint32_t max); + + /** + * Assign a fixed random variable stream number to the random variables + * used by this model. Return the number of streams (possibly zero) that + * have been assigned. + * + * \param stream first stream index to use + * \return the number of stream indices assigned by this model + */ + virtual int64_t AssignStreams (int64_t stream); + private: std::list m_nexts; }; diff --git a/src/wifi/model/wifi-phy.cc b/src/wifi/model/wifi-phy.cc index da0a541bd..0bdf2d408 100644 --- a/src/wifi/model/wifi-phy.cc +++ b/src/wifi/model/wifi-phy.cc @@ -24,7 +24,6 @@ #include "wifi-preamble.h" #include "ns3/simulator.h" #include "ns3/packet.h" -#include "ns3/random-variable.h" #include "ns3/assert.h" #include "ns3/log.h" #include "ns3/double.h" diff --git a/src/wifi/model/wifi-phy.h b/src/wifi/model/wifi-phy.h index 246e71f33..d13d12402 100644 --- a/src/wifi/model/wifi-phy.h +++ b/src/wifi/model/wifi-phy.h @@ -449,6 +449,16 @@ public: */ void NotifyMonitorSniffTx (Ptr packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble); + /** + * Assign a fixed random variable stream number to the random variables + * used by this model. Return the number of streams (possibly zero) that + * have been assigned. + * + * \param stream first stream index to use + * \return the number of stream indices assigned by this model + */ + virtual int64_t AssignStreams (int64_t stream) = 0; + private: /** diff --git a/src/wifi/model/yans-wifi-channel.cc b/src/wifi/model/yans-wifi-channel.cc index 51370a28c..f35d98ad8 100644 --- a/src/wifi/model/yans-wifi-channel.cc +++ b/src/wifi/model/yans-wifi-channel.cc @@ -138,4 +138,16 @@ YansWifiChannel::Add (Ptr phy) m_phyList.push_back (phy); } +int64_t +YansWifiChannel::AssignStreams (int64_t stream) +{ + int64_t currentStream = stream; + for (PhyList::const_iterator i = m_phyList.begin (); i != m_phyList.end (); i++) + { + Ptr yans = (*i); + currentStream += yans->AssignStreams (currentStream); + } + return (currentStream - stream); +} + } // namespace ns3 diff --git a/src/wifi/model/yans-wifi-channel.h b/src/wifi/model/yans-wifi-channel.h index 109a95a71..bb8d77d93 100644 --- a/src/wifi/model/yans-wifi-channel.h +++ b/src/wifi/model/yans-wifi-channel.h @@ -84,6 +84,16 @@ public: void Send (Ptr sender, Ptr packet, double txPowerDbm, WifiMode wifiMode, WifiPreamble preamble) const; + /** + * Assign a fixed random variable stream number to the random variables + * used by this model. Return the number of streams (possibly zero) that + * have been assigned. + * + * \param stream first stream index to use + * \return the number of stream indices assigned by this model + */ + int64_t AssignStreams (int64_t stream); + private: YansWifiChannel& operator = (const YansWifiChannel &); YansWifiChannel (const YansWifiChannel &); diff --git a/src/wifi/model/yans-wifi-phy.cc b/src/wifi/model/yans-wifi-phy.cc index b36d44431..e217c8ebc 100644 --- a/src/wifi/model/yans-wifi-phy.cc +++ b/src/wifi/model/yans-wifi-phy.cc @@ -26,7 +26,6 @@ #include "error-rate-model.h" #include "ns3/simulator.h" #include "ns3/packet.h" -#include "ns3/random-variable.h" #include "ns3/assert.h" #include "ns3/log.h" #include "ns3/double.h" @@ -128,10 +127,10 @@ YansWifiPhy::GetTypeId (void) YansWifiPhy::YansWifiPhy () : m_channelNumber (1), m_endRxEvent (), - m_random (0.0, 1.0), m_channelStartingFrequency (0) { NS_LOG_FUNCTION (this); + m_random = CreateObject (); m_state = CreateObject (); } @@ -780,7 +779,7 @@ YansWifiPhy::EndReceive (Ptr packet, Ptr even NS_LOG_DEBUG ("mode=" << (event->GetPayloadMode ().GetDataRate ()) << ", snr=" << snrPer.snr << ", per=" << snrPer.per << ", size=" << packet->GetSize ()); - if (m_random.GetValue () > snrPer.per) + if (m_random->GetValue () > snrPer.per) { NotifyRxEnd (packet); uint32_t dataRate500KbpsUnits = event->GetPayloadMode ().GetDataRate () / 500000; @@ -797,4 +796,12 @@ YansWifiPhy::EndReceive (Ptr packet, Ptr even m_state->SwitchFromRxEndError (packet, snrPer.snr); } } + +int64_t +YansWifiPhy::AssignStreams (int64_t stream) +{ + NS_LOG_FUNCTION (this << stream); + m_random->SetStream (stream); + return 1; +} } // namespace ns3 diff --git a/src/wifi/model/yans-wifi-phy.h b/src/wifi/model/yans-wifi-phy.h index 814e977c3..c7d54ab5a 100644 --- a/src/wifi/model/yans-wifi-phy.h +++ b/src/wifi/model/yans-wifi-phy.h @@ -29,7 +29,7 @@ #include "ns3/traced-callback.h" #include "ns3/nstime.h" #include "ns3/ptr.h" -#include "ns3/random-variable.h" +#include "ns3/random-variable-stream.h" #include "wifi-phy.h" #include "wifi-mode.h" #include "wifi-preamble.h" @@ -141,6 +141,16 @@ public: virtual Ptr GetChannel (void) const; virtual void ConfigureStandard (enum WifiPhyStandard standard); + /** + * Assign a fixed random variable stream number to the random variables + * used by this model. Return the number of streams (possibly zero) that + * have been assigned. + * + * \param stream first stream index to use + * \return the number of stream indices assigned by this model + */ + int64_t AssignStreams (int64_t stream); + private: YansWifiPhy (const YansWifiPhy &o); virtual void DoDispose (void); @@ -213,7 +223,8 @@ private: WifiModeList m_deviceRateSet; EventId m_endRxEvent; - UniformVariable m_random; + /// Provides uniform random variables. + Ptr m_random; /// Standard-dependent center frequency of 0-th channel, MHz double m_channelStartingFrequency; Ptr m_state;