diff --git a/CHANGES.md b/CHANGES.md index 4e60354d8..fb20a3352 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,7 @@ Changes from ns-3.40 to ns-3-dev * (spectrum) `SpectrumSignalParameters` is extended to include two new members called: `spectrumChannelMatrix` and `precodingMatrix` which are the key information needed to support MIMO simulations. * (wifi) Added new attribute `ChannelAccessManager:GenerateBackoffIfTxopWithoutTx` to invoke the backoff procedure when an AC gains the right to start a TXOP but it does not transmit any frame, provided that the queue is not actually empty. No transmission may occur,e.g., due to constraints associated with EMLSR operations. This possibility is specified by the current draft revision of the IEEE 802.11 standard. * (core) Added `BernoulliRandomVariable` class implementing the bernoulli random variable, and `BinomialRandomVariable` class implementing the binomial random variable. +* (spectrum) `SpectrumChannel::AssignStreams()` is added, to allow random variable stream assignment for all propagation loss and delay models added to the channel. ### Changes to existing API diff --git a/src/spectrum/doc/spectrum.rst b/src/spectrum/doc/spectrum.rst index 49e4df074..a7208e41c 100644 --- a/src/spectrum/doc/spectrum.rst +++ b/src/spectrum/doc/spectrum.rst @@ -292,7 +292,11 @@ Here are some notes on how the spectrum module is expected to be used. type it can attempt to receive. If not, the signal is normally expected to be considered as interference. - +* Many propagation loss and delay models can be added to these channels. + The base class ``SpectrumChannel`` provides an ``AssignStreams()`` method + to allow the deterministic configuration of random variable stream numbers + with a single API call. See the ns-3 Manual chapter on random variables + for more information. Helpers diff --git a/src/spectrum/model/spectrum-channel.cc b/src/spectrum/model/spectrum-channel.cc index abf31412e..632a237f2 100644 --- a/src/spectrum/model/spectrum-channel.cc +++ b/src/spectrum/model/spectrum-channel.cc @@ -196,4 +196,72 @@ SpectrumChannel::GetPropagationDelayModel() const return m_propagationDelay; } +int64_t +SpectrumChannel::AssignStreams(int64_t stream) +{ + NS_LOG_FUNCTION(this << stream); + auto currentStream = stream; + auto lastCurrentStream = stream; + if (m_propagationLoss) + { + currentStream += m_propagationLoss->AssignStreams(currentStream); + } + if (currentStream - lastCurrentStream) + { + NS_LOG_DEBUG("PropagationLossModel objects used " << currentStream - lastCurrentStream + << " streams"); + } + lastCurrentStream = currentStream; + if (m_propagationDelay) + { + m_propagationDelay->AssignStreams(currentStream); + currentStream += 1; + } + if (currentStream - lastCurrentStream) + { + NS_LOG_DEBUG("PropagationDelayModel object used " << currentStream - lastCurrentStream + << " streams"); + } + lastCurrentStream = currentStream; + if (m_spectrumPropagationLoss) + { + currentStream += m_spectrumPropagationLoss->AssignStreams(currentStream); + } + if (currentStream - lastCurrentStream) + { + NS_LOG_DEBUG("SpectrumPropagationLossModel objects used " + << currentStream - lastCurrentStream << " streams"); + } + lastCurrentStream = currentStream; + if (m_phasedArraySpectrumPropagationLoss) + { + currentStream += m_phasedArraySpectrumPropagationLoss->AssignStreams(currentStream); + } + if (currentStream - lastCurrentStream) + { + NS_LOG_DEBUG("PhasedArraySpectrumPropagationLossModel objects used " + << currentStream - lastCurrentStream << " streams"); + } + lastCurrentStream = currentStream; + if (m_filter) + { + currentStream += m_filter->AssignStreams(currentStream); + } + if (currentStream - lastCurrentStream) + { + NS_LOG_DEBUG("SpectrumTransmitFilter objects used " << currentStream - lastCurrentStream + << " streams"); + } + currentStream += DoAssignStreams(currentStream); + NS_LOG_DEBUG("Assigned a total of " << currentStream - stream << " streams"); + return (currentStream - stream); +} + +int64_t +SpectrumChannel::DoAssignStreams(int64_t stream) +{ + NS_LOG_FUNCTION(this << stream); + return 0; +} + } // namespace ns3 diff --git a/src/spectrum/model/spectrum-channel.h b/src/spectrum/model/spectrum-channel.h index 60633d9c7..cb6a2b38a 100644 --- a/src/spectrum/model/spectrum-channel.h +++ b/src/spectrum/model/spectrum-channel.h @@ -149,6 +149,20 @@ class SpectrumChannel : public Channel */ virtual void StartTx(Ptr params) = 0; + /** + * This method calls AssignStreams() on any/all of the PropagationLossModel, + * PropagationDelayModel, SpectrumPropagationLossModel, + * PhasedArraySpectrumPropagationLossModel, and SpectrumTransmitFilter + * objects that have been added to this channel. If any of those + * objects are chained together (e.g., multiple PropagationDelayModel + * objects), the base class of that object is responsible for ensuring + * that all models in the chain have AssignStreams recursively called. + * + * \param stream the stream index offset start + * \return the number of stream indices assigned by this model + */ + int64_t AssignStreams(int64_t stream); + /** * \brief Remove a SpectrumPhy from a channel * @@ -215,6 +229,15 @@ class SpectrumChannel : public Channel typedef void (*SignalParametersTracedCallback)(Ptr params); protected: + /** + * This provides a base class implementation that may be subclassed + * if needed by subclasses that might need additional stream assignments. + * + * \param stream first stream index to use + * \return the number of stream indices assigned by this model + */ + virtual int64_t DoAssignStreams(int64_t stream); + /** * The `PathLoss` trace source. Exporting the pointers to the Tx and Rx * SpectrumPhy and a pathloss value, in dB.