A Discrete-Event Network Simulator
API
lr-wpan-phy.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 The Boeing Company
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author:
18  * Gary Pei <guangyu.pei@boeing.com>
19  * Sascha Alexander Jopen <jopen@cs.uni-bonn.de>
20  */
21 #include "lr-wpan-phy.h"
22 
23 #include "lr-wpan-constants.h"
24 #include "lr-wpan-error-model.h"
25 #include "lr-wpan-lqi-tag.h"
26 #include "lr-wpan-net-device.h"
29 
30 #include <ns3/abort.h>
31 #include <ns3/antenna-model.h>
32 #include <ns3/double.h>
33 #include <ns3/error-model.h>
34 #include <ns3/log.h>
35 #include <ns3/mobility-model.h>
36 #include <ns3/net-device.h>
37 #include <ns3/node.h>
38 #include <ns3/packet-burst.h>
39 #include <ns3/packet.h>
40 #include <ns3/pointer.h>
41 #include <ns3/random-variable-stream.h>
42 #include <ns3/simulator.h>
43 #include <ns3/spectrum-channel.h>
44 #include <ns3/spectrum-value.h>
45 
46 namespace ns3
47 {
48 
49 NS_LOG_COMPONENT_DEFINE("LrWpanPhy");
50 
52 
60  {20.0, 20.0},
61  {40.0, 40.0},
62  {20.0, 20.0},
63  {250.0, 12.5},
64  {250.0, 50.0},
65  {250.0, 62.5},
66  {100.0, 25.0},
67  {250.0, 62.5},
68  {250.0, 62.5},
69 };
70 
79  {32.0, 8.0, 8.0},
80  {32.0, 8.0, 8.0},
81  {32.0, 8.0, 8.0},
82  {2.0, 1.0, 0.4},
83  {6.0, 1.0, 1.6},
84  {8.0, 2.0, 2.0},
85  {8.0, 2.0, 2.0},
86  {8.0, 2.0, 2.0},
87  {8.0, 2.0, 2.0},
88 };
89 
90 std::ostream&
91 operator<<(std::ostream& os, const LrWpanPhyEnumeration& state)
92 {
93  switch (state)
94  {
96  os << "BUSY";
97  break;
99  os << "BUSY_RX";
100  break;
102  os << "BUSY_TX";
103  break;
105  os << "FORCE_TRX_OFF";
106  break;
108  os << "IDLE";
109  break;
111  os << "INVALID_PARAMETER";
112  break;
114  os << "RX_ON";
115  break;
117  os << "SUCCESS";
118  break;
120  os << "TRX_OFF";
121  break;
123  os << "TX_ON";
124  break;
126  os << "UNSUPPORTED";
127  break;
129  os << "READ_ONLY";
130  break;
132  os << "UNSPECIFIED";
133  break;
134  }
135  return os;
136 };
137 
138 std::ostream&
139 operator<<(std::ostream& os, const TracedValue<LrWpanPhyEnumeration>& state)
140 {
141  LrWpanPhyEnumeration s = state;
142  return os << s;
143 };
144 
145 TypeId
147 {
148  static TypeId tid =
149  TypeId("ns3::LrWpanPhy")
151  .SetGroupName("LrWpan")
152  .AddConstructor<LrWpanPhy>()
153  .AddAttribute("PostReceptionErrorModel",
154  "An optional packet error model can be added to the receive "
155  "packet process after any propagation-based (SNR-based) error "
156  "models have been applied. Typically this is used to force "
157  "specific packet drops, for testing purposes.",
158  PointerValue(),
160  MakePointerChecker<ErrorModel>())
161  .AddTraceSource("TrxStateValue",
162  "The state of the transceiver",
164  "ns3::TracedValueCallback::LrWpanPhyEnumeration")
165  .AddTraceSource("TrxState",
166  "The state of the transceiver",
168  "ns3::LrWpanPhy::StateTracedCallback")
169  .AddTraceSource("PhyTxBegin",
170  "Trace source indicating a packet has "
171  "begun transmitting over the channel medium",
173  "ns3::Packet::TracedCallback")
174  .AddTraceSource("PhyTxEnd",
175  "Trace source indicating a packet has been "
176  "completely transmitted over the channel.",
178  "ns3::Packet::TracedCallback")
179  .AddTraceSource("PhyTxDrop",
180  "Trace source indicating a packet has been "
181  "dropped by the device during transmission",
183  "ns3::Packet::TracedCallback")
184  .AddTraceSource("PhyRxBegin",
185  "Trace source indicating a packet has begun "
186  "being received from the channel medium by the device",
188  "ns3::Packet::TracedCallback")
189  .AddTraceSource("PhyRxEnd",
190  "Trace source indicating a packet has been "
191  "completely received from the channel medium "
192  "by the device",
194  "ns3::Packet::SinrTracedCallback")
195  .AddTraceSource("PhyRxDrop",
196  "Trace source indicating a packet has been "
197  "dropped by the device during reception",
199  "ns3::Packet::TracedCallback");
200  return tid;
201 }
202 
204  : m_edRequest(),
205  m_setTRXState()
206 {
209 
210  // default PHY PIB attributes
213 
215 
216  m_random = CreateObject<UniformRandomVariable>();
217  m_random->SetAttribute("Min", DoubleValue(0.0));
218  m_random->SetAttribute("Max", DoubleValue(1.0));
219 
220  m_isRxCanceled = false;
222 }
223 
225 {
226 }
227 
228 void
230 {
231  NS_LOG_FUNCTION(this);
232 
233  // This method ensures that the local mobility model pointer holds
234  // a pointer to the Node's aggregated mobility model (if one exists)
235  // in the case that the user has not directly called SetMobility()
236  // on this LrWpanPhy during simulation setup. If the mobility model
237  // needs to be added or changed during simulation runtime, users must
238  // call SetMobility() on this object.
239 
240  if (!m_mobility)
241  {
242  NS_ABORT_MSG_UNLESS(m_device && m_device->GetNode(),
243  "Either install a MobilityModel on this object or ensure that this "
244  "object is part of a Node and NetDevice");
245  m_mobility = m_device->GetNode()->GetObject<MobilityModel>();
246  if (!m_mobility)
247  {
248  NS_LOG_WARN("Mobility not found, propagation models might not work properly");
249  }
250  }
251 }
252 
253 void
255 {
256  NS_LOG_FUNCTION(this);
257 
258  // Cancel pending transceiver state change, if one is in progress.
262 
263  m_mobility = nullptr;
264  m_device = nullptr;
265  m_channel = nullptr;
266  m_antenna = nullptr;
267  m_txPsd = nullptr;
268  m_noise = nullptr;
269  m_signal = nullptr;
270  m_errorModel = nullptr;
271  m_currentRxPacket.first = nullptr;
272  m_currentTxPacket.first = nullptr;
273  m_postReceptionErrorModel = nullptr;
274 
279 
280  m_random = nullptr;
281  m_pdDataIndicationCallback = MakeNullCallback<void, uint32_t, Ptr<Packet>, uint8_t>();
282  m_pdDataConfirmCallback = MakeNullCallback<void, LrWpanPhyEnumeration>();
283  m_plmeCcaConfirmCallback = MakeNullCallback<void, LrWpanPhyEnumeration>();
284  m_plmeEdConfirmCallback = MakeNullCallback<void, LrWpanPhyEnumeration, uint8_t>();
289  m_plmeSetTRXStateConfirmCallback = MakeNullCallback<void, LrWpanPhyEnumeration>();
291  MakeNullCallback<void, LrWpanPhyEnumeration, LrWpanPibAttributeIdentifier>();
292 
294 }
295 
298 {
299  return m_device;
300 }
301 
304 {
305  return m_mobility;
306 }
307 
308 void
310 {
311  NS_LOG_FUNCTION(this << d);
312  m_device = d;
313 }
314 
315 void
317 {
318  NS_LOG_FUNCTION(this << m);
319  m_mobility = m;
320 }
321 
322 void
324 {
325  NS_LOG_FUNCTION(this << c);
326  m_channel = c;
327 }
328 
331 {
332  NS_LOG_FUNCTION(this);
333  return m_channel;
334 }
335 
338 {
339  NS_LOG_FUNCTION(this);
340  if (m_txPsd)
341  {
342  return m_txPsd->GetSpectrumModel();
343  }
344  else
345  {
346  return nullptr;
347  }
348 }
349 
352 {
353  return m_antenna;
354 }
355 
356 void
358 {
359  NS_LOG_FUNCTION(this << a);
360  m_antenna = a;
361 }
362 
363 void
365 {
366  NS_LOG_FUNCTION(this << spectrumRxParams);
367 
368  if (!m_edRequest.IsExpired())
369  {
370  // Update the average receive power during ED.
371  Time now = Simulator::Now();
375  (now - m_edPower.lastUpdate).GetTimeStep() / m_edPower.measurementLength.GetTimeStep();
376  m_edPower.lastUpdate = now;
377  }
378 
379  Ptr<LrWpanSpectrumSignalParameters> lrWpanRxParams =
380  DynamicCast<LrWpanSpectrumSignalParameters>(spectrumRxParams);
381 
382  if (!lrWpanRxParams)
383  {
385  m_signal->AddSignal(spectrumRxParams->psd);
386 
387  // Update peak power if CCA is in progress.
388  if (!m_ccaRequest.IsExpired())
389  {
390  double power =
393  if (m_ccaPeakPower < power)
394  {
395  m_ccaPeakPower = power;
396  }
397  }
398 
399  Simulator::Schedule(spectrumRxParams->duration, &LrWpanPhy::EndRx, this, spectrumRxParams);
400  return;
401  }
402 
403  Ptr<Packet> p = (lrWpanRxParams->packetBurst->GetPackets()).front();
404  NS_ASSERT(p);
405 
406  // Prevent PHY from receiving another packet while switching the transceiver state.
408  {
409  // The specification doesn't seem to refer to BUSY_RX, but vendor
410  // data sheets suggest that this is a substate of the RX_ON state
411  // that is entered after preamble detection when the digital receiver
412  // is enabled. Here, for now, we use BUSY_RX to mark the period between
413  // StartRx() and EndRx() states.
414 
415  // We are going to BUSY_RX state when receiving the first bit of an SHR,
416  // as opposed to real receivers, which should go to this state only after
417  // successfully receiving the SHR.
418 
419  // If synchronizing to the packet is possible, change to BUSY_RX state,
420  // otherwise drop the packet and stay in RX state. The actual synchronization
421  // is not modeled.
422 
423  // Add any incoming packet to the current interference before checking the
424  // SINR.
425  NS_LOG_DEBUG(this << " receiving packet with power: "
427  lrWpanRxParams->psd,
429  30
430  << "dBm");
431  m_signal->AddSignal(lrWpanRxParams->psd);
432  Ptr<SpectrumValue> interferenceAndNoise = m_signal->GetSignalPsd();
433  *interferenceAndNoise -= *lrWpanRxParams->psd;
434  *interferenceAndNoise += *m_noise;
435  double sinr =
436  LrWpanSpectrumValueHelper::TotalAvgPower(lrWpanRxParams->psd,
438  LrWpanSpectrumValueHelper::TotalAvgPower(interferenceAndNoise,
440 
441  // Std. 802.15.4-2006, appendix E, Figure E.2
442  // At SNR < -5 the BER is less than 10e-1.
443  // It's useless to even *try* to decode the packet.
444  if (10 * log10(sinr) > -5)
445  {
447  m_currentRxPacket = std::make_pair(lrWpanRxParams, false);
449 
451  }
452  else
453  {
454  m_phyRxDropTrace(p);
455  }
456  }
458  {
459  // Drop the new packet.
460  NS_LOG_DEBUG(this << " packet collision");
461  m_phyRxDropTrace(p);
462 
463  // Check if we correctly received the old packet up to now.
465 
466  // Add the incoming packet to the current interference after we have
467  // checked for successful reception of the current packet for the time
468  // before the additional interference.
469  m_signal->AddSignal(lrWpanRxParams->psd);
470  }
471  else
472  {
473  // Simply drop the packet.
474  NS_LOG_DEBUG(this << " transceiver not in RX state");
475  m_phyRxDropTrace(p);
476 
477  // Add the signal power to the interference, anyway.
478  m_signal->AddSignal(lrWpanRxParams->psd);
479  }
480 
481  // Update peak power if CCA is in progress.
482  if (!m_ccaRequest.IsExpired())
483  {
484  double power =
487  if (m_ccaPeakPower < power)
488  {
489  m_ccaPeakPower = power;
490  }
491  }
492 
493  // Always call EndRx to update the interference.
494  // We keep track of this event, and if necessary cancel this event when a TX of a packet.
495 
496  Simulator::Schedule(spectrumRxParams->duration, &LrWpanPhy::EndRx, this, spectrumRxParams);
497 }
498 
499 void
501 {
502  // Calculate whether packet was lost.
503  LrWpanSpectrumValueHelper psdHelper;
505 
506  // We are currently receiving a packet.
508  {
509  // NS_ASSERT (currentRxParams && !m_currentRxPacket.second);
510 
511  Ptr<Packet> currentPacket = currentRxParams->packetBurst->GetPackets().front();
512  if (m_errorModel)
513  {
514  // How many bits did we receive since the last calculation?
515  double t = (Simulator::Now() - m_rxLastUpdate).ToDouble(Time::MS);
516  uint32_t chunkSize = ceil(t * (GetDataOrSymbolRate(true) / 1000));
517  Ptr<SpectrumValue> interferenceAndNoise = m_signal->GetSignalPsd();
518  *interferenceAndNoise -= *currentRxParams->psd;
519  *interferenceAndNoise += *m_noise;
520  double sinr =
521  LrWpanSpectrumValueHelper::TotalAvgPower(currentRxParams->psd,
523  LrWpanSpectrumValueHelper::TotalAvgPower(interferenceAndNoise,
525  double per = 1.0 - m_errorModel->GetChunkSuccessRate(sinr, chunkSize);
526 
527  // The LQI is the total packet success rate scaled to 0-255.
528  // If not already set, initialize to 255.
530  currentPacket->PeekPacketTag(tag);
531  uint8_t lqi = tag.Get();
532  tag.Set(lqi - (per * lqi));
533  currentPacket->ReplacePacketTag(tag);
534 
535  if (m_random->GetValue() < per)
536  {
537  // The packet was destroyed, drop the packet after reception.
538  m_currentRxPacket.second = true;
539  }
540  }
541  else
542  {
543  NS_LOG_WARN("Missing ErrorModel");
544  }
545  }
547 }
548 
549 void
551 {
552  NS_LOG_FUNCTION(this);
553 
554  Ptr<LrWpanSpectrumSignalParameters> params = DynamicCast<LrWpanSpectrumSignalParameters>(par);
555 
556  if (!m_edRequest.IsExpired())
557  {
558  // Update the average receive power during ED.
559  Time now = Simulator::Now();
563  (now - m_edPower.lastUpdate).GetTimeStep() / m_edPower.measurementLength.GetTimeStep();
564  m_edPower.lastUpdate = now;
565  }
566 
568  if (currentRxParams == params)
569  {
571  }
572 
573  // Update the interference.
574  m_signal->RemoveSignal(par->psd);
575 
576  if (!params)
577  {
578  NS_LOG_LOGIC("Node: " << m_device->GetAddress()
579  << " Removing interferent: " << *(par->psd));
580  return;
581  }
582 
583  // If this is the end of the currently received packet, check if reception was successful.
584  if (currentRxParams == params)
585  {
586  Ptr<Packet> currentPacket = currentRxParams->packetBurst->GetPackets().front();
587  NS_ASSERT(currentPacket);
588 
590  m_postReceptionErrorModel->IsCorrupt(currentPacket->Copy()))
591  {
592  NS_LOG_DEBUG("Reception failed due to post-rx error model");
593  m_currentRxPacket.second = true;
594  }
595 
596  // If there is no error model attached to the PHY, we always report the maximum LQI value.
598  currentPacket->PeekPacketTag(tag);
599  m_phyRxEndTrace(currentPacket, tag.Get());
600 
601  if (!m_currentRxPacket.second)
602  {
603  m_currentRxPacket = std::make_pair(nullptr, true);
605  NS_LOG_DEBUG("Packet successfully received");
606 
607  // The packet was successfully received, push it up the stack.
609  {
610  m_pdDataIndicationCallback(currentPacket->GetSize(), currentPacket, tag.Get());
611  }
612  }
613  else
614  {
615  // The packet was destroyed due to interference, post-rx corruption or
616  // cancelled, therefore drop it.
617  m_phyRxDropTrace(currentPacket);
618  m_currentRxPacket = std::make_pair(nullptr, true);
619 
620  if (!m_isRxCanceled)
621  {
623  }
624  else
625  {
626  // The state of The PHY was already changed when the packet was canceled
627  // due to a forced operation.
628  m_isRxCanceled = false;
629  }
630  }
631  }
632 }
633 
634 void
635 LrWpanPhy::PdDataRequest(const uint32_t psduLength, Ptr<Packet> p)
636 {
637  NS_LOG_FUNCTION(this << psduLength << p);
638 
639  if (psduLength > lrwpan::aMaxPhyPacketSize)
640  {
642  {
644  }
645  NS_LOG_DEBUG("Drop packet because psduLength too long: " << psduLength);
646  return;
647  }
648 
649  // Prevent PHY from sending a packet while switching the transceiver state.
650  if (!m_setTRXState.IsRunning())
651  {
653  {
654  // send down
656 
657  // Remove a possible LQI tag from a previous transmission of the packet.
658  LrWpanLqiTag lqiTag;
659  p->RemovePacketTag(lqiTag);
660 
662  m_currentTxPacket.first = p;
663  m_currentTxPacket.second = false;
664 
665  Ptr<LrWpanSpectrumSignalParameters> txParams = Create<LrWpanSpectrumSignalParameters>();
666  txParams->duration = CalculateTxTime(p);
667  txParams->txPhy = GetObject<SpectrumPhy>();
668  txParams->psd = m_txPsd;
669  txParams->txAntenna = m_antenna;
670  Ptr<PacketBurst> pb = CreateObject<PacketBurst>();
671  pb->AddPacket(p);
672  txParams->packetBurst = pb;
673  m_channel->StartTx(txParams);
674  m_pdDataRequest = Simulator::Schedule(txParams->duration, &LrWpanPhy::EndTx, this);
676  return;
677  }
678  else if ((m_trxState == IEEE_802_15_4_PHY_RX_ON) ||
681  {
683  {
685  }
686  // Drop packet, hit PhyTxDrop trace
687  m_phyTxDropTrace(p);
688  return;
689  }
690  else
691  {
692  NS_FATAL_ERROR("This should be unreachable, or else state "
693  << m_trxState << " should be added as a case");
694  }
695  }
696  else
697  {
698  // TODO: This error code is not covered by the standard.
699  // What is the correct behavior in this case?
701  {
703  }
704  // Drop packet, hit PhyTxDrop trace
705  m_phyTxDropTrace(p);
706  return;
707  }
708 }
709 
710 void
712 {
713  NS_LOG_FUNCTION(this);
714 
716  {
717  m_ccaPeakPower = 0.0;
718  Time ccaTime = Seconds(8.0 / GetDataOrSymbolRate(false));
720  }
721  else
722  {
724  {
726  {
728  }
729  else
730  {
732  }
733  }
734  }
735 }
736 
737 void
739 {
740  NS_LOG_FUNCTION(this);
742 }
743 
744 void
746 {
747  NS_LOG_FUNCTION(this);
749  {
750  // Average over the powers of all signals received until EndEd()
755  }
756  else
757  {
760  {
761  result = IEEE_802_15_4_PHY_TX_ON;
762  }
763 
765  {
766  m_plmeEdConfirmCallback(result, 0);
767  }
768  }
769 }
770 
771 void
773 {
774  NS_LOG_FUNCTION(this << id);
776  Ptr<LrWpanPhyPibAttributes> attributes = Create<LrWpanPhyPibAttributes>();
777 
778  switch (id)
779  {
780  case phyCurrentChannel:
781  attributes->phyCurrentChannel = m_phyPIBAttributes.phyCurrentChannel;
782  break;
783  case phyCurrentPage:
784  attributes->phyCurrentPage = m_phyPIBAttributes.phyCurrentPage;
785  break;
786  case phySHRDuration:
787  attributes->phySHRDuration = GetPhySHRDuration();
788  break;
789  case phySymbolsPerOctet:
790  attributes->phySymbolsPerOctet = GetPhySymbolsPerOctet();
791  break;
792  default:
794  break;
795  }
796 
798  {
799  m_plmeGetAttributeConfirmCallback(status, id, attributes);
800  }
801 }
802 
803 // Section 6.2.2.7.3
804 void
806 {
807  NS_LOG_FUNCTION(this << state);
808 
809  // Check valid states (Table 14)
812 
813  NS_LOG_LOGIC("Trying to set m_trxState from " << m_trxState << " to " << state);
814 
815  // this method always overrides previous state setting attempts
816  if (!m_setTRXState.IsExpired())
817  {
818  if (m_trxStatePending == state)
819  {
820  // Simply wait for the ongoing state switch.
821  return;
822  }
823  else
824  {
825  NS_LOG_DEBUG("Cancel m_setTRXState");
826  // Keep the transceiver state as the old state before the switching attempt.
828  }
829  }
831  {
833  }
834 
835  if (state == m_trxState)
836  {
838  {
840  }
841  return;
842  }
843 
844  if (((state == IEEE_802_15_4_PHY_RX_ON) || (state == IEEE_802_15_4_PHY_TRX_OFF)) &&
846  {
847  NS_LOG_DEBUG("Phy is busy; setting state pending to " << state);
848  m_trxStatePending = state;
849  return; // Send PlmeSetTRXStateConfirm later
850  }
851 
852  // specification talks about being in RX_ON and having received
853  // a valid SFD. Here, we are not modelling at that level of
854  // granularity, so we just test for BUSY_RX state (any part of
855  // a packet being actively received)
856  if (state == IEEE_802_15_4_PHY_TRX_OFF)
857  {
858  CancelEd(state);
859 
861  (!m_currentRxPacket.second))
862  {
863  NS_LOG_DEBUG("Receiver has valid SFD; defer state change");
864  m_trxStatePending = state;
865  return; // Send PlmeSetTRXStateConfirm later
866  }
868  {
871  {
873  }
874  return;
875  }
876  }
877 
878  if (state == IEEE_802_15_4_PHY_TX_ON)
879  {
880  CancelEd(state);
881 
882  NS_LOG_DEBUG("turn on PHY_TX_ON");
884  {
885  if (m_currentRxPacket.first)
886  {
887  // TX_ON is being forced during a reception (For example, when a ACK or Beacon is
888  // issued) The current RX frame is marked as incomplete and the reception as
889  // canceled EndRx () will handle the rest accordingly
890  NS_LOG_DEBUG("force TX_ON, terminate reception");
891  m_currentRxPacket.second = true;
892  m_isRxCanceled = true;
893  }
894 
895  // If CCA is in progress, cancel CCA and return BUSY.
896  if (!m_ccaRequest.IsExpired())
897  {
900  {
902  }
903  }
904 
906 
907  // Delay for turnaround time (BUSY_RX|RX_ON ---> TX_ON)
908  Time setTime = Seconds((double)lrwpan::aTurnaroundTime / GetDataOrSymbolRate(false));
910  return;
911  }
913  {
914  // We do NOT change the transceiver state here. We only report that
915  // the transceiver is already in TX_ON state.
917  {
919  }
920  return;
921  }
923  {
926  {
928  }
929  return;
930  }
931  }
932 
933  if (state == IEEE_802_15_4_PHY_FORCE_TRX_OFF)
934  {
936  {
937  NS_LOG_DEBUG("force TRX_OFF, was already off");
938  }
939  else
940  {
941  NS_LOG_DEBUG("force TRX_OFF, SUCCESS");
942  if (m_currentRxPacket.first)
943  {
944  // Terminate reception
945  // Mark the packet as incomplete and reception as canceled.
946  NS_LOG_DEBUG("force TRX_OFF, terminate reception");
947  m_currentRxPacket.second = true;
948  m_isRxCanceled = true;
949  }
951  {
952  NS_LOG_DEBUG("force TRX_OFF, terminate transmission");
953  m_currentTxPacket.second = true;
954  }
956  // Clear any other state
958  }
960  {
962  }
963  return;
964  }
965 
966  if (state == IEEE_802_15_4_PHY_RX_ON)
967  {
969  {
970  // Turnaround delay
971  // TODO: Does it really take aTurnaroundTime to switch the transceiver state,
972  // even when the transmitter is not busy? (6.9.1)
974 
975  Time setTime = Seconds((double)lrwpan::aTurnaroundTime / GetDataOrSymbolRate(false));
977  return;
978  }
980  {
982  {
984  }
985  return;
986  }
987  }
988 
989  NS_FATAL_ERROR("Unexpected transition from state " << m_trxState << " to state " << state);
990 }
991 
992 bool
994 {
995  NS_LOG_FUNCTION(this << channel);
996  bool retValue = false;
997 
998  // Bits 0-26 (27 LSB)
1000  (1 << channel)) != 0)
1001  {
1002  return retValue = true;
1003  }
1004  else
1005  {
1006  return retValue;
1007  }
1008 }
1009 
1010 bool
1012 {
1013  NS_LOG_FUNCTION(this << +page);
1014  bool retValue = false;
1015 
1016  // TODO: Only O-QPSK 2.4GHz is supported in the LrWpanSpectrumModel
1017  // we must limit the page until support for other modulation is added to the spectrum
1018  // model.
1019  //
1020  NS_ABORT_MSG_UNLESS(page == 0, " Only Page 0 (2.4Ghz O-QPSK supported).");
1021 
1022  // IEEE 802.15.4-2006, Table 23 phyChannelsSupported Bits 27-31 (5 MSB)
1023  uint8_t supportedPage = (m_phyPIBAttributes.phyChannelsSupported[page] >> 27) & (0x1F);
1024 
1025  if (page == supportedPage)
1026  {
1027  retValue = true;
1028  }
1029 
1030  return retValue;
1031 }
1032 
1033 void
1035  Ptr<LrWpanPhyPibAttributes> attribute)
1036 {
1037  NS_LOG_FUNCTION(this << id << attribute);
1038  NS_ASSERT(attribute);
1040 
1041  switch (id)
1042  {
1043  case phyCurrentPage: {
1044  if (!PageSupported(attribute->phyCurrentPage))
1045  {
1047  }
1048  else if (m_phyPIBAttributes.phyCurrentPage != attribute->phyCurrentPage)
1049  {
1050  // Cancel a pending transceiver state change.
1051  // Switch off the transceiver.
1052  // TODO: Is switching off the transceiver the right choice?
1055  {
1059  {
1061  }
1062  }
1063 
1064  // Any packet in transmission or reception will be corrupted.
1065  if (m_currentRxPacket.first)
1066  {
1067  m_currentRxPacket.second = true;
1068  }
1069  if (PhyIsBusy())
1070  {
1071  m_currentTxPacket.second = true;
1073  m_currentTxPacket.first = nullptr;
1075  {
1077  }
1078  }
1079 
1080  // Changing the Page can change they current PHY in use
1081  // Set the correct PHY according to the Page
1082  if (attribute->phyCurrentPage == 0)
1083  {
1085  {
1086  // 868 MHz BPSK
1088  NS_LOG_INFO("Page 0, 868 MHz BPSK PHY SET");
1089  }
1090  else if (m_phyPIBAttributes.phyCurrentChannel <= 10)
1091  {
1092  // 915 MHz BPSK
1094  NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1095  << ",915 MHz BPSK PHY SET");
1096  }
1097  else if (m_phyPIBAttributes.phyCurrentChannel <= 26)
1098  {
1099  // 2.4 GHz MHz O-QPSK
1101  NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1102  << ", 2.4 Ghz O-QPSK PHY SET");
1103  }
1104  }
1105  else if (attribute->phyCurrentPage == 1)
1106  {
1108  {
1109  // 868 MHz ASK
1111  NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1112  << ", 868 MHz ASK PHY SET");
1113  }
1114  else if (m_phyPIBAttributes.phyCurrentChannel <= 10)
1115  {
1116  // 915 MHz ASK
1118  NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1119  << ", 915 MHz ASK PHY SET");
1120  }
1121  else
1122  {
1123  // No longer valid channel
1126  NS_LOG_INFO("Channel no longer valid in new page "
1127  << (uint32_t)attribute->phyCurrentPage
1128  << ", setting new default channel "
1129  << (uint32_t)m_phyPIBAttributes.phyCurrentChannel);
1130  NS_LOG_INFO("868 MHz ASK PHY SET");
1131  }
1132  }
1133  else if (attribute->phyCurrentPage == 2)
1134  {
1136  {
1137  // 868 MHz O-QPSK
1139  NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1140  << ", 868 MHz O-QPSK PHY SET");
1141  }
1142  else if (m_phyPIBAttributes.phyCurrentChannel <= 10)
1143  {
1144  // 915 MHz O-QPSK
1146  NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1147  << ", 915 MHz O-QPSK PHY SET");
1148  }
1149  else
1150  {
1151  // No longer valid channel
1154  NS_LOG_INFO("Channel no longer valid in new page "
1155  << (uint32_t)attribute->phyCurrentPage
1156  << ", setting new default channel "
1157  << (uint32_t)m_phyPIBAttributes.phyCurrentChannel);
1158  NS_LOG_INFO("868 MHz O-QPSK PHY SET");
1159  }
1160  }
1161  else if (attribute->phyCurrentPage == 5)
1162  {
1164  {
1165  // 780 MHz O-QPSK
1167  NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1168  << ", 915 MHz O-QPSK PHY SET");
1169  }
1170  else
1171  {
1172  // No longer valid channel
1175  NS_LOG_INFO("Channel no longer valid in new page "
1176  << (uint32_t)attribute->phyCurrentPage
1177  << ", setting new default channel "
1178  << (uint32_t)m_phyPIBAttributes.phyCurrentChannel);
1179  NS_LOG_INFO("780 MHz O-QPSK PHY SET");
1180  }
1181  }
1182  else if (attribute->phyCurrentPage == 6)
1183  {
1185  {
1186  // 950 MHz BPSK
1188  NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1189  << ", 950 MHz BPSK PHY SET");
1190  }
1191  else
1192  {
1195  NS_LOG_INFO("Channel no longer valid in new page "
1196  << (uint32_t)attribute->phyCurrentPage
1197  << ", setting new default channel "
1198  << (uint32_t)m_phyPIBAttributes.phyCurrentChannel);
1199  NS_LOG_INFO("950 MHz BPSK PHY SET");
1200  }
1201  }
1202 
1203  m_phyPIBAttributes.phyCurrentPage = attribute->phyCurrentPage;
1204 
1205  // TODO: Set the maximum possible sensitivity by default.
1206  // This maximum sensitivity depends on the modulation used.
1207  // Currently Only O-QPSK 250kbps is supported so we use its max sensitivity.
1208  SetRxSensitivity(-106.58);
1209  }
1210  break;
1211  }
1212  case phyCurrentChannel: {
1213  if (!ChannelSupported(attribute->phyCurrentChannel))
1214  {
1216  }
1217  if (m_phyPIBAttributes.phyCurrentChannel != attribute->phyCurrentChannel)
1218  {
1219  // Cancel a pending transceiver state change.
1220  // Switch off the transceiver.
1221  // TODO: Is switching off the transceiver the right choice?
1224  {
1228  {
1230  }
1231  }
1232 
1233  // Any packet in transmission or reception will be corrupted.
1234  if (m_currentRxPacket.first)
1235  {
1236  m_currentRxPacket.second = true;
1237  }
1238  if (PhyIsBusy())
1239  {
1240  m_currentTxPacket.second = true;
1242  m_currentTxPacket.first = nullptr;
1244  {
1246  }
1247  }
1248 
1249  m_phyPIBAttributes.phyCurrentChannel = attribute->phyCurrentChannel;
1250 
1251  // use the prev configured sensitivity before changing the channel
1253  }
1254  break;
1255  }
1256  case phyChannelsSupported: { // only the first element is considered in the array
1257  if ((attribute->phyChannelsSupported[0] & 0xf8000000) != 0)
1258  { // 5 MSBs reserved
1260  }
1261  else
1262  {
1263  m_phyPIBAttributes.phyChannelsSupported[0] = attribute->phyChannelsSupported[0];
1264  }
1265  break;
1266  }
1267  case phyTransmitPower: {
1268  if (attribute->phyTransmitPower & 0xC0)
1269  {
1270  NS_LOG_LOGIC("LrWpanPhy::PlmeSetAttributeRequest error - can not change read-only "
1271  "attribute bits.");
1273  }
1274  else
1275  {
1276  m_phyPIBAttributes.phyTransmitPower = attribute->phyTransmitPower;
1277  LrWpanSpectrumValueHelper psdHelper;
1281  }
1282  break;
1283  }
1284  case phyCCAMode: {
1285  if ((attribute->phyCCAMode < 1) || (attribute->phyCCAMode > 3))
1286  {
1288  }
1289  else
1290  {
1291  m_phyPIBAttributes.phyCCAMode = attribute->phyCCAMode;
1292  }
1293  break;
1294  }
1295  default: {
1297  break;
1298  }
1299  }
1300 
1302  {
1304  }
1305 }
1306 
1307 void
1309 {
1310  NS_LOG_FUNCTION(this);
1312 }
1313 
1314 void
1316 {
1317  NS_LOG_FUNCTION(this);
1319 }
1320 
1321 void
1323 {
1324  NS_LOG_FUNCTION(this);
1326 }
1327 
1328 void
1330 {
1331  NS_LOG_FUNCTION(this);
1333 }
1334 
1335 void
1337 {
1338  NS_LOG_FUNCTION(this);
1340 }
1341 
1342 void
1344 {
1345  NS_LOG_FUNCTION(this);
1347 }
1348 
1349 void
1351 {
1352  NS_LOG_FUNCTION(this);
1354 }
1355 
1356 void
1358 {
1359  NS_LOG_LOGIC(this << " state: " << m_trxState << " -> " << newState);
1360 
1362  m_trxState = newState;
1363 }
1364 
1365 bool
1367 {
1368  NS_LOG_FUNCTION(this << m_trxState);
1369  return ((m_trxState == IEEE_802_15_4_PHY_BUSY_TX) ||
1371 }
1372 
1373 void
1375 {
1376  NS_LOG_FUNCTION(this);
1378 
1379  if (!m_edRequest.IsExpired())
1380  {
1381  m_edRequest.Cancel();
1383  {
1384  m_plmeEdConfirmCallback(state, 0);
1385  }
1386  }
1387 }
1388 
1389 void
1391 {
1392  NS_LOG_FUNCTION(this);
1393 
1397  (Simulator::Now() - m_edPower.lastUpdate).GetTimeStep() /
1399 
1400  uint8_t energyLevel;
1401 
1402  // Per IEEE802.15.4-2006 sec 6.9.7
1403  double ratio = m_edPower.averagePower / m_rxSensitivity;
1404  ratio = 10.0 * log10(ratio);
1405  if (ratio <= 10.0)
1406  { // less than 10 dB
1407  energyLevel = 0;
1408  }
1409  else if (ratio >= 40.0)
1410  { // less than 40 dB
1411  energyLevel = 255;
1412  }
1413  else
1414  {
1415  // in-between with linear increase per sec 6.9.7
1416  energyLevel = static_cast<uint8_t>(((ratio - 10.0) / 30.0) * 255.0);
1417  }
1418 
1420  {
1422  }
1423 }
1424 
1425 void
1427 {
1428  NS_LOG_FUNCTION(this);
1430 
1431  // Update peak power.
1432  double power = LrWpanSpectrumValueHelper::TotalAvgPower(m_signal->GetSignalPsd(),
1434  if (m_ccaPeakPower < power)
1435  {
1436  m_ccaPeakPower = power;
1437  }
1438 
1439  if (PhyIsBusy())
1440  {
1441  sensedChannelState = IEEE_802_15_4_PHY_BUSY;
1442  }
1443  else if (m_phyPIBAttributes.phyCCAMode == 1)
1444  { // sec 6.9.9 ED detection
1445  // -- ED threshold at most 10 dB above receiver sensitivity.
1446  if (10 * log10(m_ccaPeakPower / m_rxSensitivity) >= 10.0)
1447  {
1448  sensedChannelState = IEEE_802_15_4_PHY_BUSY;
1449  }
1450  else
1451  {
1452  sensedChannelState = IEEE_802_15_4_PHY_IDLE;
1453  }
1454  }
1455  else if (m_phyPIBAttributes.phyCCAMode == 2)
1456  {
1457  // sec 6.9.9 carrier sense only
1459  {
1460  // We currently do not model PPDU reception in detail. Instead we model
1461  // packet reception starting with the first bit of the preamble.
1462  // Therefore, this code will never be reached, as PhyIsBusy() would
1463  // already lead to a channel busy condition.
1464  // TODO: Change this, if we also model preamble and SFD detection.
1465  sensedChannelState = IEEE_802_15_4_PHY_BUSY;
1466  }
1467  else
1468  {
1469  sensedChannelState = IEEE_802_15_4_PHY_IDLE;
1470  }
1471  }
1472  else if (m_phyPIBAttributes.phyCCAMode == 3)
1473  { // sect 6.9.9 both
1474  if ((10 * log10(m_ccaPeakPower / m_rxSensitivity) >= 10.0) &&
1476  {
1477  // Again, this code will never be reached, if we are already receiving
1478  // a packet, as PhyIsBusy() would already lead to a channel busy condition.
1479  // TODO: Change this, if we also model preamble and SFD detection.
1480  sensedChannelState = IEEE_802_15_4_PHY_BUSY;
1481  }
1482  else
1483  {
1484  sensedChannelState = IEEE_802_15_4_PHY_IDLE;
1485  }
1486  }
1487  else
1488  {
1489  NS_ASSERT_MSG(false, "Invalid CCA mode");
1490  }
1491 
1492  NS_LOG_LOGIC(this << "channel sensed state: " << sensedChannelState);
1493 
1495  {
1496  m_plmeCcaConfirmCallback(sensedChannelState);
1497  }
1498 }
1499 
1500 void
1502 {
1503  NS_LOG_FUNCTION(this);
1504 
1509 
1511  {
1513  }
1514 }
1515 
1516 void
1518 {
1519  NS_LOG_FUNCTION(this);
1520 
1523 
1524  if (!m_currentTxPacket.second)
1525  {
1526  NS_LOG_DEBUG("Packet successfully transmitted");
1529  {
1531  }
1532  }
1533  else
1534  {
1535  NS_LOG_DEBUG("Packet transmission aborted");
1538  {
1539  // See if this is ever entered in another state
1542  }
1543  }
1544  m_currentTxPacket.first = nullptr;
1545  m_currentTxPacket.second = false;
1546 
1547  // We may be waiting to apply a pending state change.
1549  {
1550  // Only change the state immediately, if the transceiver is not already
1551  // switching the state.
1552  if (!m_setTRXState.IsRunning())
1553  {
1554  NS_LOG_LOGIC("Apply pending state change to " << m_trxStatePending);
1558  {
1560  }
1561  }
1562  }
1563  else
1564  {
1566  {
1568  }
1569  }
1570 }
1571 
1572 Time
1574 {
1575  NS_LOG_FUNCTION(this << packet);
1576 
1577  bool isData = true;
1578  Time txTime = GetPpduHeaderTxTime();
1579 
1580  txTime += Seconds(packet->GetSize() * 8.0 / GetDataOrSymbolRate(isData));
1581 
1582  return txTime;
1583 }
1584 
1585 uint8_t
1587 {
1589 }
1590 
1591 uint8_t
1593 {
1595 }
1596 
1597 double
1599 {
1600  double rate = 0.0;
1601 
1603 
1604  if (isData)
1605  {
1607  }
1608  else
1609  {
1611  }
1612 
1613  return (rate * 1000.0);
1614 }
1615 
1616 Time
1618 {
1619  NS_LOG_FUNCTION(this);
1620 
1621  bool isData = false;
1622  double totalPpduHdrSymbols;
1623 
1625 
1626  totalPpduHdrSymbols = ppduHeaderSymbolNumbers[m_phyOption].shrPreamble +
1629 
1630  return Seconds(totalPpduHdrSymbols / GetDataOrSymbolRate(isData));
1631 }
1632 
1633 void
1635 {
1636  NS_LOG_FUNCTION(this);
1637 
1639 
1640  // TODO: Only O-QPSK 2.4GHz is supported in the LrWpanSpectrumModel
1641  // we must limit the page until support for other modulations is added to the spectrum
1642  // model.
1643  NS_ABORT_MSG_UNLESS(phyOption == IEEE_802_15_4_2_4GHZ_OQPSK, " Only 2.4Ghz O-QPSK supported.");
1644 
1645  // Set default Channel and Page
1646  // IEEE 802.15.4-2006 Table 2, section 6.1.1
1647  // IEEE 802.15.4c-2009 Table 2, section 6.1.2.2
1648  // IEEE 802.15.4d-2009 Table 2, section 6.1.2.2
1649  switch (phyOption)
1650  {
1652  // IEEE 802.15.4-2006 868 MHz BPSK (Page 0, Channel 0)
1655  break;
1657  // IEEE 802.15.4-2006 915 MHz BPSK (Page 0, Channels 1 to 10)
1660  break;
1662  // IEEE 802.15.4d-2009 950 MHz BPSK (Page 6, Channels 0 to 9)
1665  break;
1667  // IEEE 802.15.4-2006 868 MHz ASK (Page 1, Channel 0)
1670  break;
1672  // IEEE 802.15.4-2006 915 MHz ASK (Page 1, Channel 1 to 10)
1675  break;
1677  // IEEE 802.15.4c-2009 780 MHz O-QPSK (Page 5, Channel 0 to 3)
1680  break;
1682  // IEEE 802.15.4-2006 868 MHz O-QPSK (Page 2, Channel 0)
1685  break;
1687  // IEEE 802.15.4-2006 915 MHz O-QPSK (Page 2, Channels 1 to 10)
1690  break;
1692  // IEEE 802.15.4-2009 2.4 GHz O-QPSK (Page 0, Channels 11 to 26)
1695  break;
1697  // IEEE 802.15.4-2006 Use Non-Registered Page and channel
1700  break;
1701  }
1702 
1704 
1705  m_phyOption = phyOption;
1706  // TODO: Fix/Update list when more modulations are supported.
1707  // IEEE 802.15.4-2006, Table 23
1708  // 5 MSB = Page number, 27 LSB = Supported Channels (1= supported, 0 Not supported)
1709  // Currently only page 0, channels 11-26 supported.
1711  0x7FFF800; // Page 0 should support, Channels 0 to 26 (0x07FFFFFF)
1712 
1713  for (int i = 1; i <= 31; i++)
1714  {
1715  // Page 1 to 31, No support (Page set to 31, all channels 0)
1716  m_phyPIBAttributes.phyChannelsSupported[i] = 0xF8000000;
1717  }
1718 
1719  m_edPower.averagePower = 0.0;
1720  m_edPower.lastUpdate = Seconds(0.0);
1722 
1723  // TODO: Change the limits Rx sensitivity when other modulations are supported
1724  // Currently, only O-QPSK 250kbps is supported and its maximum possible sensitivity is
1725  // equal to -106.58 dBm and its minimum sensitivity is defined as -85 dBm
1726  SetRxSensitivity(-106.58);
1727 
1728  m_rxLastUpdate = Seconds(0);
1729  m_currentRxPacket = std::make_pair(nullptr, true);
1730  m_currentTxPacket = std::make_pair(nullptr, true);
1731  m_errorModel = nullptr;
1732 }
1733 
1734 void
1735 LrWpanPhy::SetRxSensitivity(double dbmSensitivity)
1736 {
1737  NS_LOG_FUNCTION(this << dbmSensitivity << "dBm");
1738 
1739  // See IEEE 802.15.4-2011 Sections 10.3.4, 11.3.4, 13.3.4, 13.3.4, 14.3.4, 15.3.4
1741  {
1742  if (dbmSensitivity > -92)
1743  {
1744  NS_ABORT_MSG("The minimum Rx sensitivity for this band should be at least -92 dBm");
1745  }
1746  }
1747  else
1748  {
1749  if (dbmSensitivity > -85)
1750  {
1751  NS_ABORT_MSG("The minimum Rx sensitivity for this band should be at least -85 dBm");
1752  }
1753  }
1754 
1755  // Calculate the noise factor required to reduce the Rx sensitivity.
1756  // The maximum possible sensitivity in the current modulation is used as a reference
1757  // to calculate the noise factor (F). The noise factor is a dimensionless ratio.
1758  // Currently only one PHY modulation is supported:
1759  // O-QPSK 250kpps which has a Max Rx sensitivity: -106.58 dBm (Noise factor = 1).
1760  // After Rx sensitivity is set, this becomes the new point where PER < 1 % for a
1761  // PSDU of 20 bytes as described by the standard.
1762 
1763  // TODO: recalculate maxRxSensitivity (Noise factor = 1) when additional modulations are
1764  // supported.
1765  double maxRxSensitivityW = DbmToW(-106.58);
1766 
1767  LrWpanSpectrumValueHelper psdHelper;
1771  // Update thermal noise + noise factor added.
1772  long double noiseFactor = DbmToW(dbmSensitivity) / maxRxSensitivityW;
1773  psdHelper.SetNoiseFactor(noiseFactor);
1775 
1776  m_signal = Create<LrWpanInterferenceHelper>(m_noise->GetSpectrumModel());
1777  // Change receiver sensitivity from dBm to Watts
1778  m_rxSensitivity = DbmToW(dbmSensitivity);
1779 }
1780 
1781 double
1783 {
1784  NS_LOG_FUNCTION(this);
1785  // Change receiver sensitivity from Watt to dBm
1786  return WToDbm(m_rxSensitivity);
1787 }
1788 
1791 {
1792  NS_LOG_FUNCTION(this);
1793  return m_phyOption;
1794 }
1795 
1796 void
1798 {
1799  NS_LOG_FUNCTION(this << txPsd);
1800  NS_ASSERT(txPsd);
1801  m_txPsd = txPsd;
1802  NS_LOG_INFO("\t computed tx_psd: " << *txPsd << "\t stored tx_psd: " << *m_txPsd);
1803 }
1804 
1805 void
1807 {
1808  NS_LOG_FUNCTION(this << noisePsd);
1809  NS_LOG_INFO("\t computed noise_psd: " << *noisePsd);
1810  NS_ASSERT(noisePsd);
1811  m_noise = noisePsd;
1812 }
1813 
1816 {
1817  NS_LOG_FUNCTION(this);
1818  return m_noise;
1819 }
1820 
1821 void
1823 {
1824  NS_LOG_FUNCTION(this << e);
1825  NS_ASSERT(e);
1826  m_errorModel = e;
1827 }
1828 
1831 {
1832  NS_LOG_FUNCTION(this);
1833  return m_errorModel;
1834 }
1835 
1836 uint64_t
1838 {
1839  NS_LOG_FUNCTION(this);
1841 
1844 }
1845 
1846 double
1848 {
1849  NS_LOG_FUNCTION(this);
1851 
1853 }
1854 
1855 double
1857 {
1858  double powerWatts =
1861  return WToDbm(powerWatts);
1862 }
1863 
1864 int8_t
1866 {
1868 
1869  // The nominal Tx power is stored in the PIB as a 6-bit
1870  // twos-complement, signed number.
1871 
1872  // The 5 LSBs can be copied - as their representation
1873  // is the same for unsigned and signed integers.
1874  int8_t nominalTxPower = phyTransmitPower & 0x1F;
1875 
1876  // Now check the 6th LSB (the "sign" bit).
1877  // It's a twos-complement format, so the "sign"
1878  // bit represents -2^5 = -32.
1879  if (phyTransmitPower & 0x20)
1880  {
1881  nominalTxPower -= 32;
1882  }
1883  return nominalTxPower;
1884 }
1885 
1886 double
1887 LrWpanPhy::WToDbm(double watt)
1888 {
1889  return (10 * log10(1000 * watt));
1890 }
1891 
1892 double
1894 {
1895  return (pow(10.0, dbm / 10.0) / 1000.0);
1896 }
1897 
1898 int64_t
1900 {
1901  NS_LOG_FUNCTION(this);
1902  m_random->SetStream(stream);
1903  return 1;
1904 }
1905 
1906 void
1908 {
1909  NS_LOG_FUNCTION(this << em);
1911 }
1912 
1913 } // namespace ns3
#define max(a, b)
Definition: 80211b.c:42
bool IsNull() const
Check for null implementation.
Definition: callback.h:569
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
bool IsExpired() const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:69
bool IsRunning() const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:76
Represent the LQI (Link Quality Estination).
uint8_t Get() const
Get the LQI value.
void Set(uint8_t lqi)
Set the LQI to the given value.
Make LrWpanPhy a SpectrumPhy so we can enable the eventual modeling of device interference.
Definition: lr-wpan-phy.h:274
double GetCurrentSignalPsd()
Get the current accumulated sum of signals in the transceiver including signals considered as interfe...
static TypeId GetTypeId()
Get the type ID.
Definition: lr-wpan-phy.cc:146
Ptr< const SpectrumValue > m_noise
The spectral density for for the noise.
Definition: lr-wpan-phy.h:817
void SetPdDataConfirmCallback(PdDataConfirmCallback c)
set the callback for the end of a TX, as part of the interconnections between the PHY and the MAC.
void SetPhyOption(LrWpanPhyOption phyOption)
Set the modulation option used by this PHY.
void EndTx()
Finish the transmission of a frame.
EventId m_setTRXState
Scheduler event of a currently running deferred transceiver state switch.
Definition: lr-wpan-phy.h:950
Ptr< const SpectrumValue > GetNoisePowerSpectralDensity()
Get the noise power spectral density.
bool ChannelSupported(uint8_t channel)
Check if the given channel is supported by the PHY.
Definition: lr-wpan-phy.cc:993
Ptr< SpectrumValue > m_txPsd
The transmit power spectral density.
Definition: lr-wpan-phy.h:812
void ChangeTrxState(LrWpanPhyEnumeration newState)
Change the PHY state to the given new state, firing the state change trace.
PlmeSetAttributeConfirmCallback m_plmeSetAttributeConfirmCallback
This callback is used to report attribute set results back to the MAC.
Definition: lr-wpan-phy.h:882
void SetPlmeGetAttributeConfirmCallback(PlmeGetAttributeConfirmCallback c)
set the callback for the end of an GetAttribute, as part of the interconnections between the PHY and ...
Time CalculateTxTime(Ptr< const Packet > packet)
Calculate the time required for sending the given packet, including preamble, SFD and PHR.
Ptr< AntennaModel > m_antenna
The antenna used by the transceiver.
Definition: lr-wpan-phy.h:807
double GetDataOrSymbolRate(bool isData)
implement PLME SetAttribute confirm SAP bit rate is in bit/s.
void SetPlmeSetTRXStateConfirmCallback(PlmeSetTRXStateConfirmCallback c)
set the callback for the end of an SetTRXState, as part of the interconnections between the PHY and t...
void PlmeSetTRXStateRequest(LrWpanPhyEnumeration state)
IEEE 802.15.4-2006 section 6.2.2.7 PLME-SET-TRX-STATE.request Set PHY state.
Definition: lr-wpan-phy.cc:805
void SetTxPowerSpectralDensity(Ptr< SpectrumValue > txPsd)
Set the Power Spectral Density of outgoing signals in W/Hz.
void PlmeGetAttributeRequest(LrWpanPibAttributeIdentifier id)
IEEE 802.15.4-2006 section 6.2.2.5 PLME-GET.request Get attributes per definition from Table 23 in se...
Definition: lr-wpan-phy.cc:772
Ptr< UniformRandomVariable > m_random
Uniform random variable stream.
Definition: lr-wpan-phy.h:960
TracedValue< LrWpanPhyEnumeration > m_trxState
The current transceiver state.
Definition: lr-wpan-phy.h:833
TracedCallback< Ptr< const Packet > > m_phyTxEndTrace
The trace source fired when a packet ends the transmission process on the medium.
Definition: lr-wpan-phy.h:707
void SetPlmeEdConfirmCallback(PlmeEdConfirmCallback c)
set the callback for the end of an ED, as part of the interconnections between the PHY and the MAC.
LrWpanPhyOption GetMyPhyOption()
Get the currently configured PHY option.
void EndRx(Ptr< SpectrumSignalParameters > params)
Finish the reception of a frame.
Definition: lr-wpan-phy.cc:550
PlmeCcaConfirmCallback m_plmeCcaConfirmCallback
This callback is used to report CCA status to the MAC or CSMA/CA.
Definition: lr-wpan-phy.h:858
bool PhyIsBusy() const
Check if the PHY is busy, which is the case if the PHY is currently sending or receiving a frame.
Ptr< NetDevice > m_device
The configured net device.
Definition: lr-wpan-phy.h:797
uint64_t GetPhySHRDuration() const
Get the duration of the SHR (preamble and SFD) in symbols, depending on the currently selected channe...
void PdDataRequest(const uint32_t psduLength, Ptr< Packet > p)
IEEE 802.15.4-2006 section 6.2.1.1 PD-DATA.request Request to transfer MPDU from MAC (transmitting)
Definition: lr-wpan-phy.cc:635
void SetRxSensitivity(double dbmSensitivity)
Set the receiver power sensitivity used by this device in dBm.
Ptr< ErrorModel > m_postReceptionErrorModel
Error model for receive packet events.
Definition: lr-wpan-phy.h:962
Ptr< LrWpanErrorModel > m_errorModel
The error model describing the bit and packet error rates.
Definition: lr-wpan-phy.h:822
uint8_t GetCurrentPage() const
Get The current channel page number in use in this PHY from the PIB attributes.
bool PageSupported(uint8_t page)
Check if the given page is supported by the PHY.
void DoInitialize() override
Initialize() implementation.
Definition: lr-wpan-phy.cc:229
void EndEd()
Called at the end of the ED procedure.
PlmeEdConfirmCallback m_plmeEdConfirmCallback
This callback is used to report ED status to the MAC.
Definition: lr-wpan-phy.h:864
std::pair< Ptr< LrWpanSpectrumSignalParameters >, bool > m_currentRxPacket
Status information of the currently received packet.
Definition: lr-wpan-phy.h:927
EventId m_ccaRequest
Scheduler event of a currently running CCA request.
Definition: lr-wpan-phy.h:940
void CheckInterference()
Check if the interference destroys a frame currently received.
Definition: lr-wpan-phy.cc:500
void EndCca()
Called at the end of the CCA.
LrWpanEdPower m_edPower
Helper value for tracking the average power during ED.
Definition: lr-wpan-phy.h:892
Ptr< LrWpanErrorModel > GetErrorModel() const
get the error model in use
uint8_t GetCurrentChannelNum() const
Get The current channel number in use in this PHY from the PIB attributes.
PacketAndStatus m_currentTxPacket
Status information of the currently transmitted packet.
Definition: lr-wpan-phy.h:935
TracedCallback< Ptr< const Packet >, double > m_phyRxEndTrace
The trace source fired when a packet ends the reception process from the medium.
Definition: lr-wpan-phy.h:734
void SetMobility(Ptr< MobilityModel > m) override
Set the mobility model associated with this device.
Definition: lr-wpan-phy.cc:316
Ptr< SpectrumChannel > m_channel
The channel attached to this transceiver.
Definition: lr-wpan-phy.h:802
PdDataConfirmCallback m_pdDataConfirmCallback
This callback is used to report packet transmission status to the MAC layer.
Definition: lr-wpan-phy.h:852
TracedCallback< Ptr< const Packet > > m_phyTxBeginTrace
The trace source fired when a packet begins the transmission process on the medium.
Definition: lr-wpan-phy.h:699
Ptr< MobilityModel > m_mobility
The mobility model used by the PHY.
Definition: lr-wpan-phy.h:792
double GetPhySymbolsPerOctet() const
Get the number of symbols per octet, depending on the currently selected channel.
double m_ccaPeakPower
Helper value for the peak power value during CCA.
Definition: lr-wpan-phy.h:897
LrWpanPhyOption m_phyOption
The currently configured PHY type.
Definition: lr-wpan-phy.h:887
EventId m_edRequest
Scheduler event of a currently running ED request.
Definition: lr-wpan-phy.h:945
LrWpanPhyPibAttributes m_phyPIBAttributes
The current PHY PIB attributes.
Definition: lr-wpan-phy.h:827
double m_rxSensitivity
The receiver sensitivity.
Definition: lr-wpan-phy.h:902
LrWpanPhyEnumeration m_trxStatePending
The next pending state to applied after the current action of the PHY is completed.
Definition: lr-wpan-phy.h:839
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
void EndSetTRXState()
Called after applying a deferred transceiver state switch.
Ptr< LrWpanInterferenceHelper > m_signal
The accumulated signals currently received by the transceiver, including the signal of a possibly rec...
Definition: lr-wpan-phy.h:914
int8_t GetNominalTxPowerFromPib(uint8_t phyTransmitPower)
Calculates the nominal transmit power of the device in decibels relative to 1 mW according to the rep...
Ptr< MobilityModel > GetMobility() const override
Get the associated MobilityModel instance.
Definition: lr-wpan-phy.cc:303
PdDataIndicationCallback m_pdDataIndicationCallback
This callback is used to notify incoming packets to the MAC layer.
Definition: lr-wpan-phy.h:846
Time GetPpduHeaderTxTime()
Calculate the time required for sending the PPDU header, that is the preamble, SFD and PHR.
void PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier id, Ptr< LrWpanPhyPibAttributes > attribute)
IEEE 802.15.4-2006 section 6.2.2.9 PLME-SET.request Set attributes per definition from Table 23 in se...
void DoDispose() override
Destructor implementation.
Definition: lr-wpan-phy.cc:254
~LrWpanPhy() override
Definition: lr-wpan-phy.cc:224
void SetErrorModel(Ptr< LrWpanErrorModel > e)
set the error model to use
TracedCallback< Ptr< const Packet > > m_phyRxDropTrace
The trace source fired when the phy layer drops a packet it has received.
Definition: lr-wpan-phy.h:743
double WToDbm(double watt)
Transform watts (W) to decibels milliwatts (dBm).
void SetChannel(Ptr< SpectrumChannel > c) override
Set the channel attached to this device.
Definition: lr-wpan-phy.cc:323
void CcaCancel()
Cancel an ongoing CCA request.
Definition: lr-wpan-phy.cc:738
PlmeSetTRXStateConfirmCallback m_plmeSetTRXStateConfirmCallback
This callback is used to report transceiver state change status to the MAC.
Definition: lr-wpan-phy.h:876
PlmeGetAttributeConfirmCallback m_plmeGetAttributeConfirmCallback
This callback is used to report requested attribute values back to the MAC.
Definition: lr-wpan-phy.h:870
void SetPdDataIndicationCallback(PdDataIndicationCallback c)
set the callback for the end of a RX, as part of the interconnections between the PHY and the MAC.
EventId m_pdDataRequest
Scheduler event of a currently running data transmission request.
Definition: lr-wpan-phy.h:955
Ptr< NetDevice > GetDevice() const override
Get the associated NetDevice instance.
Definition: lr-wpan-phy.cc:297
void PlmeEdRequest()
IEEE 802.15.4-2006 section 6.2.2.3 PLME-ED.request Perform an ED per section 6.9.7.
Definition: lr-wpan-phy.cc:745
TracedCallback< Ptr< const Packet > > m_phyTxDropTrace
The trace source fired when the phy layer drops a packet as it tries to transmit it.
Definition: lr-wpan-phy.h:715
void SetPostReceptionErrorModel(const Ptr< ErrorModel > em)
Attach a receive ErrorModel to the LrWpanPhy.
TracedCallback< Ptr< const Packet > > m_phyRxBeginTrace
The trace source fired when a packet begins the reception process from the medium.
Definition: lr-wpan-phy.h:723
bool m_isRxCanceled
Indicates if the reception of frame has been canceled.
Definition: lr-wpan-phy.h:907
void SetPlmeSetAttributeConfirmCallback(PlmeSetAttributeConfirmCallback c)
set the callback for the end of an SetAttribute, as part of the interconnections between the PHY and ...
double DbmToW(double dbm)
Transforms decibels milliwatts (dBm) to watts (W).
Time m_rxLastUpdate
Timestamp of the last calculation of the PER of a packet currently received.
Definition: lr-wpan-phy.h:919
Ptr< SpectrumChannel > GetChannel()
Get the currently attached channel.
Definition: lr-wpan-phy.cc:330
TracedCallback< Time, LrWpanPhyEnumeration, LrWpanPhyEnumeration > m_trxStateLogger
The trace source fired when the phy layer changes the transceiver state.
Definition: lr-wpan-phy.h:753
void StartRx(Ptr< SpectrumSignalParameters > params) override
Notify the SpectrumPhy instance of an incoming waveform.
Definition: lr-wpan-phy.cc:364
LrWpanPhy()
Default constructor.
Definition: lr-wpan-phy.cc:203
void PlmeCcaRequest()
IEEE 802.15.4-2006 section 6.2.2.1 PLME-CCA.request Perform a CCA per section 6.9....
Definition: lr-wpan-phy.cc:711
void SetDevice(Ptr< NetDevice > d) override
Set the associated NetDevice instance.
Definition: lr-wpan-phy.cc:309
void CancelEd(LrWpanPhyEnumeration state)
Cancel an ongoing ED procedure.
void SetAntenna(Ptr< AntennaModel > a)
Set the attached antenna.
Definition: lr-wpan-phy.cc:357
double GetRxSensitivity()
Get the receiver power sensitivity used by this device in dBm.
void SetNoisePowerSpectralDensity(Ptr< const SpectrumValue > noisePsd)
Set the noise power spectral density.
Ptr< Object > GetAntenna() const override
Get the AntennaModel used by this SpectrumPhy instance for transmission and/or reception.
Definition: lr-wpan-phy.cc:351
void SetPlmeCcaConfirmCallback(PlmeCcaConfirmCallback c)
set the callback for the end of a CCA, as part of the interconnections between the PHY and the MAC.
Ptr< const SpectrumModel > GetRxSpectrumModel() const override
Definition: lr-wpan-phy.cc:337
This class defines all functions to create spectrum model for LrWpan.
Ptr< SpectrumValue > CreateNoisePowerSpectralDensity(uint32_t channel)
create spectrum value for noise
static double TotalAvgPower(Ptr< const SpectrumValue > psd, uint32_t channel)
total average power of the signal is the integral of the PSD using the limits of the given channel
Ptr< SpectrumValue > CreateTxPowerSpectralDensity(double txPower, uint32_t channel)
create spectrum value
void SetNoiseFactor(double f)
Set the noise factor added to the thermal noise.
Keep track of the current position and velocity of an object.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:204
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:352
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:967
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:983
bool ReplacePacketTag(Tag &tag)
Replace the value of a packet tag.
Definition: packet.cc:975
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
Abstract base class for Spectrum-aware PHY layers.
Definition: spectrum-phy.h:46
Ptr< const SpectrumModel > GetSpectrumModel() const
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
@ MS
millisecond
Definition: nstime.h:117
int64_t GetTimeStep() const
Get the raw time value, in the current resolution unit.
Definition: nstime.h:445
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
double GetValue(double min, double max)
Get the next random value drawn from the distribution.
constexpr uint32_t aMaxPhyPacketSize
The maximum packet size accepted by the PHY.
constexpr uint32_t aTurnaroundTime
The turnaround time in symbol periods for switching the transceiver from RX to TX or vice-versa.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
Callback< R, Args... > MakeNullCallback()
Definition: callback.h:747
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition: abort.h:76
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
LrWpanPhyOption
This Phy option will be used to index various Tables in IEEE802.15.4-2011.
Definition: lr-wpan-phy.h:91
LrWpanPhyEnumeration
IEEE802.15.4-2006 PHY Emumerations Table 18 in section 6.2.3.
Definition: lr-wpan-phy.h:111
LrWpanPibAttributeIdentifier
IEEE802.15.4-2006 PHY PIB Attribute Identifiers Table 23 in section 6.4.2.
Definition: lr-wpan-phy.h:163
@ IEEE_802_15_4_868MHZ_BPSK
Definition: lr-wpan-phy.h:92
@ IEEE_802_15_4_915MHZ_OQPSK
Definition: lr-wpan-phy.h:99
@ IEEE_802_15_4_868MHZ_ASK
Definition: lr-wpan-phy.h:95
@ IEEE_802_15_4_950MHZ_BPSK
Definition: lr-wpan-phy.h:94
@ IEEE_802_15_4_868MHZ_OQPSK
Definition: lr-wpan-phy.h:98
@ IEEE_802_15_4_780MHZ_OQPSK
Definition: lr-wpan-phy.h:97
@ IEEE_802_15_4_2_4GHZ_OQPSK
Definition: lr-wpan-phy.h:100
@ IEEE_802_15_4_915MHZ_ASK
Definition: lr-wpan-phy.h:96
@ IEEE_802_15_4_915MHZ_BPSK
Definition: lr-wpan-phy.h:93
@ IEEE_802_15_4_INVALID_PHY_OPTION
Definition: lr-wpan-phy.h:101
@ IEEE_802_15_4_PHY_BUSY_RX
Definition: lr-wpan-phy.h:113
@ IEEE_802_15_4_PHY_UNSUPPORTED_ATTRIBUTE
Definition: lr-wpan-phy.h:122
@ IEEE_802_15_4_PHY_BUSY
Definition: lr-wpan-phy.h:112
@ IEEE_802_15_4_PHY_SUCCESS
Definition: lr-wpan-phy.h:119
@ IEEE_802_15_4_PHY_UNSPECIFIED
Definition: lr-wpan-phy.h:124
@ IEEE_802_15_4_PHY_TRX_OFF
Definition: lr-wpan-phy.h:120
@ IEEE_802_15_4_PHY_FORCE_TRX_OFF
Definition: lr-wpan-phy.h:115
@ IEEE_802_15_4_PHY_BUSY_TX
Definition: lr-wpan-phy.h:114
@ IEEE_802_15_4_PHY_RX_ON
Definition: lr-wpan-phy.h:118
@ IEEE_802_15_4_PHY_TX_ON
Definition: lr-wpan-phy.h:121
@ IEEE_802_15_4_PHY_INVALID_PARAMETER
Definition: lr-wpan-phy.h:117
@ IEEE_802_15_4_PHY_READ_ONLY
Definition: lr-wpan-phy.h:123
@ IEEE_802_15_4_PHY_IDLE
Definition: lr-wpan-phy.h:116
@ phyChannelsSupported
Definition: lr-wpan-phy.h:165
@ phyCurrentChannel
Definition: lr-wpan-phy.h:164
@ phyCurrentPage
Definition: lr-wpan-phy.h:168
@ phyCCAMode
Definition: lr-wpan-phy.h:167
@ phySymbolsPerOctet
Definition: lr-wpan-phy.h:171
@ phySHRDuration
Definition: lr-wpan-phy.h:170
@ phyTransmitPower
Definition: lr-wpan-phy.h:166
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:227
static const LrWpanPhyDataAndSymbolRates dataSymbolRates[IEEE_802_15_4_INVALID_PHY_OPTION]
The data and symbol rates for the different PHY options.
Definition: lr-wpan-phy.cc:59
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:159
const LrWpanPhyPpduHeaderSymbolNumber ppduHeaderSymbolNumbers[IEEE_802_15_4_INVALID_PHY_OPTION]
The preamble, SFD, and PHR lengths in symbols for the different PHY options.
Definition: lr-wpan-phy.cc:78
channel
Definition: third.py:88
params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.
double averagePower
Average measured power.
Definition: lr-wpan-phy.h:55
Time lastUpdate
Last update time.
Definition: lr-wpan-phy.h:56
Time measurementLength
Total measurement period.
Definition: lr-wpan-phy.h:57
This data structure provides the Bit rate and Symbol rate for a given channel See IEEE802....
Definition: lr-wpan-phy.h:67
double symbolRate
symbol rate
Definition: lr-wpan-phy.h:69
uint32_t phyChannelsSupported[32]
BitField representing the available channels supported by a channel page.
Definition: lr-wpan-phy.h:182
uint8_t phyTransmitPower
2 MSB: tolerance on the transmit power, 6 LSB: Tx power in dBm relative to 1mW (signed int in 2-compl...
Definition: lr-wpan-phy.h:184
uint8_t phyCCAMode
CCA mode.
Definition: lr-wpan-phy.h:186
uint8_t phyCurrentPage
Current channel page.
Definition: lr-wpan-phy.h:187
uint8_t phyCurrentChannel
The RF channel to use.
Definition: lr-wpan-phy.h:181
This data structure provides number of symbols for the PPDU headers: SHR and PHR See IEEE802....
Definition: lr-wpan-phy.h:79
double shrSfd
Number of symbols for the SHR SFD.
Definition: lr-wpan-phy.h:81
double phr
Number of symbols for the PHR.
Definition: lr-wpan-phy.h:82
double shrPreamble
Number of symbols for the SHR preamble.
Definition: lr-wpan-phy.h:80
Time duration
The duration of the packet transmission.
Ptr< SpectrumValue > psd
The Power Spectral Density of the waveform, in linear units.