Loading...
Searching...
No Matches
lorawan-mac-end-device-class-a.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2017 University of Padova
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Davide Magrin <magrinda@dei.unipd.it>
19 * Martina Capuzzo <capuzzom@dei.unipd.it>
20 *
21 * Modified by: Peggy Anderson <peggy.anderson@usask.ca>
22 * qiuyukang <b612n@qq.com>
23 * Bastien Tauran <bastien.tauran@viveris.fr>
24 */
25
27
28#include "lora-tag.h"
32#include "satellite-phy.h"
33
34#include "ns3/log.h"
35#include "ns3/pointer.h"
36
37#include <algorithm>
38
39namespace ns3
40{
41
42NS_LOG_COMPONENT_DEFINE("LorawanMacEndDeviceClassA");
43
44NS_OBJECT_ENSURE_REGISTERED(LorawanMacEndDeviceClassA);
45
46TypeId
48{
49 static TypeId tid =
50 TypeId("ns3::LorawanMacEndDeviceClassA")
51 .SetParent<LorawanMacEndDevice>()
52 .AddAttribute("FirstWindowDelay",
53 "Time to wait between end of message transmission and opening of first "
54 "reception window",
55 TimeValue(Seconds(1)),
57 MakeTimeChecker())
58 .AddAttribute("SecondWindowDelay",
59 "Time to wait between end of message transmission and opening of second "
60 "reception window",
61 TimeValue(Seconds(2)),
63 MakeTimeChecker())
64 .AddAttribute("FirstWindowDuration",
65 "Duration of first reception window",
66 TimeValue(MilliSeconds(100)),
68 MakeTimeChecker())
69 .AddAttribute("SecondWindowDuration",
70 "Duration of second reception window",
71 TimeValue(MilliSeconds(100)),
73 MakeTimeChecker())
74 .AddConstructor<LorawanMacEndDeviceClassA>();
75 return tid;
76}
77
79{
80 NS_FATAL_ERROR("Default constructor not in use");
81}
82
84 uint32_t satId,
85 uint32_t beamId,
86 Ptr<SatSuperframeSeq> seq)
87 : LorawanMacEndDevice(node, satId, beamId),
88 m_superframeSeq(seq),
89 m_firstWindowDelay(Seconds(1)),
90 m_secondWindowDelay(Seconds(2)),
91 m_firstWindowDuration(MilliSeconds(100)),
92 m_secondWindowDuration(MilliSeconds(100)),
94{
95 NS_LOG_FUNCTION(this);
96}
97
98void
100{
101 NS_LOG_FUNCTION(this);
102
103 LorawanMacEndDevice::NotifyConstructionCompleted();
104
106 "Second window must open after first one is closed");
107
108 // Void the two receiveWindow events
109 m_closeFirstWindow = EventId();
110 m_closeFirstWindow.Cancel();
111 m_closeSecondWindow = EventId();
112 m_closeSecondWindow.Cancel();
113 m_secondReceiveWindow = EventId();
114 m_secondReceiveWindow.Cancel();
115}
116
118{
119 NS_LOG_FUNCTION_NOARGS();
120}
121
123// Sending methods //
125
126void
128{
130 // Add headers, prepare TX parameters and send the packet
132 NS_LOG_FUNCTION(this << packetToSend);
133
134 NS_LOG_DEBUG("PacketToSend: " << packetToSend);
135
136 if (DynamicCast<SatLoraPhyTx>(m_phy->GetPhyTx())->IsTransmitting())
137 {
138 // Device already transmitting!
139 NS_LOG_WARN("End Device is already transmitting. Aborting.");
140 return;
141 }
142
143 // Data Rate Adaptation as in LoRaWAN specification, V1.0.2 (2016)
144 if (m_enableDRAdapt && (m_dataRate > 0) && (m_retxParams.retxLeft < m_maxNumbTx) &&
145 (m_retxParams.retxLeft % 2 == 0))
146 {
147 m_txPower = 14; // Reset transmission power
149 }
150
152 {
153 SatMacTimeTag satMacTag;
154 packetToSend->RemovePacketTag(
155 satMacTag); // If packet is retransmitted, it already has a tag, updating it
156 packetToSend->AddPacketTag(SatMacTimeTag(Simulator::Now()));
157
158 // Add a SatAddressTag tag with this device's address as the source address.
159 packetToSend->AddByteTag(SatAddressTag(m_nodeInfo->GetMacAddress()));
160
161 // Add a SatDevTimeTag tag for packet delay computation at the receiver end.
162 SatDevTimeTag satDevTag;
163 packetToSend->RemovePacketTag(satDevTag);
164 packetToSend->AddPacketTag(SatDevTimeTag(Simulator::Now()));
165 }
166
167 uint32_t allocationChannel = 0; // TODO is really zero here ?
168 Ptr<SatSuperframeConf> superframeConf =
170 uint8_t frameId = superframeConf->GetRaChannelFrameId(allocationChannel);
171 Ptr<SatFrameConf> frameConf = superframeConf->GetFrameConf(frameId);
172 Ptr<SatTimeSlotConf> timeSlotConf = frameConf->GetTimeSlotConf(0);
173 Ptr<SatWaveform> wf =
174 m_superframeSeq->GetWaveformConf()->GetWaveform(timeSlotConf->GetWaveFormId());
175
177 txInfo.modCod = wf->GetModCod();
178 txInfo.fecBlockSizeInBytes = wf->GetPayloadInBytes();
179 txInfo.packetType = m_packetType;
181 txInfo.waveformId = wf->GetWaveformId();
182 // txInfo.crdsaUniquePacketId = m_crdsaUniquePacketId; // reuse the crdsaUniquePacketId to
183 // identify ESSA frames
184
185 // Craft LoraTxParameters object
186 LoraTxParameters params;
189 params.codingRate = SatUtils::GetCodingRate(wf->GetModCod());
192 params.crcEnabled = 1;
194
195 // Pick a channel on which to transmit the packet
196 Ptr<LoraLogicalChannel> txChannel = GetChannelForTx();
197 double frequency = txChannel->GetFrequency();
198 LoraTag tag;
199 packetToSend->RemovePacketTag(tag);
200 tag.SetFrequency(frequency);
202 tag.SetModcod(wf->GetModCod());
203 packetToSend->AddPacketTag(tag);
204
205 SatMacTag mTag;
206 packetToSend->RemovePacketTag(mTag);
208 {
209 mTag.SetDestAddress(Mac48Address::ConvertFrom(m_satelliteAddress));
210 }
211 else
212 {
214 }
215 mTag.SetSourceAddress(Mac48Address::ConvertFrom(m_device->GetAddress()));
216 packetToSend->AddPacketTag(mTag);
217
218 SatAddressE2ETag addressE2ETag;
219 packetToSend->RemovePacketTag(addressE2ETag);
220 addressE2ETag.SetE2EDestAddress(m_gwAddress);
221 addressE2ETag.SetE2ESourceAddress(Mac48Address::ConvertFrom(m_device->GetAddress()));
222 packetToSend->AddPacketTag(addressE2ETag);
223
225 {
226 SatGroundStationAddressTag groundStationAddressTag;
227 packetToSend->RemovePacketTag(groundStationAddressTag);
228 groundStationAddressTag = SatGroundStationAddressTag(m_gwAddress);
229 packetToSend->AddPacketTag(groundStationAddressTag);
230 }
231
233 packets.push_back(packetToSend);
234
235 uint32_t carrierId = 0;
236
237 // Compute packet duration
238 Time duration = GetOnAirTime(packetToSend, params);
239
240 m_phyRx->SwitchToTx();
241 m_phy->SendPdu(packets, carrierId, duration, txInfo);
242
243 NS_LOG_DEBUG("PacketToSend: " << packetToSend);
244
246 // Register packet transmission for duty cycle
248
249 // Register the sent packet into the DutyCycleHelper
250 m_channelHelper.AddEvent(duration, txChannel);
251
253 // Prepare for the downlink //
255
256 // Switch the PHY to the channel so that it will listen here for downlink
257 m_phyRx->SetFrequency(txChannel->GetFrequency());
258
259 // Instruct the PHY on the right Spreading Factor to listen for during the window
260 // create a SetReplyDataRate function?
261 uint8_t replyDataRate = GetFirstReceiveWindowDataRate();
262 NS_LOG_DEBUG("m_dataRate: " << unsigned(m_dataRate)
263 << ", m_rx1DrOffset: " << unsigned(m_rx1DrOffset)
264 << ", replyDataRate: " << unsigned(replyDataRate) << ".");
265
266 m_phyRx->SetSpreadingFactor(GetSfFromDataRate(replyDataRate));
267}
268
270// Receiving methods //
272
273void
275{
276 NS_LOG_FUNCTION(this << packet);
277
278 // We add good address and not broadcast for traces
279 SatMacTag macTag;
280 packet->RemovePacketTag(macTag);
281 macTag.SetDestAddress(m_nodeInfo->GetMacAddress());
282 packet->AddPacketTag(macTag);
283
284 SatAddressE2ETag addressE2ETag;
285 packet->RemovePacketTag(addressE2ETag);
286 addressE2ETag.SetE2EDestAddress(m_nodeInfo->GetMacAddress());
287 packet->AddPacketTag(addressE2ETag);
288
290 packets.push_back(packet);
291 RxTraces(packets);
292
293 m_phyRx->SwitchToStandby();
294
295 // Work on a copy of the packet
296 Ptr<Packet> packetCopy = packet->Copy();
297
298 SatMacTag mTag;
299 packetCopy->RemovePacketTag(mTag);
300
301 // Remove the Mac Header to get some information
302 LorawanMacHeader mHdr;
303 packetCopy->RemoveHeader(mHdr);
304
305 NS_LOG_DEBUG("Mac Header: " << mHdr);
306
307 // Only keep analyzing the packet if it's downlink
308 if (!mHdr.IsUplink())
309 {
310 NS_LOG_INFO("Found a downlink packet.");
311
312 // Remove the Frame Header
313 LoraFrameHeader fHdr;
314 fHdr.SetAsDownlink();
315 packetCopy->RemoveHeader(fHdr);
316
317 NS_LOG_DEBUG("Frame Header: " << fHdr);
318
319 // Determine whether this packet is for us
320 bool messageForUs = (m_address == fHdr.GetAddress());
321
322 if (messageForUs)
323 {
324 NS_LOG_INFO("The message is for us!");
325
326 // If it exists, cancel the second receive window event
327 // THIS WILL BE GetReceiveWindow()
328 Simulator::Cancel(m_secondReceiveWindow);
329
330 // Parse the MAC commands
331 ParseCommands(fHdr);
332
333 // Call the trace source
334 m_receivedPacket(packet);
335 }
336 else
337 {
338 NS_LOG_DEBUG("The message is intended for another recipient.");
339
340 // In this case, we are either receiving in the first receive window
341 // and finishing reception inside the second one, or receiving a
342 // packet in the second receive window and finding out, after the
343 // fact, that the packet is not for us. In either case, if we no
344 // longer have any retransmissions left, we declare failure.
345 if (m_retxParams.waitingAck && m_secondReceiveWindow.IsExpired())
346 {
347 if (m_retxParams.retxLeft == 0)
348 {
349 uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft);
351 false,
352 m_retxParams.firstAttempt,
353 m_retxParams.packet);
354 NS_LOG_DEBUG("Failure: no more retransmissions left. Used "
355 << unsigned(txs) << " transmissions.");
356
357 // Reset retransmission parameters
359 }
360 else // Reschedule
361 {
362 this->Send(m_retxParams.packet);
363 NS_LOG_INFO("We have " << unsigned(m_retxParams.retxLeft)
364 << " retransmissions left: rescheduling transmission.");
365 }
366 }
367 }
368 }
369 else if (m_retxParams.waitingAck && m_secondReceiveWindow.IsExpired())
370 {
371 NS_LOG_INFO("The packet we are receiving is in uplink.");
372 if (m_retxParams.retxLeft > 0)
373 {
374 this->Send(m_retxParams.packet);
375 NS_LOG_INFO("We have " << unsigned(m_retxParams.retxLeft)
376 << " retransmissions left: rescheduling transmission.");
377 }
378 else
379 {
380 uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft);
381 m_requiredTxCallback(txs, false, m_retxParams.firstAttempt, m_retxParams.packet);
382 NS_LOG_DEBUG("Failure: no more retransmissions left. Used " << unsigned(txs)
383 << " transmissions.");
384
385 // Reset retransmission parameters
387 }
388 }
389
390 m_phyRx->SwitchToSleep();
391}
392
393void
395{
396 NS_LOG_FUNCTION(this << packet);
397
398 // Switch to sleep after a failed reception
399 m_phyRx->SwitchToSleep();
400
401 if (m_secondReceiveWindow.IsExpired() && m_retxParams.waitingAck)
402 {
403 if (m_retxParams.retxLeft > 0)
404 {
405 this->Send(m_retxParams.packet);
406 NS_LOG_INFO("We have " << unsigned(m_retxParams.retxLeft)
407 << " retransmissions left: rescheduling transmission.");
408 }
409 else
410 {
411 uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft);
412 m_requiredTxCallback(txs, false, m_retxParams.firstAttempt, m_retxParams.packet);
413 NS_LOG_DEBUG("Failure: no more retransmissions left. Used " << unsigned(txs)
414 << " transmissions.");
415
416 // Reset retransmission parameters
418 }
419 }
420}
421
422void
424{
425 NS_LOG_FUNCTION_NOARGS();
426
427 m_phyRx->SwitchToStandby();
428
429 // Schedule the opening of the first receive window
430 Simulator::Schedule(m_firstWindowDelay,
432 this);
433
434 // Schedule the opening of the second receive window
435 m_secondReceiveWindow = Simulator::Schedule(m_secondWindowDelay,
437 this);
438
439 // Switch the PHY to sleep
440 m_phyRx->SwitchToSleep();
441}
442
443void
468
469void
471{
472 NS_LOG_FUNCTION_NOARGS();
473
474 // Set Phy in Standby mode
475 m_phyRx->SwitchToStandby();
476
477 // Schedule return to sleep after "at least the time required by the end
478 // device's radio transceiver to effectively detect a downlink preamble"
479 // (LoraWAN specification)
480 m_closeFirstWindow = Simulator::Schedule(m_firstWindowDuration,
482 this);
483}
484
485void
487{
488 NS_LOG_FUNCTION_NOARGS();
489
490 // Check the Phy layer's state:
491 // - RX -> We are receiving a preamble.
492 // - STANDBY -> Nothing was received.
493 // - SLEEP -> We have received a packet.
494 // We should never be in TX or SLEEP mode at this point
495 switch (m_phyRx->GetState())
496 {
497 case SatLoraPhyRx::TX:
498 NS_ABORT_MSG("PHY was in TX mode when attempting to " << "close a receive window.");
499 break;
500 case SatLoraPhyRx::RX:
501 // PHY is receiving: let it finish. The Receive method will switch it back to SLEEP.
502 break;
504 // PHY has received, and the MAC's Receive already put the device to sleep
505 break;
507 // Turn PHY layer to SLEEP
508 m_phyRx->SwitchToSleep();
509 break;
510 }
511}
512
513void
515{
516 NS_LOG_FUNCTION_NOARGS();
517
518 // Check for receiver status: if it's locked on a packet, don't open this
519 // window at all.
520 if (m_phyRx->GetState() == SatLoraPhyRx::RX)
521 {
522 NS_LOG_INFO("Won't open second receive window since we are in RX mode.");
523 return;
524 }
525
526 // Set Phy in Standby mode
527 m_phyRx->SwitchToStandby();
528
529 // Switch to appropriate channel and data rate
530 NS_LOG_INFO("Using parameters: " << m_secondReceiveWindowFrequency << "Hz, DR"
531 << unsigned(m_secondReceiveWindowDataRate));
532
535
536 // Schedule return to sleep after "at least the time required by the end
537 // device's radio transceiver to effectively detect a downlink preamble"
538 // (LoraWAN specification)
539 m_closeSecondWindow = Simulator::Schedule(m_secondWindowDuration,
541 this);
542}
543
544void
546{
547 NS_LOG_FUNCTION_NOARGS();
548
549 // NS_ASSERT (m_phyRx->m_state != SatLoraPhyRx::TX &&
550 // m_phyRx->m_state != SatLoraPhyRx::SLEEP);
551
552 // Check the Phy layer's state:
553 // - RX -> We have received a preamble.
554 // - STANDBY -> Nothing was detected.
555 switch (m_phyRx->GetState())
556 {
557 case SatLoraPhyRx::TX:
558 break;
560 break;
561 case SatLoraPhyRx::RX:
562 // PHY is receiving: let it finish
563 NS_LOG_DEBUG("PHY is receiving: Receive will handle the result.");
564 return;
566 // Turn PHY layer to sleep
567 m_phyRx->SwitchToSleep();
568 break;
569 }
570
571 if (m_retxParams.waitingAck)
572 {
573 NS_LOG_DEBUG("No reception initiated by PHY: rescheduling transmission.");
574 if (m_retxParams.retxLeft > 0)
575 {
576 NS_LOG_INFO("We have " << unsigned(m_retxParams.retxLeft)
577 << " retransmissions left: rescheduling transmission.");
578 this->Send(m_retxParams.packet);
579 }
580
581 else if (m_retxParams.retxLeft == 0 && m_phyRx->GetState() != SatLoraPhyRx::RX)
582 {
583 uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft);
584 m_requiredTxCallback(txs, false, m_retxParams.firstAttempt, m_retxParams.packet);
585 NS_LOG_DEBUG("Failure: no more retransmissions left. Used " << unsigned(txs)
586 << " transmissions.");
587
588 // Reset retransmission parameters
590 }
591
592 else
593 {
594 NS_ABORT_MSG("The number of retransmissions left is negative ! ");
595 }
596 }
597 else
598 {
599 uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft);
600 m_requiredTxCallback(txs, true, m_retxParams.firstAttempt, m_retxParams.packet);
601 NS_LOG_INFO(
602 "We have " << unsigned(m_retxParams.retxLeft)
603 << " transmissions left. We were not transmitting confirmed messages.");
604
605 // Reset retransmission parameters
607 }
608}
609
611// Getters and Setters //
613
614Time
616{
617 NS_LOG_FUNCTION_NOARGS();
618
619 // This is a new packet from APP; it can not be sent until the end of the
620 // second receive window (if the second recieve window has not closed yet)
621 if (!m_retxParams.waitingAck)
622 {
623 if (!m_closeFirstWindow.IsExpired() || !m_closeSecondWindow.IsExpired() ||
624 !m_secondReceiveWindow.IsExpired())
625 {
626 NS_LOG_WARN(
627 "Attempting to send when there are receive windows:" << " Transmission postponed.");
628 // Compute the duration of a single symbol for the second receive window DR
629 double tSym = pow(2, GetSfFromDataRate(GetSecondReceiveWindowDataRate())) /
631 // Compute the closing time of the second receive window
632 Time endSecondRxWindow = Time(m_secondReceiveWindow.GetTs()) +
633 Seconds(m_receiveWindowDurationInSymbols * tSym);
634
635 NS_LOG_DEBUG("Duration until endSecondRxWindow for new transmission:"
636 << (endSecondRxWindow - Simulator::Now()).GetSeconds());
637 waitingTime = std::max(waitingTime, endSecondRxWindow - Simulator::Now());
638 }
639 }
640 // This is a retransmitted packet, it can not be sent until the end of
641 // ACK_TIMEOUT (this timer starts when the second receive window was open)
642 else
643 {
644 double ack_timeout = m_uniformRV->GetValue(1, 3);
645 // Compute the duration until ACK_TIMEOUT (It may be a negative number, but it doesn't
646 // matter.)
647 Time retransmitWaitingTime =
648 Time(m_secondReceiveWindow.GetTs()) - Simulator::Now() + Seconds(ack_timeout);
649
650 NS_LOG_DEBUG("ack_timeout:" << ack_timeout << " retransmitWaitingTime:"
651 << retransmitWaitingTime.GetSeconds());
652 waitingTime = std::max(waitingTime, retransmitWaitingTime);
653 }
654
655 return waitingTime;
656}
657
658uint8_t
663
664void
669
670uint8_t
675
676void
681
682double
687
689// MAC command methods //
691
692void
693LorawanMacEndDeviceClassA::OnRxClassParamSetupReq(Ptr<RxParamSetupReq> rxParamSetupReq)
694{
695 NS_LOG_FUNCTION(this << rxParamSetupReq);
696
697 bool offsetOk = true;
698 bool dataRateOk = true;
699
700 uint8_t rx1DrOffset = rxParamSetupReq->GetRx1DrOffset();
701 uint8_t rx2DataRate = rxParamSetupReq->GetRx2DataRate();
702 double frequency = rxParamSetupReq->GetFrequency();
703
704 NS_LOG_FUNCTION(this << unsigned(rx1DrOffset) << unsigned(rx2DataRate) << frequency);
705
706 // Check that the desired offset is valid
707 if (!(0 <= rx1DrOffset && rx1DrOffset <= 5))
708 {
709 offsetOk = false;
710 }
711
712 // Check that the desired data rate is valid
713 if (GetSfFromDataRate(rx2DataRate) == 0 || GetBandwidthFromDataRate(rx2DataRate) == 0)
714 {
715 dataRateOk = false;
716 }
717
718 // For now, don't check for validity of frequency
719 m_secondReceiveWindowDataRate = rx2DataRate;
720 m_rx1DrOffset = rx1DrOffset;
722
723 // Craft a RxParamSetupAns as response
724 NS_LOG_INFO("Adding RxParamSetupAns reply");
725 m_macCommandList.push_back(CreateObject<RxParamSetupAns>(offsetOk, dataRateOk, true));
726}
727
728} /* namespace ns3 */
This class represents the Frame header (FHDR) used in a LoraWAN network.
void SetAsDownlink(void)
State that this is a downlink message.
LoraDeviceAddress GetAddress(void) const
Get this header's device address value.
Tag used to save various data about a packet, like its Spreading Factor and data about interference.
Definition lora-tag.h:41
void SetDataRate(uint8_t dataRate)
Set the data rate for this packet.
Definition lora-tag.cc:154
void SetFrequency(double frequency)
Set the frequency of the packet.
Definition lora-tag.cc:136
void SetModcod(uint8_t modcod)
Set the modcod for this packet.
Definition lora-tag.cc:166
Class representing the MAC layer of a Class A LoRaWAN device.
EventId m_secondReceiveWindow
The event of the second receive window opening.
uint8_t GetFirstReceiveWindowDataRate(void)
Get the Data Rate that will be used in the first receive window.
Time m_secondWindowDelay
Time to wait between end of message transmission and opening of second reception window.
virtual void TxFinished()
Perform the actions that are required after a packet send.
SatEnums::PacketType_t m_packetType
Packet type used on RTN channel.
virtual void OnRxClassParamSetupReq(Ptr< RxParamSetupReq > rxParamSetupReq)
Perform the actions that need to be taken when receiving a RxParamSetupReq command based on the Devic...
virtual void SendToPhy(Ptr< Packet > packet)
Add headers and send a packet with the sending function of the physical layer.
Time m_secondWindowDuration
Duration of second reception window.
virtual Time GetNextClassTransmissionDelay(Time waitingTime)
Find the minimum waiting time before the next possible transmission based on End Device's Class Type.
Time m_firstWindowDuration
Duration of first reception window.
double GetSecondReceiveWindowFrequency(void)
Get the frequency that is used for the second receive window.
virtual void NotifyConstructionCompleted() override
Notifier called once the ObjectBase is fully constructed.
Ptr< SatSuperframeSeq > m_superframeSeq
Used superframe sequence for the return link.
EventId m_closeSecondWindow
The event of the closing the second receive window.
void CloseFirstReceiveWindow(void)
Perform operations needed to close the first receive window.
void OpenFirstReceiveWindow(void)
Perform operations needed to open the first receive window.
void OpenSecondReceiveWindow(void)
Perform operations needed to open the second receive window.
void SetSecondReceiveWindowDataRate(uint8_t dataRate)
Set the Data Rate to be used in the second receive window.
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...
void SetSecondReceiveWindowFrequency(double frequencyMHz)
Set the frequency that will be used for the second receive window.
void CloseSecondReceiveWindow(void)
Perform operations needed to close the second receive window.
uint8_t m_rx1DrOffset
The RX1DROffset parameter value.
double m_secondReceiveWindowFrequency
The frequency to listen on for the second receive window.
virtual void Receive(Ptr< Packet > packet)
Receive a packet.
Time m_firstWindowDelay
Time to wait between end of message transmission and opening of first reception window.
EventId m_closeFirstWindow
The event of the closing the first receive window.
uint8_t GetSecondReceiveWindowDataRate(void)
Get the Data Rate that will be used in the second receive window.
void SetRaModel(SatEnums::RandomAccessModel_t randomAccessModel)
Set the random access model.
uint8_t m_secondReceiveWindowDataRate
The Data Rate to listen for during the second downlink transmission.
std::list< Ptr< LorawanMacCommand > > m_macCommandList
List of the MAC commands that need to be applied to the next UL packet.
bool m_enableDRAdapt
Enable Data Rate adaptation during the retransmission procedure.
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.
Ptr< LoraLogicalChannel > GetChannelForTx(void)
Find a suitable channel for transmission.
Ptr< SatLoraPhyRx > m_phyRx
Reception phy layer for Lora operations.
Mac48Address m_gwAddress
Gateway address used in case of transparent satellite.
uint8_t m_receiveWindowDurationInSymbols
The duration of a receive window in number of symbols.
uint8_t m_maxNumbTx
Maximum number of transmission allowed.
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.
TracedValue< uint8_t > m_dataRate
The DataRate this device is using to transmit.
void ParseCommands(LoraFrameHeader frameHeader)
Parse and take action on the commands contained on this FrameHeader.
virtual void resetRetransmissionParameters()
Reset retransmission parameters contained in the structure LoraRetxParams.
bool m_isRegenerative
Tell if satellite is regenerative.
bool m_headerDisabled
Whether or not the header is disabled for communications by this device.
LoraDeviceAddress m_address
The address of this device.
struct LoraRetxParameters m_retxParams
This class represents the Mac header of a LoRaWAN packet.
bool IsUplink(void) const
Check whether this header is for an uplink message.
TracedCallback< Ptr< const Packet > > m_receivedPacket
Trace source that is fired when a packet reaches the MAC layer.
ReplyDataRateMatrix m_replyDataRateMatrix
The matrix that decides the DR the GW will use in a reply based on the ED's sending DR and on the val...
int m_nPreambleSymbols
The number of symbols to use in the PHY preamble.
Time GetOnAirTime(Ptr< Packet > packet, LoraTxParameters txParams)
Compute the time that a packet with certain characteristics will take to be transmitted.
Ptr< SatPhy > m_phy
The PHY instance that sits under this MAC layer.
uint8_t GetSfFromDataRate(uint8_t dataRate)
Get the SF corresponding to a data rate, based on this MAC's region.
Ptr< NetDevice > m_device
The device this MAC layer is installed on.
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.
This class implements a tag that carries the satellite MAC of GW and UT.
void SetE2ESourceAddress(Mac48Address e2eSourceAddress)
Set E2E source MAC address.
void SetE2EDestAddress(Mac48Address e2eDestAddress)
Set E2E destination MAC address.
This class implements a tag that carries the MAC address of the sender of the packet.
Time tag used to identify the time when packet is enqueued at device level.
RandomAccessModel_t
The defined random access models.
Tag to store ground station destination address.
@ SLEEP
The PHY layer is sleeping.
@ TX
The PHY layer is sending a packet.
@ RX
The PHY layer is receiving a packet.
@ STANDBY
The PHY layer is in STANDBY.
void RxTraces(SatPhy::PacketContainer_t packets)
Invoke the Rx trace source for each received packet.
bool m_isStatisticsTagsEnabled
EnableStatisticsTags attribute.
Address m_satelliteAddress
MAC address of satellite on other side of the link.
Ptr< SatNodeInfo > m_nodeInfo
Node info containing node related information, such as node type, node id and MAC address (of the Sat...
This class implements a tag that carries the satellite MAC specific information, such as source and d...
void SetDestAddress(Mac48Address dest)
Set destination MAC address.
void SetSourceAddress(Mac48Address source)
Set source MAC address.
Time tag used to identify the time when packet is enqueued at MAC level.
SatSignalParameters::PacketsInBurst_t PacketContainer_t
Define PacketContainer in SatPhy.
static double GetCodingRate(SatEnums::SatModcod_t modcod)
Gets the coding rate of a certain MODCOD.
constexpr uint8_t SUPERFRAME_SEQUENCE
Used superframe sequence in the RTN link.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.
Structure to collect all parameters that are used to compute the duration of a packet (excluding payl...
bool lowDataRateOptimizationEnabled
Whether Low Data Rate Optimization is enabled.
uint32_t nPreamble
Number of preamble symbols.
bool headerDisabled
Whether to use implicit header mode.
uint8_t sf
Spreading Factor.
double bandwidthHz
Bandwidth in Hz.
bool crcEnabled
Whether Cyclic Redundancy Check is enabled.
Struct for storing the packet specific Tx information.