[link-quality] fix corner case of ScaleRawValueToRssi (#9102)

Currently if we call `ScaleRawValueToRssi` with value 0 or 1, the
result is incorrect.  Because it tries to static_cast `-130` or `-129`
to `int8_t`. I think it's not worthwhile to widen int8_t to int16_t
only for the 2 corner cases. So I prefer returning the smallest value
-128 for the 2 cases.
This commit is contained in:
Li Cao
2023-05-30 22:31:14 -07:00
committed by GitHub
parent 74c5e4ba01
commit fa81b21f4c
3 changed files with 31 additions and 1 deletions
+23
View File
@@ -131,6 +131,29 @@ template <typename UintType> uint16_t ClampToUint16(UintType aValue)
return static_cast<uint16_t>(Min(aValue, static_cast<UintType>(NumericLimits<uint16_t>::kMax)));
}
/**
* Returns a clamped version of given integer to a `int8_t`.
*
* If @p aValue is smaller than min value of a `int8_t`, the min value of `int8_t` is returned.
* If @p aValue is larger than max value of a `int8_t`, the max value of `int8_t` is returned.
*
* @tparam IntType The value type (MUST be `int16_t`, `int32_t`, or `int64_t`).
*
* @param[in] aValue The value to clamp.
*
* @returns The clamped version of @p aValue to `int8_t`.
*
*/
template <typename IntType> int8_t ClampToInt8(IntType aValue)
{
static_assert(TypeTraits::IsSame<IntType, int16_t>::kValue || TypeTraits::IsSame<IntType, int32_t>::kValue ||
TypeTraits::IsSame<IntType, int64_t>::kValue,
"IntType must be `int16_t, `int32_t`, or `int64_t`");
return static_cast<int8_t>(Clamp(aValue, static_cast<IntType>(NumericLimits<int8_t>::kMin),
static_cast<IntType>(NumericLimits<int8_t>::kMax)));
}
/**
* This template function performs a three-way comparison between two values.
*
+1 -1
View File
@@ -812,7 +812,7 @@ int8_t ScaleRawValueToRssi(uint8_t aRawValue)
value = DivideAndRoundToClosest<int32_t>(value, NumericLimits<uint8_t>::kMax);
value += kMinRssi;
return static_cast<int8_t>(value);
return ClampToInt8(value);
}
} // namespace LinkMetrics
+7
View File
@@ -518,6 +518,13 @@ public:
VerifyOrQuit(LinkMetrics::ScaleRssiToRawValue(1) == 255);
VerifyOrQuit(LinkMetrics::ScaleRssiToRawValue(10) == 255);
VerifyOrQuit(LinkMetrics::ScaleRssiToRawValue(127) == 255);
// Test corner case of ScaleRawValueToRssi
for (uint8_t rawValue = 0; rawValue < 2; rawValue++)
{
int8_t rssi = LinkMetrics::ScaleRawValueToRssi(rawValue);
printf("\nRaw Value: %u -> RSSI : %-3d", rawValue, rssi);
}
}
};