34 NS_LOG_COMPONENT_DEFINE(
"LoraAdrComponent");
36 NS_OBJECT_ENSURE_REGISTERED(LoraAdrComponent);
42 TypeId(
"ns3::LoraAdrComponent")
44 .SetParent<LoraNetworkControllerComponent>()
45 .AddAttribute(
"MultipleGwCombiningMethod",
46 "Whether to average the received power of gateways or to use the maximum",
55 .AddAttribute(
"MultiplePacketsCombiningMethod",
56 "Whether to average SNRs from multiple packets or to use the maximum",
65 .AddAttribute(
"HistoryRange",
66 "Number of packets to use for averaging",
69 MakeIntegerChecker<int>(0, 100))
70 .AddAttribute(
"ChangeTransmissionPower",
71 "Whether to toggle the transmission power or not",
74 MakeBooleanChecker());
88 Ptr<LoraEndDeviceStatus> status,
89 Ptr<LoraNetworkStatus> networkStatus)
91 NS_LOG_FUNCTION(this->
GetTypeId() << packet << networkStatus);
99 Ptr<LoraNetworkStatus> networkStatus)
101 NS_LOG_FUNCTION(
this << status << networkStatus);
103 Ptr<Packet> myPacket = status->GetLastPacketReceivedFromDevice()->Copy();
107 myPacket->RemoveHeader(mHdr);
108 myPacket->RemoveHeader(fHdr);
113 if (
int(status->GetReceivedPacketList().size()) <
historyRange)
115 NS_LOG_ERROR(
"Not enough packets received by this device ("
116 << status->GetReceivedPacketList().size()
117 <<
") for the algorithm to work (need " <<
historyRange <<
")");
121 NS_LOG_DEBUG(
"New ADR request");
124 uint8_t spreadingFactor = status->GetFirstReceiveWindowSpreadingFactor();
127 uint8_t transmissionPower = status->GetMac()->GetTransmissionPower();
139 newTxPower = transmissionPower;
142 if (newDataRate !=
SfToDr(spreadingFactor) || newTxPower != transmissionPower)
145 int channels[] = {0, 1, 2};
146 std::list<int> enabledChannels(channels, channels +
sizeof(channels) /
sizeof(
int));
151 NS_LOG_DEBUG(
"Sending LinkAdrReq with DR = " << (
unsigned)newDataRate
152 <<
" and TP = " << (
unsigned)newTxPower
155 status->m_reply.frameHeader.AddLinkAdrReq(newDataRate,
159 status->m_reply.frameHeader.SetAsDownlink();
162 status->m_reply.needsReply =
true;
166 NS_LOG_DEBUG(
"Skipped request");
178 Ptr<LoraNetworkStatus> networkStatus)
180 NS_LOG_FUNCTION(this->
GetTypeId() << networkStatus);
186 Ptr<LoraEndDeviceStatus> status)
202 NS_LOG_DEBUG(
"m_SNR = " << m_SNR);
205 uint8_t spreadingFactor = status->GetFirstReceiveWindowSpreadingFactor();
207 NS_LOG_DEBUG(
"SF = " << (
unsigned)spreadingFactor);
212 NS_LOG_DEBUG(
"Required SNR = " << req_SNR);
215 double transmissionPower = status->GetMac()->GetTransmissionPower();
217 NS_LOG_DEBUG(
"Transmission Power = " << transmissionPower);
221 double margin_SNR = m_SNR - req_SNR;
223 NS_LOG_DEBUG(
"Margin = " << margin_SNR);
227 int steps = std::floor(margin_SNR / 3);
229 NS_LOG_DEBUG(
"steps = " << steps);
244 NS_LOG_DEBUG(
"Decreased SF by 1");
248 transmissionPower -= 2;
250 NS_LOG_DEBUG(
"Decreased Ptx by 2");
254 transmissionPower += 2;
256 NS_LOG_DEBUG(
"Increased Ptx by 2");
259 *newDataRate =
SfToDr(spreadingFactor);
260 *newTxPower = transmissionPower;
293 return transmissionPower + 174 - 10 * log10(
B) -
NF;
300 LoraEndDeviceStatus::GatewayList::iterator it = gwList.begin();
301 double min = it->second.rxPower;
303 for (; it != gwList.end(); it++)
305 if (it->second.rxPower < min)
307 min = it->second.rxPower;
318 LoraEndDeviceStatus::GatewayList::iterator it = gwList.begin();
319 double max = it->second.rxPower;
321 for (; it != gwList.end(); it++)
323 if (it->second.rxPower > max)
325 max = it->second.rxPower;
338 for (LoraEndDeviceStatus::GatewayList::iterator it = gwList.begin(); it != gwList.end(); it++)
340 NS_LOG_DEBUG(
"Gateway at " << it->first <<
" has TP " << it->second.rxPower);
341 sum += it->second.rxPower;
344 double average = sum / gwList.size();
346 NS_LOG_DEBUG(
"TP (average) = " << average);
374 auto it = packetList.rbegin();
382 NS_LOG_DEBUG(
"m_SNR = " << m_SNR);
390 NS_LOG_DEBUG(
"SNR (min) = " << min);
401 auto it = packetList.rbegin();
409 NS_LOG_DEBUG(
"m_SNR = " << m_SNR);
417 NS_LOG_DEBUG(
"SNR (max) = " << max);
430 auto it = packetList.rbegin();
436 NS_LOG_DEBUG(
"m_SNR = " << m_SNR);
443 NS_LOG_DEBUG(
"SNR (average) = " << average);
455 else if (txPower >= 14)
459 else if (txPower >= 12)
463 else if (txPower >= 10)
467 else if (txPower >= 8)
471 else if (txPower >= 6)
475 else if (txPower >= 4)
enum CombiningMethod tpAveraging
uint8_t SfToDr(uint8_t sf)
double GetMinSNR(LoraEndDeviceStatus::ReceivedPacketList packetList, int historyRange)
double GetAverageSNR(LoraEndDeviceStatus::ReceivedPacketList packetList, int historyRange)
enum CombiningMethod historyAveraging
const int max_transmissionPower
virtual ~LoraAdrComponent()
void OnFailedReply(Ptr< LoraEndDeviceStatus > status, Ptr< LoraNetworkStatus > networkStatus)
Method that is called when a packet cannot be sent in the downlink.
double RxPowerToSNR(double transmissionPower)
void OnReceivedPacket(Ptr< const Packet > packet, Ptr< LoraEndDeviceStatus > status, Ptr< LoraNetworkStatus > networkStatus)
Method that is called when a new packet is received by the NetworkServer.
static TypeId GetTypeId(void)
double GetMinTxFromGateways(LoraEndDeviceStatus::GatewayList gwList)
void AdrImplementation(uint8_t *newDataRate, uint8_t *newTxPower, Ptr< LoraEndDeviceStatus > status)
double GetAverageTxFromGateways(LoraEndDeviceStatus::GatewayList gwList)
const int min_spreadingFactor
void BeforeSendingReply(Ptr< LoraEndDeviceStatus > status, Ptr< LoraNetworkStatus > networkStatus)
double GetMaxSNR(LoraEndDeviceStatus::ReceivedPacketList packetList, int historyRange)
int GetTxPowerIndex(int txPower)
double GetMaxTxFromGateways(LoraEndDeviceStatus::GatewayList gwList)
const int min_transmissionPower
double GetReceivedPower(LoraEndDeviceStatus::GatewayList gwList)
std::list< std::pair< Ptr< const Packet >, ReceivedPacketInfo > > ReceivedPacketList
std::map< Address, PacketInfoPerGw > GatewayList
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.