A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
end-device-lorawan-mac.h
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
12#ifndef END_DEVICE_LORAWAN_MAC_H
13#define END_DEVICE_LORAWAN_MAC_H
14
15#include "lora-frame-header.h"
16#include "lorawan-mac-header.h"
17#include "lorawan-mac.h"
18
19#include "ns3/random-variable-stream.h"
20#include "ns3/traced-value.h"
21
22namespace ns3
23{
24namespace lorawan
25{
26
27enum class CodingRate : uint8_t;
28
29/**
30 * @ingroup lorawan
31 *
32 * Class representing the MAC layer of a LoRaWAN device.
33 */
35{
36 public:
37 /**
38 * Register this type.
39 * @return The object TypeId.
40 */
41 static TypeId GetTypeId();
42
43 EndDeviceLorawanMac(); //!< Default constructor
44 ~EndDeviceLorawanMac() override; //!< Destructor
45
46 /////////////////////
47 // Sending methods //
48 /////////////////////
49
50 /**
51 * Send a packet.
52 *
53 * The MAC layer of the end device will take care of using the right parameters.
54 *
55 * @param packet The packet to send.
56 */
57 void Send(Ptr<Packet> packet) override;
58
59 /**
60 * Checking if we are performing the transmission of a new packet or a retransmission, and call
61 * SendToPhy function.
62 *
63 * @param packet The packet to send.
64 */
65 virtual void DoSend(Ptr<Packet> packet);
66
67 /**
68 * Add headers and send a packet with the sending function of the physical layer.
69 *
70 * @param packet The packet to send.
71 */
72 virtual void SendToPhy(Ptr<Packet> packet);
73
74 /**
75 * Postpone transmission to the specified time and delete previously scheduled transmissions if
76 * present.
77 *
78 * @param nextTxDelay Delay at which the transmission will be performed.
79 * @param packet The packet to delay the transmission of.
80 */
81 virtual void PostponeTransmission(Time nextTxDelay, Ptr<Packet> packet);
82
83 ///////////////////////
84 // Receiving methods //
85 ///////////////////////
86
87 void Receive(Ptr<const Packet> packet) override;
88
89 void FailedReception(Ptr<const Packet> packet) override;
90
91 void TxFinished(Ptr<const Packet> packet) override;
92
93 /////////////////////////
94 // Getters and Setters //
95 /////////////////////////
96
97 /**
98 * Reset retransmission parameters contained in the structure LoraRetxParams.
99 */
100 virtual void ResetRetransmissionParameters();
101
102 /**
103 * Signals to the network server that this device will or may not comply with LinkADRReq
104 * settings (data rate, transmission power and number of retransmissions) received in downlink.
105 * This also controls whether the local ADR backoff procedure can reset configurations in case
106 * of connectivity loss. A false value effectively allows for a fully static transmission
107 * parameters configuration.
108 *
109 * @note Setting this to false does not prevent the device from setting the ADRACKReq bit
110 * in its FHDR to request a keepalive downlink message from the server.
111 *
112 * @param adr The ADR bit.
113 */
114 void SetUplinkAdrBit(bool adr);
115
116 /**
117 * Get the current value of the device's uplink ADR bit of the LoRaWAN FHDR.
118 *
119 * @return true The device will comply with data rate, transmission power and number of
120 * retransmissions settings received from the network server via LinkADRReq.
121 * @return false Signals to the network server that the device may not comply with the data
122 * rate, transmission power and number of retransmissions settings received via LikADRReq.
123 */
124 bool GetUplinkAdrBit() const;
125
126 /**
127 * Set the max number of unacknowledged redundant transmissions of each packet. If,
128 * after a transmission, any acknowledgement is received, no more are sent for that packet.
129 *
130 * @param nbTrans The number of transmissions.
131 */
132 void SetMaxNumberOfTransmissions(uint8_t nbTrans);
133
134 /**
135 * Get the max number of unacknowledged redundant transmissions of each packet. If,
136 * after a transmission, any acknowledgement is received, no more are sent for that packet.
137 *
138 * @return The number of transmissions as uint8_t.
139 */
141
142 /**
143 * Set the data rate this end device will use when transmitting. For End
144 * Devices, this value is assumed to be fixed, and can be modified via MAC
145 * commands issued by the gateway.
146 *
147 * @param dataRate The dataRate to use when transmitting.
148 */
149 void SetDataRate(uint8_t dataRate);
150
151 /**
152 * Get the data rate this end device is set to use.
153 *
154 * @return The data rate this device uses when transmitting.
155 */
156 uint8_t GetDataRate();
157
158 /**
159 * Get the transmission power this end device is set to use.
160 *
161 * @return The transmission ERP [dBm] this device uses when transmitting.
162 */
164
165 /**
166 * Set the transmission power of this end device.
167 *
168 * @param txPowerDbm The transmission ERP [dBm] value.
169 */
170 void SetTransmissionPowerDbm(double txPowerDbm);
171
172 /**
173 * Set the network address of this device.
174 *
175 * @param address The address to set.
176 */
178
179 /**
180 * Get the network address of this device.
181 *
182 * @return This device's address.
183 */
185
186 // void SetRx1DrOffset (uint8_t rx1DrOffset);
187
188 // uint8_t GetRx1DrOffset ();
189
190 /**
191 * Get the last known link margin from the demodulation floor.
192 *
193 * This is intended for asynchronous polling by the Application layer of the device. For
194 * synchronous behavior provide a callback using the trace system.
195 *
196 * @return The last known link margin [dB]
197 */
198 uint8_t GetLastKnownLinkMarginDb() const;
199
200 /**
201 * Get the last known number of gateways concurrently receiving transmissions from the device.
202 *
203 * This is intended for asynchronous polling by the Application layer of the device. For
204 * synchronous behavior provide a callback using the trace system.
205 *
206 * @return The last known number of receiver gateways.
207 */
208 uint8_t GetLastKnownGatewayCount() const;
209
210 /**
211 * Get the aggregated duty cycle.
212 *
213 * @return A time instance containing the aggregated duty cycle in fractional form.
214 */
215 double GetAggregatedDutyCycle();
216
217 /////////////////////////
218 // MAC command methods //
219 /////////////////////////
220
221 /**
222 * Add the necessary options and MAC commands to the LoraFrameHeader.
223 *
224 * @param frameHeader The frame header on which to apply the options.
225 */
226 void ApplyNecessaryOptions(LoraFrameHeader& frameHeader);
227
228 /**
229 * Add the necessary options and MAC commands to the LorawanMacHeader.
230 *
231 * @param macHeader The mac header on which to apply the options.
232 */
234
235 /**
236 * Set the message type to send when the Send method is called.
237 *
238 * @param mType The message type.
239 */
241
242 /**
243 * Get the message type to send when the Send method is called.
244 *
245 * @return The message type.
246 */
248
249 /**
250 * Parse and take action on the commands contained on this FrameHeader.
251 *
252 * @param frameHeader The frame header.
253 */
254 void ParseCommands(LoraFrameHeader frameHeader);
255
256 /**
257 * Perform the actions that need to be taken when receiving a LinkCheckAns command.
258 *
259 * @param margin The margin value of the command.
260 * @param gwCnt The gateway count value of the command.
261 */
262 void OnLinkCheckAns(uint8_t margin, uint8_t gwCnt);
263
264 /**
265 * Perform the actions that need to be taken when receiving a LinkAdrReq command.
266 *
267 * @param dataRate The data rate value of the command.
268 * @param txPower The transmission power value of the command.
269 * @param chMask Mask of enabled channels of the command.
270 * @param chMaskCntl Indicator of the 16 channel bank to apply the chMask to.
271 * @param nbTrans The number of repetitions prescribed by the command.
272 */
273 void OnLinkAdrReq(uint8_t dataRate,
274 uint8_t txPower,
275 uint16_t chMask,
276 uint8_t chMaskCntl,
277 uint8_t nbTrans);
278
279 /**
280 * Perform the actions that need to be taken when receiving a DutyCycleReq command.
281 *
282 * @param maxDutyCycle The aggregate duty cycle encoded by the command.
283 */
284 void OnDutyCycleReq(uint8_t maxDutyCycle);
285
286 /**
287 * Perform the actions that need to be taken when receiving a RxParamSetupReq
288 * command based on the Device's Class Type.
289 *
290 * @param rx1DrOffset The first reception window data rate offset to set.
291 * @param rx2DataRate The data rate to use for the second receive window.
292 * @param frequencyHz The frequency [Hz] to use for the second receive window.
293 */
294 virtual void OnRxParamSetupReq(uint8_t rx1DrOffset,
295 uint8_t rx2DataRate,
296 double frequencyHz) = 0;
297
298 /**
299 * Perform the actions that need to be taken when receiving a DevStatusReq command.
300 */
301 void OnDevStatusReq();
302
303 /**
304 * Perform the actions that need to be taken when receiving a NewChannelReq command.
305 *
306 * @param chIndex The ChIndex field of the received NewChannelReq command.
307 * @param frequencyHz The Frequency [Hz] field of the received NewChannelReq command.
308 * @param minDataRate The MinDR field of the received NewChannelReq command.
309 * @param maxDataRate The MaxDR field of the received NewChannelReq command.
310 */
311 void OnNewChannelReq(uint8_t chIndex,
312 uint32_t frequencyHz,
313 uint8_t minDataRate,
314 uint8_t maxDataRate);
315
316 /**
317 * Add a MAC command to the list of those that will be sent out in the next
318 * packet.
319 *
320 * @param macCommand A pointer to the MAC command.
321 */
322 void AddMacCommand(Ptr<MacCommand> macCommand);
323
324 static constexpr uint16_t ADR_ACK_LIMIT = 64; //!< ADRACKCnt threshold for setting ADRACKReq
325 static constexpr uint16_t ADR_ACK_DELAY = 32; //!< ADRACKCnt threshold for ADR backoff action
326
327 protected:
328 /**
329 * Structure representing the parameters that will be used in the
330 * retransmission procedure.
331 */
333 {
334 Time firstAttempt; //!< Timestamp of the first transmission of the packet
335 Ptr<Packet> packet = nullptr; //!< A pointer to the packet being retransmitted
336 bool waitingAck = false; //!< Whether the packet requires explicit acknowledgment
337 uint8_t retxLeft; //!< Number of retransmission attempts left
338 };
339
340 uint8_t m_nbTrans; //!< Default number of unacknowledged redundant transmissions of each packet.
341 TracedValue<uint8_t> m_dataRate; //!< The data rate this device is using to transmit.
343 m_txPowerDbm; //!< The transmission ERP [dBm] this device is currently using.
344 CodingRate m_codingRate; //!< The coding rate used by this device.
345 bool m_headerDisabled; //!< Whether or not the LoRa PHY header is disabled for communications by
346 //!< this device.
347 LoraDeviceAddress m_address; //!< The address of this device.
348
349 /**
350 * Find the minimum wait time before the next possible transmission based
351 * on end device's Class Type.
352 *
353 * @param waitTime Currently known minimum wait time, possibly raised by this function.
354 * @return The updated minimum wait time in Time format.
355 */
356 virtual Time GetNextClassTransmissionDelay(Time waitTime);
357
358 /**
359 * Find a suitable channel for transmission. The channel is chosen randomly among the
360 * ones that are available in the end device, based on their duty cycle limitations.
361 *
362 * @return A pointer to the channel.
363 */
365
366 /**
367 * The duration of a receive window in number of symbols. This should be
368 * converted to time based or the reception parameter used.
369 *
370 * The downlink preamble transmitted by the gateways contains 8 symbols.
371 * The receiver requires 5 symbols to detect the preamble and synchronize.
372 * Therefore there must be a 5 symbols overlap between the receive window
373 * and the transmitted preamble.
374 * (Ref: Recommended SX1272/76 Settings for EU868 LoRaWAN Network Operation )
375 */
377
378 /**
379 * List of the MAC commands that need to be applied to the next UL packet.
380 */
381 std::list<Ptr<MacCommand>> m_macCommandList;
382
383 /**
384 * Structure containing the retransmission parameters for this device.
385 */
387
388 /**
389 * An uniform random variable, used to randomly pick from the channel list.
390 */
392
393 /**
394 * Used to record the last reception SNR measurement to be included in the DevStatusAns.
395 */
397
398 uint16_t m_adrAckCnt; //!< ADRACKCnt counter of the number of consecutive uplinks without
399 //!< downlink reply from the server. Reset upon reception of any Class A
400 //!< downlink destined to the device.
401
402 /////////////////
403 // Callbacks //
404 /////////////////
405
406 /**
407 * The trace source fired when the transmission procedure is finished.
408 */
410
411 private:
412 /**
413 * Get the set of active transmission channels compatible with the current device data rate and
414 * transmission power.
415 *
416 * @return A (possibly empty) vector of compatible transmission channels.
417 */
418 std::vector<Ptr<LogicalLoraChannel>> GetCompatibleTxChannels();
419
420 /**
421 * Find the base minimum wait time before the next possible transmission.
422 *
423 * @return The base minimum wait time.
424 */
426
427 /**
428 * Execute ADR backoff as in LoRaWAN specification, V1.0.4 (2020)
429 */
430 void ExecuteADRBackoff();
431
432 /**
433 * Check whether the size of the application payload is under the maximum allowed.
434 *
435 * From LoRaWAN L2 1.0.4 Specification (TS001-1.0.4), Section 4.3.2: "N is the number of octets
436 * of the application payload and SHALL be equal to or less than N ≤ M − 1 − (length of FHDR in
437 * octets), where M is the maximum MACPayload length. The valid ranges of both N and M are
438 * region-specific and defined in the “LoRaWAN Regional Parameters” [RP002] document."
439 *
440 * @param appPayloadSize Number of bytes of the application payload.
441 * @param dataRate Data rate to evaluate the max MACPayload for.
442 * @return Whether the payload size is valid.
443 */
444 bool IsPayloadSizeValid(uint32_t appPayloadSize, uint8_t dataRate);
445
446 bool m_adr; //!< Uplink ADR bit contained in the FCtrl field of the LoRaWAN FHDR.
447 //!< Controlled by the device, if set to false signals the network server
448 //!< that the device may not accept attempts to control the number of
449 //!< retransmissions, the data rate, or the TX power with downlink
450 //!< LinkADRReq commands. This also allows the device's local ADR backoff
451 //!< procedure to reset configurations in case of connectivity loss.
452
453 /**
454 * The event of retransmitting a packet in a consecutive moment if an ACK is not received.
455 *
456 * This Event is used to cancel the retransmission if the ACK is found in ParseCommand function
457 * and if a newer packet is delivered from the application to be sent.
458 */
460
461 /**
462 * The event of transmitting a packet in a consecutive moment, when the duty cycle let us
463 * transmit.
464 *
465 * This Event is used to cancel the transmission of this packet if a newer packet is delivered
466 * from the application to be sent.
467 */
469
470 /**
471 * The last known link margin in dB from the demodulation floor.
472 *
473 * This value is obtained (and updated) when a LinkCheckAns Mac command is
474 * received.
475 */
477
478 /**
479 * The last known gateway count (i.e., gateways that are in communication
480 * range with this end device).
481 *
482 * This value is obtained (and updated) when a LinkCheckAns Mac command is
483 * received.
484 */
486
487 /**
488 * The aggregated duty cycle this device needs to respect across all sub-bands.
489 */
491
492 /**
493 * The message type to apply to packets sent with the Send method.
494 */
496
497 /**
498 * current value of the device frame counter.
499 */
501
502 bool m_adrAckReq; //!< ADRACKReq bit, set to 1 after ADR_ACK_LIMIT consecutive uplinks without
503 //!< downlink messages received from the server. It requests the server to
504 //!< send a downlink for keepalive purposes.
505};
506
507} // namespace lorawan
508} // namespace ns3
509
510#endif /* END_DEVICE_LORAWAN_MAC_H */
An identifier for simulation events.
Definition event-id.h:45
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
Simulation virtual time values and global simulation resolution.
Definition nstime.h:95
Forward calls to a chain of Callback.
Trace classes with value semantics.
a unique identifier for an interface.
Definition type-id.h:50
LorawanMacHeader::MType m_mType
The message type to apply to packets sent with the Send method.
Ptr< LogicalLoraChannel > GetRandomChannelForTx()
Find a suitable channel for transmission.
virtual void ResetRetransmissionParameters()
Reset retransmission parameters contained in the structure LoraRetxParams.
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...
bool m_headerDisabled
Whether or not the LoRa PHY header is disabled for communications by this device.
void OnLinkAdrReq(uint8_t dataRate, uint8_t txPower, uint16_t chMask, uint8_t chMaskCntl, uint8_t nbTrans)
Perform the actions that need to be taken when receiving a LinkAdrReq command.
void OnDutyCycleReq(uint8_t maxDutyCycle)
Perform the actions that need to be taken when receiving a DutyCycleReq command.
TracedValue< double > m_txPowerDbm
The transmission ERP [dBm] this device is currently using.
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.
double GetTransmissionPowerDbm()
Get the transmission power this end device is set to use.
bool m_adr
Uplink ADR bit contained in the FCtrl field of the LoRaWAN FHDR.
void TxFinished(Ptr< const Packet > packet) override
Perform actions after sending a packet.
void SetUplinkAdrBit(bool adr)
Signals to the network server that this device will or may not comply with LinkADRReq settings (data ...
bool m_adrAckReq
ADRACKReq bit, set to 1 after ADR_ACK_LIMIT consecutive uplinks without downlink messages received fr...
Ptr< UniformRandomVariable > m_uniformRV
An uniform random variable, used to randomly pick from the channel list.
static constexpr uint16_t ADR_ACK_DELAY
ADRACKCnt threshold for ADR backoff action.
static TypeId GetTypeId()
Register this type.
uint8_t GetLastKnownLinkMarginDb() const
Get the last known link margin from the demodulation floor.
TracedValue< double > m_aggregatedDutyCycle
The aggregated duty cycle this device needs to respect across all sub-bands.
EventId m_nextRetx
The event of transmitting a packet in a consecutive moment, when the duty cycle let us transmit.
double GetAggregatedDutyCycle()
Get the aggregated duty cycle.
void Receive(Ptr< const Packet > packet) override
Receive a packet from the lower layer.
void SetMType(LorawanMacHeader::MType mType)
Set the message type to send when the Send method is called.
uint16_t m_adrAckCnt
ADRACKCnt counter of the number of consecutive uplinks without downlink reply from the server.
std::vector< Ptr< LogicalLoraChannel > > GetCompatibleTxChannels()
Get the set of active transmission channels compatible with the current device data rate and transmis...
void ParseCommands(LoraFrameHeader frameHeader)
Parse and take action on the commands contained on this FrameHeader.
bool IsPayloadSizeValid(uint32_t appPayloadSize, uint8_t dataRate)
Check whether the size of the application payload is under the maximum allowed.
virtual void OnRxParamSetupReq(uint8_t rx1DrOffset, uint8_t rx2DataRate, double frequencyHz)=0
Perform the actions that need to be taken when receiving a RxParamSetupReq command based on the Devic...
CodingRate m_codingRate
The coding rate used by this device.
void OnNewChannelReq(uint8_t chIndex, uint32_t frequencyHz, uint8_t minDataRate, uint8_t maxDataRate)
Perform the actions that need to be taken when receiving a NewChannelReq command.
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.
uint8_t GetMaxNumberOfTransmissions()
Get the max number of unacknowledged redundant transmissions of each packet.
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 SetMaxNumberOfTransmissions(uint8_t nbTrans)
Set the max number of unacknowledged redundant transmissions of each packet.
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.
bool GetUplinkAdrBit() const
Get the current value of the device's uplink ADR bit of the LoRaWAN FHDR.
void Send(Ptr< Packet > packet) override
Send a packet.
uint16_t m_currentFCnt
current value of the device frame counter.
uint8_t GetLastKnownGatewayCount() const
Get the last known number of gateways concurrently receiving transmissions from the device.
void AddMacCommand(Ptr< MacCommand > macCommand)
Add a MAC command to the list of those that will be sent out in the next packet.
static constexpr uint16_t ADR_ACK_LIMIT
ADRACKCnt threshold for setting ADRACKReq.
Time GetNextTransmissionDelay()
Find the base minimum wait time before the next possible transmission.
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.
double m_lastRxSnr
Used to record the last reception SNR measurement to be included in the DevStatusAns.
TracedValue< uint8_t > m_lastKnownGatewayCount
The last known gateway count (i.e., gateways that are in communication range with this end device).
uint8_t m_nbTrans
Default number of unacknowledged redundant transmissions of each packet.
void SetDataRate(uint8_t dataRate)
Set the data rate this end device will use when transmitting.
uint8_t m_receiveWindowDurationInSymbols
The duration of a receive window in number of symbols.
TracedValue< uint8_t > m_lastKnownLinkMarginDb
The last known link margin in dB from the demodulation floor.
void SetTransmissionPowerDbm(double txPowerDbm)
Set the transmission power of this end device.
uint8_t GetDataRate()
Get the data rate this end device is set to use.
virtual Time GetNextClassTransmissionDelay(Time waitTime)
Find the minimum wait time before the next possible transmission based on end device's Class Type.
void ExecuteADRBackoff()
Execute ADR backoff as in LoRaWAN specification, V1.0.4 (2020).
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.
This class represents the Mac header of a LoRaWAN packet.
LorawanMac()
Default constructor.
CodingRate
Enumeration of the LoRa supported coding rates.
Definition lora-phy.h:30
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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.