A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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
46namespace ns3
47{
48
49NS_LOG_COMPONENT_DEFINE("LrWpanPhy");
50
52
53/**
54 * The data and symbol rates for the different PHY options.
55 * See Table 1 in section 6.1.1 IEEE 802.15.4-2006, IEEE 802.15.4c-2009, IEEE 802.15.4d-2009.
56 * Bit rate is in kbit/s. Symbol rate is in ksymbol/s.
57 * The index follows LrWpanPhyOption (kb/s and ksymbol/s)
58 */
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
71/**
72 * The preamble, SFD, and PHR lengths in symbols for the different PHY options.
73 * See Table 19 and Table 20 in section 6.3 IEEE 802.15.4-2006, IEEE 802.15.4c-2009, IEEE
74 * 802.15.4d-2009.
75 * The PHR is 1 octet and it follows phySymbolsPerOctet in Table 23.
76 * The index follows LrWpanPhyOption.
77 */
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
90std::ostream&
91operator<<(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
138std::ostream&
139operator<<(std::ostream& os, const TracedValue<LrWpanPhyEnumeration>& state)
140{
141 LrWpanPhyEnumeration s = state;
142 return os << s;
143};
144
145TypeId
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
228void
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 {
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
253void
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;
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
308void
310{
311 NS_LOG_FUNCTION(this << d);
312 m_device = d;
313}
314
315void
317{
318 NS_LOG_FUNCTION(this << m);
319 m_mobility = m;
320}
321
322void
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
356void
358{
359 NS_LOG_FUNCTION(this << a);
360 m_antenna = a;
361}
362
363void
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();
376 m_edPower.lastUpdate = now;
377 }
378
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 =
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 {
455 }
456 }
458 {
459 // Drop the new packet.
460 NS_LOG_DEBUG(this << " packet collision");
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");
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
499void
501{
502 // Calculate whether packet was lost.
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.
529 LrWpanLqiTag tag(std::numeric_limits<uint8_t>::max());
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
549void
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();
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.
597 LrWpanLqiTag tag(std::numeric_limits<uint8_t>::max());
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
634void
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.
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
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
706 return;
707 }
708}
709
710void
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
737void
739{
740 NS_LOG_FUNCTION(this);
742}
743
744void
746{
747 NS_LOG_FUNCTION(this);
749 {
750 // Average over the powers of all signals received until EndEd()
755 }
756 else
757 {
760 {
762 }
763
765 {
766 m_plmeEdConfirmCallback(result, 0);
767 }
768 }
769}
770
771void
773{
774 NS_LOG_FUNCTION(this << id);
776 Ptr<LrWpanPhyPibAttributes> attributes = Create<LrWpanPhyPibAttributes>();
777
778 switch (id)
779 {
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;
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
804void
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
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
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
992bool
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
1010bool
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
1033void
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 }
1091 {
1092 // 915 MHz BPSK
1094 NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1095 << ",915 MHz BPSK PHY SET");
1096 }
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 }
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 "
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 }
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 "
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 "
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 "
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
1307void
1309{
1310 NS_LOG_FUNCTION(this);
1312}
1313
1314void
1316{
1317 NS_LOG_FUNCTION(this);
1319}
1320
1321void
1323{
1324 NS_LOG_FUNCTION(this);
1326}
1327
1328void
1330{
1331 NS_LOG_FUNCTION(this);
1333}
1334
1335void
1337{
1338 NS_LOG_FUNCTION(this);
1340}
1341
1342void
1344{
1345 NS_LOG_FUNCTION(this);
1347}
1348
1349void
1351{
1352 NS_LOG_FUNCTION(this);
1354}
1355
1356void
1358{
1359 NS_LOG_LOGIC(this << " state: " << m_trxState << " -> " << newState);
1360
1362 m_trxState = newState;
1363}
1364
1365bool
1367{
1368 NS_LOG_FUNCTION(this << m_trxState);
1371}
1372
1373void
1375{
1376 NS_LOG_FUNCTION(this);
1378
1379 if (!m_edRequest.IsExpired())
1380 {
1383 {
1384 m_plmeEdConfirmCallback(state, 0);
1385 }
1386 }
1387}
1388
1389void
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
1425void
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
1500void
1502{
1503 NS_LOG_FUNCTION(this);
1504
1509
1511 {
1513 }
1514}
1515
1516void
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
1572Time
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
1585uint8_t
1587{
1589}
1590
1591uint8_t
1593{
1595}
1596
1597double
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
1616Time
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
1633void
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)
1717 }
1718
1719 m_edPower.averagePower = 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
1729 m_currentRxPacket = std::make_pair(nullptr, true);
1730 m_currentTxPacket = std::make_pair(nullptr, true);
1731 m_errorModel = nullptr;
1732}
1733
1734void
1735LrWpanPhy::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
1781double
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
1796void
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
1805void
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
1821void
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
1836uint64_t
1838{
1839 NS_LOG_FUNCTION(this);
1841
1844}
1845
1846double
1848{
1849 NS_LOG_FUNCTION(this);
1851
1853}
1854
1855double
1857{
1858 double powerWatts =
1861 return WToDbm(powerWatts);
1862}
1863
1864int8_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
1886double
1888{
1889 return (10 * log10(1000 * watt));
1890}
1891
1892double
1894{
1895 return (pow(10.0, dbm / 10.0) / 1000.0);
1896}
1897
1898int64_t
1900{
1901 NS_LOG_FUNCTION(this);
1902 m_random->SetStream(stream);
1903 return 1;
1904}
1905
1906void
1908{
1909 NS_LOG_FUNCTION(this << em);
1911}
1912
1913} // namespace ns3
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:211
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:444
AttributeValue implementation for Pointer.
Definition: pointer.h:48
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
Trace classes with value semantics.
Definition: traced-value.h:116
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
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)
Definition: pointer.h:259
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.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:159
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
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