32 #include <ns3/ipv4-header.h>
34 #include <ns3/simulator.h>
41 NS_LOG_COMPONENT_DEFINE(
"LorawanMacEndDevice");
43 NS_OBJECT_ENSURE_REGISTERED(LorawanMacEndDevice);
49 TypeId(
"ns3::LorawanMacEndDevice")
51 .AddTraceSource(
"RequiredTransmissions",
52 "Total number of transmissions required to deliver this packet",
54 "ns3::TracedValueCallback::uint8_t")
55 .AddAttribute(
"DataRate",
56 "Data Rate currently employed by this end device",
59 MakeUintegerChecker<uint8_t>(0, 5))
60 .AddTraceSource(
"DataRate",
61 "Data Rate currently employed by this end device",
63 "ns3::TracedValueCallback::uint8_t")
64 .AddAttribute(
"DRControl",
65 "Whether to request the NS to control this device's Data Rate",
69 .AddTraceSource(
"TxPower",
70 "Transmission power currently employed by this end device",
72 "ns3::TracedValueCallback::Double")
73 .AddTraceSource(
"LastKnownLinkMargin",
74 "Last known demodulation margin in "
75 "communications between this end device "
78 "ns3::TracedValueCallback::Double")
79 .AddTraceSource(
"LastKnownGatewayCount",
80 "Last known number of gateways able to "
81 "listen to this end device",
83 "ns3::TracedValueCallback::Int")
84 .AddTraceSource(
"AggregatedDutyCycle",
85 "Aggregate duty cycle, in fraction form, "
86 "this end device must respect",
88 "ns3::TracedValueCallback::Double")
89 .AddAttribute(
"MaxTransmissions",
90 "Maximum number of transmissions for a packet",
93 MakeIntegerChecker<uint8_t>())
94 .AddAttribute(
"EnableEDDataRateAdaptation",
95 "Whether the End Device should up its Data Rate "
96 "in case it doesn't get a reply from the NS.",
100 .AddAttribute(
"MType",
101 "Specify type of message will be sent by this ED.",
113 NS_FATAL_ERROR(
"Default constructor not in use");
118 m_enableDRAdapt(false),
122 m_codingRate(4.0 / 5),
128 m_receiveWindowDurationInSymbols(8),
129 m_gatewayUpdateCallback(),
131 m_controlDataRate(false),
132 m_lastKnownLinkMargin(0),
133 m_lastKnownGatewayCount(0),
134 m_aggregatedDutyCycle(1),
139 NS_LOG_FUNCTION(
this);
143 m_uniformRV = CreateObject<UniformRandomVariable>();
156 NS_LOG_FUNCTION_NOARGS();
166 NS_LOG_FUNCTION(
this << packet);
171 if (netxTxDelay != Seconds(0))
184 NS_LOG_INFO(
"Cannot send because of duty cycle.");
189 NS_LOG_INFO(
"Max number of transmission achieved: packet not transmitted.");
198 " The selected power is too hight to be supported by this channel.");
206 NS_LOG_FUNCTION(
this);
210 NS_LOG_WARN(
"Attempting to send, but the aggregate duty cycle won't allow it. Scheduling a tx "
212 << netxTxDelay.GetSeconds() <<
".");
218 NS_LOG_FUNCTION(
this);
223 "Received a new packet from application. Resetting retransmission parameters.");
225 NS_LOG_DEBUG(
"APP packet: " << packet <<
".");
230 NS_LOG_WARN(
"Attempting to send a packet larger than the maximum allowed"
231 <<
" size at this DataRate (DR" <<
unsigned(
m_dataRate)
232 <<
"). Transmission canceled. ");
239 packet->AddHeader(frameHdr);
240 NS_LOG_INFO(
"Added frame header of size " << frameHdr.
GetSerializedSize() <<
" bytes.");
245 packet->AddHeader(macHdr);
255 NS_LOG_DEBUG(
" Received new packet from the application layer: stopping retransmission "
257 <<
unsigned(txs) <<
" transmissions out of a maximum of "
275 NS_LOG_DEBUG(
"Message type is " <<
m_mType);
276 NS_LOG_DEBUG(
"It is a confirmed packet. Setting retransmission parameters and "
277 "decreasing the number of transmissions left.");
296 packet->RemovePacketTag(satPhyTimeTag);
298 packet->RemovePacketTag(satPhyLinkTimeTag);
304 packet->RemoveHeader(macHdr);
305 packet->RemoveHeader(frameHdr);
310 packet->AddHeader(frameHdr);
312 NS_LOG_INFO(
"Added frame header of size " << frameHdr.
GetSerializedSize() <<
" bytes.");
317 packet->AddHeader(macHdr);
320 NS_LOG_DEBUG(
"Retransmitting an old packet.");
338 Ptr<SatSignalParameters> )
341 for (SatPhy::PacketContainer_t::iterator i = packets.begin(); i != packets.end(); i++)
355 NS_LOG_FUNCTION(
this << frameHeader);
361 NS_LOG_INFO(
"The message is an ACK, not waiting for it anymore.");
363 NS_LOG_DEBUG(
"Reset retransmission variables to default values and cancel "
364 "retransmission if already scheduled.");
368 NS_LOG_DEBUG(
"Received ACK packet after "
369 <<
unsigned(txs) <<
" transmissions: stopping retransmission procedure. ");
377 "Received downlink message not containing an ACK while we were waiting for it!");
381 std::list<Ptr<LorawanMacCommand>> commands = frameHeader.
GetCommands();
382 std::list<Ptr<LorawanMacCommand>>::iterator it;
383 for (it = commands.begin(); it != commands.end(); it++)
385 NS_LOG_DEBUG(
"Iterating over the MAC commands...");
390 NS_LOG_DEBUG(
"Detected a LinkCheckAns command.");
393 Ptr<LinkCheckAns> linkCheckAns = (*it)->GetObject<
LinkCheckAns>();
396 OnLinkCheckAns(linkCheckAns->GetMargin(), linkCheckAns->GetGwCnt());
401 NS_LOG_DEBUG(
"Detected a LinkAdrReq command.");
404 Ptr<LinkAdrReq> linkAdrReq = (*it)->GetObject<
LinkAdrReq>();
408 linkAdrReq->GetTxPower(),
409 linkAdrReq->GetEnabledChannelsList(),
410 linkAdrReq->GetRepetitions());
415 NS_LOG_DEBUG(
"Detected a DutyCycleReq command.");
418 Ptr<DutyCycleReq> dutyCycleReq = (*it)->GetObject<
DutyCycleReq>();
426 NS_LOG_DEBUG(
"Detected a RxParamSetupReq command.");
429 Ptr<RxParamSetupReq> rxParamSetupReq = (*it)->GetObject<
RxParamSetupReq>();
437 NS_LOG_DEBUG(
"Detected a DevStatusReq command.");
440 Ptr<DevStatusReq> devStatusReq = (*it)->GetObject<
DevStatusReq>();
448 NS_LOG_DEBUG(
"Detected a NewChannelReq command.");
451 Ptr<NewChannelReq> newChannelReq = (*it)->GetObject<
NewChannelReq>();
455 newChannelReq->GetFrequency(),
456 newChannelReq->GetMinDataRate(),
457 newChannelReq->GetMaxDataRate());
470 NS_LOG_ERROR(
"CID not recognized");
480 NS_LOG_FUNCTION_NOARGS();
494 NS_LOG_INFO(
"Applying a MAC Command of CID " <<
unsigned(
504 NS_LOG_FUNCTION_NOARGS();
514 NS_LOG_DEBUG(
"Message type is set to " << mType);
531 NS_LOG_FUNCTION_NOARGS();
538 NS_LOG_FUNCTION_NOARGS();
543 std::vector<Ptr<LoraLogicalChannel>> logicalChannels;
548 Time waitingTime = Time::Max();
551 std::vector<Ptr<LoraLogicalChannel>>::iterator it;
552 for (it = logicalChannels.begin(); it != logicalChannels.end(); ++it)
555 Ptr<LoraLogicalChannel> logicalChannel = *it;
556 double frequency = logicalChannel->GetFrequency();
560 NS_LOG_DEBUG(
"Waiting time before the next transmission in channel with frequecy "
561 << frequency <<
" is = " << waitingTime.GetSeconds() <<
".");
569 Ptr<LoraLogicalChannel>
572 NS_LOG_FUNCTION_NOARGS();
575 std::vector<Ptr<LoraLogicalChannel>> logicalChannels;
578 logicalChannels =
Shuffle(logicalChannels);
581 std::vector<Ptr<LoraLogicalChannel>>::iterator it;
582 for (it = logicalChannels.begin(); it != logicalChannels.end(); ++it)
585 Ptr<LoraLogicalChannel> logicalChannel = *it;
586 double frequency = logicalChannel->GetFrequency();
588 NS_LOG_DEBUG(
"Frequency of the current channel: " << frequency);
593 NS_LOG_DEBUG(
"Waiting time for current channel = " << waitingTime.GetSeconds());
596 if (waitingTime == Seconds(0))
602 NS_LOG_DEBUG(
"Packet cannot be immediately transmitted on "
603 <<
"the current channel because of duty cycle limitations.");
609 std::vector<Ptr<LoraLogicalChannel>>
612 NS_LOG_FUNCTION_NOARGS();
614 int size = vector.size();
616 for (
int i = 0; i < size; ++i)
618 uint16_t random = std::floor(
m_uniformRV->GetValue(0, size));
619 Ptr<LoraLogicalChannel> temp = vector.at(random);
620 vector.at(random) = vector.at(i);
646 NS_LOG_FUNCTION(
this << adapt);
659 NS_LOG_FUNCTION(
this <<
unsigned(maxNumbTx));
667 NS_LOG_FUNCTION(
this);
674 NS_LOG_FUNCTION(
this <<
unsigned(dataRate));
682 NS_LOG_FUNCTION(
this);
690 NS_LOG_FUNCTION(
this << address);
698 NS_LOG_FUNCTION(
this);
706 NS_LOG_FUNCTION(
this <<
unsigned(margin) <<
unsigned(gwCnt));
715 std::list<int> enabledChannels,
718 NS_LOG_FUNCTION(
this <<
unsigned(dataRate) <<
unsigned(txPower) << repetitions);
721 bool channelMaskOk =
true;
722 bool dataRateOk =
true;
723 bool txPowerOk =
true;
729 int channelListSize = channelList.size();
731 for (
auto it = enabledChannels.begin(); it != enabledChannels.end(); it++)
733 if ((*it) > channelListSize)
735 channelMaskOk =
false;
749 NS_LOG_DEBUG(
"SF: " <<
unsigned(sf) <<
", BW: " << bw);
750 if (sf == 0 || bw == 0)
753 NS_LOG_DEBUG(
"Data rate non valid");
759 if (dataRateOk && channelMaskOk)
761 bool foundAvailableChannel =
false;
762 for (
auto it = enabledChannels.begin(); it != enabledChannels.end(); it++)
764 NS_LOG_DEBUG(
"MinDR: " <<
unsigned(channelList.at(*it)->GetMinimumDataRate()));
765 NS_LOG_DEBUG(
"MaxDR: " <<
unsigned(channelList.at(*it)->GetMaximumDataRate()));
766 if (channelList.at(*it)->GetMinimumDataRate() <= dataRate &&
767 channelList.at(*it)->GetMaximumDataRate() >= dataRate)
769 foundAvailableChannel =
true;
774 if (!foundAvailableChannel)
777 NS_LOG_DEBUG(
"Available channel not found");
789 NS_LOG_DEBUG(
"Finished checking. "
790 <<
"ChannelMaskOk: " << channelMaskOk <<
", "
791 <<
"DataRateOk: " << dataRateOk <<
", "
792 <<
"txPowerOk: " << txPowerOk);
796 if (channelMaskOk && dataRateOk && txPowerOk)
801 if (std::find(enabledChannels.begin(), enabledChannels.end(), i) !=
802 enabledChannels.end())
805 NS_LOG_DEBUG(
"Channel " << i <<
" enabled");
810 NS_LOG_DEBUG(
"Channel " << i <<
" disabled");
823 m_macCommandList.push_back(CreateObject<LinkAdrAns>(txPowerOk, dataRateOk, channelMaskOk));
829 NS_LOG_FUNCTION(
this << dutyCycle);
832 NS_ASSERT(0 <= dutyCycle && dutyCycle < 1);
838 NS_LOG_INFO(
"Adding DutyCycleAns reply");
850 NS_LOG_FUNCTION(
this << rxParamSetupReq);
859 NS_LOG_FUNCTION(
this);
861 uint8_t battery = 10;
865 NS_LOG_INFO(
"Adding DevStatusAns reply");
875 NS_LOG_FUNCTION(
this);
877 bool dataRateRangeOk =
true;
878 bool channelFrequencyOk =
true;
885 NS_LOG_INFO(
"Adding NewChannelAns reply");
886 m_macCommandList.push_back(CreateObject<NewChannelAns>(dataRateRangeOk, channelFrequencyOk));
892 NS_LOG_FUNCTION(
this << frequency);
900 NS_LOG_FUNCTION(
this << logicalChannel);
911 NS_LOG_FUNCTION(
this <<
unsigned(chIndex) << frequency <<
unsigned(minDataRate)
912 <<
unsigned(maxDataRate));
916 CreateObject<LoraLogicalChannel>(frequency, minDataRate, maxDataRate));
923 double maxTxPowerDbm)
925 NS_LOG_FUNCTION_NOARGS();
933 NS_LOG_FUNCTION_NOARGS();
941 NS_LOG_FUNCTION(
this << macCommand);
955 NS_LOG_FUNCTION(
this << &cb);
962 NS_LOG_FUNCTION(
this << gwAddress);
Implementation of the DevStatusReq LoRaWAN MAC command.
Implementation of the DutyCycleReq LoRaWAN MAC command.
Implementation of the LinkAdrReq LoRaWAN MAC command.
Implementation of the LinkCheckAns LoRaWAN MAC command.
This class represents the device address of a LoraWAN End Device.
Time GetWaitingTime(Ptr< LoraLogicalChannel > channel)
Get the time it is necessary to wait for before transmitting on a given channel.
void AddLoraSubBand(double firstFrequency, double lastFrequency, double dutyCycle, double maxTxPowerDbm)
Add a new LoraSubBand to this helper.
void SetChannel(uint8_t chIndex, Ptr< LoraLogicalChannel > logicalChannel)
Set a new channel at a fixed index.
void AddChannel(double frequency)
Add a new channel to the list.
std::vector< Ptr< LoraLogicalChannel > > GetChannelList(void)
Get the list of LoraLogicalChannels currently registered on this helper.
std::vector< Ptr< LoraLogicalChannel > > GetEnabledChannelList(void)
Get the list of LoraLogicalChannels currently registered on this helper that have been enabled for Up...
double GetTxPowerForChannel(Ptr< LoraLogicalChannel > logicalChannel)
Returns the maximum transmission power [dBm] that is allowed on a channel.
static uint8_t GetCIDFromLorawanMacCommand(enum MacCommandType commandType)
Get the CID that corresponds to this MAC command.
void SetDeviceAddress(LoraDeviceAddress address)
Set the network address of this device.
Time GetNextTransmissionDelay(void)
Find the minimum waiting time before the next possible transmission.
std::list< Ptr< LorawanMacCommand > > m_macCommandList
List of the MAC commands that need to be applied to the next UL packet.
uint8_t GetDataRate(void)
Get the data rate this end device is set to use.
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.
uint8_t GetMaxNumberOfTransmissions(void)
Set the maximum number of transmissions allowed.
bool m_enableDRAdapt
Enable Data Rate adaptation during the retransmission procedure.
static TypeId GetTypeId(void)
EventId m_nextTx
The event of retransmitting a packet in a consecutive moment if an ACK is not received.
virtual void FailedReception(Ptr< const Packet > packet)
Function called by lower layers to inform this layer that reception of a packet we were locked on fai...
TracedValue< double > m_txPower
The transmission power this device is using to transmit.
TracedCallback< uint8_t, bool, Time, Ptr< Packet > > m_requiredTxCallback
The trace source fired when the transmission procedure is finished.
LorawanMacHeader::MType m_mType
The message type to apply to packets sent with the Send method.
void OnLinkCheckAns(uint8_t margin, uint8_t gwCnt)
Perform the actions that need to be taken when receiving a LinkCheckAns command.
Callback< void, Mac48Address > GatewayUpdateCallback
Callback to update gateway address after handover.
LorawanMacHeader::MType GetMType(void)
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 SetMType(LorawanMacHeader::MType mType)
Set the message type to send when the Send method is called.
bool GetDataRateAdaptation(void)
Get if data rate adaptation is enabled or not.
TracedValue< double > m_aggregatedDutyCycle
The aggregated duty cycle this device needs to respect across all sub-bands.
virtual void postponeTransmission(Time nextTxDelay, Ptr< Packet >)
Postpone transmission to the specified time and delete previously scheduled transmissions if present.
LorawanMacEndDevice::GatewayUpdateCallback m_gatewayUpdateCallback
Gateway address update callback.
void SetPhyRx(Ptr< SatLoraPhyRx > phyRx)
Ptr< LoraLogicalChannel > GetChannelForTx(void)
Find a suitable channel for transmission.
Ptr< SatLoraPhyRx > m_phyRx
Reception phy layer for Lora operations.
double GetAggregatedDutyCycle(void)
Set a value for the RX1DROffset parameter.
TracedValue< double > m_lastKnownLinkMargin
The last known link margin.
uint8_t m_maxNumbTx
Maximum number of transmission allowed.
bool m_controlDataRate
Whether this device's data rate should be controlled by the NS.
uint32_t m_raChannel
RA channel assigned to the UT.
virtual void SendToPhy(Ptr< Packet > packet)
Add headers and send a packet with the sending function of the physical layer.
Ptr< SatLoraPhyRx > GetPhyRx()
void SetDataRateAdaptation(bool adapt)
Enable data rate adaptation in the retransmitting procedure.
void OnDevStatusReq(void)
Perform the actions that need to be taken when receiving a DevStatusReq command.
Ptr< UniformRandomVariable > m_uniformRV
An uniform random variable, used by the Shuffle method to randomly reorder the channel list.
virtual void Send(Ptr< Packet > packet)
Send a packet.
void SetDataRate(uint8_t dataRate)
Set the data rate this end device will use when transmitting.
void AddLogicalChannel(double frequency)
Add a logical channel to the helper.
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.
void AddLorawanMacCommand(Ptr< LorawanMacCommand > macCommand)
Add a MAC command to the list of those that will be sent out in the next packet.
void AddLoraSubBand(double startFrequency, double endFrequency, double dutyCycle, double maxTxPowerDbm)
Add a subband to the logical channel helper.
void SetLogicalChannel(uint8_t chIndex, double frequency, uint8_t minDataRate, uint8_t maxDataRate)
Set a new logical channel in the helper.
void SetRaChannel(uint32_t raChannel)
Set RA channel assigned for this UT.
TracedValue< uint8_t > m_dataRate
The DataRate this device is using to transmit.
LoraDeviceAddress GetDeviceAddress(void)
Get the network address of this device.
TracedValue< int > m_lastKnownGatewayCount
The last known gateway count (i.e., gateways that are in communication range with this end device)
virtual void TxFinished()
Perform the actions that are required after a packet send.
void ParseCommands(LoraFrameHeader frameHeader)
Parse and take action on the commands contained on this FrameHeader.
void SetGwAddress(Mac48Address gwAddress)
Set address of the GW (or its MAC) serving this UT.
std::vector< Ptr< LoraLogicalChannel > > Shuffle(std::vector< Ptr< LoraLogicalChannel >> vector)
Randomly shuffle a Ptr<LoraLogicalChannel> vector.
virtual void resetRetransmissionParameters()
Reset retransmission parameters contained in the structure LoraRetxParams.
virtual uint8_t GetTransmissionPower(void)
Get the transmission power this end device is set to use.
void SetGatewayUpdateCallback(LorawanMacEndDevice::GatewayUpdateCallback cb)
Method to set the gateway address update callback.
LoraDeviceAddress m_address
The address of this device.
struct LoraRetxParameters m_retxParams
void ApplyNecessaryOptions(LoraFrameHeader &frameHeader)
Add the necessary options and MAC commands to the LoraFrameHeader.
virtual void Receive(Ptr< Packet > packet)=0
Receive a packet.
virtual void OnRxClassParamSetupReq(Ptr< RxParamSetupReq > rxParamSetupReq)
Perform the actions that need to be taken when receiving a RxParamSetupReq command based on the Devic...
virtual Time GetNextClassTransmissionDelay(Time waitingTime)
Find the minimum waiting time before the next possible transmission based on End Device's Class Type.
void OnDutyCycleReq(double dutyCycle)
Perform the actions that need to be taken when receiving a DutyCycleReq command.
void OnRxParamSetupReq(Ptr< RxParamSetupReq > rxParamSetupReq)
Perform the actions that need to be taken when receiving a RxParamSetupReq command.
virtual ~LorawanMacEndDevice()
void SetMaxNumberOfTransmissions(uint8_t maxNumbTx)
Set the maximum number of transmissions allowed.
Class representing the LoRaWAN MAC layer.
std::vector< uint32_t > m_maxAppPayloadForDataRate
A vector holding the maximum app payload size that corresponds to a certain DataRate.
TracedCallback< Ptr< const Packet > > m_cannotSendBecauseDutyCycle
The trace source that is fired when a packet cannot be sent because of duty cycle limitations.
TracedCallback< Ptr< const Packet > > m_sentNewPacket
Trace source that is fired when a new APP layer packet arrives at the MAC layer.
uint8_t GetSfFromDataRate(uint8_t dataRate)
Get the SF corresponding to a data rate, based on this MAC's region.
double GetDbmForTxPower(uint8_t txPower)
Get the transmission power in dBm that corresponds, in this region, to the encoded 8-bit txPower.
LoraLogicalChannelHelper m_channelHelper
The LoraLogicalChannelHelper instance that is assigned to this MAC.
double GetBandwidthFromDataRate(uint8_t dataRate)
Get the BW corresponding to a data rate, based on this MAC's region.
Implementation of the NewChannelReq LoRaWAN MAC command.
Implementation of the RxParamSetupReq LoRaWAN MAC command.
SatSignalParameters::PacketsInBurst_t PacketContainer_t
Define PacketContainer in SatPhy.
Time tag used to identify the time when packet is enqueued at PHY on current link level.
Time tag used to identify the time when packet is enqueued at PHY on first link between GW and UT lev...
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.
MacCommandType
Enum for every possible command type.
Structure representing the parameters that will be used in the retransmission procedure.