diff --git a/src/platform/Linux/ConnectivityManagerImpl.cpp b/src/platform/Linux/ConnectivityManagerImpl.cpp index 2495f1cfeffe14..80fab03505fac8 100644 --- a/src/platform/Linux/ConnectivityManagerImpl.cpp +++ b/src/platform/Linux/ConnectivityManagerImpl.cpp @@ -243,6 +243,11 @@ CHIP_ERROR ConnectivityManagerImpl::_Init() ChipLogError(DeviceLayer, "Failed to get WiFi interface"); mWiFiIfName[0] = '\0'; } + + if (ResetWiFiStatsCount() != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to reset WiFi statistic counts"); + } #endif return CHIP_NO_ERROR; @@ -1165,6 +1170,7 @@ CHIP_ERROR ConnectivityManagerImpl::_GetWiFiRssi(int8_t & rssi) CHIP_ERROR ConnectivityManagerImpl::_GetWiFiBeaconLostCount(uint32_t & beaconLostCount) { int skfd; + uint32_t count; if (mWiFiIfName[0] == '\0') { @@ -1177,7 +1183,11 @@ CHIP_ERROR ConnectivityManagerImpl::_GetWiFiBeaconLostCount(uint32_t & beaconLos return CHIP_ERROR_OPEN_FAILED; } - return ConnectivityUtils::GetWiFiBeaconLostCount(skfd, mWiFiIfName, beaconLostCount); + ReturnErrorOnFailure(ConnectivityUtils::GetWiFiBeaconLostCount(skfd, mWiFiIfName, count)); + VerifyOrReturnError(count >= mBeaconLostCount, CHIP_ERROR_INVALID_INTEGER_VALUE); + beaconLostCount = count - mBeaconLostCount; + + return CHIP_NO_ERROR; } CHIP_ERROR ConnectivityManagerImpl::_GetWiFiCurrentMaxRate(uint64_t & currentMaxRate) @@ -1201,37 +1211,126 @@ CHIP_ERROR ConnectivityManagerImpl::_GetWiFiCurrentMaxRate(uint64_t & currentMax CHIP_ERROR ConnectivityManagerImpl::_GetWiFiPacketMulticastRxCount(uint32_t & packetMulticastRxCount) { uint64_t count; - return GetWiFiStatsCount(WiFiStatsCountType::kWiFiMulticastPacketRxCount, count); + + ReturnErrorOnFailure(GetWiFiStatsCount(WiFiStatsCountType::kWiFiMulticastPacketRxCount, count)); + VerifyOrReturnError(count >= mPacketMulticastRxCount, CHIP_ERROR_INVALID_INTEGER_VALUE); + + count -= mPacketMulticastRxCount; + VerifyOrReturnError(count <= UINT32_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE); + + packetMulticastRxCount = static_cast(count); + + return CHIP_NO_ERROR; } CHIP_ERROR ConnectivityManagerImpl::_GetWiFiPacketMulticastTxCount(uint32_t & packetMulticastTxCount) { uint64_t count; - return GetWiFiStatsCount(WiFiStatsCountType::kWiFiMulticastPacketTxCount, count); + + ReturnErrorOnFailure(GetWiFiStatsCount(WiFiStatsCountType::kWiFiMulticastPacketTxCount, count)); + VerifyOrReturnError(count >= mPacketMulticastTxCount, CHIP_ERROR_INVALID_INTEGER_VALUE); + + count -= mPacketMulticastTxCount; + VerifyOrReturnError(count <= UINT32_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE); + + packetMulticastTxCount = static_cast(count); + + return CHIP_NO_ERROR; } CHIP_ERROR ConnectivityManagerImpl::_GetWiFiPacketUnicastRxCount(uint32_t & packetUnicastRxCount) { uint64_t count; - return GetWiFiStatsCount(WiFiStatsCountType::kWiFiUnicastPacketRxCount, count); + + ReturnErrorOnFailure(GetWiFiStatsCount(WiFiStatsCountType::kWiFiUnicastPacketRxCount, count)); + VerifyOrReturnError(count >= mPacketUnicastRxCount, CHIP_ERROR_INVALID_INTEGER_VALUE); + + count -= mPacketUnicastRxCount; + VerifyOrReturnError(count <= UINT32_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE); + + packetUnicastRxCount = static_cast(count); + + return CHIP_NO_ERROR; } CHIP_ERROR ConnectivityManagerImpl::_GetWiFiPacketUnicastTxCount(uint32_t & packetUnicastTxCount) { uint64_t count; - return GetWiFiStatsCount(WiFiStatsCountType::kWiFiUnicastPacketTxCount, count); + + ReturnErrorOnFailure(GetWiFiStatsCount(WiFiStatsCountType::kWiFiUnicastPacketTxCount, count)); + VerifyOrReturnError(count >= mPacketUnicastTxCount, CHIP_ERROR_INVALID_INTEGER_VALUE); + + count -= mPacketUnicastTxCount; + VerifyOrReturnError(count <= UINT32_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE); + + packetUnicastTxCount = static_cast(count); + + return CHIP_NO_ERROR; } CHIP_ERROR ConnectivityManagerImpl::_GetWiFiOverrunCount(uint64_t & overrunCount) { - return GetWiFiStatsCount(WiFiStatsCountType::kWiFiOverrunCount, overrunCount); + uint64_t count; + + ReturnErrorOnFailure(GetWiFiStatsCount(WiFiStatsCountType::kWiFiOverrunCount, count)); + VerifyOrReturnError(count >= mOverrunCount, CHIP_ERROR_INVALID_INTEGER_VALUE); + + overrunCount = count - mOverrunCount; + + return CHIP_NO_ERROR; } CHIP_ERROR ConnectivityManagerImpl::_ResetWiFiNetworkDiagnosticsCounts() { - // On Linux simulation, the packet statistic informations are shared by all running programs, - // the current running program does not have permission to reset those counts. - return CHIP_NO_ERROR; + return ResetWiFiStatsCount(); +} + +CHIP_ERROR ConnectivityManagerImpl::ResetWiFiStatsCount() +{ + CHIP_ERROR ret = CHIP_ERROR_READ_FAILED; + struct ifaddrs * ifaddr = nullptr; + + ReturnErrorOnFailure(_GetWiFiBeaconLostCount(mBeaconLostCount)); + + if (getifaddrs(&ifaddr) == -1) + { + ChipLogError(DeviceLayer, "Failed to get network interfaces"); + } + else + { + struct ifaddrs * ifa = nullptr; + + /* Walk through linked list, maintaining head pointer so we + can free list later */ + for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) + { + if (ConnectivityUtils::GetInterfaceConnectionType(ifa->ifa_name) == ConnectionType::kConnectionWiFi) + { + ChipLogProgress(DeviceLayer, "Found the primary WiFi interface:%s", ifa->ifa_name); + break; + } + } + + if (ifa != nullptr) + { + if (ifa->ifa_addr->sa_family == AF_PACKET && ifa->ifa_data != nullptr) + { + struct rtnl_link_stats * stats = (struct rtnl_link_stats *) ifa->ifa_data; + + mPacketMulticastRxCount = stats->multicast; + mPacketMulticastTxCount = 0; + mPacketUnicastRxCount = stats->rx_packets; + mPacketUnicastTxCount = stats->tx_packets; + mOverrunCount = stats->rx_over_errors; + + ret = CHIP_NO_ERROR; + } + } + + freeifaddrs(ifaddr); + } + + return ret; } #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI diff --git a/src/platform/Linux/ConnectivityManagerImpl.h b/src/platform/Linux/ConnectivityManagerImpl.h index 406cc26c89c1d2..f8748b79cb4fe6 100644 --- a/src/platform/Linux/ConnectivityManagerImpl.h +++ b/src/platform/Linux/ConnectivityManagerImpl.h @@ -174,6 +174,10 @@ class ConnectivityManagerImpl final : public ConnectivityManager, CHIP_ERROR ResetEthernetStatsCount(); +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI + CHIP_ERROR ResetWiFiStatsCount(); +#endif + #if CHIP_DEVICE_CONFIG_ENABLE_WPA void DriveAPState(); CHIP_ERROR ConfigureWiFiAP(); @@ -206,6 +210,12 @@ class ConnectivityManagerImpl final : public ConnectivityManager, #endif #if CHIP_DEVICE_CONFIG_ENABLE_WIFI + uint32_t mBeaconLostCount = 0; + uint32_t mPacketMulticastRxCount = 0; + uint32_t mPacketMulticastTxCount = 0; + uint32_t mPacketUnicastRxCount = 0; + uint32_t mPacketUnicastTxCount = 0; + uint64_t mOverrunCount = 0; char mWiFiIfName[IFNAMSIZ]; #endif };