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{
48namespace lrwpan
49{
50
51NS_LOG_COMPONENT_DEFINE("LrWpanPhy");
53
54/**
55 * The data and symbol rates for the different PHY options.
56 * See Table 1 in section 6.1.1 IEEE 802.15.4-2006, IEEE 802.15.4c-2009, IEEE 802.15.4d-2009.
57 * Bit rate is in kbit/s. Symbol rate is in ksymbol/s.
58 * The index follows LrWpanPhyOption (kb/s and ksymbol/s)
59 */
61 {20.0, 20.0},
62 {40.0, 40.0},
63 {20.0, 20.0},
64 {250.0, 12.5},
65 {250.0, 50.0},
66 {250.0, 62.5},
67 {100.0, 25.0},
68 {250.0, 62.5},
69 {250.0, 62.5},
70};
71
72/**
73 * The preamble, SFD, and PHR lengths in symbols for the different PHY options.
74 * See Table 19 and Table 20 in section 6.3 IEEE 802.15.4-2006, IEEE 802.15.4c-2009, IEEE
75 * 802.15.4d-2009.
76 * The PHR is 1 octet and it follows phySymbolsPerOctet in Table 23.
77 * The index follows LrWpanPhyOption.
78 */
80 {32.0, 8.0, 8.0},
81 {32.0, 8.0, 8.0},
82 {32.0, 8.0, 8.0},
83 {2.0, 1.0, 0.4},
84 {6.0, 1.0, 1.6},
85 {8.0, 2.0, 2.0},
86 {8.0, 2.0, 2.0},
87 {8.0, 2.0, 2.0},
88 {8.0, 2.0, 2.0},
89};
90
91std::ostream&
92operator<<(std::ostream& os, const PhyEnumeration& state)
93{
94 switch (state)
95 {
97 os << "BUSY";
98 break;
100 os << "BUSY_RX";
101 break;
103 os << "BUSY_TX";
104 break;
106 os << "FORCE_TRX_OFF";
107 break;
109 os << "IDLE";
110 break;
112 os << "INVALID_PARAMETER";
113 break;
115 os << "RX_ON";
116 break;
118 os << "SUCCESS";
119 break;
121 os << "TRX_OFF";
122 break;
124 os << "TX_ON";
125 break;
127 os << "UNSUPPORTED";
128 break;
130 os << "READ_ONLY";
131 break;
133 os << "UNSPECIFIED";
134 break;
135 }
136 return os;
137};
138
139std::ostream&
140operator<<(std::ostream& os, const TracedValue<PhyEnumeration>& state)
141{
142 PhyEnumeration s = state;
143 return os << s;
144};
145
146TypeId
148{
149 static TypeId tid =
150 TypeId("ns3::LrWpanPhy")
152 .SetGroupName("LrWpan")
153 .AddConstructor<LrWpanPhy>()
154 .AddAttribute("PostReceptionErrorModel",
155 "An optional packet error model can be added to the receive "
156 "packet process after any propagation-based (SNR-based) error "
157 "models have been applied. Typically this is used to force "
158 "specific packet drops, for testing purposes.",
159 PointerValue(),
161 MakePointerChecker<ErrorModel>())
162 .AddTraceSource("TrxStateValue",
163 "The state of the transceiver",
165 "ns3::TracedValueCallback::LrWpanPhyEnumeration")
166 .AddTraceSource("TrxState",
167 "The state of the transceiver",
169 "ns3::LrWpanPhy::StateTracedCallback")
170 .AddTraceSource("PhyTxBegin",
171 "Trace source indicating a packet has "
172 "begun transmitting over the channel medium",
174 "ns3::Packet::TracedCallback")
175 .AddTraceSource("PhyTxEnd",
176 "Trace source indicating a packet has been "
177 "completely transmitted over the channel.",
179 "ns3::Packet::TracedCallback")
180 .AddTraceSource("PhyTxDrop",
181 "Trace source indicating a packet has been "
182 "dropped by the device during transmission",
184 "ns3::Packet::TracedCallback")
185 .AddTraceSource("PhyRxBegin",
186 "Trace source indicating a packet has begun "
187 "being received from the channel medium by the device",
189 "ns3::Packet::TracedCallback")
190 .AddTraceSource("PhyRxEnd",
191 "Trace source indicating a packet has been "
192 "completely received from the channel medium "
193 "by the device",
195 "ns3::Packet::SinrTracedCallback")
196 .AddTraceSource("PhyRxDrop",
197 "Trace source indicating a packet has been "
198 "dropped by the device during reception",
200 "ns3::Packet::TracedCallback");
201 return tid;
202}
203
205 : m_edRequest(),
206 m_setTRXState()
207{
210
211 // default PHY PIB attributes
214
216
217 m_random = CreateObject<UniformRandomVariable>();
218 m_random->SetAttribute("Min", DoubleValue(0.0));
219 m_random->SetAttribute("Max", DoubleValue(1.0));
220
221 m_isRxCanceled = false;
223}
224
226{
227}
228
229void
231{
232 NS_LOG_FUNCTION(this);
233
234 // This method ensures that the local mobility model pointer holds
235 // a pointer to the Node's aggregated mobility model (if one exists)
236 // in the case that the user has not directly called SetMobility()
237 // on this LrWpanPhy during simulation setup. If the mobility model
238 // needs to be added or changed during simulation runtime, users must
239 // call SetMobility() on this object.
240
241 if (!m_mobility)
242 {
244 "Either install a MobilityModel on this object or ensure that this "
245 "object is part of a Node and NetDevice");
246 m_mobility = m_device->GetNode()->GetObject<MobilityModel>();
247 if (!m_mobility)
248 {
249 NS_LOG_WARN("Mobility not found, propagation models might not work properly");
250 }
251 }
252}
253
254void
256{
257 NS_LOG_FUNCTION(this);
258
259 // Cancel pending transceiver state change, if one is in progress.
263
264 m_mobility = nullptr;
265 m_device = nullptr;
266 m_channel = nullptr;
267 m_antenna = nullptr;
268 m_txPsd = nullptr;
269 m_noise = nullptr;
270 m_signal = nullptr;
271 m_errorModel = nullptr;
272 m_currentRxPacket.first = nullptr;
273 m_currentTxPacket.first = nullptr;
275
280
281 m_random = nullptr;
282 m_pdDataIndicationCallback = MakeNullCallback<void, uint32_t, Ptr<Packet>, uint8_t>();
283 m_pdDataConfirmCallback = MakeNullCallback<void, PhyEnumeration>();
284 m_plmeCcaConfirmCallback = MakeNullCallback<void, PhyEnumeration>();
285 m_plmeEdConfirmCallback = MakeNullCallback<void, PhyEnumeration, uint8_t>();
287 MakeNullCallback<void, PhyEnumeration, PhyPibAttributeIdentifier, Ptr<PhyPibAttributes>>();
288 m_plmeSetTRXStateConfirmCallback = MakeNullCallback<void, PhyEnumeration>();
290 MakeNullCallback<void, PhyEnumeration, PhyPibAttributeIdentifier>();
291
293}
294
297{
298 return m_device;
299}
300
303{
304 return m_mobility;
305}
306
307void
309{
310 NS_LOG_FUNCTION(this << d);
311 m_device = d;
312}
313
314void
316{
317 NS_LOG_FUNCTION(this << m);
318 m_mobility = m;
319}
320
321void
323{
324 NS_LOG_FUNCTION(this << c);
325 m_channel = c;
326}
327
330{
331 NS_LOG_FUNCTION(this);
332 return m_channel;
333}
334
337{
338 NS_LOG_FUNCTION(this);
339 if (m_txPsd)
340 {
341 return m_txPsd->GetSpectrumModel();
342 }
343 else
344 {
345 return nullptr;
346 }
347}
348
351{
352 return m_antenna;
353}
354
355void
357{
358 NS_LOG_FUNCTION(this << a);
359 m_antenna = a;
360}
361
362void
364{
365 NS_LOG_FUNCTION(this << spectrumRxParams);
366
367 if (!m_edRequest.IsExpired())
368 {
369 // Update the average receive power during ED.
370 Time now = Simulator::Now();
375 m_edPower.lastUpdate = now;
376 }
377
379 DynamicCast<LrWpanSpectrumSignalParameters>(spectrumRxParams);
380
381 if (!lrWpanRxParams)
382 {
384 m_signal->AddSignal(spectrumRxParams->psd);
385
386 // Update peak power if CCA is in progress.
387 if (!m_ccaRequest.IsExpired())
388 {
389 double power =
392 if (m_ccaPeakPower < power)
393 {
394 m_ccaPeakPower = power;
395 }
396 }
397
398 Simulator::Schedule(spectrumRxParams->duration, &LrWpanPhy::EndRx, this, spectrumRxParams);
399 return;
400 }
401
402 Ptr<Packet> p = (lrWpanRxParams->packetBurst->GetPackets()).front();
403 NS_ASSERT(p);
404
405 // Prevent PHY from receiving another packet while switching the transceiver state.
407 {
408 // The specification doesn't seem to refer to BUSY_RX, but vendor
409 // data sheets suggest that this is a substate of the RX_ON state
410 // that is entered after preamble detection when the digital receiver
411 // is enabled. Here, for now, we use BUSY_RX to mark the period between
412 // StartRx() and EndRx() states.
413
414 // We are going to BUSY_RX state when receiving the first bit of an SHR,
415 // as opposed to real receivers, which should go to this state only after
416 // successfully receiving the SHR.
417
418 // If synchronizing to the packet is possible, change to BUSY_RX state,
419 // otherwise drop the packet and stay in RX state. The actual synchronization
420 // is not modeled.
421
422 // Add any incoming packet to the current interference before checking the
423 // SINR.
424 NS_LOG_DEBUG(this << " receiving packet with power: "
426 lrWpanRxParams->psd,
428 30
429 << "dBm");
430 m_signal->AddSignal(lrWpanRxParams->psd);
431 Ptr<SpectrumValue> interferenceAndNoise = m_signal->GetSignalPsd();
432 *interferenceAndNoise -= *lrWpanRxParams->psd;
433 *interferenceAndNoise += *m_noise;
434 double sinr =
437 LrWpanSpectrumValueHelper::TotalAvgPower(interferenceAndNoise,
439
440 // Std. 802.15.4-2006, appendix E, Figure E.2
441 // At SNR < -5 the BER is less than 10e-1.
442 // It's useless to even *try* to decode the packet.
443 if (10 * log10(sinr) > -5)
444 {
446 m_currentRxPacket = std::make_pair(lrWpanRxParams, false);
448
450 }
451 else
452 {
454 }
455 }
457 {
458 // Drop the new packet.
459 NS_LOG_DEBUG(this << " packet collision");
461
462 // Check if we correctly received the old packet up to now.
464
465 // Add the incoming packet to the current interference after we have
466 // checked for successful reception of the current packet for the time
467 // before the additional interference.
468 m_signal->AddSignal(lrWpanRxParams->psd);
469 }
470 else
471 {
472 // Simply drop the packet.
473 NS_LOG_DEBUG(this << " transceiver not in RX state");
475
476 // Add the signal power to the interference, anyway.
477 m_signal->AddSignal(lrWpanRxParams->psd);
478 }
479
480 // Update peak power if CCA is in progress.
481 if (!m_ccaRequest.IsExpired())
482 {
483 double power =
486 if (m_ccaPeakPower < power)
487 {
488 m_ccaPeakPower = power;
489 }
490 }
491
492 // Always call EndRx to update the interference.
493 // We keep track of this event, and if necessary cancel this event when a TX of a packet.
494
495 Simulator::Schedule(spectrumRxParams->duration, &LrWpanPhy::EndRx, this, spectrumRxParams);
496}
497
498void
500{
501 // Calculate whether packet was lost.
504
505 // We are currently receiving a packet.
507 {
508 // NS_ASSERT (currentRxParams && !m_currentRxPacket.second);
509
510 Ptr<Packet> currentPacket = currentRxParams->packetBurst->GetPackets().front();
511 if (m_errorModel)
512 {
513 // How many bits did we receive since the last calculation?
514 double t = (Simulator::Now() - m_rxLastUpdate).ToDouble(Time::MS);
515 uint32_t chunkSize = ceil(t * (GetDataOrSymbolRate(true) / 1000));
516 Ptr<SpectrumValue> interferenceAndNoise = m_signal->GetSignalPsd();
517 *interferenceAndNoise -= *currentRxParams->psd;
518 *interferenceAndNoise += *m_noise;
519 double sinr =
520 LrWpanSpectrumValueHelper::TotalAvgPower(currentRxParams->psd,
522 LrWpanSpectrumValueHelper::TotalAvgPower(interferenceAndNoise,
524 double per = 1.0 - m_errorModel->GetChunkSuccessRate(sinr, chunkSize);
525
526 // The LQI is the total packet success rate scaled to 0-255.
527 // If not already set, initialize to 255.
528 LrWpanLqiTag tag(std::numeric_limits<uint8_t>::max());
529 currentPacket->PeekPacketTag(tag);
530 uint8_t lqi = tag.Get();
531 tag.Set(lqi - (per * lqi));
532 currentPacket->ReplacePacketTag(tag);
533
534 if (m_random->GetValue() < per)
535 {
536 // The packet was destroyed, drop the packet after reception.
537 m_currentRxPacket.second = true;
538 }
539 }
540 else
541 {
542 NS_LOG_WARN("Missing ErrorModel");
543 }
544 }
546}
547
548void
550{
551 NS_LOG_FUNCTION(this);
552
553 Ptr<LrWpanSpectrumSignalParameters> params = DynamicCast<LrWpanSpectrumSignalParameters>(par);
554
555 if (!m_edRequest.IsExpired())
556 {
557 // Update the average receive power during ED.
558 Time now = Simulator::Now();
563 m_edPower.lastUpdate = now;
564 }
565
567 if (currentRxParams == params)
568 {
570 }
571
572 // Update the interference.
573 m_signal->RemoveSignal(par->psd);
574
575 if (!params)
576 {
577 NS_LOG_LOGIC("Node: " << m_device->GetAddress()
578 << " Removing interferent: " << *(par->psd));
579 return;
580 }
581
582 // If this is the end of the currently received packet, check if reception was successful.
583 if (currentRxParams == params)
584 {
585 Ptr<Packet> currentPacket = currentRxParams->packetBurst->GetPackets().front();
586 NS_ASSERT(currentPacket);
587
589 m_postReceptionErrorModel->IsCorrupt(currentPacket->Copy()))
590 {
591 NS_LOG_DEBUG("Reception failed due to post-rx error model");
592 m_currentRxPacket.second = true;
593 }
594
595 // If there is no error model attached to the PHY, we always report the maximum LQI value.
596 LrWpanLqiTag tag(std::numeric_limits<uint8_t>::max());
597 currentPacket->PeekPacketTag(tag);
598 m_phyRxEndTrace(currentPacket, tag.Get());
599
600 if (!m_currentRxPacket.second)
601 {
602 m_currentRxPacket = std::make_pair(nullptr, true);
604 NS_LOG_DEBUG("Packet successfully received");
605
606 // The packet was successfully received, push it up the stack.
608 {
609 m_pdDataIndicationCallback(currentPacket->GetSize(), currentPacket, tag.Get());
610 }
611 }
612 else
613 {
614 // The packet was destroyed due to interference, post-rx corruption or
615 // cancelled, therefore drop it.
616 m_phyRxDropTrace(currentPacket);
617 m_currentRxPacket = std::make_pair(nullptr, true);
618
619 if (!m_isRxCanceled)
620 {
622 }
623 else
624 {
625 // The state of The PHY was already changed when the packet was canceled
626 // due to a forced operation.
627 m_isRxCanceled = false;
628 }
629 }
630 }
631}
632
633void
635{
636 NS_LOG_FUNCTION(this << psduLength << p);
637
638 if (psduLength > lrwpan::aMaxPhyPacketSize)
639 {
641 {
643 }
644 NS_LOG_DEBUG("Drop packet because psduLength too long: " << psduLength);
645 return;
646 }
647
648 // Prevent PHY from sending a packet while switching the transceiver state.
650 {
652 {
653 // send down
655
656 // Remove a possible LQI tag from a previous transmission of the packet.
657 LrWpanLqiTag lqiTag;
658 p->RemovePacketTag(lqiTag);
659
661 m_currentTxPacket.first = p;
662 m_currentTxPacket.second = false;
663
664 Ptr<LrWpanSpectrumSignalParameters> txParams = Create<LrWpanSpectrumSignalParameters>();
665 txParams->duration = CalculateTxTime(p);
666 txParams->txPhy = GetObject<SpectrumPhy>();
667 txParams->psd = m_txPsd;
668 txParams->txAntenna = m_antenna;
669 Ptr<PacketBurst> pb = CreateObject<PacketBurst>();
670 pb->AddPacket(p);
671 txParams->packetBurst = pb;
672 m_channel->StartTx(txParams);
673 m_pdDataRequest = Simulator::Schedule(txParams->duration, &LrWpanPhy::EndTx, this);
675 return;
676 }
677 else if ((m_trxState == IEEE_802_15_4_PHY_RX_ON) ||
680 {
682 {
684 }
685 // Drop packet, hit PhyTxDrop trace
687 return;
688 }
689 else
690 {
691 NS_FATAL_ERROR("This should be unreachable, or else state "
692 << m_trxState << " should be added as a case");
693 }
694 }
695 else
696 {
697 // TODO: This error code is not covered by the standard.
698 // What is the correct behavior in this case?
700 {
702 }
703 // Drop packet, hit PhyTxDrop trace
705 return;
706 }
707}
708
709void
711{
712 NS_LOG_FUNCTION(this);
713
715 {
716 m_ccaPeakPower = 0.0;
717 Time ccaTime = Seconds(8.0 / GetDataOrSymbolRate(false));
719 }
720 else
721 {
723 {
725 {
727 }
728 else
729 {
731 }
732 }
733 }
734}
735
736void
738{
739 NS_LOG_FUNCTION(this);
741}
742
743void
745{
746 NS_LOG_FUNCTION(this);
748 {
749 // Average over the powers of all signals received until EndEd()
754 }
755 else
756 {
757 PhyEnumeration result = m_trxState;
759 {
761 }
762
764 {
765 m_plmeEdConfirmCallback(result, 0);
766 }
767 }
768}
769
770void
772{
773 NS_LOG_FUNCTION(this << id);
775 Ptr<PhyPibAttributes> attributes = Create<PhyPibAttributes>();
776
777 switch (id)
778 {
780 attributes->phyCurrentChannel = m_phyPIBAttributes.phyCurrentChannel;
781 break;
782 case phyCurrentPage:
783 attributes->phyCurrentPage = m_phyPIBAttributes.phyCurrentPage;
784 break;
785 case phySHRDuration:
786 attributes->phySHRDuration = GetPhySHRDuration();
787 break;
789 attributes->phySymbolsPerOctet = GetPhySymbolsPerOctet();
790 break;
791 default:
793 break;
794 }
795
797 {
798 m_plmeGetAttributeConfirmCallback(status, id, attributes);
799 }
800}
801
802// Section 6.2.2.7.3
803void
805{
806 NS_LOG_FUNCTION(this << state);
807
808 // Check valid states (Table 14)
811
812 NS_LOG_LOGIC("Trying to set m_trxState from " << m_trxState << " to " << state);
813
814 // this method always overrides previous state setting attempts
816 {
817 if (m_trxStatePending == state)
818 {
819 // Simply wait for the ongoing state switch.
820 return;
821 }
822 else
823 {
824 NS_LOG_DEBUG("Cancel m_setTRXState");
825 // Keep the transceiver state as the old state before the switching attempt.
827 }
828 }
830 {
832 }
833
834 if (state == m_trxState)
835 {
837 {
839 }
840 return;
841 }
842
843 if (((state == IEEE_802_15_4_PHY_RX_ON) || (state == IEEE_802_15_4_PHY_TRX_OFF)) &&
845 {
846 NS_LOG_DEBUG("Phy is busy; setting state pending to " << state);
847 m_trxStatePending = state;
848 return; // Send PlmeSetTRXStateConfirm later
849 }
850
851 // specification talks about being in RX_ON and having received
852 // a valid SFD. Here, we are not modelling at that level of
853 // granularity, so we just test for BUSY_RX state (any part of
854 // a packet being actively received)
855 if (state == IEEE_802_15_4_PHY_TRX_OFF)
856 {
857 CancelEd(state);
858
860 (!m_currentRxPacket.second))
861 {
862 NS_LOG_DEBUG("Receiver has valid SFD; defer state change");
863 m_trxStatePending = state;
864 return; // Send PlmeSetTRXStateConfirm later
865 }
867 {
870 {
872 }
873 return;
874 }
875 }
876
877 if (state == IEEE_802_15_4_PHY_TX_ON)
878 {
879 CancelEd(state);
880
881 NS_LOG_DEBUG("turn on PHY_TX_ON");
883 {
884 if (m_currentRxPacket.first)
885 {
886 // TX_ON is being forced during a reception (For example, when a ACK or Beacon is
887 // issued) The current RX frame is marked as incomplete and the reception as
888 // canceled EndRx () will handle the rest accordingly
889 NS_LOG_DEBUG("force TX_ON, terminate reception");
890 m_currentRxPacket.second = true;
891 m_isRxCanceled = true;
892 }
893
894 // If CCA is in progress, cancel CCA and return BUSY.
895 if (!m_ccaRequest.IsExpired())
896 {
899 {
901 }
902 }
903
905
906 // Delay for turnaround time (BUSY_RX|RX_ON ---> TX_ON)
907 Time setTime = Seconds((double)lrwpan::aTurnaroundTime / GetDataOrSymbolRate(false));
909 return;
910 }
912 {
913 // We do NOT change the transceiver state here. We only report that
914 // the transceiver is already in TX_ON state.
916 {
918 }
919 return;
920 }
922 {
925 {
927 }
928 return;
929 }
930 }
931
933 {
935 {
936 NS_LOG_DEBUG("force TRX_OFF, was already off");
937 }
938 else
939 {
940 NS_LOG_DEBUG("force TRX_OFF, SUCCESS");
941 if (m_currentRxPacket.first)
942 {
943 // Terminate reception
944 // Mark the packet as incomplete and reception as canceled.
945 NS_LOG_DEBUG("force TRX_OFF, terminate reception");
946 m_currentRxPacket.second = true;
947 m_isRxCanceled = true;
948 }
950 {
951 NS_LOG_DEBUG("force TRX_OFF, terminate transmission");
952 m_currentTxPacket.second = true;
953 }
955 // Clear any other state
957 }
959 {
961 }
962 return;
963 }
964
965 if (state == IEEE_802_15_4_PHY_RX_ON)
966 {
968 {
969 // Turnaround delay
970 // TODO: Does it really take aTurnaroundTime to switch the transceiver state,
971 // even when the transmitter is not busy? (6.9.1)
973
974 Time setTime = Seconds((double)lrwpan::aTurnaroundTime / GetDataOrSymbolRate(false));
976 return;
977 }
979 {
981 {
983 }
984 return;
985 }
986 }
987
988 NS_FATAL_ERROR("Unexpected transition from state " << m_trxState << " to state " << state);
989}
990
991bool
993{
994 NS_LOG_FUNCTION(this << channel);
995 bool retValue = false;
996
997 // Bits 0-26 (27 LSB)
999 (1 << channel)) != 0)
1000 {
1001 return retValue = true;
1002 }
1003 else
1004 {
1005 return retValue;
1006 }
1007}
1008
1009bool
1011{
1012 NS_LOG_FUNCTION(this << +page);
1013 bool retValue = false;
1014
1015 // TODO: Only O-QPSK 2.4GHz is supported in the LrWpanSpectrumModel
1016 // we must limit the page until support for other modulation is added to the spectrum
1017 // model.
1018 //
1019 NS_ABORT_MSG_UNLESS(page == 0, " Only Page 0 (2.4Ghz O-QPSK supported).");
1020
1021 // IEEE 802.15.4-2006, Table 23 phyChannelsSupported Bits 27-31 (5 MSB)
1022 uint8_t supportedPage = (m_phyPIBAttributes.phyChannelsSupported[page] >> 27) & (0x1F);
1023
1024 if (page == supportedPage)
1025 {
1026 retValue = true;
1027 }
1028
1029 return retValue;
1030}
1031
1032void
1034{
1035 NS_LOG_FUNCTION(this << id << attribute);
1036 NS_ASSERT(attribute);
1038
1039 switch (id)
1040 {
1041 case phyCurrentPage: {
1042 if (!PageSupported(attribute->phyCurrentPage))
1043 {
1045 }
1046 else if (m_phyPIBAttributes.phyCurrentPage != attribute->phyCurrentPage)
1047 {
1048 // Cancel a pending transceiver state change.
1049 // Switch off the transceiver.
1050 // TODO: Is switching off the transceiver the right choice?
1053 {
1057 {
1059 }
1060 }
1061
1062 // Any packet in transmission or reception will be corrupted.
1063 if (m_currentRxPacket.first)
1064 {
1065 m_currentRxPacket.second = true;
1066 }
1067 if (PhyIsBusy())
1068 {
1069 m_currentTxPacket.second = true;
1071 m_currentTxPacket.first = nullptr;
1073 {
1075 }
1076 }
1077
1078 // Changing the Page can change they current PHY in use
1079 // Set the correct PHY according to the Page
1080 if (attribute->phyCurrentPage == 0)
1081 {
1083 {
1084 // 868 MHz BPSK
1086 NS_LOG_INFO("Page 0, 868 MHz BPSK PHY SET");
1087 }
1089 {
1090 // 915 MHz BPSK
1092 NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1093 << ",915 MHz BPSK PHY SET");
1094 }
1096 {
1097 // 2.4 GHz MHz O-QPSK
1099 NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1100 << ", 2.4 Ghz O-QPSK PHY SET");
1101 }
1102 }
1103 else if (attribute->phyCurrentPage == 1)
1104 {
1106 {
1107 // 868 MHz ASK
1109 NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1110 << ", 868 MHz ASK PHY SET");
1111 }
1113 {
1114 // 915 MHz ASK
1116 NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1117 << ", 915 MHz ASK PHY SET");
1118 }
1119 else
1120 {
1121 // No longer valid channel
1124 NS_LOG_INFO("Channel no longer valid in new page "
1125 << (uint32_t)attribute->phyCurrentPage
1126 << ", setting new default channel "
1128 NS_LOG_INFO("868 MHz ASK PHY SET");
1129 }
1130 }
1131 else if (attribute->phyCurrentPage == 2)
1132 {
1134 {
1135 // 868 MHz O-QPSK
1137 NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1138 << ", 868 MHz O-QPSK PHY SET");
1139 }
1141 {
1142 // 915 MHz O-QPSK
1144 NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1145 << ", 915 MHz O-QPSK PHY SET");
1146 }
1147 else
1148 {
1149 // No longer valid channel
1152 NS_LOG_INFO("Channel no longer valid in new page "
1153 << (uint32_t)attribute->phyCurrentPage
1154 << ", setting new default channel "
1156 NS_LOG_INFO("868 MHz O-QPSK PHY SET");
1157 }
1158 }
1159 else if (attribute->phyCurrentPage == 5)
1160 {
1162 {
1163 // 780 MHz O-QPSK
1165 NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1166 << ", 915 MHz O-QPSK PHY SET");
1167 }
1168 else
1169 {
1170 // No longer valid channel
1173 NS_LOG_INFO("Channel no longer valid in new page "
1174 << (uint32_t)attribute->phyCurrentPage
1175 << ", setting new default channel "
1177 NS_LOG_INFO("780 MHz O-QPSK PHY SET");
1178 }
1179 }
1180 else if (attribute->phyCurrentPage == 6)
1181 {
1183 {
1184 // 950 MHz BPSK
1186 NS_LOG_INFO("Page " << (uint32_t)attribute->phyCurrentPage
1187 << ", 950 MHz BPSK PHY SET");
1188 }
1189 else
1190 {
1193 NS_LOG_INFO("Channel no longer valid in new page "
1194 << (uint32_t)attribute->phyCurrentPage
1195 << ", setting new default channel "
1197 NS_LOG_INFO("950 MHz BPSK PHY SET");
1198 }
1199 }
1200
1201 m_phyPIBAttributes.phyCurrentPage = attribute->phyCurrentPage;
1202
1203 // TODO: Set the maximum possible sensitivity by default.
1204 // This maximum sensitivity depends on the modulation used.
1205 // Currently Only O-QPSK 250kbps is supported so we use its max sensitivity.
1206 SetRxSensitivity(-106.58);
1207 }
1208 break;
1209 }
1210 case phyCurrentChannel: {
1211 if (!ChannelSupported(attribute->phyCurrentChannel))
1212 {
1214 }
1215 if (m_phyPIBAttributes.phyCurrentChannel != attribute->phyCurrentChannel)
1216 {
1217 // Cancel a pending transceiver state change.
1218 // Switch off the transceiver.
1219 // TODO: Is switching off the transceiver the right choice?
1222 {
1226 {
1228 }
1229 }
1230
1231 // Any packet in transmission or reception will be corrupted.
1232 if (m_currentRxPacket.first)
1233 {
1234 m_currentRxPacket.second = true;
1235 }
1236 if (PhyIsBusy())
1237 {
1238 m_currentTxPacket.second = true;
1240 m_currentTxPacket.first = nullptr;
1242 {
1244 }
1245 }
1246
1247 m_phyPIBAttributes.phyCurrentChannel = attribute->phyCurrentChannel;
1248
1249 // use the prev configured sensitivity before changing the channel
1251 }
1252 break;
1253 }
1254 case phyChannelsSupported: { // only the first element is considered in the array
1255 if ((attribute->phyChannelsSupported[0] & 0xf8000000) != 0)
1256 { // 5 MSBs reserved
1258 }
1259 else
1260 {
1261 m_phyPIBAttributes.phyChannelsSupported[0] = attribute->phyChannelsSupported[0];
1262 }
1263 break;
1264 }
1265 case phyTransmitPower: {
1266 if (attribute->phyTransmitPower & 0xC0)
1267 {
1268 NS_LOG_LOGIC("LrWpanPhy::PlmeSetAttributeRequest error - can not change read-only "
1269 "attribute bits.");
1271 }
1272 else
1273 {
1274 m_phyPIBAttributes.phyTransmitPower = attribute->phyTransmitPower;
1275 LrWpanSpectrumValueHelper psdHelper;
1279 }
1280 break;
1281 }
1282 case phyCCAMode: {
1283 if ((attribute->phyCCAMode < 1) || (attribute->phyCCAMode > 3))
1284 {
1286 }
1287 else
1288 {
1289 m_phyPIBAttributes.phyCCAMode = attribute->phyCCAMode;
1290 }
1291 break;
1292 }
1293 default: {
1295 break;
1296 }
1297 }
1298
1300 {
1302 }
1303}
1304
1305void
1307{
1308 NS_LOG_FUNCTION(this);
1310}
1311
1312void
1314{
1315 NS_LOG_FUNCTION(this);
1317}
1318
1319void
1321{
1322 NS_LOG_FUNCTION(this);
1324}
1325
1326void
1328{
1329 NS_LOG_FUNCTION(this);
1331}
1332
1333void
1335{
1336 NS_LOG_FUNCTION(this);
1338}
1339
1340void
1342{
1343 NS_LOG_FUNCTION(this);
1345}
1346
1347void
1349{
1350 NS_LOG_FUNCTION(this);
1352}
1353
1354void
1356{
1357 NS_LOG_LOGIC(this << " state: " << m_trxState << " -> " << newState);
1358
1360 m_trxState = newState;
1361}
1362
1363bool
1365{
1366 NS_LOG_FUNCTION(this << m_trxState);
1369}
1370
1371void
1373{
1374 NS_LOG_FUNCTION(this);
1376
1377 if (!m_edRequest.IsExpired())
1378 {
1381 {
1382 m_plmeEdConfirmCallback(state, 0);
1383 }
1384 }
1385}
1386
1387void
1389{
1390 NS_LOG_FUNCTION(this);
1391
1395 (Simulator::Now() - m_edPower.lastUpdate).GetTimeStep() /
1397
1398 uint8_t energyLevel;
1399
1400 // Per IEEE802.15.4-2006 sec 6.9.7
1401 double ratio = m_edPower.averagePower / m_rxSensitivity;
1402 ratio = 10.0 * log10(ratio);
1403 if (ratio <= 10.0)
1404 { // less than 10 dB
1405 energyLevel = 0;
1406 }
1407 else if (ratio >= 40.0)
1408 { // less than 40 dB
1409 energyLevel = 255;
1410 }
1411 else
1412 {
1413 // in-between with linear increase per sec 6.9.7
1414 energyLevel = static_cast<uint8_t>(((ratio - 10.0) / 30.0) * 255.0);
1415 }
1416
1418 {
1420 }
1421}
1422
1423void
1425{
1426 NS_LOG_FUNCTION(this);
1427 PhyEnumeration sensedChannelState = IEEE_802_15_4_PHY_UNSPECIFIED;
1428
1429 // Update peak power.
1430 double power = LrWpanSpectrumValueHelper::TotalAvgPower(m_signal->GetSignalPsd(),
1432 if (m_ccaPeakPower < power)
1433 {
1434 m_ccaPeakPower = power;
1435 }
1436
1437 if (PhyIsBusy())
1438 {
1439 sensedChannelState = IEEE_802_15_4_PHY_BUSY;
1440 }
1441 else if (m_phyPIBAttributes.phyCCAMode == 1)
1442 { // sec 6.9.9 ED detection
1443 // -- ED threshold at most 10 dB above receiver sensitivity.
1444 if (10 * log10(m_ccaPeakPower / m_rxSensitivity) >= 10.0)
1445 {
1446 sensedChannelState = IEEE_802_15_4_PHY_BUSY;
1447 }
1448 else
1449 {
1450 sensedChannelState = IEEE_802_15_4_PHY_IDLE;
1451 }
1452 }
1453 else if (m_phyPIBAttributes.phyCCAMode == 2)
1454 {
1455 // sec 6.9.9 carrier sense only
1457 {
1458 // We currently do not model PPDU reception in detail. Instead we model
1459 // packet reception starting with the first bit of the preamble.
1460 // Therefore, this code will never be reached, as PhyIsBusy() would
1461 // already lead to a channel busy condition.
1462 // TODO: Change this, if we also model preamble and SFD detection.
1463 sensedChannelState = IEEE_802_15_4_PHY_BUSY;
1464 }
1465 else
1466 {
1467 sensedChannelState = IEEE_802_15_4_PHY_IDLE;
1468 }
1469 }
1470 else if (m_phyPIBAttributes.phyCCAMode == 3)
1471 { // sect 6.9.9 both
1472 if ((10 * log10(m_ccaPeakPower / m_rxSensitivity) >= 10.0) &&
1474 {
1475 // Again, this code will never be reached, if we are already receiving
1476 // a packet, as PhyIsBusy() would already lead to a channel busy condition.
1477 // TODO: Change this, if we also model preamble and SFD detection.
1478 sensedChannelState = IEEE_802_15_4_PHY_BUSY;
1479 }
1480 else
1481 {
1482 sensedChannelState = IEEE_802_15_4_PHY_IDLE;
1483 }
1484 }
1485 else
1486 {
1487 NS_ASSERT_MSG(false, "Invalid CCA mode");
1488 }
1489
1490 NS_LOG_LOGIC(this << "channel sensed state: " << sensedChannelState);
1491
1493 {
1494 m_plmeCcaConfirmCallback(sensedChannelState);
1495 }
1496}
1497
1498void
1500{
1501 NS_LOG_FUNCTION(this);
1502
1507
1509 {
1511 }
1512}
1513
1514void
1516{
1517 NS_LOG_FUNCTION(this);
1518
1521
1522 if (!m_currentTxPacket.second)
1523 {
1524 NS_LOG_DEBUG("Packet successfully transmitted");
1527 {
1529 }
1530 }
1531 else
1532 {
1533 NS_LOG_DEBUG("Packet transmission aborted");
1536 {
1537 // See if this is ever entered in another state
1540 }
1541 }
1542 m_currentTxPacket.first = nullptr;
1543 m_currentTxPacket.second = false;
1544
1545 // We may be waiting to apply a pending state change.
1547 {
1548 // Only change the state immediately, if the transceiver is not already
1549 // switching the state.
1550 if (!m_setTRXState.IsRunning())
1551 {
1552 NS_LOG_LOGIC("Apply pending state change to " << m_trxStatePending);
1556 {
1558 }
1559 }
1560 }
1561 else
1562 {
1564 {
1566 }
1567 }
1568}
1569
1570Time
1572{
1573 NS_LOG_FUNCTION(this << packet);
1574
1575 bool isData = true;
1576 Time txTime = GetPpduHeaderTxTime();
1577
1578 txTime += Seconds(packet->GetSize() * 8.0 / GetDataOrSymbolRate(isData));
1579
1580 return txTime;
1581}
1582
1583uint8_t
1585{
1587}
1588
1589uint8_t
1591{
1593}
1594
1595double
1597{
1598 double rate = 0.0;
1599
1601
1602 if (isData)
1603 {
1605 }
1606 else
1607 {
1609 }
1610
1611 return (rate * 1000.0);
1612}
1613
1614Time
1616{
1617 NS_LOG_FUNCTION(this);
1618
1619 bool isData = false;
1620 double totalPpduHdrSymbols;
1621
1623
1624 totalPpduHdrSymbols = ppduHeaderSymbolNumbers[m_phyOption].shrPreamble +
1627
1628 return Seconds(totalPpduHdrSymbols / GetDataOrSymbolRate(isData));
1629}
1630
1631void
1633{
1634 NS_LOG_FUNCTION(this);
1635
1637
1638 // TODO: Only O-QPSK 2.4GHz is supported in the LrWpanSpectrumModel
1639 // we must limit the page until support for other modulations is added to the spectrum
1640 // model.
1641 NS_ABORT_MSG_UNLESS(phyOption == IEEE_802_15_4_2_4GHZ_OQPSK, " Only 2.4Ghz O-QPSK supported.");
1642
1643 // Set default Channel and Page
1644 // IEEE 802.15.4-2006 Table 2, section 6.1.1
1645 // IEEE 802.15.4c-2009 Table 2, section 6.1.2.2
1646 // IEEE 802.15.4d-2009 Table 2, section 6.1.2.2
1647 switch (phyOption)
1648 {
1650 // IEEE 802.15.4-2006 868 MHz BPSK (Page 0, Channel 0)
1653 break;
1655 // IEEE 802.15.4-2006 915 MHz BPSK (Page 0, Channels 1 to 10)
1658 break;
1660 // IEEE 802.15.4d-2009 950 MHz BPSK (Page 6, Channels 0 to 9)
1663 break;
1665 // IEEE 802.15.4-2006 868 MHz ASK (Page 1, Channel 0)
1668 break;
1670 // IEEE 802.15.4-2006 915 MHz ASK (Page 1, Channel 1 to 10)
1673 break;
1675 // IEEE 802.15.4c-2009 780 MHz O-QPSK (Page 5, Channel 0 to 3)
1678 break;
1680 // IEEE 802.15.4-2006 868 MHz O-QPSK (Page 2, Channel 0)
1683 break;
1685 // IEEE 802.15.4-2006 915 MHz O-QPSK (Page 2, Channels 1 to 10)
1688 break;
1690 // IEEE 802.15.4-2009 2.4 GHz O-QPSK (Page 0, Channels 11 to 26)
1693 break;
1695 // IEEE 802.15.4-2006 Use Non-Registered Page and channel
1698 break;
1699 }
1700
1702
1703 m_phyOption = phyOption;
1704 // TODO: Fix/Update list when more modulations are supported.
1705 // IEEE 802.15.4-2006, Table 23
1706 // 5 MSB = Page number, 27 LSB = Supported Channels (1= supported, 0 Not supported)
1707 // Currently only page 0, channels 11-26 supported.
1709 0x7FFF800; // Page 0 should support, Channels 0 to 26 (0x07FFFFFF)
1710
1711 for (int i = 1; i <= 31; i++)
1712 {
1713 // Page 1 to 31, No support (Page set to 31, all channels 0)
1715 }
1716
1717 m_edPower.averagePower = 0.0;
1720
1721 // TODO: Change the limits Rx sensitivity when other modulations are supported
1722 // Currently, only O-QPSK 250kbps is supported and its maximum possible sensitivity is
1723 // equal to -106.58 dBm and its minimum sensitivity is defined as -85 dBm
1724 SetRxSensitivity(-106.58);
1725
1727 m_currentRxPacket = std::make_pair(nullptr, true);
1728 m_currentTxPacket = std::make_pair(nullptr, true);
1729 m_errorModel = nullptr;
1730}
1731
1732void
1733LrWpanPhy::SetRxSensitivity(double dbmSensitivity)
1734{
1735 NS_LOG_FUNCTION(this << dbmSensitivity << "dBm");
1736
1737 // 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
1739 {
1740 if (dbmSensitivity > -92)
1741 {
1742 NS_ABORT_MSG("The minimum Rx sensitivity for this band should be at least -92 dBm");
1743 }
1744 }
1745 else
1746 {
1747 if (dbmSensitivity > -85)
1748 {
1749 NS_ABORT_MSG("The minimum Rx sensitivity for this band should be at least -85 dBm");
1750 }
1751 }
1752
1753 // Calculate the noise factor required to reduce the Rx sensitivity.
1754 // The maximum possible sensitivity in the current modulation is used as a reference
1755 // to calculate the noise factor (F). The noise factor is a dimensionless ratio.
1756 // Currently only one PHY modulation is supported:
1757 // O-QPSK 250kpps which has a Max Rx sensitivity: -106.58 dBm (Noise factor = 1).
1758 // After Rx sensitivity is set, this becomes the new point where PER < 1 % for a
1759 // PSDU of 20 bytes as described by the standard.
1760
1761 // TODO: recalculate maxRxSensitivity (Noise factor = 1) when additional modulations are
1762 // supported.
1763 double maxRxSensitivityW = DbmToW(-106.58);
1764
1765 LrWpanSpectrumValueHelper psdHelper;
1769 // Update thermal noise + noise factor added.
1770 long double noiseFactor = DbmToW(dbmSensitivity) / maxRxSensitivityW;
1771 psdHelper.SetNoiseFactor(noiseFactor);
1773
1774 m_signal = Create<LrWpanInterferenceHelper>(m_noise->GetSpectrumModel());
1775 // Change receiver sensitivity from dBm to Watts
1776 m_rxSensitivity = DbmToW(dbmSensitivity);
1777}
1778
1779double
1781{
1782 NS_LOG_FUNCTION(this);
1783 // Change receiver sensitivity from Watt to dBm
1784 return WToDbm(m_rxSensitivity);
1785}
1786
1789{
1790 NS_LOG_FUNCTION(this);
1791 return m_phyOption;
1792}
1793
1794void
1796{
1797 NS_LOG_FUNCTION(this << txPsd);
1798 NS_ASSERT(txPsd);
1799 m_txPsd = txPsd;
1800 NS_LOG_INFO("\t computed tx_psd: " << *txPsd << "\t stored tx_psd: " << *m_txPsd);
1801}
1802
1803void
1805{
1806 NS_LOG_FUNCTION(this << noisePsd);
1807 NS_LOG_INFO("\t computed noise_psd: " << *noisePsd);
1808 NS_ASSERT(noisePsd);
1809 m_noise = noisePsd;
1810}
1811
1814{
1815 NS_LOG_FUNCTION(this);
1816 return m_noise;
1817}
1818
1819void
1821{
1822 NS_LOG_FUNCTION(this << e);
1823 NS_ASSERT(e);
1824 m_errorModel = e;
1825}
1826
1829{
1830 NS_LOG_FUNCTION(this);
1831 return m_errorModel;
1832}
1833
1834uint64_t
1836{
1837 NS_LOG_FUNCTION(this);
1839
1842}
1843
1844double
1846{
1847 NS_LOG_FUNCTION(this);
1849
1851}
1852
1853double
1855{
1856 double powerWatts =
1859 return WToDbm(powerWatts);
1860}
1861
1862int8_t
1864{
1866
1867 // The nominal Tx power is stored in the PIB as a 6-bit
1868 // twos-complement, signed number.
1869
1870 // The 5 LSBs can be copied - as their representation
1871 // is the same for unsigned and signed integers.
1872 int8_t nominalTxPower = phyTransmitPower & 0x1F;
1873
1874 // Now check the 6th LSB (the "sign" bit).
1875 // It's a twos-complement format, so the "sign"
1876 // bit represents -2^5 = -32.
1877 if (phyTransmitPower & 0x20)
1878 {
1879 nominalTxPower -= 32;
1880 }
1881 return nominalTxPower;
1882}
1883
1884double
1886{
1887 return (10 * log10(1000 * watt));
1888}
1889
1890double
1892{
1893 return (pow(10.0, dbm / 10.0) / 1000.0);
1894}
1895
1896int64_t
1898{
1899 NS_LOG_FUNCTION(this);
1900 m_random->SetStream(stream);
1901 return 1;
1902}
1903
1904void
1906{
1907 NS_LOG_FUNCTION(this << em);
1909}
1910
1911} // namespace lrwpan
1912} // namespace ns3
bool IsNull() const
Check for null implementation.
Definition: callback.h:571
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
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.
Represent the LQI (Link Quality Estination).
void Set(uint8_t lqi)
Set the LQI to the given value.
uint8_t Get() const
Get the LQI value.
Make LrWpanPhy a SpectrumPhy so we can enable the eventual modeling of device interference.
Definition: lr-wpan-phy.h:274
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:744
void PlmeSetAttributeRequest(PhyPibAttributeIdentifier id, Ptr< PhyPibAttributes > attribute)
IEEE 802.15.4-2006 section 6.2.2.9 PLME-SET.request Set attributes per definition from Table 23 in se...
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
void SetRxSensitivity(double dbmSensitivity)
Set the receiver power sensitivity used by this device in dBm.
EventId m_pdDataRequest
Scheduler event of a currently running data transmission request.
Definition: lr-wpan-phy.h:954
void EndRx(Ptr< SpectrumSignalParameters > params)
Finish the reception of a frame.
Definition: lr-wpan-phy.cc:549
void SetTxPowerSpectralDensity(Ptr< SpectrumValue > txPsd)
Set the Power Spectral Density of outgoing signals in W/Hz.
Ptr< AntennaModel > m_antenna
The antenna used by the transceiver.
Definition: lr-wpan-phy.h:806
std::pair< Ptr< LrWpanSpectrumSignalParameters >, bool > m_currentRxPacket
Status information of the currently received packet.
Definition: lr-wpan-phy.h:926
Ptr< NetDevice > m_device
The configured net device.
Definition: lr-wpan-phy.h:796
bool ChannelSupported(uint8_t channel)
Check if the given channel is supported by the PHY.
Definition: lr-wpan-phy.cc:992
void SetPlmeGetAttributeConfirmCallback(PlmeGetAttributeConfirmCallback c)
set the callback for the end of an GetAttribute, as part of the interconnections between the PHY and ...
int8_t GetNominalTxPowerFromPib(uint8_t phyTransmitPower)
Calculates the nominal transmit power of the device in decibels relative to 1 mW according to the rep...
void DoInitialize() override
Initialize() implementation.
Definition: lr-wpan-phy.cc:230
void SetAntenna(Ptr< AntennaModel > a)
Set the attached antenna.
Definition: lr-wpan-phy.cc:356
Ptr< const SpectrumModel > GetRxSpectrumModel() const override
Definition: lr-wpan-phy.cc:336
void DoDispose() override
Destructor implementation.
Definition: lr-wpan-phy.cc:255
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:698
void EndCca()
Called at the end of the CCA.
Ptr< SpectrumChannel > m_channel
The channel attached to this transceiver.
Definition: lr-wpan-phy.h:801
void SetPostReceptionErrorModel(const Ptr< ErrorModel > em)
Attach a receive ErrorModel to the LrWpanPhy.
double GetRxSensitivity()
Get the receiver power sensitivity used by this device in dBm.
PhyOption GetMyPhyOption()
Get the currently configured PHY option.
PacketAndStatus m_currentTxPacket
Status information of the currently transmitted packet.
Definition: lr-wpan-phy.h:934
void EndSetTRXState()
Called after applying a deferred transceiver state switch.
PdDataConfirmCallback m_pdDataConfirmCallback
This callback is used to report packet transmission status to the MAC layer.
Definition: lr-wpan-phy.h:851
void SetChannel(Ptr< SpectrumChannel > c) override
Set the channel attached to this device.
Definition: lr-wpan-phy.cc:322
void PlmeGetAttributeRequest(PhyPibAttributeIdentifier 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:771
void SetPdDataConfirmCallback(PdDataConfirmCallback c)
set the callback for the end of a TX, as part of the interconnections between the PHY and the MAC.
Ptr< LrWpanInterferenceHelper > m_signal
The accumulated signals currently received by the transceiver, including the signal of a possibly rec...
Definition: lr-wpan-phy.h:913
void SetPdDataIndicationCallback(PdDataIndicationCallback c)
set the callback for the end of a RX, as part of the interconnections between the PHY and the MAC.
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:706
double WToDbm(double watt)
Transform watts (W) to decibels milliwatts (dBm).
uint8_t GetCurrentPage() const
Get The current channel page number in use in this PHY from the PIB attributes.
PhyPibAttributes m_phyPIBAttributes
The current PHY PIB attributes.
Definition: lr-wpan-phy.h:826
Ptr< MobilityModel > m_mobility
The mobility model used by the PHY.
Definition: lr-wpan-phy.h:791
void SetErrorModel(Ptr< LrWpanErrorModel > e)
set the error model to use
void SetMobility(Ptr< MobilityModel > m) override
Set the mobility model associated with this device.
Definition: lr-wpan-phy.cc:315
PlmeSetTRXStateConfirmCallback m_plmeSetTRXStateConfirmCallback
This callback is used to report transceiver state change status to the MAC.
Definition: lr-wpan-phy.h:875
void SetNoisePowerSpectralDensity(Ptr< const SpectrumValue > noisePsd)
Set the noise power spectral density.
TracedCallback< Time, PhyEnumeration, PhyEnumeration > m_trxStateLogger
The trace source fired when the phy layer changes the transceiver state.
Definition: lr-wpan-phy.h:752
EdPower m_edPower
Helper value for tracking the average power during ED.
Definition: lr-wpan-phy.h:891
Time m_rxLastUpdate
Timestamp of the last calculation of the PER of a packet currently received.
Definition: lr-wpan-phy.h:918
EventId m_setTRXState
Scheduler event of a currently running deferred transceiver state switch.
Definition: lr-wpan-phy.h:949
Ptr< MobilityModel > GetMobility() const override
Get the associated MobilityModel instance.
Definition: lr-wpan-phy.cc:302
void SetPlmeSetAttributeConfirmCallback(PlmeSetAttributeConfirmCallback c)
set the callback for the end of an SetAttribute, as part of the interconnections between the PHY and ...
void SetPhyOption(PhyOption phyOption)
Set the modulation option used by this PHY.
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:710
TracedValue< PhyEnumeration > m_trxState
The current transceiver state.
Definition: lr-wpan-phy.h:832
void SetPlmeSetTRXStateConfirmCallback(PlmeSetTRXStateConfirmCallback c)
set the callback for the end of an SetTRXState, as part of the interconnections between the PHY and t...
double GetCurrentSignalPsd()
Get the current accumulated sum of signals in the transceiver including signals considered as interfe...
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< LrWpanErrorModel > m_errorModel
The error model describing the bit and packet error rates.
Definition: lr-wpan-phy.h:821
void EndTx()
Finish the transmission of a frame.
void SetPlmeEdConfirmCallback(PlmeEdConfirmCallback c)
set the callback for the end of an ED, as part of the interconnections between the PHY and the MAC.
uint8_t GetCurrentChannelNum() const
Get The current channel number in use in this PHY from the PIB attributes.
void PlmeSetTRXStateRequest(PhyEnumeration state)
IEEE 802.15.4-2006 section 6.2.2.7 PLME-SET-TRX-STATE.request Set PHY state.
Definition: lr-wpan-phy.cc:804
LrWpanPhy()
Default constructor.
Definition: lr-wpan-phy.cc:204
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:722
PlmeSetAttributeConfirmCallback m_plmeSetAttributeConfirmCallback
This callback is used to report attribute set results back to the MAC.
Definition: lr-wpan-phy.h:881
PhyEnumeration m_trxStatePending
The next pending state to applied after the current action of the PHY is completed.
Definition: lr-wpan-phy.h:838
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:742
double GetPhySymbolsPerOctet() const
Get the number of symbols per octet, depending on the currently selected channel.
PdDataIndicationCallback m_pdDataIndicationCallback
This callback is used to notify incoming packets to the MAC layer.
Definition: lr-wpan-phy.h:845
Ptr< LrWpanErrorModel > GetErrorModel() const
get the error model in use
void StartRx(Ptr< SpectrumSignalParameters > params) override
Notify the SpectrumPhy instance of an incoming waveform.
Definition: lr-wpan-phy.cc:363
double m_rxSensitivity
The receiver sensitivity.
Definition: lr-wpan-phy.h:901
void CcaCancel()
Cancel an ongoing CCA request.
Definition: lr-wpan-phy.cc:737
void CheckInterference()
Check if the interference destroys a frame currently received.
Definition: lr-wpan-phy.cc:499
EventId m_ccaRequest
Scheduler event of a currently running CCA request.
Definition: lr-wpan-phy.h:939
Ptr< SpectrumChannel > GetChannel()
Get the currently attached channel.
Definition: lr-wpan-phy.cc:329
Ptr< ErrorModel > m_postReceptionErrorModel
Error model for receive packet events.
Definition: lr-wpan-phy.h:961
PlmeCcaConfirmCallback m_plmeCcaConfirmCallback
This callback is used to report CCA status to the MAC or CSMA/CA.
Definition: lr-wpan-phy.h:857
uint64_t GetPhySHRDuration() const
Get the duration of the SHR (preamble and SFD) in symbols, depending on the currently selected channe...
bool m_isRxCanceled
Indicates if the reception of frame has been canceled.
Definition: lr-wpan-phy.h:906
void CancelEd(PhyEnumeration state)
Cancel an ongoing ED procedure.
Ptr< NetDevice > GetDevice() const override
Get the associated NetDevice instance.
Definition: lr-wpan-phy.cc:296
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:634
double DbmToW(double dbm)
Transforms decibels milliwatts (dBm) to watts (W).
Ptr< UniformRandomVariable > m_random
Uniform random variable stream.
Definition: lr-wpan-phy.h:959
EventId m_edRequest
Scheduler event of a currently running ED request.
Definition: lr-wpan-phy.h:944
PhyOption m_phyOption
The currently configured PHY type.
Definition: lr-wpan-phy.h:886
Ptr< SpectrumValue > m_txPsd
The transmit power spectral density.
Definition: lr-wpan-phy.h:811
bool PageSupported(uint8_t page)
Check if the given page is supported by the PHY.
Time GetPpduHeaderTxTime()
Calculate the time required for sending the PPDU header, that is the preamble, SFD and PHR.
void EndEd()
Called at the end of the ED procedure.
void SetDevice(Ptr< NetDevice > d) override
Set the associated NetDevice instance.
Definition: lr-wpan-phy.cc:308
double GetDataOrSymbolRate(bool isData)
implement PLME SetAttribute confirm SAP bit rate is in bit/s.
PlmeGetAttributeConfirmCallback m_plmeGetAttributeConfirmCallback
This callback is used to report requested attribute values back to the MAC.
Definition: lr-wpan-phy.h:869
Ptr< Object > GetAntenna() const override
Get the AntennaModel used by this SpectrumPhy instance for transmission and/or reception.
Definition: lr-wpan-phy.cc:350
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:714
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:733
double m_ccaPeakPower
Helper value for the peak power value during CCA.
Definition: lr-wpan-phy.h:896
Time CalculateTxTime(Ptr< const Packet > packet)
Calculate the time required for sending the given packet, including preamble, SFD and PHR.
Ptr< const SpectrumValue > GetNoisePowerSpectralDensity()
Get the noise power spectral density.
bool PhyIsBusy() const
Check if the PHY is busy, which is the case if the PHY is currently sending or receiving a frame.
PlmeEdConfirmCallback m_plmeEdConfirmCallback
This callback is used to report ED status to the MAC.
Definition: lr-wpan-phy.h:863
Ptr< const SpectrumValue > m_noise
The spectral density for for the noise.
Definition: lr-wpan-phy.h:816
void ChangeTrxState(PhyEnumeration newState)
Change the PHY state to the given new state, firing the state change trace.
static TypeId GetTypeId()
Get the type ID.
Definition: lr-wpan-phy.cc:147
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.
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
#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
PhyOption
This Phy option will be used to index various Tables in IEEE802.15.4-2011.
Definition: lr-wpan-phy.h:95
PhyEnumeration
IEEE802.15.4-2006 PHY Emumerations Table 18 in section 6.2.3.
Definition: lr-wpan-phy.h:115
PhyPibAttributeIdentifier
IEEE802.15.4-2006 PHY PIB Attribute Identifiers Table 23 in section 6.4.2.
Definition: lr-wpan-phy.h:167
@ IEEE_802_15_4_915MHZ_OQPSK
Definition: lr-wpan-phy.h:103
@ IEEE_802_15_4_2_4GHZ_OQPSK
Definition: lr-wpan-phy.h:104
@ IEEE_802_15_4_915MHZ_ASK
Definition: lr-wpan-phy.h:100
@ IEEE_802_15_4_780MHZ_OQPSK
Definition: lr-wpan-phy.h:101
@ IEEE_802_15_4_868MHZ_OQPSK
Definition: lr-wpan-phy.h:102
@ IEEE_802_15_4_915MHZ_BPSK
Definition: lr-wpan-phy.h:97
@ IEEE_802_15_4_868MHZ_BPSK
Definition: lr-wpan-phy.h:96
@ IEEE_802_15_4_950MHZ_BPSK
Definition: lr-wpan-phy.h:98
@ IEEE_802_15_4_INVALID_PHY_OPTION
Definition: lr-wpan-phy.h:105
@ IEEE_802_15_4_868MHZ_ASK
Definition: lr-wpan-phy.h:99
@ IEEE_802_15_4_PHY_BUSY
Definition: lr-wpan-phy.h:116
@ IEEE_802_15_4_PHY_READ_ONLY
Definition: lr-wpan-phy.h:127
@ IEEE_802_15_4_PHY_BUSY_TX
Definition: lr-wpan-phy.h:118
@ IEEE_802_15_4_PHY_RX_ON
Definition: lr-wpan-phy.h:122
@ IEEE_802_15_4_PHY_TRX_OFF
Definition: lr-wpan-phy.h:124
@ IEEE_802_15_4_PHY_TX_ON
Definition: lr-wpan-phy.h:125
@ IEEE_802_15_4_PHY_INVALID_PARAMETER
Definition: lr-wpan-phy.h:121
@ IEEE_802_15_4_PHY_UNSUPPORTED_ATTRIBUTE
Definition: lr-wpan-phy.h:126
@ IEEE_802_15_4_PHY_SUCCESS
Definition: lr-wpan-phy.h:123
@ IEEE_802_15_4_PHY_FORCE_TRX_OFF
Definition: lr-wpan-phy.h:119
@ IEEE_802_15_4_PHY_BUSY_RX
Definition: lr-wpan-phy.h:117
@ IEEE_802_15_4_PHY_IDLE
Definition: lr-wpan-phy.h:120
@ IEEE_802_15_4_PHY_UNSPECIFIED
Definition: lr-wpan-phy.h:128
@ phySymbolsPerOctet
Definition: lr-wpan-phy.h:175
@ phyChannelsSupported
Definition: lr-wpan-phy.h:169
#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:1319
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
static const PhyDataAndSymbolRates dataSymbolRates[IEEE_802_15_4_INVALID_PHY_OPTION]
The data and symbol rates for the different PHY options.
Definition: lr-wpan-phy.cc:60
const PhyPpduHeaderSymbolNumber 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:79
std::ostream & operator<<(std::ostream &os, const SuperframeField &superframeField)
Stream insertion operator.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double averagePower
Average measured power.
Definition: lr-wpan-phy.h:59
Time lastUpdate
Last update time.
Definition: lr-wpan-phy.h:60
Time measurementLength
Total measurement period.
Definition: lr-wpan-phy.h:61
This data structure provides the Bit rate and Symbol rate for a given channel See IEEE802....
Definition: lr-wpan-phy.h:71
uint8_t phyCCAMode
CCA mode.
Definition: lr-wpan-phy.h:190
uint8_t phyCurrentChannel
The RF channel to use.
Definition: lr-wpan-phy.h:185
uint8_t phyCurrentPage
Current channel page.
Definition: lr-wpan-phy.h:191
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:188
uint32_t phyChannelsSupported[32]
BitField representing the available channels supported by a channel page.
Definition: lr-wpan-phy.h:186
This data structure provides number of symbols for the PPDU headers: SHR and PHR See IEEE802....
Definition: lr-wpan-phy.h:83
double phr
Number of symbols for the PHR.
Definition: lr-wpan-phy.h:86
double shrPreamble
Number of symbols for the SHR preamble.
Definition: lr-wpan-phy.h:84
double shrSfd
Number of symbols for the SHR SFD.
Definition: lr-wpan-phy.h:85