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"
29 #include "lorawan-mac-end-device.h"
31 #include "satellite-phy.h"
32 
33 #include <ns3/log.h>
34 #include <ns3/pointer.h>
35 
36 #include <algorithm>
37 
38 namespace ns3
39 {
40 
41 NS_LOG_COMPONENT_DEFINE("LorawanMacEndDeviceClassA");
42 
43 NS_OBJECT_ENSURE_REGISTERED(LorawanMacEndDeviceClassA);
44 
45 TypeId
47 {
48  static TypeId tid =
49  TypeId("ns3::LorawanMacEndDeviceClassA")
50  .SetParent<LorawanMacEndDevice>()
51  .AddAttribute("FirstWindowDelay",
52  "Time to wait between end of message transmission and opening of first "
53  "reception window",
54  TimeValue(Seconds(1)),
56  MakeTimeChecker())
57  .AddAttribute("SecondWindowDelay",
58  "Time to wait between end of message transmission and opening of second "
59  "reception window",
60  TimeValue(Seconds(2)),
62  MakeTimeChecker())
63  .AddAttribute("FirstWindowDuration",
64  "Duration of first reception window",
65  TimeValue(MilliSeconds(100)),
67  MakeTimeChecker())
68  .AddAttribute("SecondWindowDuration",
69  "Duration of second reception window",
70  TimeValue(MilliSeconds(100)),
72  MakeTimeChecker())
73  .AddConstructor<LorawanMacEndDeviceClassA>();
74  return tid;
75 }
76 
78 {
79  NS_FATAL_ERROR("Default constructor not in use");
80 }
81 
83  uint32_t beamId,
84  Ptr<SatSuperframeSeq> seq)
85  : LorawanMacEndDevice(satId, beamId),
86  m_superframeSeq(seq),
87  m_firstWindowDelay(Seconds(1)),
88  m_secondWindowDelay(Seconds(2)),
89  m_firstWindowDuration(MilliSeconds(100)),
90  m_secondWindowDuration(MilliSeconds(100)),
91  m_rx1DrOffset(0)
92 {
93  NS_LOG_FUNCTION(this);
94 
95  // Void the two receiveWindow events
96  m_closeFirstWindow = EventId();
97  m_closeFirstWindow.Cancel();
98  m_closeSecondWindow = EventId();
99  m_closeSecondWindow.Cancel();
100  m_secondReceiveWindow = EventId();
101  m_secondReceiveWindow.Cancel();
102 }
103 
105 {
106  NS_LOG_FUNCTION_NOARGS();
107 }
108 
110 // Sending methods //
112 
113 void
114 LorawanMacEndDeviceClassA::SendToPhy(Ptr<Packet> packetToSend)
115 {
117  // Add headers, prepare TX parameters and send the packet
119  NS_LOG_FUNCTION(this);
120 
121  NS_LOG_DEBUG("PacketToSend: " << packetToSend);
122 
123  if (DynamicCast<SatLoraPhyTx>(m_phy->GetPhyTx())->IsTransmitting())
124  {
125  // Device already transmitting!
126  NS_LOG_WARN("End Device is already transmitting. Aborting.");
127  return;
128  }
129 
130  // Data Rate Adaptation as in LoRaWAN specification, V1.0.2 (2016)
132  (m_retxParams.retxLeft % 2 == 0))
133  {
134  m_txPower = 14; // Reset transmission power
135  m_dataRate = m_dataRate - 1;
136  }
137 
139  {
140  SatMacTimeTag satMacTag;
141  packetToSend->RemovePacketTag(
142  satMacTag); // If packet is retransmitted, it already has a tag, updating it
143  packetToSend->AddPacketTag(SatMacTimeTag(Simulator::Now()));
144 
145  // Add a SatAddressTag tag with this device's address as the source address.
146  packetToSend->AddByteTag(SatAddressTag(m_nodeInfo->GetMacAddress()));
147 
148  // Add a SatDevTimeTag tag for packet delay computation at the receiver end.
149  SatDevTimeTag satDevTag;
150  packetToSend->RemovePacketTag(satDevTag);
151  packetToSend->AddPacketTag(SatDevTimeTag(Simulator::Now()));
152  }
153 
154  uint32_t allocationChannel = 0; // TODO is really zero here ?
155  Ptr<SatSuperframeConf> superframeConf =
157  uint8_t frameId = superframeConf->GetRaChannelFrameId(allocationChannel);
158  Ptr<SatFrameConf> frameConf = superframeConf->GetFrameConf(frameId);
159  Ptr<SatTimeSlotConf> timeSlotConf = frameConf->GetTimeSlotConf(0);
160  Ptr<SatWaveform> wf =
161  m_superframeSeq->GetWaveformConf()->GetWaveform(timeSlotConf->GetWaveFormId());
162 
164  txInfo.modCod = wf->GetModCod();
165  txInfo.fecBlockSizeInBytes = wf->GetPayloadInBytes();
166  txInfo.packetType = m_packetType;
168  txInfo.waveformId = wf->GetWaveformId();
169  // txInfo.crdsaUniquePacketId = m_crdsaUniquePacketId; // reuse the crdsaUniquePacketId to
170  // identify ESSA frames
171 
172  // Craft LoraTxParameters object
173  LoraTxParameters params;
174  params.sf = GetSfFromDataRate(m_dataRate);
176  params.codingRate = SatUtils::GetCodingRate(wf->GetModCod());
178  params.nPreamble = m_nPreambleSymbols;
179  params.crcEnabled = 1;
181 
182  // Pick a channel on which to transmit the packet
183  Ptr<LoraLogicalChannel> txChannel = GetChannelForTx();
184  double frequency = txChannel->GetFrequency();
185  LoraTag tag;
186  packetToSend->RemovePacketTag(tag);
187  tag.SetFrequency(frequency);
188  tag.SetDataRate(m_dataRate);
189  tag.SetModcod(wf->GetModCod());
190  packetToSend->AddPacketTag(tag);
191 
192  SatMacTag mTag;
193  packetToSend->RemovePacketTag(mTag);
195  mTag.SetSourceAddress(Mac48Address::ConvertFrom(m_device->GetAddress()));
196  packetToSend->AddPacketTag(mTag);
197 
198  SatAddressE2ETag addressE2ETag;
199  packetToSend->RemovePacketTag(addressE2ETag);
200  addressE2ETag.SetE2EDestAddress(Mac48Address::GetBroadcast());
201  addressE2ETag.SetE2ESourceAddress(Mac48Address::ConvertFrom(m_device->GetAddress()));
202  packetToSend->AddPacketTag(addressE2ETag);
203 
205  packets.push_back(packetToSend);
206 
207  uint32_t carrierId = 0;
208 
209  // Compute packet duration
210  Time duration = GetOnAirTime(packetToSend, params);
211 
212  m_phyRx->SwitchToTx();
213  m_phy->SendPdu(packets, carrierId, duration, txInfo);
214 
215  NS_LOG_DEBUG("PacketToSend: " << packetToSend);
216 
218  // Register packet transmission for duty cycle
220 
221  // Register the sent packet into the DutyCycleHelper
222  m_channelHelper.AddEvent(duration, txChannel);
223 
225  // Prepare for the downlink //
227 
228  // Switch the PHY to the channel so that it will listen here for downlink
229  m_phyRx->SetFrequency(txChannel->GetFrequency());
230 
231  // Instruct the PHY on the right Spreading Factor to listen for during the window
232  // create a SetReplyDataRate function?
233  uint8_t replyDataRate = GetFirstReceiveWindowDataRate();
234  NS_LOG_DEBUG("m_dataRate: " << unsigned(m_dataRate)
235  << ", m_rx1DrOffset: " << unsigned(m_rx1DrOffset)
236  << ", replyDataRate: " << unsigned(replyDataRate) << ".");
237 
238  m_phyRx->SetSpreadingFactor(GetSfFromDataRate(replyDataRate));
239 }
240 
242 // Receiving methods //
244 
245 void
247 {
248  NS_LOG_FUNCTION(this << packet);
249 
250  // We add good address and not broadcast for traces
251  SatMacTag macTag;
252  packet->RemovePacketTag(macTag);
253  macTag.SetDestAddress(m_nodeInfo->GetMacAddress());
254  packet->AddPacketTag(macTag);
255 
256  SatAddressE2ETag addressE2ETag;
257  packet->RemovePacketTag(addressE2ETag);
258  addressE2ETag.SetE2EDestAddress(m_nodeInfo->GetMacAddress());
259  packet->AddPacketTag(addressE2ETag);
260 
262  packets.push_back(packet);
263  RxTraces(packets);
264 
265  m_phyRx->SwitchToStandby();
266 
267  // Work on a copy of the packet
268  Ptr<Packet> packetCopy = packet->Copy();
269 
270  SatMacTag mTag;
271  packetCopy->RemovePacketTag(mTag);
272 
273  // Remove the Mac Header to get some information
274  LorawanMacHeader mHdr;
275  packetCopy->RemoveHeader(mHdr);
276 
277  NS_LOG_DEBUG("Mac Header: " << mHdr);
278 
279  // Only keep analyzing the packet if it's downlink
280  if (!mHdr.IsUplink())
281  {
282  NS_LOG_INFO("Found a downlink packet.");
283 
284  // Remove the Frame Header
285  LoraFrameHeader fHdr;
286  fHdr.SetAsDownlink();
287  packetCopy->RemoveHeader(fHdr);
288 
289  NS_LOG_DEBUG("Frame Header: " << fHdr);
290 
291  // Determine whether this packet is for us
292  bool messageForUs = (m_address == fHdr.GetAddress());
293 
294  if (messageForUs)
295  {
296  NS_LOG_INFO("The message is for us!");
297 
298  // If it exists, cancel the second receive window event
299  // THIS WILL BE GetReceiveWindow()
300  Simulator::Cancel(m_secondReceiveWindow);
301 
302  // Parse the MAC commands
303  ParseCommands(fHdr);
304 
305  // m_device->GetObject<SatLorawanNetDevice> ()->Receive (packetCopy);
306 
307  // Call the trace source
308  m_receivedPacket(packet);
309  }
310  else
311  {
312  NS_LOG_DEBUG("The message is intended for another recipient.");
313 
314  // In this case, we are either receiving in the first receive window
315  // and finishing reception inside the second one, or receiving a
316  // packet in the second receive window and finding out, after the
317  // fact, that the packet is not for us. In either case, if we no
318  // longer have any retransmissions left, we declare failure.
319  if (m_retxParams.waitingAck && m_secondReceiveWindow.IsExpired())
320  {
321  if (m_retxParams.retxLeft == 0)
322  {
323  uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft);
325  false,
328  NS_LOG_DEBUG("Failure: no more retransmissions left. Used "
329  << unsigned(txs) << " transmissions.");
330 
331  // Reset retransmission parameters
333  }
334  else // Reschedule
335  {
336  this->Send(m_retxParams.packet);
337  NS_LOG_INFO("We have " << unsigned(m_retxParams.retxLeft)
338  << " retransmissions left: rescheduling transmission.");
339  }
340  }
341  }
342  }
343  else if (m_retxParams.waitingAck && m_secondReceiveWindow.IsExpired())
344  {
345  NS_LOG_INFO("The packet we are receiving is in uplink.");
346  if (m_retxParams.retxLeft > 0)
347  {
348  this->Send(m_retxParams.packet);
349  NS_LOG_INFO("We have " << unsigned(m_retxParams.retxLeft)
350  << " retransmissions left: rescheduling transmission.");
351  }
352  else
353  {
354  uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft);
356  NS_LOG_DEBUG("Failure: no more retransmissions left. Used " << unsigned(txs)
357  << " transmissions.");
358 
359  // Reset retransmission parameters
361  }
362  }
363 
364  m_phyRx->SwitchToSleep();
365 }
366 
367 void
369 {
370  NS_LOG_FUNCTION(this << packet);
371 
372  // Switch to sleep after a failed reception
373  m_phyRx->SwitchToSleep();
374 
375  if (m_secondReceiveWindow.IsExpired() && m_retxParams.waitingAck)
376  {
377  if (m_retxParams.retxLeft > 0)
378  {
379  this->Send(m_retxParams.packet);
380  NS_LOG_INFO("We have " << unsigned(m_retxParams.retxLeft)
381  << " retransmissions left: rescheduling transmission.");
382  }
383  else
384  {
385  uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft);
387  NS_LOG_DEBUG("Failure: no more retransmissions left. Used " << unsigned(txs)
388  << " transmissions.");
389 
390  // Reset retransmission parameters
392  }
393  }
394 }
395 
396 void
398 {
399  NS_LOG_FUNCTION_NOARGS();
400 
401  m_phyRx->SwitchToStandby();
402 
403  // Schedule the opening of the first receive window
404  Simulator::Schedule(m_firstWindowDelay,
406  this);
407 
408  // Schedule the opening of the second receive window
409  m_secondReceiveWindow = Simulator::Schedule(m_secondWindowDelay,
411  this);
412 
413  // Switch the PHY to sleep
414  m_phyRx->SwitchToSleep();
415 }
416 
417 void
419 {
420  switch (randomAccessModel)
421  {
422  case SatEnums::RA_MODEL_OFF: {
424  break;
425  }
428  break;
429  }
434  break;
435  }
438  break;
439  }
440  }
441 }
442 
443 void
445 {
446  NS_LOG_FUNCTION_NOARGS();
447 
448  // Set Phy in Standby mode
449  m_phyRx->SwitchToStandby();
450 
451  // Schedule return to sleep after "at least the time required by the end
452  // device's radio transceiver to effectively detect a downlink preamble"
453  // (LoraWAN specification)
454  m_closeFirstWindow = Simulator::Schedule(m_firstWindowDuration,
456  this);
457 }
458 
459 void
461 {
462  NS_LOG_FUNCTION_NOARGS();
463 
464  // Check the Phy layer's state:
465  // - RX -> We are receiving a preamble.
466  // - STANDBY -> Nothing was received.
467  // - SLEEP -> We have received a packet.
468  // We should never be in TX or SLEEP mode at this point
469  switch (m_phyRx->GetState())
470  {
471  case SatLoraPhyRx::TX:
472  NS_ABORT_MSG("PHY was in TX mode when attempting to "
473  << "close a receive window.");
474  break;
475  case SatLoraPhyRx::RX:
476  // PHY is receiving: let it finish. The Receive method will switch it back to SLEEP.
477  break;
478  case SatLoraPhyRx::SLEEP:
479  // PHY has received, and the MAC's Receive already put the device to sleep
480  break;
482  // Turn PHY layer to SLEEP
483  m_phyRx->SwitchToSleep();
484  break;
485  }
486 }
487 
488 void
490 {
491  NS_LOG_FUNCTION_NOARGS();
492 
493  // Check for receiver status: if it's locked on a packet, don't open this
494  // window at all.
495  if (m_phyRx->GetState() == SatLoraPhyRx::RX)
496  {
497  NS_LOG_INFO("Won't open second receive window since we are in RX mode.");
498  return;
499  }
500 
501  // Set Phy in Standby mode
502  m_phyRx->SwitchToStandby();
503 
504  // Switch to appropriate channel and data rate
505  NS_LOG_INFO("Using parameters: " << m_secondReceiveWindowFrequency << "Hz, DR"
506  << unsigned(m_secondReceiveWindowDataRate));
507 
510 
511  // Schedule return to sleep after "at least the time required by the end
512  // device's radio transceiver to effectively detect a downlink preamble"
513  // (LoraWAN specification)
514  m_closeSecondWindow = Simulator::Schedule(m_secondWindowDuration,
516  this);
517 }
518 
519 void
521 {
522  NS_LOG_FUNCTION_NOARGS();
523 
524  // NS_ASSERT (m_phyRx->m_state != SatLoraPhyRx::TX &&
525  // m_phyRx->m_state != SatLoraPhyRx::SLEEP);
526 
527  // Check the Phy layer's state:
528  // - RX -> We have received a preamble.
529  // - STANDBY -> Nothing was detected.
530  switch (m_phyRx->GetState())
531  {
532  case SatLoraPhyRx::TX:
533  break;
534  case SatLoraPhyRx::SLEEP:
535  break;
536  case SatLoraPhyRx::RX:
537  // PHY is receiving: let it finish
538  NS_LOG_DEBUG("PHY is receiving: Receive will handle the result.");
539  return;
541  // Turn PHY layer to sleep
542  m_phyRx->SwitchToSleep();
543  break;
544  }
545 
547  {
548  NS_LOG_DEBUG("No reception initiated by PHY: rescheduling transmission.");
549  if (m_retxParams.retxLeft > 0)
550  {
551  NS_LOG_INFO("We have " << unsigned(m_retxParams.retxLeft)
552  << " retransmissions left: rescheduling transmission.");
553  this->Send(m_retxParams.packet);
554  }
555 
556  else if (m_retxParams.retxLeft == 0 && m_phyRx->GetState() != SatLoraPhyRx::RX)
557  {
558  uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft);
560  NS_LOG_DEBUG("Failure: no more retransmissions left. Used " << unsigned(txs)
561  << " transmissions.");
562 
563  // Reset retransmission parameters
565  }
566 
567  else
568  {
569  NS_ABORT_MSG("The number of retransmissions left is negative ! ");
570  }
571  }
572  else
573  {
574  uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft);
576  NS_LOG_INFO(
577  "We have " << unsigned(m_retxParams.retxLeft)
578  << " transmissions left. We were not transmitting confirmed messages.");
579 
580  // Reset retransmission parameters
582  }
583 }
584 
586 // Getters and Setters //
588 
589 Time
591 {
592  NS_LOG_FUNCTION_NOARGS();
593 
594  // This is a new packet from APP; it can not be sent until the end of the
595  // second receive window (if the second recieve window has not closed yet)
597  {
598  if (!m_closeFirstWindow.IsExpired() || !m_closeSecondWindow.IsExpired() ||
599  !m_secondReceiveWindow.IsExpired())
600  {
601  NS_LOG_WARN("Attempting to send when there are receive windows:"
602  << " Transmission postponed.");
603  // Compute the duration of a single symbol for the second receive window DR
604  double tSym = pow(2, GetSfFromDataRate(GetSecondReceiveWindowDataRate())) /
606  // Compute the closing time of the second receive window
607  Time endSecondRxWindow = Time(m_secondReceiveWindow.GetTs()) +
608  Seconds(m_receiveWindowDurationInSymbols * tSym);
609 
610  NS_LOG_DEBUG("Duration until endSecondRxWindow for new transmission:"
611  << (endSecondRxWindow - Simulator::Now()).GetSeconds());
612  waitingTime = std::max(waitingTime, endSecondRxWindow - Simulator::Now());
613  }
614  }
615  // This is a retransmitted packet, it can not be sent until the end of
616  // ACK_TIMEOUT (this timer starts when the second receive window was open)
617  else
618  {
619  double ack_timeout = m_uniformRV->GetValue(1, 3);
620  // Compute the duration until ACK_TIMEOUT (It may be a negative number, but it doesn't
621  // matter.)
622  Time retransmitWaitingTime =
623  Time(m_secondReceiveWindow.GetTs()) - Simulator::Now() + Seconds(ack_timeout);
624 
625  NS_LOG_DEBUG("ack_timeout:" << ack_timeout << " retransmitWaitingTime:"
626  << retransmitWaitingTime.GetSeconds());
627  waitingTime = std::max(waitingTime, retransmitWaitingTime);
628  }
629 
630  return waitingTime;
631 }
632 
633 uint8_t
635 {
637 }
638 
639 void
641 {
643 }
644 
645 uint8_t
647 {
649 }
650 
651 void
653 {
654  m_secondReceiveWindowFrequency = frequencyMHz;
655 }
656 
657 double
659 {
661 }
662 
664 // MAC command methods //
666 
667 void
668 LorawanMacEndDeviceClassA::OnRxClassParamSetupReq(Ptr<RxParamSetupReq> rxParamSetupReq)
669 {
670  NS_LOG_FUNCTION(this << rxParamSetupReq);
671 
672  bool offsetOk = true;
673  bool dataRateOk = true;
674 
675  uint8_t rx1DrOffset = rxParamSetupReq->GetRx1DrOffset();
676  uint8_t rx2DataRate = rxParamSetupReq->GetRx2DataRate();
677  double frequency = rxParamSetupReq->GetFrequency();
678 
679  NS_LOG_FUNCTION(this << unsigned(rx1DrOffset) << unsigned(rx2DataRate) << frequency);
680 
681  // Check that the desired offset is valid
682  if (!(0 <= rx1DrOffset && rx1DrOffset <= 5))
683  {
684  offsetOk = false;
685  }
686 
687  // Check that the desired data rate is valid
688  if (GetSfFromDataRate(rx2DataRate) == 0 || GetBandwidthFromDataRate(rx2DataRate) == 0)
689  {
690  dataRateOk = false;
691  }
692 
693  // For now, don't check for validity of frequency
694  m_secondReceiveWindowDataRate = rx2DataRate;
695  m_rx1DrOffset = rx1DrOffset;
696  m_secondReceiveWindowFrequency = frequency;
697 
698  // Craft a RxParamSetupAns as response
699  NS_LOG_INFO("Adding RxParamSetupAns reply");
700  m_macCommandList.push_back(CreateObject<RxParamSetupAns>(offsetOk, dataRateOk, true));
701 }
702 
703 } /* 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.
void AddEvent(Time duration, Ptr< LoraLogicalChannel > channel)
Register the transmission of a packet.
Tag used to save various data about a packet, like its Spreading Factor and data about interference.
Definition: lora-tag.h:38
void SetDataRate(uint8_t dataRate)
Set the data rate for this packet.
Definition: lora-tag.cc:152
void SetFrequency(double frequency)
Set the frequency of the packet.
Definition: lora-tag.cc:134
void SetModcod(uint8_t modcod)
Set the modcod for this packet.
Definition: lora-tag.cc:164
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.
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.
Class representing the MAC layer of a LoRaWAN device.
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.
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_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.
Definition: lorawan-mac.h:268
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...
Definition: lorawan-mac.h:321
int m_nPreambleSymbols
The number of symbols to use in the PHY preamble.
Definition: lorawan-mac.h:310
Time GetOnAirTime(Ptr< Packet > packet, LoraTxParameters txParams)
Compute the time that a packet with certain characteristics will take to be transmitted.
Definition: lorawan-mac.cc:164
Ptr< SatPhy > m_phy
The PHY instance that sits under this MAC layer.
Definition: lorawan-mac.h:279
uint8_t GetSfFromDataRate(uint8_t dataRate)
Get the SF corresponding to a data rate, based on this MAC's region.
Definition: lorawan-mac.cc:123
Ptr< NetDevice > m_device
The device this MAC layer is installed on.
Definition: lorawan-mac.h:284
LoraLogicalChannelHelper m_channelHelper
The LoraLogicalChannelHelper instance that is assigned to this MAC.
Definition: lorawan-mac.h:289
double GetBandwidthFromDataRate(uint8_t dataRate)
Get the BW corresponding to a data rate, based on this MAC's region.
Definition: lorawan-mac.cc:137
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.
@ 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.
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.
Definition: satellite-phy.h:78
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.