diff --git a/src/spectrum/model/multi-model-spectrum-channel.cc b/src/spectrum/model/multi-model-spectrum-channel.cc index c592f3467..74c787ec3 100644 --- a/src/spectrum/model/multi-model-spectrum-channel.cc +++ b/src/spectrum/model/multi-model-spectrum-channel.cc @@ -238,6 +238,7 @@ MultiModelSpectrumChannel::StartTx(Ptr txParams) NS_LOG_LOGIC("converter map first element: " << txInfoIterator->second.m_spectrumConverterMap.begin()->first); + std::map> convertedPsds{}; for (auto rxInfoIterator = m_rxSpectrumModelInfoMap.begin(); rxInfoIterator != m_rxSpectrumModelInfoMap.end(); ++rxInfoIterator) @@ -264,6 +265,21 @@ MultiModelSpectrumChannel::StartTx(Ptr txParams) } convertedTxPowerSpectrum = rxConverterIterator->second.Convert(txParams->psd); } + convertedPsds.emplace(rxSpectrumModelUid, convertedTxPowerSpectrum); + } + + for (auto rxInfoIterator = m_rxSpectrumModelInfoMap.begin(); + rxInfoIterator != m_rxSpectrumModelInfoMap.end(); + ++rxInfoIterator) + { + const auto rxSpectrumModelUid = rxInfoIterator->second.m_rxSpectrumModel->GetUid(); + + if ((txSpectrumModelUid != rxSpectrumModelUid) && + !txInfoIterator->second.m_spectrumConverterMap.contains(rxSpectrumModelUid)) + { + // No converter means TX SpectrumModel is orthogonal to RX SpectrumModel + continue; + } for (auto rxPhyIterator = rxInfoIterator->second.m_rxPhys.begin(); rxPhyIterator != rxInfoIterator->second.m_rxPhys.end(); @@ -297,7 +313,7 @@ MultiModelSpectrumChannel::StartTx(Ptr txParams) NS_LOG_LOGIC("copying signal parameters " << txParams); auto rxParams = txParams->Copy(); - rxParams->psd = Copy(convertedTxPowerSpectrum); + rxParams->psd = Copy(convertedPsds.at(rxSpectrumModelUid)); Time delay{0}; auto receiverMobility = (*rxPhyIterator)->GetMobility(); @@ -371,7 +387,8 @@ MultiModelSpectrumChannel::StartTx(Ptr txParams) this, txParams->psd, rxParams, - *rxPhyIterator); + *rxPhyIterator, + convertedPsds); } else { @@ -382,7 +399,8 @@ MultiModelSpectrumChannel::StartTx(Ptr txParams) this, txParams->psd, rxParams, - *rxPhyIterator); + *rxPhyIterator, + convertedPsds); } } } @@ -390,9 +408,11 @@ MultiModelSpectrumChannel::StartTx(Ptr txParams) } void -MultiModelSpectrumChannel::StartRx(Ptr txPsd, - Ptr params, - Ptr receiver) +MultiModelSpectrumChannel::StartRx( + Ptr txPsd, + Ptr params, + Ptr receiver, + const std::map>& availableConvertedPsds) { NS_LOG_FUNCTION(this); @@ -404,24 +424,34 @@ MultiModelSpectrumChannel::StartRx(Ptr txPsd, if (rxSpectrumModelUid != phySpectrumModelUid) { NS_LOG_LOGIC("SpectrumModelUid changed since TX started"); - const auto txInfoIterator = FindAndEventuallyAddTxSpectrumModel(txPsd->GetSpectrumModel()); - NS_ASSERT(txInfoIterator != m_txSpectrumModelInfoMap.cend()); - const auto txSpectrumModelUid = txPsd->GetSpectrumModelUid(); - NS_LOG_LOGIC("converting txPowerSpectrum SpectrumModelUids " - << txSpectrumModelUid << " --> " << phySpectrumModelUid); - const auto rxConverterIterator = - txInfoIterator->second.m_spectrumConverterMap.find(phySpectrumModelUid); - if (rxConverterIterator == txInfoIterator->second.m_spectrumConverterMap.cend()) + const auto itConvertedPsd = availableConvertedPsds.find(phySpectrumModelUid); + if (itConvertedPsd != availableConvertedPsds.cend()) { - // No converter means TX SpectrumModel is orthogonal to current PHY SpectrumModel - params->psd = txPsd; + NS_LOG_LOGIC("converted PSD already exists for " << phySpectrumModelUid); + params->psd = itConvertedPsd->second; } else { - params->psd = rxConverterIterator->second.Convert(txPsd); + const auto txInfoIterator = + FindAndEventuallyAddTxSpectrumModel(txPsd->GetSpectrumModel()); + NS_ASSERT(txInfoIterator != m_txSpectrumModelInfoMap.cend()); + + const auto txSpectrumModelUid = txPsd->GetSpectrumModelUid(); + NS_LOG_LOGIC("converting txPowerSpectrum SpectrumModelUids " + << txSpectrumModelUid << " --> " << phySpectrumModelUid); + const auto rxConverterIterator = + txInfoIterator->second.m_spectrumConverterMap.find(phySpectrumModelUid); + if (rxConverterIterator == txInfoIterator->second.m_spectrumConverterMap.cend()) + { + // No converter means TX SpectrumModel is orthogonal to current PHY SpectrumModel + params->psd = txPsd; + } + else + { + params->psd = rxConverterIterator->second.Convert(txPsd); + } } - NS_LOG_LOGIC("converted PSD " << params->psd->GetValuesN()); } if (m_spectrumPropagationLoss) diff --git a/src/spectrum/model/multi-model-spectrum-channel.h b/src/spectrum/model/multi-model-spectrum-channel.h index 7da22afc1..725874c07 100644 --- a/src/spectrum/model/multi-model-spectrum-channel.h +++ b/src/spectrum/model/multi-model-spectrum-channel.h @@ -132,8 +132,13 @@ class MultiModelSpectrumChannel : public SpectrumChannel * @param txPsd The transmitted PSD. * @param params The signal parameters. * @param receiver A pointer to the receiver SpectrumPhy. + * @param availableConvertedPsds available converted PSDs from the TX PSD. */ - virtual void StartRx(Ptr txPsd, Ptr params, Ptr receiver); + virtual void StartRx( + Ptr txPsd, + Ptr params, + Ptr receiver, + const std::map>& availableConvertedPsds); /** * Data structure holding, for each TX SpectrumModel, all the