34 #include <ns3/pointer.h>
41 NS_LOG_COMPONENT_DEFINE(
"LorawanMacEndDeviceClassA");
43 NS_OBJECT_ENSURE_REGISTERED(LorawanMacEndDeviceClassA);
49 TypeId(
"ns3::LorawanMacEndDeviceClassA")
51 .AddAttribute(
"FirstWindowDelay",
52 "Time to wait between end of message transmission and opening of first "
54 TimeValue(Seconds(1)),
57 .AddAttribute(
"SecondWindowDelay",
58 "Time to wait between end of message transmission and opening of second "
60 TimeValue(Seconds(2)),
63 .AddAttribute(
"FirstWindowDuration",
64 "Duration of first reception window",
65 TimeValue(MilliSeconds(100)),
68 .AddAttribute(
"SecondWindowDuration",
69 "Duration of second reception window",
70 TimeValue(MilliSeconds(100)),
73 .AddConstructor<LorawanMacEndDeviceClassA>();
79 NS_FATAL_ERROR(
"Default constructor not in use");
84 Ptr<SatSuperframeSeq> seq)
87 m_firstWindowDelay(Seconds(1)),
88 m_secondWindowDelay(Seconds(2)),
89 m_firstWindowDuration(MilliSeconds(100)),
90 m_secondWindowDuration(MilliSeconds(100)),
93 NS_LOG_FUNCTION(
this);
106 NS_LOG_FUNCTION_NOARGS();
119 NS_LOG_FUNCTION(
this);
121 NS_LOG_DEBUG(
"PacketToSend: " << packetToSend);
123 if (DynamicCast<SatLoraPhyTx>(
m_phy->GetPhyTx())->IsTransmitting())
126 NS_LOG_WARN(
"End Device is already transmitting. Aborting.");
141 packetToSend->RemovePacketTag(
150 packetToSend->RemovePacketTag(satDevTag);
154 uint32_t allocationChannel = 0;
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());
164 txInfo.
modCod = wf->GetModCod();
184 double frequency = txChannel->GetFrequency();
186 packetToSend->RemovePacketTag(tag);
190 packetToSend->AddPacketTag(tag);
193 packetToSend->RemovePacketTag(mTag);
196 packetToSend->AddPacketTag(mTag);
199 packetToSend->RemovePacketTag(addressE2ETag);
202 packetToSend->AddPacketTag(addressE2ETag);
205 packets.push_back(packetToSend);
207 uint32_t carrierId = 0;
213 m_phy->SendPdu(packets, carrierId, duration, txInfo);
215 NS_LOG_DEBUG(
"PacketToSend: " << packetToSend);
229 m_phyRx->SetFrequency(txChannel->GetFrequency());
234 NS_LOG_DEBUG(
"m_dataRate: " <<
unsigned(
m_dataRate)
236 <<
", replyDataRate: " <<
unsigned(replyDataRate) <<
".");
248 NS_LOG_FUNCTION(
this << packet);
252 packet->RemovePacketTag(macTag);
254 packet->AddPacketTag(macTag);
257 packet->RemovePacketTag(addressE2ETag);
259 packet->AddPacketTag(addressE2ETag);
262 packets.push_back(packet);
268 Ptr<Packet> packetCopy = packet->Copy();
271 packetCopy->RemovePacketTag(mTag);
275 packetCopy->RemoveHeader(mHdr);
277 NS_LOG_DEBUG(
"Mac Header: " << mHdr);
282 NS_LOG_INFO(
"Found a downlink packet.");
287 packetCopy->RemoveHeader(fHdr);
289 NS_LOG_DEBUG(
"Frame Header: " << fHdr);
296 NS_LOG_INFO(
"The message is for us!");
312 NS_LOG_DEBUG(
"The message is intended for another recipient.");
328 NS_LOG_DEBUG(
"Failure: no more retransmissions left. Used "
329 <<
unsigned(txs) <<
" transmissions.");
338 <<
" retransmissions left: rescheduling transmission.");
345 NS_LOG_INFO(
"The packet we are receiving is in uplink.");
350 <<
" retransmissions left: rescheduling transmission.");
356 NS_LOG_DEBUG(
"Failure: no more retransmissions left. Used " <<
unsigned(txs)
357 <<
" transmissions.");
370 NS_LOG_FUNCTION(
this << packet);
381 <<
" retransmissions left: rescheduling transmission.");
387 NS_LOG_DEBUG(
"Failure: no more retransmissions left. Used " <<
unsigned(txs)
388 <<
" transmissions.");
399 NS_LOG_FUNCTION_NOARGS();
420 switch (randomAccessModel)
446 NS_LOG_FUNCTION_NOARGS();
462 NS_LOG_FUNCTION_NOARGS();
472 NS_ABORT_MSG(
"PHY was in TX mode when attempting to "
473 <<
"close a receive window.");
491 NS_LOG_FUNCTION_NOARGS();
497 NS_LOG_INFO(
"Won't open second receive window since we are in RX mode.");
522 NS_LOG_FUNCTION_NOARGS();
538 NS_LOG_DEBUG(
"PHY is receiving: Receive will handle the result.");
548 NS_LOG_DEBUG(
"No reception initiated by PHY: rescheduling transmission.");
552 <<
" retransmissions left: rescheduling transmission.");
560 NS_LOG_DEBUG(
"Failure: no more retransmissions left. Used " <<
unsigned(txs)
561 <<
" transmissions.");
569 NS_ABORT_MSG(
"The number of retransmissions left is negative ! ");
578 <<
" transmissions left. We were not transmitting confirmed messages.");
592 NS_LOG_FUNCTION_NOARGS();
601 NS_LOG_WARN(
"Attempting to send when there are receive windows:"
602 <<
" Transmission postponed.");
610 NS_LOG_DEBUG(
"Duration until endSecondRxWindow for new transmission:"
611 << (endSecondRxWindow - Simulator::Now()).GetSeconds());
612 waitingTime = std::max(waitingTime, endSecondRxWindow - Simulator::Now());
622 Time retransmitWaitingTime =
625 NS_LOG_DEBUG(
"ack_timeout:" << ack_timeout <<
" retransmitWaitingTime:"
626 << retransmitWaitingTime.GetSeconds());
627 waitingTime = std::max(waitingTime, retransmitWaitingTime);
670 NS_LOG_FUNCTION(
this << rxParamSetupReq);
672 bool offsetOk =
true;
673 bool dataRateOk =
true;
675 uint8_t rx1DrOffset = rxParamSetupReq->GetRx1DrOffset();
676 uint8_t rx2DataRate = rxParamSetupReq->GetRx2DataRate();
677 double frequency = rxParamSetupReq->GetFrequency();
679 NS_LOG_FUNCTION(
this <<
unsigned(rx1DrOffset) <<
unsigned(rx2DataRate) << frequency);
682 if (!(0 <= rx1DrOffset && rx1DrOffset <= 5))
699 NS_LOG_INFO(
"Adding RxParamSetupAns reply");
700 m_macCommandList.push_back(CreateObject<RxParamSetupAns>(offsetOk, dataRateOk,
true));
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.
void SetDataRate(uint8_t dataRate)
Set the data rate for this packet.
void SetFrequency(double frequency)
Set the frequency of the packet.
void SetModcod(uint8_t modcod)
Set the modcod for this packet.
LorawanMacEndDeviceClassA()
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...
static TypeId GetTypeId(void)
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.
virtual ~LorawanMacEndDeviceClassA()
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
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.
@ RA_MODEL_RCS2_SPECIFICATION
@ PACKET_TYPE_DEDICATED_ACCESS
@ PACKET_TYPE_SLOTTED_ALOHA
@ 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.
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.
double codingRate
Code rate.
bool crcEnabled
Whether Cyclic Redundancy Check is enabled.
Struct for storing the packet specific Tx information.
SatEnums::PacketType_t packetType
SatEnums::SatBbFrameType_t frameType
uint32_t fecBlockSizeInBytes
SatEnums::SatModcod_t modCod