blob: 086d74774a87239f86529eb2a81aea3339b1ce8b [file] [log] [blame]
Abtin Keshavarziancb338982016-06-27 14:15:11 -07001/*
Jonathan Hui44350172016-09-13 15:57:11 -07002 * Copyright (c) 2016, The OpenThread Authors.
Abtin Keshavarziancb338982016-06-27 14:15:11 -07003 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. Neither the name of the copyright holder nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/**
30 * @file
31 * This file includes definitions for storing and processing link quality information.
32 */
33
34#ifndef LINK_QUALITY_HPP_
35#define LINK_QUALITY_HPP_
36
Abtin Keshavarzian2ea56442017-10-17 09:46:34 -070037#include "openthread-core-config.h"
38
Jonathan Hui69d98d42018-02-06 14:14:57 -080039#include <openthread/platform/radio.h>
Abtin Keshavarziancb338982016-06-27 14:15:11 -070040
Li Cao2dc8d712020-11-04 08:06:04 +080041#include "common/clearable.hpp"
Abtin Keshavarzian2437a752020-02-16 22:09:58 -080042#include "common/locator.hpp"
Abtin Keshavarzian4b918f82018-06-11 09:10:52 -070043#include "common/string.hpp"
Abtin Keshavarzian052fccb2022-12-21 10:19:17 -080044#include "thread/mle_types.hpp"
Abtin Keshavarzian4b918f82018-06-11 09:10:52 -070045
Jonathan Hui1eabda62017-04-27 22:29:05 -070046namespace ot {
Abtin Keshavarziancb338982016-06-27 14:15:11 -070047
48/**
49 * @addtogroup core-link-quality
50 *
51 * @brief
52 * This module includes definitions for Thread link quality metrics.
53 *
54 * @{
55 */
56
Abtin Keshavarzianc2d22742018-01-22 08:56:18 -080057/**
58 * This class implements an operation Success Rate Tracker.
59 *
60 * This can be used to track different link quality related metrics, e.g., CCA failure rate, frame tx success rate).
61 * The success rate is maintained using an exponential moving IIR averaging filter with a `uint16_t` as the storage.
62 *
63 */
Li Cao2dc8d712020-11-04 08:06:04 +080064class SuccessRateTracker : public Clearable<SuccessRateTracker>
Abtin Keshavarzianc2d22742018-01-22 08:56:18 -080065{
66public:
Abtin Keshavarzian312ef5a2021-08-06 10:22:11 -070067 static constexpr uint16_t kMaxRateValue = 0xffff; ///< Value corresponding to max (failure/success) rate of 100%.
Abtin Keshavarzianc2d22742018-01-22 08:56:18 -080068
69 /**
Abtin Keshavarzianc2d22742018-01-22 08:56:18 -080070 * This method adds a sample (success or failure) to `SuccessRateTracker`.
71 *
72 * @param[in] aSuccess The sample status be added, `true` for success, `false` for failure.
73 * @param[in] aWeight The weight coefficient used for adding the new sample into average.
74 *
75 */
76 void AddSample(bool aSuccess, uint16_t aWeight = kDefaultWeight);
77
78 /**
79 * This method returns the average failure rate.
80 *
81 * @retval the average failure rate `[0-kMaxRateValue]` with `kMaxRateValue` corresponding to 100%.
82 *
83 */
Abtin Keshavarzian68a605f2018-01-31 12:40:23 -080084 uint16_t GetFailureRate(void) const { return mFailureRate; }
Abtin Keshavarzianc2d22742018-01-22 08:56:18 -080085
86 /**
87 * This method returns the average success rate.
88 *
89 * @retval the average success rate as [0-kMaxRateValue] with `kMaxRateValue` corresponding to 100%.
90 *
91 */
Abtin Keshavarzian68a605f2018-01-31 12:40:23 -080092 uint16_t GetSuccessRate(void) const { return kMaxRateValue - mFailureRate; }
Abtin Keshavarzianc2d22742018-01-22 08:56:18 -080093
94private:
Abtin Keshavarzian312ef5a2021-08-06 10:22:11 -070095 static constexpr uint16_t kDefaultWeight = 64;
Abtin Keshavarzianc2d22742018-01-22 08:56:18 -080096
Abtin Keshavarzian68a605f2018-01-31 12:40:23 -080097 uint16_t mFailureRate;
Abtin Keshavarzianc2d22742018-01-22 08:56:18 -080098};
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -070099
100/**
101 * This class implements a Received Signal Strength (RSS) averager.
102 *
103 * The average is maintained using an adaptive exponentially weighted moving filter.
104 *
105 */
Li Cao2dc8d712020-11-04 08:06:04 +0800106class RssAverager : public Clearable<RssAverager>
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700107{
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700108public:
Abtin Keshavarzian312ef5a2021-08-06 10:22:11 -0700109 static constexpr uint16_t kStringSize = 10; ///< Max string size for average (@sa ToString()).
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700110
111 /**
Abtin Keshavarzian4b918f82018-06-11 09:10:52 -0700112 * This type defines the fixed-length `String` object returned from `ToString()`.
113 *
114 */
115 typedef String<kStringSize> InfoString;
116
117 /**
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700118 * This method indicates whether the averager contains an average (i.e., at least one RSS value has been added).
119 *
120 * @retval true If the average value is available (at least one RSS value has been added).
121 * @retval false Averager is empty (no RSS value added yet).
122 *
123 */
124 bool HasAverage(void) const { return (mCount != 0); }
125
126 /**
127 * This method adds a received signal strength (RSS) value to the average.
128 *
Abtin Keshavarzianba4389a2022-08-30 09:10:18 -0700129 * If @p aRss is `Radio::kInvalidRssi`, it is ignored and error status kErrorInvalidArgs is returned.
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700130 * The value of RSS is capped at 0dBm (i.e., for any given RSS value higher than 0dBm, 0dBm is used instead).
131 *
132 * @param[in] aRss Received signal strength value (in dBm) to be added to the average.
133 *
Abtin Keshavarzian7dca56e2021-03-15 21:07:07 -0700134 * @retval kErrorNone New RSS value added to average successfully.
Abtin Keshavarzianba4389a2022-08-30 09:10:18 -0700135 * @retval kErrorInvalidArgs Value of @p aRss is `Radio::kInvalidRssi`.
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700136 *
137 */
Abtin Keshavarzian7dca56e2021-03-15 21:07:07 -0700138 Error Add(int8_t aRss);
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700139
140 /**
141 * This method returns the current average signal strength value maintained by the averager.
142 *
Abtin Keshavarzianba4389a2022-08-30 09:10:18 -0700143 * @returns The current average value (in dBm) or `Radio::kInvalidRssi` if no average is available.
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700144 *
145 */
146 int8_t GetAverage(void) const;
147
148 /**
149 * This method returns an raw/encoded version of current average signal strength value. The raw value is the
150 * average multiplied by a precision factor (currently set as -8).
151 *
152 * @returns The current average multiplied by precision factor or zero if no average is available.
153 *
154 */
155 uint16_t GetRaw(void) const { return mAverage; }
156
157 /**
158 * This method converts the current average RSS value to a human-readable string (e.g., "-80.375"). If the
159 * average is unknown, empty string is returned.
160 *
Abtin Keshavarzian4b918f82018-06-11 09:10:52 -0700161 * @returns An `InfoString` object containing the string representation of average RSS.
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700162 *
163 */
Abtin Keshavarzian4b918f82018-06-11 09:10:52 -0700164 InfoString ToString(void) const;
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700165
166private:
167 /*
168 * The RssAverager uses an adaptive exponentially weighted filter to maintain the average. It keeps track of
169 * current average and the number of added RSS values (up to a 8).
170 *
171 * For the first 8 added RSS values, the average is the arithmetic mean of the added values (e.g., if 5 values are
172 * added, the average is sum of the 5 added RSS values divided by 5. After the 8th RSS value, a weighted filter is
173 * used with coefficients (1/8, 7/8), i.e., newAverage = 1/8 * newRss + 7/8 * oldAverage.
174 *
175 * To add to accuracy of the averaging process, the RSS values and the maintained average are multiplied by a
176 * precision factor of -8.
177 *
178 */
Abtin Keshavarzian312ef5a2021-08-06 10:22:11 -0700179 static constexpr uint8_t kPrecisionBitShift = 3; // Precision multiple for RSS average (1 << PrecisionBitShift).
180 static constexpr uint8_t kPrecision = (1 << kPrecisionBitShift);
181 static constexpr uint8_t kPrecisionBitMask = (kPrecision - 1);
182 static constexpr uint8_t kCoeffBitShift = 3; // Coeff for exp weighted filter (1 << kCoeffBitShift).
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700183
184 // Member variables fit into two bytes.
185
Jonathan Hui69d98d42018-02-06 14:14:57 -0800186 uint16_t mAverage : 11; // The raw average signal strength value (stored as RSS times precision multiple).
187 uint16_t mCount : 5; // Number of RSS values added to averager so far (limited to 2^kCoeffBitShift-1).
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700188};
189
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700190/**
Li Caodc947582020-09-26 00:50:09 +0800191 * This class implements a Link Quality Indicator (LQI) averager.
192 *
193 * It maintains the exponential moving average value of LQI.
194 *
195 */
Li Cao2dc8d712020-11-04 08:06:04 +0800196class LqiAverager : public Clearable<LqiAverager>
Li Caodc947582020-09-26 00:50:09 +0800197{
198public:
199 /**
Li Caodc947582020-09-26 00:50:09 +0800200 * This method adds a link quality indicator (LQI) value to the average.
201 *
202 * @param[in] aLqi Link Quality Indicator value to be added to the average.
203 *
204 */
205 void Add(uint8_t aLqi);
206
207 /**
208 * This method returns the current average link quality value maintained by the averager.
209 *
210 * @returns The current average value.
211 *
212 */
213 uint8_t GetAverage(void) const { return mAverage; }
214
215 /**
216 * This method returns the count of frames calculated so far.
217 *
218 * @returns The count of frames calculated.
219 *
220 */
221 uint8_t GetCount(void) const { return mCount; }
222
223private:
Abtin Keshavarzian312ef5a2021-08-06 10:22:11 -0700224 static constexpr uint8_t kCoeffBitShift = 3; // Coeff used for exp weighted filter (1 << kCoeffBitShift).
Li Caodc947582020-09-26 00:50:09 +0800225
Abtin Keshavarzian312ef5a2021-08-06 10:22:11 -0700226 uint8_t mAverage; // The average link quality indicator value.
227 uint8_t mCount; // Number of LQI values added to averager so far.
Li Caodc947582020-09-26 00:50:09 +0800228};
229
230/**
Abtin Keshavarzian8714ec12022-05-09 14:17:33 -0700231 * This enumeration represents the link quality constants.
232 *
233 * Link Quality is an integer in [0, 3]. A higher link quality indicates a more usable link, with 0 indicating that the
234 * link is non-existent or unusable.
235 *
236 */
237enum LinkQuality : uint8_t
238{
239 kLinkQuality0 = 0, ///< Link quality 0 (non-existent link)
240 kLinkQuality1 = 1, ///< Link quality 1
241 kLinkQuality2 = 2, ///< Link quality 2
242 kLinkQuality3 = 3, ///< Link quality 3
243};
244
Abtin Keshavarzian052fccb2022-12-21 10:19:17 -0800245constexpr uint8_t kCostForLinkQuality0 = Mle::kMaxRouteCost; ///< Link Cost for Link Quality 0.
246constexpr uint8_t kCostForLinkQuality1 = 4; ///< Link Cost for Link Quality 1.
247constexpr uint8_t kCostForLinkQuality2 = 2; ///< Link Cost for Link Quality 2.
248constexpr uint8_t kCostForLinkQuality3 = 1; ///< Link Cost for Link Quality 3.
249
250/**
251 * This function converts link quality to route cost.
252 *
253 * @param[in] aLinkQuality The link quality to covert.
254 *
255 * @returns The route cost corresponding to @p aLinkQuality.
256 *
257 */
258uint8_t CostForLinkQuality(LinkQuality aLinkQuality);
259
Abtin Keshavarzian8714ec12022-05-09 14:17:33 -0700260/**
Abtin Keshavarzianba006222022-08-25 14:10:29 -0700261 * This function computes the link margin from a given noise floor and received signal strength.
262 *
263 * @param[in] aNoiseFloor The noise floor value (in dBm).
264 * @param[in] aRss The received signal strength value (in dBm).
265 *
266 * @returns The link margin value in dB.
267 *
268 */
269uint8_t ComputeLinkMargin(int8_t aNoiseFloor, int8_t aRss);
270
271/**
272 * This function converts a link margin value to a link quality value.
273 *
274 * @param[in] aLinkMargin The Link Margin in dB.
275 *
276 * @returns The link quality value (0-3).
277 *
278 */
279LinkQuality LinkQualityForLinkMargin(uint8_t aLinkMargin);
280
281/**
282 * This function gets the typical received signal strength value for a given link quality.
283 *
284 * @param[in] aNoiseFloor The noise floor value (in dBm).
285 * @param[in] aLinkQuality The link quality value in [0, 3].
286 *
287 * @returns The typical platform RSSI in dBm.
288 *
289 */
290int8_t GetTypicalRssForLinkQuality(int8_t aNoiseFloor, LinkQuality aLinkQuality);
291
292/**
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700293 * This class encapsulates/stores all relevant information about quality of a link, including average received signal
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700294 * strength (RSS), last RSS, link margin, and link quality.
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700295 *
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700296 */
Abtin Keshavarzian2437a752020-02-16 22:09:58 -0800297class LinkQualityInfo : public InstanceLocatorInit
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700298{
Abtin Keshavarzianba006222022-08-25 14:10:29 -0700299 friend LinkQuality LinkQualityForLinkMargin(uint8_t aLinkMargin);
300 friend int8_t GetTypicalRssForLinkQuality(int8_t aNoiseFloor, LinkQuality aLinkQuality);
301
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700302public:
Abtin Keshavarzian312ef5a2021-08-06 10:22:11 -0700303 static constexpr uint16_t kInfoStringSize = 50; ///< `InfoString` size (@sa ToInfoString()).
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700304
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700305 /**
Abtin Keshavarzian4b918f82018-06-11 09:10:52 -0700306 * This type defines the fixed-length `String` object returned from `ToInfoString()`.
307 *
308 */
309 typedef String<kInfoStringSize> InfoString;
310
311 /**
Abtin Keshavarzian2437a752020-02-16 22:09:58 -0800312 * This method initializes the `LinkQualityInfo` object.
313 *
314 * @param[in] aInstance A reference to the OpenThread instance.
315 *
316 */
317 void Init(Instance &aInstance) { InstanceLocatorInit::Init(aInstance); }
318
319 /**
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700320 * This method clears the all the data in the object.
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700321 *
322 */
323 void Clear(void);
324
325 /**
Abtin Keshavarziana1979fd2023-01-13 11:41:07 -0800326 * This method clears the average RSS value.
327 *
328 */
Jonathan Hui3d39d242023-04-11 22:39:35 -0700329 void ClearAverageRss(void) { mRssAverager.Clear(); }
Abtin Keshavarziana1979fd2023-01-13 11:41:07 -0800330
331 /**
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700332 * This method adds a new received signal strength (RSS) value to the average.
333 *
Abtin Keshavarzianb3976f52017-04-14 14:32:55 -0700334 * @param[in] aRss A new received signal strength value (in dBm) to be added to the average.
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700335 *
336 */
Abtin Keshavarzian5cddf902020-02-16 23:16:01 -0800337 void AddRss(int8_t aRss);
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700338
339 /**
Abtin Keshavarzianc2d22742018-01-22 08:56:18 -0800340 * This method returns the current average received signal strength value.
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700341 *
Abtin Keshavarzianba4389a2022-08-30 09:10:18 -0700342 * @returns The current average value or `Radio::kInvalidRssi` if no average is available.
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700343 *
344 */
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700345 int8_t GetAverageRss(void) const { return mRssAverager.GetAverage(); }
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700346
347 /**
348 * This method returns an encoded version of current average signal strength value. The encoded value is the
349 * average multiplied by a precision factor (currently -8).
350 *
351 * @returns The current average multiplied by precision factor or zero if no average is available.
352 *
353 */
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700354 uint16_t GetAverageRssRaw(void) const { return mRssAverager.GetRaw(); }
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700355
356 /**
Abtin Keshavarzian4b918f82018-06-11 09:10:52 -0700357 * This method converts the link quality info to info/debug human-readable string.
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700358 *
Abtin Keshavarzian4b918f82018-06-11 09:10:52 -0700359 * @returns An `InfoString` representing the link quality info.
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700360 *
361 */
Abtin Keshavarzian4b918f82018-06-11 09:10:52 -0700362 InfoString ToInfoString(void) const;
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700363
364 /**
365 * This method returns the link margin. The link margin is calculated using the link's current average received
366 * signal strength (RSS) and average noise floor.
367 *
368 * @returns Link margin derived from average received signal strength and average noise floor.
369 *
370 */
Abtin Keshavarzian5cddf902020-02-16 23:16:01 -0800371 uint8_t GetLinkMargin(void) const;
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700372
373 /**
374 * Returns the current one-way link quality value. The link quality value is a number 0-3.
375 *
376 * The link quality is calculated by comparing the current link margin with a set of thresholds (per Thread spec).
377 * More specifically, link margin > 20 dB gives link quality 3, link margin > 10 dB gives link quality 2,
378 * link margin > 2 dB gives link quality 1, and link margin below or equal to 2 dB yields link quality of 0.
379 *
380 * In order to ensure that a link margin near the boundary of two different link quality values does not cause
381 * frequent changes, a hysteresis of 2 dB is applied when determining the link quality. For example, the average
382 * link margin must be at least 12 dB to change a quality 1 link to a quality 2 link.
383 *
384 * @returns The current link quality value (value 0-3 as per Thread specification).
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700385 *
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700386 */
Abtin Keshavarzian8714ec12022-05-09 14:17:33 -0700387 LinkQuality GetLinkQuality(void) const { return mLinkQuality; }
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700388
389 /**
Adam Eliot89521042017-03-28 09:41:57 -0700390 * Returns the most recent RSS value.
391 *
392 * @returns The most recent RSS
393 *
394 */
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700395 int8_t GetLastRss(void) const { return mLastRss; }
Adam Eliot89521042017-03-28 09:41:57 -0700396
Abtin Keshavarzian68a605f2018-01-31 12:40:23 -0800397 /**
398 * This method adds a MAC frame transmission status (success/failure) and updates the frame tx error rate.
399 *
400 * @param[in] aTxStatus Success/Failure of MAC frame transmission (`true` -> success, `false` -> failure).
401 *
402 */
Jonathan Hui69d98d42018-02-06 14:14:57 -0800403 void AddFrameTxStatus(bool aTxStatus)
404 {
Abtin Keshavarzian68a605f2018-01-31 12:40:23 -0800405 mFrameErrorRate.AddSample(aTxStatus, OPENTHREAD_CONFIG_FRAME_TX_ERR_RATE_AVERAGING_WINDOW);
406 }
407
408 /**
409 * This method adds a message transmission status (success/failure) and updates the message error rate.
410 *
411 * @param[in] aTxStatus Success/Failure of message (`true` -> success, `false` -> message tx failed).
412 * A larger (IPv6) message may be fragmented and sent as multiple MAC frames. The message
413 * transmission is considered a failure, if any of its fragments fail after all MAC retry
414 * attempts.
415 *
416 */
Jonathan Hui69d98d42018-02-06 14:14:57 -0800417 void AddMessageTxStatus(bool aTxStatus)
418 {
Abtin Keshavarzian68a605f2018-01-31 12:40:23 -0800419 mMessageErrorRate.AddSample(aTxStatus, OPENTHREAD_CONFIG_IPV6_TX_ERR_RATE_AVERAGING_WINDOW);
420 }
421
422 /**
423 * This method returns the MAC frame transmission error rate for the link.
424 *
425 * The rate is maintained over a window of (roughly) last `OPENTHREAD_CONFIG_FRAME_TX_ERR_RATE_AVERAGING_WINDOW`
426 * frame transmissions.
427 *
428 * @returns The error rate with maximum value `0xffff` corresponding to 100% failure rate.
429 *
430 */
431 uint16_t GetFrameErrorRate(void) const { return mFrameErrorRate.GetFailureRate(); }
432
433 /**
434 * This method returns the message error rate for the link.
435 *
436 * The rate is maintained over a window of (roughly) last `OPENTHREAD_CONFIG_IPV6_TX_ERR_RATE_AVERAGING_WINDOW`
437 * (IPv6) messages.
438 *
439 * Note that a larger (IPv6) message can be fragmented and sent as multiple MAC frames. The message transmission is
440 * considered a failure, if any of its fragments fail after all MAC retry attempts.
441 *
442 * @returns The error rate with maximum value `0xffff` corresponding to 100% failure rate.
443 *
444 */
445 uint16_t GetMessageErrorRate(void) const { return mMessageErrorRate.GetFailureRate(); }
446
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700447private:
Abtin Keshavarzian312ef5a2021-08-06 10:22:11 -0700448 // Constants for obtaining link quality from link margin:
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700449
Abtin Keshavarzian312ef5a2021-08-06 10:22:11 -0700450 static constexpr uint8_t kThreshold3 = 20; // Link margin threshold for quality 3 link.
451 static constexpr uint8_t kThreshold2 = 10; // Link margin threshold for quality 2 link.
452 static constexpr uint8_t kThreshold1 = 2; // Link margin threshold for quality 1 link.
453 static constexpr uint8_t kHysteresisThreshold = 2; // Link margin hysteresis threshold.
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700454
Abtin Keshavarzian312ef5a2021-08-06 10:22:11 -0700455 static constexpr int8_t kLinkQuality3LinkMargin = 50; // link margin for Link Quality 3 (21 - 255)
456 static constexpr int8_t kLinkQuality2LinkMargin = 15; // link margin for Link Quality 3 (21 - 255)
457 static constexpr int8_t kLinkQuality1LinkMargin = 5; // link margin for Link Quality 3 (21 - 255)
458 static constexpr int8_t kLinkQuality0LinkMargin = 0; // link margin for Link Quality 3 (21 - 255)
rongli502c6ca2017-07-12 13:38:49 +0800459
Abtin Keshavarzian312ef5a2021-08-06 10:22:11 -0700460 static constexpr uint8_t kNoLinkQuality = 0xff; // Indicate that there is no previous/last link quality.
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700461
Abtin Keshavarzian8714ec12022-05-09 14:17:33 -0700462 void SetLinkQuality(LinkQuality aLinkQuality) { mLinkQuality = aLinkQuality; }
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700463
Abtin Keshavarzian8714ec12022-05-09 14:17:33 -0700464 static LinkQuality CalculateLinkQuality(uint8_t aLinkMargin, uint8_t aLastLinkQuality);
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700465
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700466 RssAverager mRssAverager;
Abtin Keshavarzian8714ec12022-05-09 14:17:33 -0700467 LinkQuality mLinkQuality;
Abtin Keshavarzian92b0ddc2017-07-11 09:10:54 -0700468 int8_t mLastRss;
Jonathan Hui2a9f1c72019-12-18 10:24:13 -0800469
Abtin Keshavarzian68a605f2018-01-31 12:40:23 -0800470 SuccessRateTracker mFrameErrorRate;
471 SuccessRateTracker mMessageErrorRate;
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700472};
473
474/**
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700475 * @}
476 */
477
Jonathan Hui69d98d42018-02-06 14:14:57 -0800478} // namespace ot
Abtin Keshavarziancb338982016-06-27 14:15:11 -0700479
480#endif // LINK_QUALITY_HPP_