OLD | NEW |
(Empty) | |
| 1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ |
| 2 /* |
| 3 * Copyright (c) 2009 CTTC |
| 4 * |
| 5 * This program is free software; you can redistribute it and/or modify |
| 6 * it under the terms of the GNU General Public License version 2 as |
| 7 * published by the Free Software Foundation; |
| 8 * |
| 9 * This program is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 * GNU General Public License for more details. |
| 13 * |
| 14 * You should have received a copy of the GNU General Public License |
| 15 * along with this program; if not, write to the Free Software |
| 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 17 * |
| 18 * Author: Nicola Baldo <nbaldo@cttc.es> |
| 19 */ |
| 20 |
| 21 #include <ns3/object.h> |
| 22 #include <ns3/simulator.h> |
| 23 #include <ns3/log.h> |
| 24 #include <ns3/packet.h> |
| 25 #include <ns3/net-device.h> |
| 26 #include <ns3/node.h> |
| 27 #include <ns3/mobility-model.h> |
| 28 #include <ns3/spectrum-phy.h> |
| 29 #include <ns3/spectrum-converter.h> |
| 30 #include <iostream> |
| 31 #include <utility> |
| 32 #include "multi-model-spectrum-channel.h" |
| 33 |
| 34 |
| 35 NS_LOG_COMPONENT_DEFINE ("MultiModelSpectrumChannel"); |
| 36 |
| 37 |
| 38 namespace ns3 { |
| 39 |
| 40 |
| 41 NS_OBJECT_ENSURE_REGISTERED (MultiModelSpectrumChannel); |
| 42 |
| 43 |
| 44 std::ostream& operator<< (std::ostream& lhs, TxSpectrumModelInfoMap_t& rhs) |
| 45 { |
| 46 for (TxSpectrumModelInfoMap_t::iterator it = rhs.begin (); |
| 47 it != rhs.end (); |
| 48 ++it) |
| 49 { |
| 50 SpectrumConverterMap_t::iterator jt; |
| 51 for (jt = it->second.m_spectrumConverterMap.begin (); |
| 52 jt != it->second.m_spectrumConverterMap.end (); |
| 53 ++jt) |
| 54 { |
| 55 lhs << "(" << it->first << "," << jt->first << ") "; |
| 56 } |
| 57 } |
| 58 return lhs; |
| 59 } |
| 60 |
| 61 TxSpectrumModelInfo::TxSpectrumModelInfo (Ptr<const SpectrumModel> txSpectrumMod
el) |
| 62 : m_txSpectrumModel (txSpectrumModel) |
| 63 { |
| 64 } |
| 65 |
| 66 |
| 67 RxSpectrumModelInfo::RxSpectrumModelInfo (Ptr<const SpectrumModel> rxSpectrumMod
el) |
| 68 : m_rxSpectrumModel (rxSpectrumModel) |
| 69 { |
| 70 } |
| 71 |
| 72 |
| 73 MultiModelSpectrumChannel::MultiModelSpectrumChannel () |
| 74 : m_PropagationDelay (0), |
| 75 m_PropagationLoss (0) |
| 76 { |
| 77 |
| 78 } |
| 79 |
| 80 |
| 81 TypeId |
| 82 MultiModelSpectrumChannel::GetTypeId (void) |
| 83 { |
| 84 static TypeId tid = TypeId ("ns3::MultiModelSpectrumChannel") |
| 85 .SetParent<SpectrumChannel> () |
| 86 .AddConstructor<MultiModelSpectrumChannel> () |
| 87 ; |
| 88 return tid; |
| 89 } |
| 90 |
| 91 |
| 92 |
| 93 void |
| 94 MultiModelSpectrumChannel::AddRx (Ptr<SpectrumPhy> phy) |
| 95 { |
| 96 NS_LOG_FUNCTION (this << phy); |
| 97 |
| 98 Ptr<const SpectrumModel> rxSpectrumModel = phy->GetRxSpectrumModel (); |
| 99 |
| 100 NS_ASSERT_MSG ((0 != rxSpectrumModel), "phy->GetRxSpectrumModel () returned 0.
Please check that the RxSpectrumModel is already set for the phy before calling
MultiModelSpectrumChannel::AddRx (phy)"); |
| 101 |
| 102 SpectrumModelUid_t rxSpectrumModelUid = rxSpectrumModel->GetUid (); |
| 103 ···· |
| 104 std::vector<Ptr<SpectrumPhy> >::const_iterator it; |
| 105 |
| 106 // make sure this phy had not been already added |
| 107 for ( it = m_phyVector.begin (); it != m_phyVector.end (); ++it) |
| 108 { |
| 109 NS_ASSERT (*it != phy); |
| 110 } |
| 111 m_phyVector.push_back (phy); |
| 112 ···· |
| 113 RxSpectrumModelInfoMap_t::iterator rxInfoIterator = m_rxSpectrumModelInfoMap.f
ind (rxSpectrumModelUid); |
| 114 |
| 115 if (rxInfoIterator == m_rxSpectrumModelInfoMap.end ()) |
| 116 { |
| 117 // spectrum model unknown, add it to the list of RxSpectrumModels |
| 118 std::pair<RxSpectrumModelInfoMap_t::iterator, bool> ret; |
| 119 ret = m_rxSpectrumModelInfoMap.insert (std::make_pair (rxSpectrumModelUid,
RxSpectrumModelInfo (rxSpectrumModel)));············ |
| 120 NS_ASSERT (ret.second); |
| 121 // also add the phy to the newly created list of SpectrumPhy for this RxSp
ectrumModel |
| 122 ret.first->second.m_rxPhyList.push_back (phy); |
| 123 ······ |
| 124 // and create the necessary converters for all the TX spectrum models that
we know of |
| 125 for (TxSpectrumModelInfoMap_t::iterator txInfoIterator = m_txSpectrumModel
InfoMap.begin (); |
| 126 txInfoIterator != m_txSpectrumModelInfoMap.end (); |
| 127 ++txInfoIterator) |
| 128 { |
| 129 Ptr<const SpectrumModel> txSpectrumModel = txInfoIterator->second.m_tx
SpectrumModel; |
| 130 SpectrumModelUid_t txSpectrumModelUid = txSpectrumModel->GetUid (); |
| 131 NS_LOG_LOGIC ("Creating converters between SpectrumModelUids " << txSp
ectrumModelUid << " and " << rxSpectrumModelUid ); |
| 132 SpectrumConverter converter (txSpectrumModel, rxSpectrumModel); |
| 133 std::pair<SpectrumConverterMap_t::iterator, bool> ret2; |
| 134 ret2 = txInfoIterator->second.m_spectrumConverterMap.insert (std::make
_pair (rxSpectrumModelUid, converter));····················· |
| 135 NS_ASSERT (ret2.second); |
| 136 } |
| 137 } |
| 138 else |
| 139 { |
| 140 // spectrum model is already known, just add the device to the correspondi
ng list |
| 141 rxInfoIterator->second.m_rxPhyList.push_back (phy); |
| 142 } |
| 143 ·· |
| 144 } |
| 145 |
| 146 |
| 147 TxSpectrumModelInfoMap_t::const_iterator |
| 148 MultiModelSpectrumChannel::FindAndEventuallyAddTxSpectrumModel (Ptr<const Spectr
umModel> txSpectrumModel) |
| 149 { |
| 150 NS_LOG_FUNCTION (this << txSpectrumModel); |
| 151 SpectrumModelUid_t txSpectrumModelUid = txSpectrumModel->GetUid (); |
| 152 TxSpectrumModelInfoMap_t::iterator txInfoIterator = m_txSpectrumModelInfoMap.f
ind (txSpectrumModelUid); |
| 153 ·· |
| 154 if (txInfoIterator == m_txSpectrumModelInfoMap.end ()) |
| 155 {····· |
| 156 // first time we see this TX SpectrumModel |
| 157 // we add it to the list |
| 158 std::pair<TxSpectrumModelInfoMap_t::iterator, bool> ret; |
| 159 ret = m_txSpectrumModelInfoMap.insert (std::make_pair (txSpectrumModelUid,
TxSpectrumModelInfo (txSpectrumModel))); |
| 160 NS_ASSERT (ret.second);· |
| 161 txInfoIterator = ret.first; |
| 162 ······ |
| 163 // and we create the converters for all the RX SpectrumModels that we know
of |
| 164 for (RxSpectrumModelInfoMap_t::const_iterator rxInfoIterator = m_rxSpectru
mModelInfoMap.begin (); |
| 165 rxInfoIterator != m_rxSpectrumModelInfoMap.end (); |
| 166 ++rxInfoIterator) |
| 167 { |
| 168 Ptr<const SpectrumModel> rxSpectrumModel = rxInfoIterator->second.m_rx
SpectrumModel; |
| 169 SpectrumModelUid_t rxSpectrumModelUid = rxSpectrumModel->GetUid (); |
| 170 |
| 171 if (rxSpectrumModelUid != txSpectrumModelUid) |
| 172 { |
| 173 NS_LOG_LOGIC ("Creating converters between SpectrumModelUids " <<
txSpectrumModelUid << " and " << rxSpectrumModelUid ); |
| 174 |
| 175 SpectrumConverter converter (txSpectrumModel, rxSpectrumModel); |
| 176 std::pair<SpectrumConverterMap_t::iterator, bool> ret2; |
| 177 ret2 = txInfoIterator->second.m_spectrumConverterMap.insert (std::
make_pair (rxSpectrumModelUid, converter));····················· |
| 178 NS_ASSERT (ret2.second); |
| 179 } |
| 180 }················ |
| 181 } |
| 182 else |
| 183 { |
| 184 NS_LOG_LOGIC ("SpectrumModelUid " << txSpectrumModelUid << " already prese
nt");····· |
| 185 } |
| 186 return txInfoIterator; |
| 187 } |
| 188 |
| 189 |
| 190 void |
| 191 MultiModelSpectrumChannel::StartTx (Ptr<const Packet> p, Ptr <SpectrumValue> ori
ginalTxPowerSpectrum, SpectrumType st, Time duration, Ptr<SpectrumPhy> txPhy) |
| 192 { |
| 193 NS_LOG_FUNCTION (this << p << *originalTxPowerSpectrum << duration << txPhy); |
| 194 |
| 195 NS_ASSERT (txPhy); |
| 196 NS_ASSERT (originalTxPowerSpectrum); |
| 197 ·· |
| 198 |
| 199 Ptr<MobilityModel> txMobility = txPhy->GetMobility ()->GetObject<MobilityModel
> (); |
| 200 SpectrumModelUid_t txSpectrumModelUid = originalTxPowerSpectrum->GetSpectrumMo
delUid (); |
| 201 NS_LOG_LOGIC (" txSpectrumModelUid " << txSpectrumModelUid); |
| 202 |
| 203 // |
| 204 TxSpectrumModelInfoMap_t::const_iterator txInfoIteratorerator = FindAndEventua
llyAddTxSpectrumModel (originalTxPowerSpectrum->GetSpectrumModel ()); |
| 205 NS_ASSERT (txInfoIteratorerator != m_txSpectrumModelInfoMap.end ()); |
| 206 |
| 207 NS_LOG_LOGIC ("converter map for TX SpectrumModel with Uid " << txInfoIterator
erator->first); |
| 208 NS_LOG_LOGIC ("converter map size: " << txInfoIteratorerator->second.m_spectru
mConverterMap.size ()); |
| 209 NS_LOG_LOGIC ("converter map first element: " << txInfoIteratorerator->second.
m_spectrumConverterMap.begin ()->first); |
| 210 |
| 211 for (RxSpectrumModelInfoMap_t::const_iterator rxInfoIterator = m_rxSpectrumMod
elInfoMap.begin (); |
| 212 rxInfoIterator != m_rxSpectrumModelInfoMap.end (); |
| 213 ++rxInfoIterator) |
| 214 { |
| 215 SpectrumModelUid_t rxSpectrumModelUid = rxInfoIterator->second.m_rxSpectru
mModel->GetUid (); |
| 216 NS_LOG_LOGIC (" rxSpectrumModelUids " << rxSpectrumModelUid); |
| 217 |
| 218 Ptr <SpectrumValue> convertedTxPowerSpectrum; |
| 219 |
| 220 if (txSpectrumModelUid == rxSpectrumModelUid) |
| 221 { |
| 222 NS_LOG_LOGIC ("no conversion needed"); |
| 223 convertedTxPowerSpectrum = originalTxPowerSpectrum; |
| 224 } |
| 225 else |
| 226 { |
| 227 NS_LOG_LOGIC (" converting txPowerSpectrum SpectrumModelUids" << txSpe
ctrumModelUid << " --> " << rxSpectrumModelUid); |
| 228 SpectrumConverterMap_t::const_iterator rxConverterIterator = txInfoIte
ratorerator->second.m_spectrumConverterMap.find (rxSpectrumModelUid); |
| 229 NS_ASSERT (rxConverterIterator != txInfoIteratorerator->second.m_spect
rumConverterMap.end ()); |
| 230 convertedTxPowerSpectrum = rxConverterIterator->second.Convert (origin
alTxPowerSpectrum); |
| 231 } |
| 232 |
| 233 std::list<Ptr<SpectrumPhy> >::const_iterator rxPhyIterator = rxInfoIterato
r->second.m_rxPhyList.begin (); |
| 234 while (rxPhyIterator != rxInfoIterator->second.m_rxPhyList.end ()) |
| 235 { |
| 236 NS_ASSERT_MSG ((*rxPhyIterator)->GetRxSpectrumModel ()->GetUid () == r
xSpectrumModelUid, |
| 237 "MultiModelSpectrumChannel only supports devices that u
se a single RxSpectrumModel that does not change for the whole simulation"); |
| 238 ·········· |
| 239 if ((*rxPhyIterator) != txPhy) |
| 240 { |
| 241 Ptr <SpectrumValue> rxPowerSpectrum; |
| 242 Time delay; |
| 243 Ptr<MobilityModel> receiverMobility = (*rxPhyIterator)->GetMobilit
y ()->GetObject<MobilityModel> (); |
| 244 |
| 245 if (txMobility && receiverMobility) |
| 246 { |
| 247 if (m_PropagationLoss) |
| 248 { |
| 249 rxPowerSpectrum = m_PropagationLoss->CalcRxPowerSpectralDe
nsity (convertedTxPowerSpectrum, txMobility, receiverMobility); |
| 250 } |
| 251 else |
| 252 { |
| 253 // rxPowerSpectrum = Copy<SpectrumValue> (convertedTxPower
Spectrum); |
| 254 rxPowerSpectrum = convertedTxPowerSpectrum->Copy (); |
| 255 } |
| 256 |
| 257 if (m_PropagationDelay) |
| 258 { |
| 259 delay = m_PropagationDelay->GetDelay (txMobility, receiver
Mobility); |
| 260 } |
| 261 else |
| 262 { |
| 263 delay = MicroSeconds (0); |
| 264 } |
| 265 } |
| 266 else |
| 267 { |
| 268 // rxPowerSpectrum = Copy<SpectrumValue> (convertedTxPowerSpec
trum); |
| 269 rxPowerSpectrum = convertedTxPowerSpectrum->Copy (); |
| 270 delay = MicroSeconds (0); |
| 271 } |
| 272 |
| 273 Ptr<Packet> pktCopy = p->Copy (); |
| 274 Ptr<Object> netDevObj = (*rxPhyIterator)->GetDevice (); |
| 275 if (netDevObj) |
| 276 { |
| 277 // the receiver has a NetDevice, so we expect that it is attac
hed to a Node |
| 278 uint32_t dstNode = netDevObj->GetObject<NetDevice> ()->GetNod
e ()->GetId (); |
| 279 Simulator::ScheduleWithContext (dstNode, delay, &MultiModelSpe
ctrumChannel::StartRx, this, |
| 280 pktCopy, rxPowerSpectrum, st,
duration, *rxPhyIterator); |
| 281 } |
| 282 else |
| 283 { |
| 284 // the receiver is not attached to a NetDevice, so we cannot a
ssume that it is attached to a node |
| 285 Simulator::Schedule (delay, &MultiModelSpectrumChannel::StartR
x, this, |
| 286 pktCopy, rxPowerSpectrum, st, duration, *
rxPhyIterator); |
| 287 } |
| 288 }········· |
| 289 ++rxPhyIterator; |
| 290 } |
| 291 |
| 292 } |
| 293 |
| 294 } |
| 295 |
| 296 void |
| 297 MultiModelSpectrumChannel::StartRx (Ptr<Packet> p, Ptr <SpectrumValue> rxPsd, Sp
ectrumType st, Time duration, Ptr<SpectrumPhy> receiver) |
| 298 { |
| 299 NS_LOG_FUNCTION (this); |
| 300 receiver->StartRx (p, rxPsd, st, duration); |
| 301 } |
| 302 |
| 303 |
| 304 |
| 305 uint32_t |
| 306 MultiModelSpectrumChannel::GetNDevices (void) const |
| 307 { |
| 308 return m_phyVector.size (); |
| 309 |
| 310 } |
| 311 |
| 312 |
| 313 Ptr<NetDevice> |
| 314 MultiModelSpectrumChannel::GetDevice (uint32_t i) const |
| 315 { |
| 316 return m_phyVector.at (i)->GetDevice ()->GetObject<NetDevice> (); |
| 317 } |
| 318 |
| 319 |
| 320 |
| 321 void |
| 322 MultiModelSpectrumChannel::AddSpectrumPropagationLossModel (Ptr<SpectrumPropagat
ionLossModel> loss) |
| 323 { |
| 324 NS_ASSERT (m_PropagationLoss == 0); |
| 325 m_PropagationLoss = loss; |
| 326 } |
| 327 |
| 328 void |
| 329 MultiModelSpectrumChannel::SetPropagationDelayModel (Ptr<PropagationDelayModel>
delay) |
| 330 { |
| 331 NS_ASSERT (m_PropagationDelay == 0); |
| 332 m_PropagationDelay = delay; |
| 333 } |
| 334 |
| 335 |
| 336 } // namespace ns3 |
OLD | NEW |