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 TypeId
92 {
93  static TypeId tid =
94  TypeId("ns3::LrWpanPhy")
96  .SetGroupName("LrWpan")
97  .AddConstructor<LrWpanPhy>()
98  .AddAttribute("PostReceptionErrorModel",
99  "An optional packet error model can be added to the receive "
100  "packet process after any propagation-based (SNR-based) error "
101  "models have been applied. Typically this is used to force "
102  "specific packet drops, for testing purposes.",
103  PointerValue(),
105  MakePointerChecker<ErrorModel>())
106  .AddTraceSource("TrxStateValue",
107  "The state of the transceiver",
109  "ns3::TracedValueCallback::LrWpanPhyEnumeration")
110  .AddTraceSource("TrxState",
111  "The state of the transceiver",
113  "ns3::LrWpanPhy::StateTracedCallback")
114  .AddTraceSource("PhyTxBegin",
115  "Trace source indicating a packet has "
116  "begun transmitting over the channel medium",
118  "ns3::Packet::TracedCallback")
119  .AddTraceSource("PhyTxEnd",
120  "Trace source indicating a packet has been "
121  "completely transmitted over the channel.",
123  "ns3::Packet::TracedCallback")
124  .AddTraceSource("PhyTxDrop",
125  "Trace source indicating a packet has been "
126  "dropped by the device during transmission",
128  "ns3::Packet::TracedCallback")
129  .AddTraceSource("PhyRxBegin",
130  "Trace source indicating a packet has begun "
131  "being received from the channel medium by the device",
133  "ns3::Packet::TracedCallback")
134  .AddTraceSource("PhyRxEnd",
135  "Trace source indicating a packet has been "
136  "completely received from the channel medium "
137  "by the device",
139  "ns3::Packet::SinrTracedCallback")
140  .AddTraceSource("PhyRxDrop",
141  "Trace source indicating a packet has been "
142  "dropped by the device during reception",
144  "ns3::Packet::TracedCallback");
145  return tid;
146 }
147 
149  : m_edRequest(),
150  m_setTRXState()
151 {
154 
155  // default PHY PIB attributes
158 
160 
161  m_random = CreateObject<UniformRandomVariable>();
162  m_random->SetAttribute("Min", DoubleValue(0.0));
163  m_random->SetAttribute("Max", DoubleValue(1.0));
164 
165  m_isRxCanceled = false;
167 }
168 
170 {
171 }
172 
173 void
175 {
176  NS_LOG_FUNCTION(this);
177 
178  // This method ensures that the local mobility model pointer holds
179  // a pointer to the Node's aggregated mobility model (if one exists)
180  // in the case that the user has not directly called SetMobility()
181  // on this LrWpanPhy during simulation setup. If the mobility model
182  // needs to be added or changed during simulation runtime, users must
183  // call SetMobility() on this object.
184 
185  if (!m_mobility)
186  {
187  NS_ABORT_MSG_UNLESS(m_device && m_device->GetNode(),
188  "Either install a MobilityModel on this object or ensure that this "
189  "object is part of a Node and NetDevice");
190  m_mobility = m_device->GetNode()->GetObject<MobilityModel>();
191  if (!m_mobility)
192  {
193  NS_LOG_WARN("Mobility not found, propagation models might not work properly");
194  }
195  }
196 }
197 
198 void
200 {
201  NS_LOG_FUNCTION(this);
202 
203  // Cancel pending transceiver state change, if one is in progress.
207 
208  m_mobility = nullptr;
209  m_device = nullptr;
210  m_channel = nullptr;
211  m_antenna = nullptr;
212  m_txPsd = nullptr;
213  m_noise = nullptr;
214  m_signal = nullptr;
215  m_errorModel = nullptr;
216  m_currentRxPacket.first = nullptr;
217  m_currentTxPacket.first = nullptr;
218  m_postReceptionErrorModel = nullptr;
219 
224 
225  m_random = nullptr;
226  m_pdDataIndicationCallback = MakeNullCallback<void, uint32_t, Ptr<Packet>, uint8_t>();
227  m_pdDataConfirmCallback = MakeNullCallback<void, LrWpanPhyEnumeration>();
228  m_plmeCcaConfirmCallback = MakeNullCallback<void, LrWpanPhyEnumeration>();
229  m_plmeEdConfirmCallback = MakeNullCallback<void, LrWpanPhyEnumeration, uint8_t>();
234  m_plmeSetTRXStateConfirmCallback = MakeNullCallback<void, LrWpanPhyEnumeration>();
236  MakeNullCallback<void, LrWpanPhyEnumeration, LrWpanPibAttributeIdentifier>();
237 
239 }
240 
243 {
244  NS_LOG_FUNCTION(this);
245  return m_device;
246 }
247 
250 {
251  NS_LOG_FUNCTION(this);
252  return m_mobility;
253 }
254 
255 void
257 {
258  NS_LOG_FUNCTION(this << d);
259  m_device = d;
260 }
261 
262 void
264 {
265  NS_LOG_FUNCTION(this << m);
266  m_mobility = m;
267 }
268 
269 void
271 {
272  NS_LOG_FUNCTION(this << c);
273  m_channel = c;
274 }
275 
278 {
279  NS_LOG_FUNCTION(this);
280  return m_channel;
281 }
282 
285 {
286  NS_LOG_FUNCTION(this);
287  if (m_txPsd)
288  {
289  return m_txPsd->GetSpectrumModel();
290  }
291  else
292  {
293  return nullptr;
294  }
295 }
296 
299 {
300  NS_LOG_FUNCTION(this);
301  return m_antenna;
302 }
303 
304 void
306 {
307  NS_LOG_FUNCTION(this << a);
308  m_antenna = a;
309 }
310 
311 void
313 {
314  NS_LOG_FUNCTION(this << spectrumRxParams);
315 
316  if (!m_edRequest.IsExpired())
317  {
318  // Update the average receive power during ED.
319  Time now = Simulator::Now();
323  (now - m_edPower.lastUpdate).GetTimeStep() / m_edPower.measurementLength.GetTimeStep();
324  m_edPower.lastUpdate = now;
325  }
326 
327  Ptr<LrWpanSpectrumSignalParameters> lrWpanRxParams =
328  DynamicCast<LrWpanSpectrumSignalParameters>(spectrumRxParams);
329 
330  if (!lrWpanRxParams)
331  {
333  m_signal->AddSignal(spectrumRxParams->psd);
334 
335  // Update peak power if CCA is in progress.
336  if (!m_ccaRequest.IsExpired())
337  {
338  double power =
341  if (m_ccaPeakPower < power)
342  {
343  m_ccaPeakPower = power;
344  }
345  }
346 
347  Simulator::Schedule(spectrumRxParams->duration, &LrWpanPhy::EndRx, this, spectrumRxParams);
348  return;
349  }
350 
351  Ptr<Packet> p = (lrWpanRxParams->packetBurst->GetPackets()).front();
352  NS_ASSERT(p);
353 
354  // Prevent PHY from receiving another packet while switching the transceiver state.
356  {
357  // The specification doesn't seem to refer to BUSY_RX, but vendor
358  // data sheets suggest that this is a substate of the RX_ON state
359  // that is entered after preamble detection when the digital receiver
360  // is enabled. Here, for now, we use BUSY_RX to mark the period between
361  // StartRx() and EndRx() states.
362 
363  // We are going to BUSY_RX state when receiving the first bit of an SHR,
364  // as opposed to real receivers, which should go to this state only after
365  // successfully receiving the SHR.
366 
367  // If synchronizing to the packet is possible, change to BUSY_RX state,
368  // otherwise drop the packet and stay in RX state. The actual synchronization
369  // is not modeled.
370 
371  // Add any incoming packet to the current interference before checking the
372  // SINR.
373  NS_LOG_DEBUG(this << " receiving packet with power: "
375  lrWpanRxParams->psd,
377  30
378  << "dBm");
379  m_signal->AddSignal(lrWpanRxParams->psd);
380  Ptr<SpectrumValue> interferenceAndNoise = m_signal->GetSignalPsd();
381  *interferenceAndNoise -= *lrWpanRxParams->psd;
382  *interferenceAndNoise += *m_noise;
383  double sinr =
384  LrWpanSpectrumValueHelper::TotalAvgPower(lrWpanRxParams->psd,
386  LrWpanSpectrumValueHelper::TotalAvgPower(interferenceAndNoise,
388 
389  // Std. 802.15.4-2006, appendix E, Figure E.2
390  // At SNR < -5 the BER is less than 10e-1.
391  // It's useless to even *try* to decode the packet.
392  if (10 * log10(sinr) > -5)
393  {
395  m_currentRxPacket = std::make_pair(lrWpanRxParams, false);
397 
399  }
400  else
401  {
402  m_phyRxDropTrace(p);
403  }
404  }
406  {
407  // Drop the new packet.
408  NS_LOG_DEBUG(this << " packet collision");
409  m_phyRxDropTrace(p);
410 
411  // Check if we correctly received the old packet up to now.
413 
414  // Add the incoming packet to the current interference after we have
415  // checked for successful reception of the current packet for the time
416  // before the additional interference.
417  m_signal->AddSignal(lrWpanRxParams->psd);
418  }
419  else
420  {
421  // Simply drop the packet.
422  NS_LOG_DEBUG(this << " transceiver not in RX state");
423  m_phyRxDropTrace(p);
424 
425  // Add the signal power to the interference, anyway.
426  m_signal->AddSignal(lrWpanRxParams->psd);
427  }
428 
429  // Update peak power if CCA is in progress.
430  if (!m_ccaRequest.IsExpired())
431  {
432  double power =
435  if (m_ccaPeakPower < power)
436  {
437  m_ccaPeakPower = power;
438  }
439  }
440 
441  // Always call EndRx to update the interference.
442  // We keep track of this event, and if necessary cancel this event when a TX of a packet.
443 
444  Simulator::Schedule(spectrumRxParams->duration, &LrWpanPhy::EndRx, this, spectrumRxParams);
445 }
446 
447 void
449 {
450  // Calculate whether packet was lost.
451  LrWpanSpectrumValueHelper psdHelper;
453 
454  // We are currently receiving a packet.
456  {
457  // NS_ASSERT (currentRxParams && !m_currentRxPacket.second);
458 
459  Ptr<Packet> currentPacket = currentRxParams->packetBurst->GetPackets().front();
460  if (m_errorModel)
461  {
462  // How many bits did we receive since the last calculation?
463  double t = (Simulator::Now() - m_rxLastUpdate).ToDouble(Time::MS);
464  uint32_t chunkSize = ceil(t * (GetDataOrSymbolRate(true) / 1000));
465  Ptr<SpectrumValue> interferenceAndNoise = m_signal->GetSignalPsd();
466  *interferenceAndNoise -= *currentRxParams->psd;
467  *interferenceAndNoise += *m_noise;
468  double sinr =
469  LrWpanSpectrumValueHelper::TotalAvgPower(currentRxParams->psd,
471  LrWpanSpectrumValueHelper::TotalAvgPower(interferenceAndNoise,
473  double per = 1.0 - m_errorModel->GetChunkSuccessRate(sinr, chunkSize);
474 
475  // The LQI is the total packet success rate scaled to 0-255.
476  // If not already set, initialize to 255.
478  currentPacket->PeekPacketTag(tag);
479  uint8_t lqi = tag.Get();
480  tag.Set(lqi - (per * lqi));
481  currentPacket->ReplacePacketTag(tag);
482 
483  if (m_random->GetValue() < per)
484  {
485  // The packet was destroyed, drop the packet after reception.
486  m_currentRxPacket.second = true;
487  }
488  }
489  else
490  {
491  NS_LOG_WARN("Missing ErrorModel");
492  }
493  }
495 }
496 
497 void
499 {
500  NS_LOG_FUNCTION(this);
501 
502  Ptr<LrWpanSpectrumSignalParameters> params = DynamicCast<LrWpanSpectrumSignalParameters>(par);
503 
504  if (!m_edRequest.IsExpired())
505  {
506  // Update the average receive power during ED.
507  Time now = Simulator::Now();
511  (now - m_edPower.lastUpdate).GetTimeStep() / m_edPower.measurementLength.GetTimeStep();
512  m_edPower.lastUpdate = now;
513  }
514 
516  if (currentRxParams == params)
517  {
519  }
520 
521  // Update the interference.
522  m_signal->RemoveSignal(par->psd);
523 
524  if (!params)
525  {
526  NS_LOG_LOGIC("Node: " << m_device->GetAddress()
527  << " Removing interferent: " << *(par->psd));
528  return;
529  }
530 
531  // If this is the end of the currently received packet, check if reception was successful.
532  if (currentRxParams == params)
533  {
534  Ptr<Packet> currentPacket = currentRxParams->packetBurst->GetPackets().front();
535  NS_ASSERT(currentPacket);
536 
538  m_postReceptionErrorModel->IsCorrupt(currentPacket->Copy()))
539  {
540  NS_LOG_DEBUG("Reception failed due to post-rx error model");
541  m_currentRxPacket.second = true;
542  }
543 
544  // If there is no error model attached to the PHY, we always report the maximum LQI value.
546  currentPacket->PeekPacketTag(tag);
547  m_phyRxEndTrace(currentPacket, tag.Get());
548 
549  if (!m_currentRxPacket.second)
550  {
551  // The packet was successfully received, push it up the stack.
553  {
554  m_pdDataIndicationCallback(currentPacket->GetSize(), currentPacket, tag.Get());
555  }
556  }
557  else
558  {
559  // The packet was destroyed, drop it.
560  m_phyRxDropTrace(currentPacket);
561  }
563  m_currentRxPacket = std::make_pair(none, true);
564 
565  if (!m_isRxCanceled)
566  {
567  // We may be waiting to apply a pending state change.
569  {
570  // Only change the state immediately, if the transceiver is not already
571  // switching the state.
572  if (!m_setTRXState.IsRunning())
573  {
574  NS_LOG_LOGIC("Apply pending state change to " << m_trxStatePending);
578  {
580  }
581  }
582  }
583  else
584  {
586  }
587  }
588  else
589  {
590  // A TX event was forced during the reception of the frame.
591  // There is no need to change the PHY state after handling the signal,
592  // because the Forced TX already changed the PHY state.
593  // Return flag to default state
594  m_isRxCanceled = false;
595  }
596  }
597 }
598 
599 void
600 LrWpanPhy::PdDataRequest(const uint32_t psduLength, Ptr<Packet> p)
601 {
602  NS_LOG_FUNCTION(this << psduLength << p);
603 
604  if (psduLength > lrwpan::aMaxPhyPacketSize)
605  {
607  {
609  }
610  NS_LOG_DEBUG("Drop packet because psduLength too long: " << psduLength);
611  return;
612  }
613 
614  // Prevent PHY from sending a packet while switching the transceiver state.
615  if (!m_setTRXState.IsRunning())
616  {
618  {
619  // send down
621 
622  // Remove a possible LQI tag from a previous transmission of the packet.
623  LrWpanLqiTag lqiTag;
624  p->RemovePacketTag(lqiTag);
625 
627  m_currentTxPacket.first = p;
628  m_currentTxPacket.second = false;
629 
630  Ptr<LrWpanSpectrumSignalParameters> txParams = Create<LrWpanSpectrumSignalParameters>();
631  txParams->duration = CalculateTxTime(p);
632  txParams->txPhy = GetObject<SpectrumPhy>();
633  txParams->psd = m_txPsd;
634  txParams->txAntenna = m_antenna;
635  Ptr<PacketBurst> pb = CreateObject<PacketBurst>();
636  pb->AddPacket(p);
637  txParams->packetBurst = pb;
638  m_channel->StartTx(txParams);
639  m_pdDataRequest = Simulator::Schedule(txParams->duration, &LrWpanPhy::EndTx, this);
641  return;
642  }
643  else if ((m_trxState == IEEE_802_15_4_PHY_RX_ON) ||
646  {
648  {
650  }
651  // Drop packet, hit PhyTxDrop trace
652  m_phyTxDropTrace(p);
653  return;
654  }
655  else
656  {
657  NS_FATAL_ERROR("This should be unreachable, or else state "
658  << m_trxState << " should be added as a case");
659  }
660  }
661  else
662  {
663  // TODO: This error code is not covered by the standard.
664  // What is the correct behavior in this case?
666  {
668  }
669  // Drop packet, hit PhyTxDrop trace
670  m_phyTxDropTrace(p);
671  return;
672  }
673 }
674 
675 void
677 {
678  NS_LOG_FUNCTION(this);
679 
681  {
682  m_ccaPeakPower = 0.0;
683  Time ccaTime = Seconds(8.0 / GetDataOrSymbolRate(false));
685  }
686  else
687  {
689  {
691  {
693  }
694  else
695  {
697  }
698  }
699  }
700 }
701 
702 void
704 {
705  NS_LOG_FUNCTION(this);
707 }
708 
709 void
711 {
712  NS_LOG_FUNCTION(this);
714  {
715  // Average over the powers of all signals received until EndEd()
720  }
721  else
722  {
725  {
726  result = IEEE_802_15_4_PHY_TX_ON;
727  }
728 
730  {
731  m_plmeEdConfirmCallback(result, 0);
732  }
733  }
734 }
735 
736 void
738 {
739  NS_LOG_FUNCTION(this << id);
740  LrWpanPhyEnumeration status;
741 
742  switch (id)
743  {
744  case phyCurrentChannel:
746  case phyTransmitPower:
747  case phyCCAMode:
748  case phyCurrentPage:
749  case phyMaxFrameDuration:
750  case phySHRDuration:
751  case phySymbolsPerOctet: {
752  status = IEEE_802_15_4_PHY_SUCCESS;
753  break;
754  }
755  default: {
757  break;
758  }
759  }
761  {
762  LrWpanPhyPibAttributes retValue;
763  memcpy(&retValue, &m_phyPIBAttributes, sizeof(LrWpanPhyPibAttributes));
764  m_plmeGetAttributeConfirmCallback(status, id, &retValue);
765  }
766 }
767 
768 // Section 6.2.2.7.3
769 void
771 {
772  NS_LOG_FUNCTION(this << state);
773 
774  // Check valid states (Table 14)
777 
778  NS_LOG_LOGIC("Trying to set m_trxState from " << m_trxState << " to " << state);
779  // this method always overrides previous state setting attempts
780  if (!m_setTRXState.IsExpired())
781  {
782  if (m_trxStatePending == state)
783  {
784  // Simply wait for the ongoing state switch.
785  return;
786  }
787  else
788  {
789  NS_LOG_DEBUG("Cancel m_setTRXState");
790  // Keep the transceiver state as the old state before the switching attempt.
792  }
793  }
795  {
797  }
798 
799  if (state == m_trxState)
800  {
802  {
804  }
805  return;
806  }
807 
808  if (((state == IEEE_802_15_4_PHY_RX_ON) || (state == IEEE_802_15_4_PHY_TRX_OFF)) &&
810  {
811  NS_LOG_DEBUG("Phy is busy; setting state pending to " << state);
812  m_trxStatePending = state;
813  return; // Send PlmeSetTRXStateConfirm later
814  }
815 
816  // specification talks about being in RX_ON and having received
817  // a valid SFD. Here, we are not modelling at that level of
818  // granularity, so we just test for BUSY_RX state (any part of
819  // a packet being actively received)
820  if (state == IEEE_802_15_4_PHY_TRX_OFF)
821  {
822  CancelEd(state);
823 
825  (!m_currentRxPacket.second))
826  {
827  NS_LOG_DEBUG("Receiver has valid SFD; defer state change");
828  m_trxStatePending = state;
829  return; // Send PlmeSetTRXStateConfirm later
830  }
832  {
835  {
837  }
838  return;
839  }
840  }
841 
842  if (state == IEEE_802_15_4_PHY_TX_ON)
843  {
844  CancelEd(state);
845 
846  NS_LOG_DEBUG("turn on PHY_TX_ON");
848  {
849  if (m_currentRxPacket.first)
850  {
851  // TX_ON is being forced during a reception (For example, when a ACK or Beacon is
852  // issued) The current RX frame is marked as incomplete and the reception as
853  // canceled EndRx () will handle the rest accordingly
854  NS_LOG_DEBUG("force TX_ON, terminate reception");
855  m_currentRxPacket.second = true;
856  m_isRxCanceled = true;
857  }
858 
859  // If CCA is in progress, cancel CCA and return BUSY.
860  if (!m_ccaRequest.IsExpired())
861  {
864  {
866  }
867  }
868 
870 
871  // Delay for turnaround time (BUSY_RX|RX_ON ---> TX_ON)
872  Time setTime = Seconds((double)lrwpan::aTurnaroundTime / GetDataOrSymbolRate(false));
874  return;
875  }
877  {
878  // We do NOT change the transceiver state here. We only report that
879  // the transceiver is already in TX_ON state.
881  {
883  }
884  return;
885  }
887  {
890  {
892  }
893  return;
894  }
895  }
896 
897  if (state == IEEE_802_15_4_PHY_FORCE_TRX_OFF)
898  {
900  {
901  NS_LOG_DEBUG("force TRX_OFF, was already off");
902  }
903  else
904  {
905  NS_LOG_DEBUG("force TRX_OFF, SUCCESS");
906  if (m_currentRxPacket.first)
907  {
908  // Terminate reception
909  // Mark the packet as incomplete and reception as canceled.
910  NS_LOG_DEBUG("force TRX_OFF, terminate reception");
911  m_currentRxPacket.second = true;
912  m_isRxCanceled = true;
913  }
915  {
916  NS_LOG_DEBUG("force TRX_OFF, terminate transmission");
917  m_currentTxPacket.second = true;
918  }
920  // Clear any other state
922  }
924  {
926  }
927  return;
928  }
929 
930  if (state == IEEE_802_15_4_PHY_RX_ON)
931  {
933  {
934  // Turnaround delay
935  // TODO: Does it really take aTurnaroundTime to switch the transceiver state,
936  // even when the transmitter is not busy? (6.9.1)
938 
939  Time setTime = Seconds((double)lrwpan::aTurnaroundTime / GetDataOrSymbolRate(false));
941  return;
942  }
944  {
946  {
948  }
949  return;
950  }
951  }
952 
953  NS_FATAL_ERROR("Unexpected transition from state " << m_trxState << " to state " << state);
954 }
955 
956 bool
958 {
959  NS_LOG_FUNCTION(this << channel);
960  bool retValue = false;
961 
962  // Bits 0-26 (27 LSB)
964  (1 << channel)) != 0)
965  {
966  return retValue = true;
967  }
968  else
969  {
970  return retValue;
971  }
972 }
973 
974 bool
976 {
977  NS_LOG_FUNCTION(this << +page);
978  bool retValue = false;
979 
980  // TODO: Only O-QPSK 2.4GHz is supported in the LrWpanSpectrumModel
981  // we must limit the page until support for other modulation is added to the spectrum
982  // model.
983  //
984  NS_ABORT_MSG_UNLESS(page == 0, " Only Page 0 (2.4Ghz O-QPSK supported).");
985 
986  // IEEE 802.15.4-2006, Table 23 phyChannelsSupported Bits 27-31 (5 MSB)
987  uint8_t supportedPage = (m_phyPIBAttributes.phyChannelsSupported[page] >> 27) & (0x1F);
988 
989  if (page == supportedPage)
990  {
991  retValue = true;
992  }
993 
994  return retValue;
995 }
996 
997 void
999  LrWpanPhyPibAttributes* attribute)
1000 {
1001  NS_LOG_FUNCTION(this << id << attribute);
1002  NS_ASSERT(attribute);
1004 
1005  switch (id)
1006  {
1007  case phyCurrentPage: {
1008  if (!PageSupported(attribute->phyCurrentPage))
1009  {
1011  }
1012  else if (m_phyPIBAttributes.phyCurrentPage != attribute->phyCurrentPage)
1013  {
1014  // Cancel a pending transceiver state change.
1015  // Switch off the transceiver.
1016  // TODO: Is switching off the transceiver the right choice?
1019  {
1023  {
1025  }
1026  }
1027 
1028  // Any packet in transmission or reception will be corrupted.
1029  if (m_currentRxPacket.first)
1030  {
1031  m_currentRxPacket.second = true;
1032  }
1033  if (PhyIsBusy())
1034  {
1035  m_currentTxPacket.second = true;
1037  m_currentTxPacket.first = nullptr;
1039  {
1041  }
1042  }
1043 
1044  // Changing the Page can change they current PHY in use
1045  // Set the correct PHY according to the Page
1046  if (attribute->phyCurrentPage == 0)
1047  {
1049  {
1050  // 868 MHz BPSK
1052  NS_LOG_INFO("Page 0, 868 MHz BPSK PHY SET");
1053  }
1054  else if (m_phyPIBAttributes.phyCurrentChannel <= 10)
1055  {
1056  // 915 MHz BPSK
1058  NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1059  << ",915 MHz BPSK PHY SET");
1060  }
1061  else if (m_phyPIBAttributes.phyCurrentChannel <= 26)
1062  {
1063  // 2.4 GHz MHz O-QPSK
1065  NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1066  << ", 2.4 Ghz O-QPSK PHY SET");
1067  }
1068  }
1069  else if (attribute->phyCurrentPage == 1)
1070  {
1072  {
1073  // 868 MHz ASK
1075  NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1076  << ", 868 MHz ASK PHY SET");
1077  }
1078  else if (m_phyPIBAttributes.phyCurrentChannel <= 10)
1079  {
1080  // 915 MHz ASK
1082  NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1083  << ", 915 MHz ASK PHY SET");
1084  }
1085  else
1086  {
1087  // No longer valid channel
1090  NS_LOG_INFO("Channel no longer valid in new page "
1091  << (uint32_t)attribute->phyCurrentPage
1092  << ", setting new default channel "
1093  << (uint32_t)m_phyPIBAttributes.phyCurrentChannel);
1094  NS_LOG_INFO("868 MHz ASK PHY SET");
1095  }
1096  }
1097  else if (attribute->phyCurrentPage == 2)
1098  {
1100  {
1101  // 868 MHz O-QPSK
1103  NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1104  << ", 868 MHz O-QPSK PHY SET");
1105  }
1106  else if (m_phyPIBAttributes.phyCurrentChannel <= 10)
1107  {
1108  // 915 MHz O-QPSK
1110  NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1111  << ", 915 MHz O-QPSK PHY SET");
1112  }
1113  else
1114  {
1115  // No longer valid channel
1118  NS_LOG_INFO("Channel no longer valid in new page "
1119  << (uint32_t)attribute->phyCurrentPage
1120  << ", setting new default channel "
1121  << (uint32_t)m_phyPIBAttributes.phyCurrentChannel);
1122  NS_LOG_INFO("868 MHz O-QPSK PHY SET");
1123  }
1124  }
1125  else if (attribute->phyCurrentPage == 5)
1126  {
1128  {
1129  // 780 MHz O-QPSK
1131  NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1132  << ", 915 MHz O-QPSK PHY SET");
1133  }
1134  else
1135  {
1136  // No longer valid channel
1139  NS_LOG_INFO("Channel no longer valid in new page "
1140  << (uint32_t)attribute->phyCurrentPage
1141  << ", setting new default channel "
1142  << (uint32_t)m_phyPIBAttributes.phyCurrentChannel);
1143  NS_LOG_INFO("780 MHz O-QPSK PHY SET");
1144  }
1145  }
1146  else if (attribute->phyCurrentPage == 6)
1147  {
1149  {
1150  // 950 MHz BPSK
1152  NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1153  << ", 950 MHz BPSK PHY SET");
1154  }
1155  else
1156  {
1159  NS_LOG_INFO("Channel no longer valid in new page "
1160  << (uint32_t)attribute->phyCurrentPage
1161  << ", setting new default channel "
1162  << (uint32_t)m_phyPIBAttributes.phyCurrentChannel);
1163  NS_LOG_INFO("950 MHz BPSK PHY SET");
1164  }
1165  }
1166 
1168 
1169  // TODO: Set the maximum possible sensitivity by default.
1170  // This maximum sensitivity depends on the modulation used.
1171  // Currently Only O-QPSK 250kbps is supported so we use its max sensitivity.
1172  SetRxSensitivity(-106.58);
1173  }
1174  break;
1175  }
1176  case phyCurrentChannel: {
1177  if (!ChannelSupported(attribute->phyCurrentChannel))
1178  {
1180  }
1182  {
1183  // Cancel a pending transceiver state change.
1184  // Switch off the transceiver.
1185  // TODO: Is switching off the transceiver the right choice?
1188  {
1192  {
1194  }
1195  }
1196 
1197  // Any packet in transmission or reception will be corrupted.
1198  if (m_currentRxPacket.first)
1199  {
1200  m_currentRxPacket.second = true;
1201  }
1202  if (PhyIsBusy())
1203  {
1204  m_currentTxPacket.second = true;
1206  m_currentTxPacket.first = nullptr;
1208  {
1210  }
1211  }
1212 
1214 
1215  // use the prev configured sensitivity before changing the channel
1217  }
1218  break;
1219  }
1220  case phyChannelsSupported: { // only the first element is considered in the array
1221  if ((attribute->phyChannelsSupported[0] & 0xf8000000) != 0)
1222  { // 5 MSBs reserved
1224  }
1225  else
1226  {
1228  }
1229  break;
1230  }
1231  case phyTransmitPower: {
1232  if (attribute->phyTransmitPower & 0xC0)
1233  {
1234  NS_LOG_LOGIC("LrWpanPhy::PlmeSetAttributeRequest error - can not change read-only "
1235  "attribute bits.");
1237  }
1238  else
1239  {
1241  LrWpanSpectrumValueHelper psdHelper;
1245  }
1246  break;
1247  }
1248  case phyCCAMode: {
1249  if ((attribute->phyCCAMode < 1) || (attribute->phyCCAMode > 3))
1250  {
1252  }
1253  else
1254  {
1256  }
1257  break;
1258  }
1259  default: {
1261  break;
1262  }
1263  }
1264 
1266  {
1268  }
1269 }
1270 
1271 void
1273 {
1274  NS_LOG_FUNCTION(this);
1276 }
1277 
1278 void
1280 {
1281  NS_LOG_FUNCTION(this);
1283 }
1284 
1285 void
1287 {
1288  NS_LOG_FUNCTION(this);
1290 }
1291 
1292 void
1294 {
1295  NS_LOG_FUNCTION(this);
1297 }
1298 
1299 void
1301 {
1302  NS_LOG_FUNCTION(this);
1304 }
1305 
1306 void
1308 {
1309  NS_LOG_FUNCTION(this);
1311 }
1312 
1313 void
1315 {
1316  NS_LOG_FUNCTION(this);
1318 }
1319 
1320 void
1322 {
1323  NS_LOG_LOGIC(this << " state: " << m_trxState << " -> " << newState);
1325  m_trxState = newState;
1326 }
1327 
1328 bool
1330 {
1331  NS_LOG_FUNCTION(this << m_trxState);
1332  return ((m_trxState == IEEE_802_15_4_PHY_BUSY_TX) ||
1334 }
1335 
1336 void
1338 {
1339  NS_LOG_FUNCTION(this);
1341 
1342  if (!m_edRequest.IsExpired())
1343  {
1344  m_edRequest.Cancel();
1346  {
1347  m_plmeEdConfirmCallback(state, 0);
1348  }
1349  }
1350 }
1351 
1352 void
1354 {
1355  NS_LOG_FUNCTION(this);
1356 
1360  (Simulator::Now() - m_edPower.lastUpdate).GetTimeStep() /
1362 
1363  uint8_t energyLevel;
1364 
1365  // Per IEEE802.15.4-2006 sec 6.9.7
1366  double ratio = m_edPower.averagePower / m_rxSensitivity;
1367  ratio = 10.0 * log10(ratio);
1368  if (ratio <= 10.0)
1369  { // less than 10 dB
1370  energyLevel = 0;
1371  }
1372  else if (ratio >= 40.0)
1373  { // less than 40 dB
1374  energyLevel = 255;
1375  }
1376  else
1377  {
1378  // in-between with linear increase per sec 6.9.7
1379  energyLevel = static_cast<uint8_t>(((ratio - 10.0) / 30.0) * 255.0);
1380  }
1381 
1383  {
1385  }
1386 }
1387 
1388 void
1390 {
1391  NS_LOG_FUNCTION(this);
1393 
1394  // Update peak power.
1395  double power = LrWpanSpectrumValueHelper::TotalAvgPower(m_signal->GetSignalPsd(),
1397  if (m_ccaPeakPower < power)
1398  {
1399  m_ccaPeakPower = power;
1400  }
1401 
1402  if (PhyIsBusy())
1403  {
1404  sensedChannelState = IEEE_802_15_4_PHY_BUSY;
1405  }
1406  else if (m_phyPIBAttributes.phyCCAMode == 1)
1407  { // sec 6.9.9 ED detection
1408  // -- ED threshold at most 10 dB above receiver sensitivity.
1409  if (10 * log10(m_ccaPeakPower / m_rxSensitivity) >= 10.0)
1410  {
1411  sensedChannelState = IEEE_802_15_4_PHY_BUSY;
1412  }
1413  else
1414  {
1415  sensedChannelState = IEEE_802_15_4_PHY_IDLE;
1416  }
1417  }
1418  else if (m_phyPIBAttributes.phyCCAMode == 2)
1419  {
1420  // sec 6.9.9 carrier sense only
1422  {
1423  // We currently do not model PPDU reception in detail. Instead we model
1424  // packet reception starting with the first bit of the preamble.
1425  // Therefore, this code will never be reached, as PhyIsBusy() would
1426  // already lead to a channel busy condition.
1427  // TODO: Change this, if we also model preamble and SFD detection.
1428  sensedChannelState = IEEE_802_15_4_PHY_BUSY;
1429  }
1430  else
1431  {
1432  sensedChannelState = IEEE_802_15_4_PHY_IDLE;
1433  }
1434  }
1435  else if (m_phyPIBAttributes.phyCCAMode == 3)
1436  { // sect 6.9.9 both
1437  if ((10 * log10(m_ccaPeakPower / m_rxSensitivity) >= 10.0) &&
1439  {
1440  // Again, this code will never be reached, if we are already receiving
1441  // a packet, as PhyIsBusy() would already lead to a channel busy condition.
1442  // TODO: Change this, if we also model preamble and SFD detection.
1443  sensedChannelState = IEEE_802_15_4_PHY_BUSY;
1444  }
1445  else
1446  {
1447  sensedChannelState = IEEE_802_15_4_PHY_IDLE;
1448  }
1449  }
1450  else
1451  {
1452  NS_ASSERT_MSG(false, "Invalid CCA mode");
1453  }
1454 
1455  NS_LOG_LOGIC(this << "channel sensed state: " << sensedChannelState);
1456 
1458  {
1459  m_plmeCcaConfirmCallback(sensedChannelState);
1460  }
1461 }
1462 
1463 void
1465 {
1466  NS_LOG_FUNCTION(this);
1467 
1472 
1474  {
1476  }
1477 }
1478 
1479 void
1481 {
1482  NS_LOG_FUNCTION(this);
1483 
1486 
1487  if (m_currentTxPacket.second == false)
1488  {
1489  NS_LOG_DEBUG("Packet successfully transmitted");
1492  {
1494  }
1495  }
1496  else
1497  {
1498  NS_LOG_DEBUG("Packet transmission aborted");
1501  {
1502  // See if this is ever entered in another state
1505  }
1506  }
1507  m_currentTxPacket.first = nullptr;
1508  m_currentTxPacket.second = false;
1509 
1510  // We may be waiting to apply a pending state change.
1512  {
1513  // Only change the state immediately, if the transceiver is not already
1514  // switching the state.
1515  if (!m_setTRXState.IsRunning())
1516  {
1517  NS_LOG_LOGIC("Apply pending state change to " << m_trxStatePending);
1521  {
1523  }
1524  }
1525  }
1526  else
1527  {
1529  {
1531  }
1532  }
1533 }
1534 
1535 Time
1537 {
1538  NS_LOG_FUNCTION(this << packet);
1539 
1540  bool isData = true;
1541  Time txTime = GetPpduHeaderTxTime();
1542 
1543  txTime += Seconds(packet->GetSize() * 8.0 / GetDataOrSymbolRate(isData));
1544 
1545  return txTime;
1546 }
1547 
1548 uint8_t
1550 {
1552 }
1553 
1554 uint8_t
1556 {
1558 }
1559 
1560 double
1562 {
1563  NS_LOG_FUNCTION(this << isData);
1564 
1565  double rate = 0.0;
1566 
1568 
1569  if (isData)
1570  {
1572  }
1573  else
1574  {
1576  }
1577 
1578  return (rate * 1000.0);
1579 }
1580 
1581 Time
1583 {
1584  NS_LOG_FUNCTION(this);
1585 
1586  bool isData = false;
1587  double totalPpduHdrSymbols;
1588 
1590 
1591  totalPpduHdrSymbols = ppduHeaderSymbolNumbers[m_phyOption].shrPreamble +
1594 
1595  return Seconds(totalPpduHdrSymbols / GetDataOrSymbolRate(isData));
1596 }
1597 
1598 void
1600 {
1601  NS_LOG_FUNCTION(this);
1602 
1604 
1605  // TODO: Only O-QPSK 2.4GHz is supported in the LrWpanSpectrumModel
1606  // we must limit the page until support for other modulations is added to the spectrum
1607  // model.
1608  NS_ABORT_MSG_UNLESS(phyOption == IEEE_802_15_4_2_4GHZ_OQPSK, " Only 2.4Ghz O-QPSK supported.");
1609 
1610  // Set default Channel and Page
1611  // IEEE 802.15.4-2006 Table 2, section 6.1.1
1612  // IEEE 802.15.4c-2009 Table 2, section 6.1.2.2
1613  // IEEE 802.15.4d-2009 Table 2, section 6.1.2.2
1614  switch (phyOption)
1615  {
1617  // IEEE 802.15.4-2006 868 MHz BPSK (Page 0, Channel 0)
1620  break;
1622  // IEEE 802.15.4-2006 915 MHz BPSK (Page 0, Channels 1 to 10)
1625  break;
1627  // IEEE 802.15.4d-2009 950 MHz BPSK (Page 6, Channels 0 to 9)
1630  break;
1632  // IEEE 802.15.4-2006 868 MHz ASK (Page 1, Channel 0)
1635  break;
1637  // IEEE 802.15.4-2006 915 MHz ASK (Page 1, Channel 1 to 10)
1640  break;
1642  // IEEE 802.15.4c-2009 780 MHz O-QPSK (Page 5, Channel 0 to 3)
1645  break;
1647  // IEEE 802.15.4-2006 868 MHz O-QPSK (Page 2, Channel 0)
1650  break;
1652  // IEEE 802.15.4-2006 915 MHz O-QPSK (Page 2, Channels 1 to 10)
1655  break;
1657  // IEEE 802.15.4-2009 2.4 GHz O-QPSK (Page 0, Channels 11 to 26)
1660  break;
1662  // IEEE 802.15.4-2006 Use Non-Registered Page and channel
1665  break;
1666  }
1667 
1669 
1670  m_phyOption = phyOption;
1671  // TODO: Fix/Update list when more modulations are supported.
1672  // IEEE 802.15.4-2006, Table 23
1673  // 5 MSB = Page number, 27 LSB = Supported Channels (1= supported, 0 Not supported)
1674  // Currently only page 0, channels 11-26 supported.
1676  0x7FFF800; // Page 0 should support, Channels 0 to 26 (0x07FFFFFF)
1677 
1678  for (int i = 1; i <= 31; i++)
1679  {
1680  // Page 1 to 31, No support (Page set to 31, all channels 0)
1681  m_phyPIBAttributes.phyChannelsSupported[i] = 0xF8000000;
1682  }
1683 
1684  m_edPower.averagePower = 0.0;
1685  m_edPower.lastUpdate = Seconds(0.0);
1687 
1688  // TODO: Change the limits Rx sensitivity when other modulations are supported
1689  // Currently, only O-QPSK 250kbps is supported and its maximum possible sensitivity is
1690  // equal to -106.58 dBm and its minimum sensitivity is defined as -85 dBm
1691  SetRxSensitivity(-106.58);
1692 
1693  m_rxLastUpdate = Seconds(0);
1694  Ptr<Packet> none_packet = nullptr;
1695  Ptr<LrWpanSpectrumSignalParameters> none_params = nullptr;
1696  m_currentRxPacket = std::make_pair(none_params, true);
1697  m_currentTxPacket = std::make_pair(none_packet, true);
1698  m_errorModel = nullptr;
1699 }
1700 
1701 void
1702 LrWpanPhy::SetRxSensitivity(double dbmSensitivity)
1703 {
1704  NS_LOG_FUNCTION(this << dbmSensitivity << "dBm");
1705 
1706  // 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
1708  {
1709  if (dbmSensitivity > -92)
1710  {
1711  NS_ABORT_MSG("The minimum Rx sensitivity for this band should be at least -92 dBm");
1712  }
1713  }
1714  else
1715  {
1716  if (dbmSensitivity > -85)
1717  {
1718  NS_ABORT_MSG("The minimum Rx sensitivity for this band should be at least -85 dBm");
1719  }
1720  }
1721 
1722  // Calculate the noise factor required to reduce the Rx sensitivity.
1723  // The maximum possible sensitivity in the current modulation is used as a reference
1724  // to calculate the noise factor (F). The noise factor is a dimensionless ratio.
1725  // Currently only one PHY modulation is supported:
1726  // O-QPSK 250kpps which has a Max Rx sensitivity: -106.58 dBm (Noise factor = 1).
1727  // After Rx sensitivity is set, this becomes the new point where PER < 1 % for a
1728  // PSDU of 20 bytes as described by the standard.
1729 
1730  // TODO: recalculate maxRxSensitivity (Noise factor = 1) when additional modulations are
1731  // supported.
1732  double maxRxSensitivityW = DbmToW(-106.58);
1733 
1734  LrWpanSpectrumValueHelper psdHelper;
1738  // Update thermal noise + noise factor added.
1739  long double noiseFactor = DbmToW(dbmSensitivity) / maxRxSensitivityW;
1740  psdHelper.SetNoiseFactor(noiseFactor);
1742 
1743  m_signal = Create<LrWpanInterferenceHelper>(m_noise->GetSpectrumModel());
1744  // Change receiver sensitivity from dBm to Watts
1745  m_rxSensitivity = DbmToW(dbmSensitivity);
1746 }
1747 
1748 double
1750 {
1751  NS_LOG_FUNCTION(this);
1752  // Change receiver sensitivity from Watt to dBm
1753  return WToDbm(m_rxSensitivity);
1754 }
1755 
1758 {
1759  NS_LOG_FUNCTION(this);
1760  return m_phyOption;
1761 }
1762 
1763 void
1765 {
1766  NS_LOG_FUNCTION(this << txPsd);
1767  NS_ASSERT(txPsd);
1768  m_txPsd = txPsd;
1769  NS_LOG_INFO("\t computed tx_psd: " << *txPsd << "\t stored tx_psd: " << *m_txPsd);
1770 }
1771 
1772 void
1774 {
1775  NS_LOG_FUNCTION(this << noisePsd);
1776  NS_LOG_INFO("\t computed noise_psd: " << *noisePsd);
1777  NS_ASSERT(noisePsd);
1778  m_noise = noisePsd;
1779 }
1780 
1783 {
1784  NS_LOG_FUNCTION(this);
1785  return m_noise;
1786 }
1787 
1788 void
1790 {
1791  NS_LOG_FUNCTION(this << e);
1792  NS_ASSERT(e);
1793  m_errorModel = e;
1794 }
1795 
1798 {
1799  NS_LOG_FUNCTION(this);
1800  return m_errorModel;
1801 }
1802 
1803 uint64_t
1805 {
1806  NS_LOG_FUNCTION(this);
1808 
1811 }
1812 
1813 double
1815 {
1816  NS_LOG_FUNCTION(this);
1818 
1820 }
1821 
1822 double
1824 {
1825  double powerWatts =
1828  return WToDbm(powerWatts);
1829 }
1830 
1831 int8_t
1833 {
1835 
1836  // The nominal Tx power is stored in the PIB as a 6-bit
1837  // twos-complement, signed number.
1838 
1839  // The 5 LSBs can be copied - as their representation
1840  // is the same for unsigned and signed integers.
1841  int8_t nominalTxPower = phyTransmitPower & 0x1F;
1842 
1843  // Now check the 6th LSB (the "sign" bit).
1844  // It's a twos-complement format, so the "sign"
1845  // bit represents -2^5 = -32.
1846  if (phyTransmitPower & 0x20)
1847  {
1848  nominalTxPower -= 32;
1849  }
1850  return nominalTxPower;
1851 }
1852 
1853 double
1854 LrWpanPhy::WToDbm(double watt)
1855 {
1856  return (10 * log10(1000 * watt));
1857 }
1858 
1859 double
1861 {
1862  return (pow(10.0, dbm / 10.0) / 1000.0);
1863 }
1864 
1865 int64_t
1867 {
1868  NS_LOG_FUNCTION(this);
1869  m_random->SetStream(stream);
1870  return 1;
1871 }
1872 
1873 void
1875 {
1876  NS_LOG_FUNCTION(this << em);
1878 }
1879 
1880 } // namespace ns3
#define max(a, b)
Definition: 80211b.c:43
bool IsNull() const
Check for null implementation.
Definition: callback.h:572
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:251
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:91
Ptr< const SpectrumValue > m_noise
The spectral density for for the noise.
Definition: lr-wpan-phy.h:789
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:922
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:957
Ptr< SpectrumValue > m_txPsd
The transmit power spectral density.
Definition: lr-wpan-phy.h:784
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:854
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:779
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:770
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:737
Ptr< UniformRandomVariable > m_random
Uniform random variable stream.
Definition: lr-wpan-phy.h:932
TracedValue< LrWpanPhyEnumeration > m_trxState
The current transceiver state.
Definition: lr-wpan-phy.h:805
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:684
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:498
PlmeCcaConfirmCallback m_plmeCcaConfirmCallback
This callback is used to report CCA status to the MAC or CSMA/CA.
Definition: lr-wpan-phy.h:830
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:769
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:600
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:934
Ptr< LrWpanErrorModel > m_errorModel
The error model describing the bit and packet error rates.
Definition: lr-wpan-phy.h:794
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.
Definition: lr-wpan-phy.cc:975
void DoInitialize() override
Initialize() implementation.
Definition: lr-wpan-phy.cc:174
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:836
std::pair< Ptr< LrWpanSpectrumSignalParameters >, bool > m_currentRxPacket
Statusinformation of the currently received packet.
Definition: lr-wpan-phy.h:899
EventId m_ccaRequest
Scheduler event of a currently running CCA request.
Definition: lr-wpan-phy.h:912
void CheckInterference()
Check if the interference destroys a frame currently received.
Definition: lr-wpan-phy.cc:448
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:864
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
Statusinformation of the currently transmitted packet.
Definition: lr-wpan-phy.h:907
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:708
void SetMobility(Ptr< MobilityModel > m) override
Set the mobility model associated with this device.
Definition: lr-wpan-phy.cc:263
Ptr< SpectrumChannel > m_channel
The channel attached to this transceiver.
Definition: lr-wpan-phy.h:774
PdDataConfirmCallback m_pdDataConfirmCallback
This callback is used to report packet transmission status to the MAC layer.
Definition: lr-wpan-phy.h:824
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:676
Ptr< MobilityModel > m_mobility
The mobility model used by the PHY.
Definition: lr-wpan-phy.h:764
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:869
LrWpanPhyOption m_phyOption
The currently configured PHY type.
Definition: lr-wpan-phy.h:859
EventId m_edRequest
Scheduler event of a currently running ED request.
Definition: lr-wpan-phy.h:917
LrWpanPhyPibAttributes m_phyPIBAttributes
The current PHY PIB attributes.
Definition: lr-wpan-phy.h:799
double m_rxSensitivity
The receiver sensitivity.
Definition: lr-wpan-phy.h:874
LrWpanPhyEnumeration m_trxStatePending
The next pending state to applied after the current action of the PHY is completed.
Definition: lr-wpan-phy.h:811
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:886
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:249
PdDataIndicationCallback m_pdDataIndicationCallback
This callback is used to notify incoming packets to the MAC layer.
Definition: lr-wpan-phy.h:818
Time GetPpduHeaderTxTime()
Calculate the time required for sending the PPDU header, that is the preamble, SFD and PHR.
void DoDispose() override
Destructor implementation.
Definition: lr-wpan-phy.cc:199
~LrWpanPhy() override
Definition: lr-wpan-phy.cc:169
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:715
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:270
void CcaCancel()
Cancel an ongoing CCA request.
Definition: lr-wpan-phy.cc:703
PlmeSetTRXStateConfirmCallback m_plmeSetTRXStateConfirmCallback
This callback is used to report transceiver state change status to the MAC.
Definition: lr-wpan-phy.h:848
void PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier id, LrWpanPhyPibAttributes *attribute)
IEEE 802.15.4-2006 section 6.2.2.9 PLME-SET.request Set attributes per definition from Table 23 in se...
Definition: lr-wpan-phy.cc:998
PlmeGetAttributeConfirmCallback m_plmeGetAttributeConfirmCallback
This callback is used to report requested attribute values back to the MAC.
Definition: lr-wpan-phy.h:842
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:927
Ptr< NetDevice > GetDevice() const override
Get the associated NetDevice instance.
Definition: lr-wpan-phy.cc:242
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:710
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:692
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:700
bool m_isRxCanceled
Indicates if the reception of frame has been canceled.
Definition: lr-wpan-phy.h:879
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:891
Ptr< SpectrumChannel > GetChannel()
Get the currently attached channel.
Definition: lr-wpan-phy.cc:277
TracedCallback< Time, LrWpanPhyEnumeration, LrWpanPhyEnumeration > m_trxStateLogger
The trace source fired when the phy layer changes the transceiver state.
Definition: lr-wpan-phy.h:725
void StartRx(Ptr< SpectrumSignalParameters > params) override
Notify the SpectrumPhy instance of an incoming waveform.
Definition: lr-wpan-phy.cc:312
LrWpanPhy()
Default constructor.
Definition: lr-wpan-phy.cc:148
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:676
void SetDevice(Ptr< NetDevice > d) override
Set the associated NetDevice instance.
Definition: lr-wpan-phy.cc:256
void CancelEd(LrWpanPhyEnumeration state)
Cancel an ongoing ED procedure.
void SetAntenna(Ptr< AntennaModel > a)
Set the attached antenna.
Definition: lr-wpan-phy.cc:305
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:298
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:284
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:200
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:986
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:863
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:1002
bool ReplacePacketTag(Tag &tag)
Replace the value of a packet tag.
Definition: packet.cc:994
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
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:568
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
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:444
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
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
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: pointer.h:231
Callback< R, Args... > MakeNullCallback()
Definition: callback.h:750
#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:89
LrWpanPhyEnumeration
IEEE802.15.4-2006 PHY Emumerations Table 18 in section 6.2.3.
Definition: lr-wpan-phy.h:109
LrWpanPibAttributeIdentifier
IEEE802.15.4-2006 PHY PIB Attribute Identifiers Table 23 in section 6.4.2.
Definition: lr-wpan-phy.h:143
@ IEEE_802_15_4_868MHZ_BPSK
Definition: lr-wpan-phy.h:90
@ IEEE_802_15_4_915MHZ_OQPSK
Definition: lr-wpan-phy.h:97
@ IEEE_802_15_4_868MHZ_ASK
Definition: lr-wpan-phy.h:93
@ IEEE_802_15_4_950MHZ_BPSK
Definition: lr-wpan-phy.h:92
@ IEEE_802_15_4_868MHZ_OQPSK
Definition: lr-wpan-phy.h:96
@ IEEE_802_15_4_780MHZ_OQPSK
Definition: lr-wpan-phy.h:95
@ IEEE_802_15_4_2_4GHZ_OQPSK
Definition: lr-wpan-phy.h:98
@ IEEE_802_15_4_915MHZ_ASK
Definition: lr-wpan-phy.h:94
@ IEEE_802_15_4_915MHZ_BPSK
Definition: lr-wpan-phy.h:91
@ IEEE_802_15_4_INVALID_PHY_OPTION
Definition: lr-wpan-phy.h:99
@ IEEE_802_15_4_PHY_BUSY_RX
Definition: lr-wpan-phy.h:111
@ IEEE_802_15_4_PHY_UNSUPPORTED_ATTRIBUTE
Definition: lr-wpan-phy.h:120
@ IEEE_802_15_4_PHY_BUSY
Definition: lr-wpan-phy.h:110
@ IEEE_802_15_4_PHY_SUCCESS
Definition: lr-wpan-phy.h:117
@ IEEE_802_15_4_PHY_UNSPECIFIED
Definition: lr-wpan-phy.h:122
@ IEEE_802_15_4_PHY_TRX_OFF
Definition: lr-wpan-phy.h:118
@ IEEE_802_15_4_PHY_FORCE_TRX_OFF
Definition: lr-wpan-phy.h:113
@ IEEE_802_15_4_PHY_BUSY_TX
Definition: lr-wpan-phy.h:112
@ IEEE_802_15_4_PHY_RX_ON
Definition: lr-wpan-phy.h:116
@ IEEE_802_15_4_PHY_TX_ON
Definition: lr-wpan-phy.h:119
@ IEEE_802_15_4_PHY_INVALID_PARAMETER
Definition: lr-wpan-phy.h:115
@ IEEE_802_15_4_PHY_IDLE
Definition: lr-wpan-phy.h:114
@ phyMaxFrameDuration
Definition: lr-wpan-phy.h:149
@ phyChannelsSupported
Definition: lr-wpan-phy.h:145
@ phyCurrentChannel
Definition: lr-wpan-phy.h:144
@ phyCurrentPage
Definition: lr-wpan-phy.h:148
@ phyCCAMode
Definition: lr-wpan-phy.h:147
@ phySymbolsPerOctet
Definition: lr-wpan-phy.h:151
@ phySHRDuration
Definition: lr-wpan-phy.h:150
@ phyTransmitPower
Definition: lr-wpan-phy.h:146
#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:1336
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.
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
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:81
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:53
Time lastUpdate
Last update time.
Definition: lr-wpan-phy.h:54
Time measurementLength
Total measurement period.
Definition: lr-wpan-phy.h:55
This data structure provides the Bit rate and Symbol rate for a given channel See IEEE802....
Definition: lr-wpan-phy.h:65
double symbolRate
symbol rate
Definition: lr-wpan-phy.h:67
IEEE802.15.4-2006 PHY PIB Attributes Table 23 in section 6.4.2.
Definition: lr-wpan-phy.h:160
uint32_t phyChannelsSupported[32]
BitField representing the available channels supported by a channel page.
Definition: lr-wpan-phy.h:162
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:164
uint8_t phyCCAMode
CCA mode.
Definition: lr-wpan-phy.h:166
uint8_t phyCurrentPage
Current channel page.
Definition: lr-wpan-phy.h:167
uint8_t phyCurrentChannel
The RF channel to use.
Definition: lr-wpan-phy.h:161
This data structure provides number of symbols for the PPDU headers: SHR and PHR See IEEE802....
Definition: lr-wpan-phy.h:77
double shrSfd
Number of symbols for the SHR SFD.
Definition: lr-wpan-phy.h:79
double phr
Number of symbols for the PHR.
Definition: lr-wpan-phy.h:80
double shrPreamble
Number of symbols for the SHR preamble.
Definition: lr-wpan-phy.h:78
Time duration
The duration of the packet transmission.
Ptr< SpectrumValue > psd
The Power Spectral Density of the waveform, in linear units.