37 NS_LOG_COMPONENT_DEFINE(
"LoraAdrComponent");
39 NS_OBJECT_ENSURE_REGISTERED(LoraAdrComponent);
45 TypeId(
"ns3::LoraAdrComponent")
47 .SetParent<LoraNetworkControllerComponent>()
49 "MultipleGwCombiningMethod",
50 "Whether to average the received power of gateways or to use the maximum",
59 .AddAttribute(
"MultiplePacketsCombiningMethod",
60 "Whether to average SNRs from multiple packets or to use the maximum",
62 MakeEnumAccessor<LoraAdrComponent::CombiningMethod>(
70 .AddAttribute(
"HistoryRange",
71 "Number of packets to use for averaging",
74 MakeIntegerChecker<int>(0, 100))
75 .AddAttribute(
"ChangeTransmissionPower",
76 "Whether to toggle the transmission power or not",
79 MakeBooleanChecker());
93 Ptr<LoraEndDeviceStatus> status,
94 Ptr<LoraNetworkStatus> networkStatus)
96 NS_LOG_FUNCTION(this->
GetTypeId() << packet << networkStatus);
104 Ptr<LoraNetworkStatus> networkStatus)
106 NS_LOG_FUNCTION(
this << status << networkStatus);
108 Ptr<Packet> myPacket = status->GetLastPacketReceivedFromDevice()->Copy();
112 myPacket->RemoveHeader(mHdr);
113 myPacket->RemoveHeader(fHdr);
118 if (
int(status->GetReceivedPacketList().size()) <
historyRange)
120 NS_LOG_ERROR(
"Not enough packets received by this device ("
121 << status->GetReceivedPacketList().size()
122 <<
") for the algorithm to work (need " <<
historyRange <<
")");
126 NS_LOG_DEBUG(
"New ADR request");
129 uint8_t spreadingFactor = status->GetFirstReceiveWindowSpreadingFactor();
132 uint8_t transmissionPower = status->GetMac()->GetTransmissionPower();
144 newTxPower = transmissionPower;
147 if (newDataRate !=
SfToDr(spreadingFactor) || newTxPower != transmissionPower)
150 int channels[] = {0, 1, 2};
151 std::list<int> enabledChannels(channels, channels +
sizeof(channels) /
sizeof(
int));
156 NS_LOG_DEBUG(
"Sending LinkAdrReq with DR = " << (
unsigned)newDataRate
157 <<
" and TP = " << (
unsigned)newTxPower
160 status->m_reply.frameHeader.AddLinkAdrReq(newDataRate,
164 status->m_reply.frameHeader.SetAsDownlink();
167 status->m_reply.needsReply =
true;
171 NS_LOG_DEBUG(
"Skipped request");
183 Ptr<LoraNetworkStatus> networkStatus)
185 NS_LOG_FUNCTION(this->
GetTypeId() << networkStatus);
191 Ptr<LoraEndDeviceStatus> status)
207 NS_LOG_DEBUG(
"m_SNR = " << m_SNR);
210 uint8_t spreadingFactor = status->GetFirstReceiveWindowSpreadingFactor();
212 NS_LOG_DEBUG(
"SF = " << (
unsigned)spreadingFactor);
217 NS_LOG_DEBUG(
"Required SNR = " << req_SNR);
220 double transmissionPower = status->GetMac()->GetTransmissionPower();
222 NS_LOG_DEBUG(
"Transmission Power = " << transmissionPower);
226 double margin_SNR = m_SNR - req_SNR;
228 NS_LOG_DEBUG(
"Margin = " << margin_SNR);
232 int steps = std::floor(margin_SNR / 3);
234 NS_LOG_DEBUG(
"steps = " << steps);
249 NS_LOG_DEBUG(
"Decreased SF by 1");
253 transmissionPower -= 2;
255 NS_LOG_DEBUG(
"Decreased Ptx by 2");
259 transmissionPower += 2;
261 NS_LOG_DEBUG(
"Increased Ptx by 2");
264 *newDataRate =
SfToDr(spreadingFactor);
265 *newTxPower = transmissionPower;
298 return transmissionPower + 174 - 10 * log10(
B) -
NF;
305 LoraEndDeviceStatus::GatewayList::iterator it = gwList.begin();
306 double min = it->second.rxPower;
308 for (; it != gwList.end(); it++)
310 if (it->second.rxPower < min)
312 min = it->second.rxPower;
323 LoraEndDeviceStatus::GatewayList::iterator it = gwList.begin();
324 double max = it->second.rxPower;
326 for (; it != gwList.end(); it++)
328 if (it->second.rxPower > max)
330 max = it->second.rxPower;
343 for (LoraEndDeviceStatus::GatewayList::iterator it = gwList.begin(); it != gwList.end(); it++)
345 NS_LOG_DEBUG(
"Gateway at " << it->first <<
" has TP " << it->second.rxPower);
346 sum += it->second.rxPower;
349 double average = sum / gwList.size();
351 NS_LOG_DEBUG(
"TP (average) = " << average);
379 auto it = packetList.rbegin();
387 NS_LOG_DEBUG(
"m_SNR = " << m_SNR);
395 NS_LOG_DEBUG(
"SNR (min) = " << min);
406 auto it = packetList.rbegin();
414 NS_LOG_DEBUG(
"m_SNR = " << m_SNR);
422 NS_LOG_DEBUG(
"SNR (max) = " << max);
435 auto it = packetList.rbegin();
441 NS_LOG_DEBUG(
"m_SNR = " << m_SNR);
448 NS_LOG_DEBUG(
"SNR (average) = " << average);
460 else if (txPower >= 14)
464 else if (txPower >= 12)
468 else if (txPower >= 10)
472 else if (txPower >= 8)
476 else if (txPower >= 6)
480 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.