A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
end-device-lorawan-mac.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017 University of Padova
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Davide Magrin <magrinda@dei.unipd.it>
7 * Martina Capuzzo <capuzzom@dei.unipd.it>
8 *
9 * Modified by: Peggy Anderson <peggy.anderson@usask.ca>
10 */
11
13
15#include "end-device-lora-phy.h"
16
17#include "ns3/log.h"
18#include "ns3/simulator.h"
19
20#include <algorithm>
21
22namespace ns3
23{
24namespace lorawan
25{
26
27NS_LOG_COMPONENT_DEFINE("EndDeviceLorawanMac");
28
29NS_OBJECT_ENSURE_REGISTERED(EndDeviceLorawanMac);
30
31TypeId
33{
34 static TypeId tid =
35 TypeId("ns3::EndDeviceLorawanMac")
37 .SetGroupName("lorawan")
38 .AddTraceSource("RequiredTransmissions",
39 "Total number of transmissions required to deliver this packet",
41 "ns3::TracedValueCallback::uint8_t")
42 .AddAttribute("DataRate",
43 "Data rate currently employed by this end device",
47 .AddTraceSource("DataRate",
48 "Data rate currently employed by this end device",
50 "ns3::TracedValueCallback::uint8_t")
51 .AddAttribute(
52 "DRControl",
53 "Whether to request the network server to control this device's data rate",
57 .AddTraceSource("TxPower",
58 "Transmission power currently employed by this end device",
60 "ns3::TracedValueCallback::Double")
61 .AddTraceSource("LastKnownLinkMargin",
62 "Last known demodulation margin in "
63 "communications between this end device "
64 "and a gateway",
66 "ns3::TracedValueCallback::Double")
67 .AddTraceSource("LastKnownGatewayCount",
68 "Last known number of gateways able to "
69 "listen to this end device",
71 "ns3::TracedValueCallback::Int")
72 .AddTraceSource("AggregatedDutyCycle",
73 "Aggregate duty cycle, in fraction form, "
74 "this end device must respect",
76 "ns3::TracedValueCallback::Double")
77 .AddAttribute("MaxTransmissions",
78 "Maximum number of transmissions for a packet",
79 IntegerValue(8),
82 .AddAttribute("EnableEDDataRateAdaptation",
83 "Whether the end device should up its data rate "
84 "in case it doesn't get a reply from the network server.",
85 BooleanValue(false),
88 .AddAttribute("MType",
89 "Specify type of message will be sent by this end device.",
93 "Unconfirmed",
95 "Confirmed"))
96 .AddConstructor<EndDeviceLorawanMac>();
97 return tid;
98}
99
101 : m_enableDRAdapt(false),
102 m_maxNumbTx(8),
103 m_dataRate(0),
104 m_txPower(14),
105 m_codingRate(1),
106 // LoraWAN default
107 m_headerDisabled(false),
108 // LoraWAN default
109 m_address(LoraDeviceAddress(0)),
110 // LoraWAN default
111 m_receiveWindowDurationInSymbols(8),
112 // LoraWAN default
113 m_controlDataRate(false),
114 m_lastKnownLinkMargin(0),
115 m_lastKnownGatewayCount(0),
116 m_aggregatedDutyCycle(1),
117 m_mType(LorawanMacHeader::CONFIRMED_DATA_UP),
118 m_currentFCnt(0)
119{
120 NS_LOG_FUNCTION(this);
121
122 // Initialize the random variable we'll use to decide which channel to
123 // transmit on.
125
126 // Void the transmission event
127 m_nextTx = EventId();
129
130 // Initialize structure for retransmission parameters
133}
134
139
140////////////////////////
141// Sending methods //
142////////////////////////
143
144void
146{
147 NS_LOG_FUNCTION(this << packet);
148
149 // If it is not possible to transmit now because of the duty cycle,
150 // or because we are receiving, schedule a tx/retx later
151
152 Time netxTxDelay = GetNextTransmissionDelay();
153 if (netxTxDelay != Seconds(0))
154 {
155 postponeTransmission(netxTxDelay, packet);
156 return;
157 }
158
159 // Pick a channel on which to transmit the packet
161
162 if (!(txChannel && m_retxParams.retxLeft > 0))
163 {
164 if (!txChannel)
165 {
167 }
168 else
169 {
170 NS_LOG_INFO("Max number of transmission achieved: packet not transmitted.");
171 }
172 }
173 else
174 // the transmitting channel is available and we have not run out the maximum number of
175 // retransmissions
176 {
177 // Make sure we can transmit at the current power on this channel
178 NS_ASSERT_MSG(m_txPower <= m_channelHelper->GetTxPowerForChannel(txChannel),
179 " The selected power is too high to be supported by this channel.");
180 DoSend(packet);
181 }
182}
183
184void
186{
187 NS_LOG_FUNCTION(this);
188 // Delete previously scheduled transmissions if any.
190 m_nextTx = Simulator::Schedule(netxTxDelay, &EndDeviceLorawanMac::DoSend, this, packet);
191 NS_LOG_WARN("Attempting to send, but the aggregate duty cycle won't allow it. Scheduling a tx "
192 "at a delay "
193 << netxTxDelay.GetSeconds() << ".");
194}
195
196void
198{
199 NS_LOG_FUNCTION(this);
200 // Checking if this is the transmission of a new packet
201 if (packet != m_retxParams.packet)
202 {
204 "Received a new packet from application. Resetting retransmission parameters.");
206 NS_LOG_DEBUG("APP packet: " << packet << ".");
207
208 // Add the Lora Frame Header to the packet
209 LoraFrameHeader frameHdr;
210 ApplyNecessaryOptions(frameHdr);
211 packet->AddHeader(frameHdr);
212
213 NS_LOG_INFO("Added frame header of size " << frameHdr.GetSerializedSize() << " bytes.");
214
215 // Check that MACPayload length is below the allowed maximum
216 if (packet->GetSize() > m_maxAppPayloadForDataRate.at(m_dataRate))
217 {
218 NS_LOG_WARN("Attempting to send a packet larger than the maximum allowed"
219 << " size at this Data Rate (DR" << unsigned(m_dataRate)
220 << "). Transmission canceled.");
221 return;
222 }
223
224 // Add the Lora Mac header to the packet
225 LorawanMacHeader macHdr;
226 ApplyNecessaryOptions(macHdr);
227 packet->AddHeader(macHdr);
228
229 // Reset MAC command list
230 m_macCommandList.clear();
231
233 {
234 // Call the callback to notify about the failure
235 uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft);
237 NS_LOG_DEBUG(" Received new packet from the application layer: stopping retransmission "
238 "procedure. Used "
239 << unsigned(txs) << " transmissions out of a maximum of "
240 << unsigned(m_maxNumbTx) << ".");
241 }
242
243 // Reset retransmission parameters
245
246 // If this is the first transmission of a confirmed packet, save parameters for the
247 // (possible) next retransmissions.
249 {
250 m_retxParams.packet = packet->Copy();
255 m_retxParams.retxLeft - 1; // decreasing the number of retransmissions
256
257 NS_LOG_DEBUG("Message type is " << m_mType);
258 NS_LOG_DEBUG("It is a confirmed packet. Setting retransmission parameters and "
259 "decreasing the number of transmissions left.");
260
261 NS_LOG_INFO("Added MAC header of size " << macHdr.GetSerializedSize() << " bytes.");
262
263 // Sent a new packet
264 NS_LOG_DEBUG("Copied packet: " << m_retxParams.packet);
266
267 // static_cast<ClassAEndDeviceLorawanMac*>(this)->SendToPhy (m_retxParams.packet);
269 }
270 else
271 {
272 m_sentNewPacket(packet);
273 // static_cast<ClassAEndDeviceLorawanMac*>(this)->SendToPhy (packet);
274 SendToPhy(packet);
275 }
276 }
277 // this is a retransmission
278 else
279 {
281 {
282 // Remove the headers
283 LorawanMacHeader macHdr;
284 LoraFrameHeader frameHdr;
285 packet->RemoveHeader(macHdr);
286 packet->RemoveHeader(frameHdr);
287
288 // Add the Lora Frame Header to the packet
289 frameHdr = LoraFrameHeader();
290 ApplyNecessaryOptions(frameHdr);
291 packet->AddHeader(frameHdr);
292
293 NS_LOG_INFO("Added frame header of size " << frameHdr.GetSerializedSize() << " bytes.");
294
295 // Add the Lorawan Mac header to the packet
296 macHdr = LorawanMacHeader();
297 ApplyNecessaryOptions(macHdr);
298 packet->AddHeader(macHdr);
300 m_retxParams.retxLeft - 1; // decreasing the number of retransmissions
301 NS_LOG_DEBUG("Retransmitting an old packet.");
302
303 // static_cast<ClassAEndDeviceLorawanMac*>(this)->SendToPhy (m_retxParams.packet);
305 }
306 }
307}
308
309void
313
314//////////////////////////
315// Receiving methods //
316//////////////////////////
317
318void
322
323void
327
328void
330{
331 NS_LOG_FUNCTION(this << frameHeader);
332
334 {
335 if (frameHeader.GetAck())
336 {
337 NS_LOG_INFO("The message is an ACK, not waiting for it anymore.");
338
339 NS_LOG_DEBUG("Reset retransmission variables to default values and cancel "
340 "retransmission if already scheduled.");
341
342 uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft);
344 NS_LOG_DEBUG("Received ACK packet after "
345 << unsigned(txs) << " transmissions: stopping retransmission procedure. ");
346
347 // Reset retransmission parameters
349 }
350 else
351 {
353 "Received downlink message not containing an ACK while we were waiting for it!");
354 }
355 }
356
357 std::list<Ptr<MacCommand>> commands = frameHeader.GetCommands();
358 std::list<Ptr<MacCommand>>::iterator it;
359 for (it = commands.begin(); it != commands.end(); it++)
360 {
361 NS_LOG_DEBUG("Iterating over the MAC commands...");
362 enum MacCommandType type = (*it)->GetCommandType();
363 switch (type)
364 {
365 case (LINK_CHECK_ANS): {
366 NS_LOG_DEBUG("Detected a LinkCheckAns command.");
367
368 // Cast the command
370
371 // Call the appropriate function to take action
372 OnLinkCheckAns(linkCheckAns->GetMargin(), linkCheckAns->GetGwCnt());
373
374 break;
375 }
376 case (LINK_ADR_REQ): {
377 NS_LOG_DEBUG("Detected a LinkAdrReq command.");
378
379 // Cast the command
381
382 // Call the appropriate function to take action
383 OnLinkAdrReq(linkAdrReq->GetDataRate(),
384 linkAdrReq->GetTxPower(),
385 linkAdrReq->GetEnabledChannelsList(),
386 linkAdrReq->GetRepetitions());
387
388 break;
389 }
390 case (DUTY_CYCLE_REQ): {
391 NS_LOG_DEBUG("Detected a DutyCycleReq command.");
392
393 // Cast the command
395
396 // Call the appropriate function to take action
397 OnDutyCycleReq(dutyCycleReq->GetMaximumAllowedDutyCycle());
398
399 break;
400 }
401 case (RX_PARAM_SETUP_REQ): {
402 NS_LOG_DEBUG("Detected a RxParamSetupReq command.");
403
404 // Cast the command
406
407 // Call the appropriate function to take action
408 OnRxParamSetupReq(rxParamSetupReq);
409
410 break;
411 }
412 case (DEV_STATUS_REQ): {
413 NS_LOG_DEBUG("Detected a DevStatusReq command.");
414
415 // Cast the command
417
418 // Call the appropriate function to take action
420
421 break;
422 }
423 case (NEW_CHANNEL_REQ): {
424 NS_LOG_DEBUG("Detected a NewChannelReq command.");
425
426 // Cast the command
428
429 // Call the appropriate function to take action
430 OnNewChannelReq(newChannelReq->GetChannelIndex(),
431 newChannelReq->GetFrequency(),
432 newChannelReq->GetMinDataRate(),
433 newChannelReq->GetMaxDataRate());
434
435 break;
436 }
437 case (RX_TIMING_SETUP_REQ):
438 case (TX_PARAM_SETUP_REQ):
439 case (DL_CHANNEL_REQ):
440 default: {
441 NS_LOG_ERROR("CID not recognized or supported");
442 break;
443 }
444 }
445 }
446}
447
448void
450{
452
453 frameHeader.SetAsUplink();
454 frameHeader.SetFPort(1); // TODO Use an appropriate frame port based on the application
455 frameHeader.SetAddress(m_address);
456 frameHeader.SetAdr(m_controlDataRate);
457 frameHeader.SetAdrAckReq(false); // TODO Set ADRACKREQ if a member variable is true
458
459 // FPending does not exist in uplink messages
460 frameHeader.SetFCnt(m_currentFCnt);
461
462 // Add listed MAC commands
463 for (const auto& command : m_macCommandList)
464 {
465 NS_LOG_INFO("Applying a MAC Command of CID "
466 << unsigned(MacCommand::GetCIDFromMacCommand(command->GetCommandType())));
467
468 frameHeader.AddCommand(command);
469 }
470}
471
472void
474{
476
477 macHeader.SetMType(m_mType);
478 macHeader.SetMajor(1);
479}
480
481void
483{
484 m_mType = mType;
485 NS_LOG_DEBUG("Message type is set to " << mType);
486}
487
493
494void
498
499Time
501{
503 return waitingTime;
504}
505
506Time
508{
510
511 // Check duty cycle //
512
513 // Pick a random channel to transmit on
514 std::vector<Ptr<LogicalLoraChannel>> logicalChannels;
515 logicalChannels =
516 m_channelHelper->GetEnabledChannelList(); // Use a separate list to do the shuffle
517 // logicalChannels = Shuffle (logicalChannels);
518
519 Time waitingTime = Time::Max();
520
521 // Try every channel
522 std::vector<Ptr<LogicalLoraChannel>>::iterator it;
523 for (it = logicalChannels.begin(); it != logicalChannels.end(); ++it)
524 {
525 // Pointer to the current channel
526 Ptr<LogicalLoraChannel> logicalChannel = *it;
527 double frequency = logicalChannel->GetFrequency();
528
529 waitingTime = std::min(waitingTime, m_channelHelper->GetWaitingTime(logicalChannel));
530
531 NS_LOG_DEBUG("Waiting time before the next transmission in channel with frequency "
532 << frequency << " is = " << waitingTime.GetSeconds() << ".");
533 }
534
535 waitingTime = GetNextClassTransmissionDelay(waitingTime);
536
537 return waitingTime;
538}
539
542{
544
545 // Pick a random channel to transmit on
546 std::vector<Ptr<LogicalLoraChannel>> logicalChannels;
547 logicalChannels =
548 m_channelHelper->GetEnabledChannelList(); // Use a separate list to do the shuffle
549 logicalChannels = Shuffle(logicalChannels);
550
551 // Try every channel
552 std::vector<Ptr<LogicalLoraChannel>>::iterator it;
553 for (it = logicalChannels.begin(); it != logicalChannels.end(); ++it)
554 {
555 // Pointer to the current channel
556 Ptr<LogicalLoraChannel> logicalChannel = *it;
557 double frequency = logicalChannel->GetFrequency();
558
559 NS_LOG_DEBUG("Frequency of the current channel: " << frequency);
560
561 // Verify that we can send the packet
562 Time waitingTime = m_channelHelper->GetWaitingTime(logicalChannel);
563
564 NS_LOG_DEBUG("Waiting time for current channel = " << waitingTime.GetSeconds());
565
566 // Send immediately if we can
567 if (waitingTime == Seconds(0))
568 {
569 return *it;
570 }
571 else
572 {
573 NS_LOG_DEBUG("Packet cannot be immediately transmitted on "
574 << "the current channel because of duty cycle limitations.");
575 }
576 }
577 return nullptr; // In this case, no suitable channel was found
578}
579
580std::vector<Ptr<LogicalLoraChannel>>
582{
584
585 int size = vector.size();
586
587 for (int i = 0; i < size; ++i)
588 {
589 uint16_t random = std::floor(m_uniformRV->GetValue(0, size));
590 Ptr<LogicalLoraChannel> temp = vector.at(random);
591 vector.at(random) = vector.at(i);
592 vector.at(i) = temp;
593 }
594
595 return vector;
596}
597
598/////////////////////////
599// Setters and Getters //
600/////////////////////////
601
602void
604{
605 m_retxParams.waitingAck = false;
607 m_retxParams.packet = nullptr;
609
610 // Cancel next retransmissions, if any
612}
613
614void
616{
617 NS_LOG_FUNCTION(this << adapt);
618 m_enableDRAdapt = adapt;
619}
620
621bool
626
627void
629{
630 NS_LOG_FUNCTION(this << unsigned(maxNumbTx));
631 m_maxNumbTx = maxNumbTx;
632 m_retxParams.retxLeft = maxNumbTx;
633}
634
635uint8_t
641
642void
644{
645 NS_LOG_FUNCTION(this << unsigned(dataRate));
646
647 m_dataRate = dataRate;
648}
649
650uint8_t
652{
653 NS_LOG_FUNCTION(this);
654
655 return m_dataRate;
656}
657
658void
660{
661 NS_LOG_FUNCTION(this << address);
662
663 m_address = address;
664}
665
673
674void
675EndDeviceLorawanMac::OnLinkCheckAns(uint8_t margin, uint8_t gwCnt)
676{
677 NS_LOG_FUNCTION(this << unsigned(margin) << unsigned(gwCnt));
678
679 m_lastKnownLinkMargin = margin;
681}
682
683void
685 uint8_t txPower,
686 std::list<int> enabledChannels,
687 int repetitions)
688{
689 NS_LOG_FUNCTION(this << unsigned(dataRate) << unsigned(txPower) << repetitions);
690
691 // Three bools for three requirements before setting things up
692 bool channelMaskOk = true;
693 bool dataRateOk = true;
694 bool txPowerOk = true;
695
696 // Check the channel mask
697 /////////////////////////
698 // Check whether all specified channels exist on this device
699 auto channelList = m_channelHelper->GetChannelList();
700 int channelListSize = channelList.size();
701
702 for (auto it = enabledChannels.begin(); it != enabledChannels.end(); it++)
703 {
704 if ((*it) > channelListSize)
705 {
706 channelMaskOk = false;
707 break;
708 }
709 }
710
711 // Check the dataRate
712 /////////////////////
713 // We need to know we can use it at all
714 // To assess this, we try and convert it to a spreading factor / bandwidth combination and check
715 // if those values are valid. Since GetSfFromDataRate and GetBandwidthFromDataRate return 0 if
716 // the dataRate is not recognized, we can check against this.
717 uint8_t sf = GetSfFromDataRate(dataRate);
718 double bw = GetBandwidthFromDataRate(dataRate);
719 NS_LOG_DEBUG("SF: " << unsigned(sf) << ", BW: " << bw);
720 if (sf == 0 || bw == 0)
721 {
722 dataRateOk = false;
723 NS_LOG_DEBUG("Data rate non valid");
724 }
725
726 // We need to know we can use it in at least one of the enabled channels
727 // Cycle through available channels, stop when at least one is enabled for the
728 // specified dataRate.
729 if (dataRateOk && channelMaskOk) // If false, skip the check
730 {
731 bool foundAvailableChannel = false;
732 for (auto it = enabledChannels.begin(); it != enabledChannels.end(); it++)
733 {
734 NS_LOG_DEBUG("MinDR: " << unsigned(channelList.at(*it)->GetMinimumDataRate()));
735 NS_LOG_DEBUG("MaxDR: " << unsigned(channelList.at(*it)->GetMaximumDataRate()));
736 if (channelList.at(*it)->GetMinimumDataRate() <= dataRate &&
737 channelList.at(*it)->GetMaximumDataRate() >= dataRate)
738 {
739 foundAvailableChannel = true;
740 break;
741 }
742 }
743
744 if (!foundAvailableChannel)
745 {
746 dataRateOk = false;
747 NS_LOG_DEBUG("Available channel not found");
748 }
749 }
750
751 // Check the txPower
752 ////////////////////
753 // Check whether we can use this transmission power
754 if (GetDbmForTxPower(txPower) == 0)
755 {
756 txPowerOk = false;
757 }
758
759 NS_LOG_DEBUG("Finished checking. ChannelMaskOk: " << channelMaskOk << ", "
760 << "DataRateOk: " << dataRateOk << ", "
761 << "txPowerOk: " << txPowerOk);
762
763 // If all checks are successful, set parameters up
764 //////////////////////////////////////////////////
765 if (channelMaskOk && dataRateOk && txPowerOk)
766 {
767 // Cycle over all channels in the list
768 for (uint32_t i = 0; i < m_channelHelper->GetChannelList().size(); i++)
769 {
770 if (std::find(enabledChannels.begin(), enabledChannels.end(), i) !=
771 enabledChannels.end())
772 {
773 m_channelHelper->GetChannelList().at(i)->SetEnabledForUplink();
774 NS_LOG_DEBUG("Channel " << i << " enabled");
775 }
776 else
777 {
778 m_channelHelper->GetChannelList().at(i)->DisableForUplink();
779 NS_LOG_DEBUG("Channel " << i << " disabled");
780 }
781 }
782
783 // Set the data rate
784 m_dataRate = dataRate;
785
786 // Set the transmission power
787 m_txPower = GetDbmForTxPower(txPower);
788 }
789
790 // Craft a LinkAdrAns MAC command as a response
791 ///////////////////////////////////////////////
792 m_macCommandList.emplace_back(CreateObject<LinkAdrAns>(txPowerOk, dataRateOk, channelMaskOk));
793}
794
795void
797{
798 NS_LOG_FUNCTION(this << dutyCycle);
799
800 // Make sure we get a value that makes sense
801 NS_ASSERT(0 <= dutyCycle && dutyCycle < 1);
802
803 // Set the new duty cycle value
804 m_aggregatedDutyCycle = dutyCycle;
805
806 // Craft a DutyCycleAns as response
807 NS_LOG_INFO("Adding DutyCycleAns reply");
809}
810
811void
815
816void
818{
819 NS_LOG_FUNCTION(this << rxParamSetupReq);
820
821 // static_cast<ClassAEndDeviceLorawanMac*>(this)->OnRxClassParamSetupReq (rxParamSetupReq);
822 OnRxClassParamSetupReq(rxParamSetupReq);
823}
824
825void
827{
828 NS_LOG_FUNCTION(this);
829
830 uint8_t battery = 10; // XXX Fake battery level
831 uint8_t margin = 10; // XXX Fake margin
832
833 // Craft a RxParamSetupAns as response
834 NS_LOG_INFO("Adding DevStatusAns reply");
835 m_macCommandList.emplace_back(CreateObject<DevStatusAns>(battery, margin));
836}
837
838void
840 double frequency,
841 uint8_t minDataRate,
842 uint8_t maxDataRate)
843{
844 NS_LOG_FUNCTION(this);
845
846 bool dataRateRangeOk = true; // XXX Check whether the new data rate range is ok
847 bool channelFrequencyOk = true; // XXX Check whether the frequency is ok
848
849 // TODO Return false if one of the checks above failed
850 // TODO Create new channel in the LogicalLoraChannelHelper
851
852 SetLogicalChannel(chIndex, frequency, minDataRate, maxDataRate);
853
854 NS_LOG_INFO("Adding NewChannelAns reply");
855 m_macCommandList.emplace_back(CreateObject<NewChannelAns>(dataRateRangeOk, channelFrequencyOk));
856}
857
858void
860{
861 NS_LOG_FUNCTION(this << frequency);
862
863 m_channelHelper->AddChannel(frequency);
864}
865
866void
868{
869 NS_LOG_FUNCTION(this << logicalChannel);
870
871 m_channelHelper->AddChannel(logicalChannel);
872}
873
874void
876 double frequency,
877 uint8_t minDataRate,
878 uint8_t maxDataRate)
879{
880 NS_LOG_FUNCTION(this << unsigned(chIndex) << frequency << unsigned(minDataRate)
881 << unsigned(maxDataRate));
882
883 m_channelHelper->SetChannel(
884 chIndex,
885 CreateObject<LogicalLoraChannel>(frequency, minDataRate, maxDataRate));
886}
887
888void
890 double endFrequency,
891 double dutyCycle,
892 double maxTxPowerDbm)
893{
895
896 m_channelHelper->AddSubBand(startFrequency, endFrequency, dutyCycle, maxTxPowerDbm);
897}
898
899double
906
907void
909{
910 NS_LOG_FUNCTION(this << macCommand);
911
912 m_macCommandList.push_back(macCommand);
913}
914
915uint8_t
920} // namespace lorawan
921} // namespace ns3
Hold variables of type enum.
Definition enum.h:52
An identifier for simulation events.
Definition event-id.h:45
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition event-id.cc:44
Hold a signed integer type.
Definition integer.h:34
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
Definition simulator.cc:274
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:392
static Time Max()
Maximum representable Time Not to be confused with Max(Time,Time).
Definition nstime.h:286
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Hold an unsigned integer type.
Definition uinteger.h:34
LorawanMacHeader::MType m_mType
The message type to apply to packets sent with the Send method.
uint8_t m_maxNumbTx
Default number of unacknowledged redundant transmissions of each packet.
TracedValue< int > m_lastKnownGatewayCount
The last known gateway count (i.e., gateways that are in communication range with this end device).
bool GetDataRateAdaptation() const
Get if data rate adaptation is enabled or not.
void SetLogicalChannel(uint8_t chIndex, double frequency, uint8_t minDataRate, uint8_t maxDataRate)
Set a new logical channel in the helper.
void FailedReception(Ptr< const Packet > packet) override
Function called by lower layers to inform this layer that reception of a packet we were locked on fai...
virtual void OnRxClassParamSetupReq(Ptr< RxParamSetupReq > rxParamSetupReq)
Perform the actions that need to be taken when receiving a RxParamSetupReq command based on the Devic...
void AddSubBand(double startFrequency, double endFrequency, double dutyCycle, double maxTxPowerDbm)
Add a subband to the logical channel helper.
bool m_controlDataRate
Whether this device's data rate should be controlled by the network server.
virtual void postponeTransmission(Time nextTxDelay, Ptr< Packet > packet)
Postpone transmission to the specified time and delete previously scheduled transmissions if present.
virtual void SendToPhy(Ptr< Packet > packet)
Add headers and send a packet with the sending function of the physical layer.
Ptr< LogicalLoraChannel > GetChannelForTx()
Find a suitable channel for transmission.
void OnDutyCycleReq(double dutyCycle)
Perform the actions that need to be taken when receiving a DutyCycleReq command.
TracedValue< double > m_txPower
The transmission power this device is using to transmit.
bool m_enableDRAdapt
Enable data rate adaptation (ADR) during the retransmission procedure.
void TxFinished(Ptr< const Packet > packet) override
Perform the actions that are required after a packet send.
Ptr< UniformRandomVariable > m_uniformRV
An uniform random variable, used by the Shuffle method to randomly reorder the channel list.
void OnRxParamSetupReq(Ptr< RxParamSetupReq > rxParamSetupReq)
Perform the actions that need to be taken when receiving a RxParamSetupReq command.
static TypeId GetTypeId()
Register this type.
TracedValue< double > m_aggregatedDutyCycle
The aggregated duty cycle this device needs to respect across all sub-bands.
double GetAggregatedDutyCycle()
Get the aggregated duty cycle.
void Receive(Ptr< const Packet > packet) override
Receive a packet.
void SetMType(LorawanMacHeader::MType mType)
Set the message type to send when the Send method is called.
virtual void resetRetransmissionParameters()
Reset retransmission parameters contained in the structure LoraRetxParams.
virtual Time GetNextClassTransmissionDelay(Time waitingTime)
Find the minimum waiting time before the next possible transmission based on end device's Class Type.
void ParseCommands(LoraFrameHeader frameHeader)
Parse and take action on the commands contained on this FrameHeader.
void ApplyNecessaryOptions(LoraFrameHeader &frameHeader)
Add the necessary options and MAC commands to the LoraFrameHeader.
TracedCallback< uint8_t, bool, Time, Ptr< Packet > > m_requiredTxCallback
The trace source fired when the transmission procedure is finished.
virtual uint8_t GetTransmissionPower()
Get the transmission power this end device is set to use.
uint8_t GetMaxNumberOfTransmissions()
Get the max number of unacknowledged redundant transmissions of each packet.
void SetDataRateAdaptation(bool adapt)
Enable data rate adaptation in the retransmitting procedure.
void OnLinkCheckAns(uint8_t margin, uint8_t gwCnt)
Perform the actions that need to be taken when receiving a LinkCheckAns command.
EventId m_nextTx
The event of retransmitting a packet in a consecutive moment if an ACK is not received.
void OnLinkAdrReq(uint8_t dataRate, uint8_t txPower, std::list< int > enabledChannels, int repetitions)
Perform the actions that need to be taken when receiving a LinkAdrReq command.
std::list< Ptr< MacCommand > > m_macCommandList
List of the MAC commands that need to be applied to the next UL packet.
TracedValue< uint8_t > m_dataRate
The data rate this device is using to transmit.
LoraDeviceAddress m_address
The address of this device.
void Send(Ptr< Packet > packet) override
Send a packet.
uint16_t m_currentFCnt
current value of the device frame counter.
void AddMacCommand(Ptr< MacCommand > macCommand)
Add a MAC command to the list of those that will be sent out in the next packet.
void SetMaxNumberOfTransmissions(uint8_t maxNumbTx)
Set the max number of unacknowledged redundant transmissions of each packet.
TracedValue< double > m_lastKnownLinkMargin
The last known link margin.
void AddLogicalChannel(double frequency)
Add a logical channel to the helper.
Time GetNextTransmissionDelay()
Find the base minimum waiting time before the next possible transmission.
std::vector< Ptr< LogicalLoraChannel > > Shuffle(std::vector< Ptr< LogicalLoraChannel > > vector)
Randomly shuffle a Ptr<LogicalLoraChannel> vector.
LorawanMacHeader::MType GetMType()
Get the message type to send when the Send method is called.
virtual void DoSend(Ptr< Packet > packet)
Checking if we are performing the transmission of a new packet or a retransmission,...
void OnDevStatusReq()
Perform the actions that need to be taken when receiving a DevStatusReq command.
LoraDeviceAddress GetDeviceAddress()
Get the network address of this device.
void OnNewChannelReq(uint8_t chIndex, double frequency, uint8_t minDataRate, uint8_t maxDataRate)
Perform the actions that need to be taken when receiving a NewChannelReq command.
void SetDataRate(uint8_t dataRate)
Set the data rate this end device will use when transmitting.
uint8_t GetDataRate()
Get the data rate this end device is set to use.
void SetDeviceAddress(LoraDeviceAddress address)
Set the network address of this device.
struct LoraRetxParameters m_retxParams
Structure containing the retransmission parameters for this device.
This class represents the device address of a LoraWAN end device.
This class represents the Frame header (FHDR) used in a LoraWAN network.
bool GetAck() const
Get the value of the ACK bit field.
void AddCommand(Ptr< MacCommand > macCommand)
Add a predefined command to the list in this frame header.
void SetFCnt(uint16_t fCnt)
Set the FCnt value.
void SetAdr(bool adr)
Set the value of the ADR bit field.
uint32_t GetSerializedSize() const override
Return the size required for serialization of this header.
void SetAddress(LoraDeviceAddress address)
Set the address.
void SetAsUplink()
State that this is an uplink message.
void SetAdrAckReq(bool adrAckReq)
Set the value of the ADRACKReq bit field.
std::list< Ptr< MacCommand > > GetCommands()
Return a list of pointers to all the MAC commands saved in this header.
void SetFPort(uint8_t fPort)
Set the FPort value.
This class represents the Mac header of a LoRaWAN packet.
void SetMajor(uint8_t major)
Set the major version of this header.
void SetMType(enum MType mtype)
Set the message type.
uint32_t GetSerializedSize() const override
Class representing the LoRaWAN MAC layer.
Definition lorawan-mac.h:37
TracedCallback< Ptr< const Packet > > m_cannotSendBecauseDutyCycle
The trace source that is fired when a packet cannot be sent because of duty cycle limitations.
std::vector< uint32_t > m_maxAppPayloadForDataRate
A vector holding the maximum app payload size that corresponds to a certain data rate.
double GetDbmForTxPower(uint8_t txPower)
Get the transmission power in dBm that corresponds, in this region, to the encoded 8-bit txPower.
uint8_t GetSfFromDataRate(uint8_t dataRate)
Get the spreading factor corresponding to a data rate, based on this MAC's region.
double GetBandwidthFromDataRate(uint8_t dataRate)
Get the bandwidth corresponding to a data rate, based on this MAC's region.
Ptr< LogicalLoraChannelHelper > m_channelHelper
The LogicalLoraChannelHelper instance that is assigned to this MAC.
TracedCallback< Ptr< const Packet > > m_sentNewPacket
Trace source that is fired when a new APP layer packet arrives at the MAC layer.
static uint8_t GetCIDFromMacCommand(enum MacCommandType commandType)
Get the CID that corresponds to a type of MAC command.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#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:75
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition log.h:243
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#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:250
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
MacCommandType
Enum for every possible command type.
Definition mac-command.h:25
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition boolean.cc:113
Ptr< const AttributeChecker > MakeIntegerChecker()
Definition integer.h:99
Ptr< const AttributeAccessor > MakeIntegerAccessor(T1 a1)
Definition integer.h:35
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition uinteger.h:35
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition enum.h:179
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition boolean.h:70
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Definition enum.h:221
Structure representing the parameters that will be used in the retransmission procedure.
bool waitingAck
Whether the packet requires explicit acknowledgment.
uint8_t retxLeft
Number of retransmission attempts left.
Time firstAttempt
Timestamp of the first transmission of the packet.
Ptr< Packet > packet
A pointer to the packet being retransmitted.