35 #include <ns3/pointer.h>
42 NS_LOG_COMPONENT_DEFINE(
"LorawanMacEndDeviceClassA");
44 NS_OBJECT_ENSURE_REGISTERED(LorawanMacEndDeviceClassA);
50 TypeId(
"ns3::LorawanMacEndDeviceClassA")
52 .AddAttribute(
"FirstWindowDelay",
53 "Time to wait between end of message transmission and opening of first "
55 TimeValue(Seconds(1)),
58 .AddAttribute(
"SecondWindowDelay",
59 "Time to wait between end of message transmission and opening of second "
61 TimeValue(Seconds(2)),
64 .AddAttribute(
"FirstWindowDuration",
65 "Duration of first reception window",
66 TimeValue(MilliSeconds(100)),
69 .AddAttribute(
"SecondWindowDuration",
70 "Duration of second reception window",
71 TimeValue(MilliSeconds(100)),
74 .AddConstructor<LorawanMacEndDeviceClassA>();
86 NS_FATAL_ERROR(
"Default constructor not in use");
92 Ptr<SatSuperframeSeq> seq)
95 m_firstWindowDelay(Seconds(1)),
96 m_secondWindowDelay(Seconds(2)),
97 m_firstWindowDuration(MilliSeconds(100)),
98 m_secondWindowDuration(MilliSeconds(100)),
101 NS_LOG_FUNCTION(
this);
103 ObjectBase::ConstructSelf(AttributeConstructionList());
106 "Second window must open after first one is closed");
119 NS_LOG_FUNCTION_NOARGS();
132 NS_LOG_FUNCTION(
this << packetToSend);
134 NS_LOG_DEBUG(
"PacketToSend: " << packetToSend);
136 if (DynamicCast<SatLoraPhyTx>(
m_phy->GetPhyTx())->IsTransmitting())
139 NS_LOG_WARN(
"End Device is already transmitting. Aborting.");
154 packetToSend->RemovePacketTag(
163 packetToSend->RemovePacketTag(satDevTag);
167 uint32_t allocationChannel = 0;
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());
177 txInfo.
modCod = wf->GetModCod();
197 double frequency = txChannel->GetFrequency();
199 packetToSend->RemovePacketTag(tag);
203 packetToSend->AddPacketTag(tag);
206 packetToSend->RemovePacketTag(mTag);
216 packetToSend->AddPacketTag(mTag);
219 packetToSend->RemovePacketTag(addressE2ETag);
222 packetToSend->AddPacketTag(addressE2ETag);
227 packetToSend->RemovePacketTag(groundStationAddressTag);
229 packetToSend->AddPacketTag(groundStationAddressTag);
233 packets.push_back(packetToSend);
235 uint32_t carrierId = 0;
241 m_phy->SendPdu(packets, carrierId, duration, txInfo);
243 NS_LOG_DEBUG(
"PacketToSend: " << packetToSend);
257 m_phyRx->SetFrequency(txChannel->GetFrequency());
262 NS_LOG_DEBUG(
"m_dataRate: " <<
unsigned(
m_dataRate)
264 <<
", replyDataRate: " <<
unsigned(replyDataRate) <<
".");
276 NS_LOG_FUNCTION(
this << packet);
280 packet->RemovePacketTag(macTag);
282 packet->AddPacketTag(macTag);
285 packet->RemovePacketTag(addressE2ETag);
287 packet->AddPacketTag(addressE2ETag);
290 packets.push_back(packet);
296 Ptr<Packet> packetCopy = packet->Copy();
299 packetCopy->RemovePacketTag(mTag);
303 packetCopy->RemoveHeader(mHdr);
305 NS_LOG_DEBUG(
"Mac Header: " << mHdr);
310 NS_LOG_INFO(
"Found a downlink packet.");
315 packetCopy->RemoveHeader(fHdr);
317 NS_LOG_DEBUG(
"Frame Header: " << fHdr);
324 NS_LOG_INFO(
"The message is for us!");
338 NS_LOG_DEBUG(
"The message is intended for another recipient.");
354 NS_LOG_DEBUG(
"Failure: no more retransmissions left. Used "
355 <<
unsigned(txs) <<
" transmissions.");
364 <<
" retransmissions left: rescheduling transmission.");
371 NS_LOG_INFO(
"The packet we are receiving is in uplink.");
376 <<
" retransmissions left: rescheduling transmission.");
382 NS_LOG_DEBUG(
"Failure: no more retransmissions left. Used " <<
unsigned(txs)
383 <<
" transmissions.");
396 NS_LOG_FUNCTION(
this << packet);
407 <<
" retransmissions left: rescheduling transmission.");
413 NS_LOG_DEBUG(
"Failure: no more retransmissions left. Used " <<
unsigned(txs)
414 <<
" transmissions.");
425 NS_LOG_FUNCTION_NOARGS();
446 switch (randomAccessModel)
472 NS_LOG_FUNCTION_NOARGS();
488 NS_LOG_FUNCTION_NOARGS();
498 NS_ABORT_MSG(
"PHY was in TX mode when attempting to "
499 <<
"close a receive window.");
517 NS_LOG_FUNCTION_NOARGS();
523 NS_LOG_INFO(
"Won't open second receive window since we are in RX mode.");
548 NS_LOG_FUNCTION_NOARGS();
564 NS_LOG_DEBUG(
"PHY is receiving: Receive will handle the result.");
574 NS_LOG_DEBUG(
"No reception initiated by PHY: rescheduling transmission.");
578 <<
" retransmissions left: rescheduling transmission.");
586 NS_LOG_DEBUG(
"Failure: no more retransmissions left. Used " <<
unsigned(txs)
587 <<
" transmissions.");
595 NS_ABORT_MSG(
"The number of retransmissions left is negative ! ");
604 <<
" transmissions left. We were not transmitting confirmed messages.");
618 NS_LOG_FUNCTION_NOARGS();
627 NS_LOG_WARN(
"Attempting to send when there are receive windows:"
628 <<
" Transmission postponed.");
636 NS_LOG_DEBUG(
"Duration until endSecondRxWindow for new transmission:"
637 << (endSecondRxWindow - Simulator::Now()).GetSeconds());
638 waitingTime = std::max(waitingTime, endSecondRxWindow - Simulator::Now());
648 Time retransmitWaitingTime =
651 NS_LOG_DEBUG(
"ack_timeout:" << ack_timeout <<
" retransmitWaitingTime:"
652 << retransmitWaitingTime.GetSeconds());
653 waitingTime = std::max(waitingTime, retransmitWaitingTime);
696 NS_LOG_FUNCTION(
this << rxParamSetupReq);
698 bool offsetOk =
true;
699 bool dataRateOk =
true;
701 uint8_t rx1DrOffset = rxParamSetupReq->GetRx1DrOffset();
702 uint8_t rx2DataRate = rxParamSetupReq->GetRx2DataRate();
703 double frequency = rxParamSetupReq->GetFrequency();
705 NS_LOG_FUNCTION(
this <<
unsigned(rx1DrOffset) <<
unsigned(rx2DataRate) << frequency);
708 if (!(0 <= rx1DrOffset && rx1DrOffset <= 5))
725 NS_LOG_INFO(
"Adding RxParamSetupAns reply");
726 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.
TypeId GetInstanceTypeId(void) const
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.
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
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
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.
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