From e21530551d3d7aaa22aa9faa13fda439dda6a650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 23 Sep 2026 01:26:49 +0800 Subject: [PATCH] Common (Percent): adds ffRssiToSignalQuality --- src/common/percent.h | 8 ++++++++ src/detection/wifi/wifi_apple.m | 8 ++------ src/detection/wifi/wifi_linux.c | 10 +++------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/common/percent.h b/src/common/percent.h index a71a62267..e54c47525 100644 --- a/src/common/percent.h +++ b/src/common/percent.h @@ -20,6 +20,14 @@ typedef struct FFPercentageModuleConfig { FFPercentageTypeFlags type; } FFPercentageModuleConfig; +// Maps a received signal strength in dBm onto the 0-100 scale the percentage formatters want. +// -50 dBm and above counts as a perfect link, -100 dBm and below as no link at all, and the range in +// between is linear. Both ends are clamped rather than extrapolated, so the result is always a +// percentage -- which also keeps it usable with `{?x}` guards, unlike a raw negative RSSI. +[[gnu::const]] static inline double ffRssiToSignalQuality(int32_t rssi) { + return (double) (rssi >= -50 ? 100 : rssi <= -100 ? 0 : (rssi + 100) * 2); +} + // if (green <= yellow) // [0, green]: print green // (green, yellow]: print yellow diff --git a/src/detection/wifi/wifi_apple.m b/src/detection/wifi/wifi_apple.m index 3807ef0e8..658a43d31 100644 --- a/src/detection/wifi/wifi_apple.m +++ b/src/detection/wifi/wifi_apple.m @@ -1,4 +1,5 @@ #include "wifi.h" +#include "common/percent.h" #include "common/processing.h" #include "common/strutil.h" #include "common/apple/cf_helpers.h" @@ -7,11 +8,6 @@ #import #import -static inline double rssiToSignalQuality(int rssi) { - return (double) (rssi >= -50 ? 100 : rssi <= -100 ? 0 - : (rssi + 100) * 2); -} - @interface CWNetworkProfile () @property (readonly, retain, nullable) NSArray* bssidList; @end @@ -101,7 +97,7 @@ const char* ffDetectWifi(FFlist* result) { } break; } - item->conn.signalQuality = rssiToSignalQuality((int) inf.rssiValue); + item->conn.signalQuality = ffRssiToSignalQuality((int) inf.rssiValue); item->conn.txRate = inf.transmitRate; switch (inf.security) { diff --git a/src/detection/wifi/wifi_linux.c b/src/detection/wifi/wifi_linux.c index c0a56ede4..71a829921 100644 --- a/src/detection/wifi/wifi_linux.c +++ b/src/detection/wifi/wifi_linux.c @@ -2,6 +2,7 @@ #include "common/endian.h" #include "common/io.h" #include "common/debug.h" +#include "common/percent.h" #include "common/strutil.h" #include @@ -35,11 +36,6 @@ typedef struct FFWifiSecurityFlags { bool eap : 1; } FFWifiSecurityFlags; -static inline double rssiToSignalQuality(int rssi) { - return (double) (rssi >= -50 ? 100 : rssi <= -100 ? 0 - : (rssi + 100) * 2); -} - static inline uint32_t ffWifiGetNetlinkPortId(int sockFd) { struct sockaddr_nl addr = {}; socklen_t addrLen = sizeof(addr); @@ -605,7 +601,7 @@ static void ffWifiParseBssAttr(const struct nlattr* bssAttr, FFWifiResult* item) item->conn.channel = ffWifiFreqToChannel(item->conn.frequency); } else if (type == NL80211_BSS_SIGNAL_MBM && payload >= sizeof(int32_t)) { int rssi = *(int32_t*) ffWifiNlAttrData(attr) / 100; // mBm (100 * dBm) => dBm - item->conn.signalQuality = rssiToSignalQuality(rssi); + item->conn.signalQuality = ffRssiToSignalQuality(rssi); } else if (type == NL80211_BSS_CAPABILITY && payload >= sizeof(uint16_t)) { uint16_t capability = *(uint16_t*) ffWifiNlAttrData(attr); sec.privacy = (capability & (1u << 4u)) != 0; // IEEE 802.11 capability bit 4: privacy @@ -717,7 +713,7 @@ static void ffWifiParseStationInfo(const struct nlattr* staInfoAttr, FFWifiResul if (type == NL80211_STA_INFO_SIGNAL && payload >= sizeof(uint8_t) && item->conn.signalQuality == -DBL_MAX) { int rssi = (int8_t) *(const uint8_t*) ffWifiNlAttrData(attr); - item->conn.signalQuality = rssiToSignalQuality(rssi); + item->conn.signalQuality = ffRssiToSignalQuality(rssi); } else if (type == NL80211_STA_INFO_TX_BITRATE && (item->conn.txRate == -DBL_MAX || item->conn.channelWidth == 0)) { double tx = ffWifiParseBitrateFromRateInfo(attr, &item->conn.protocol, &item->conn.channelWidth); if (tx != -DBL_MAX) {