Skip to content

Commit

Permalink
Implement the ResetEthNetworkDiagnosticsCounts method in Connectivity…
Browse files Browse the repository at this point in the history
…Manager (#10122)

* Implement the ResetEthNetworkDiagnosticsCounts method for the zcl command

* Address the review comments
  • Loading branch information
yufengwangca authored Oct 1, 2021
1 parent 43b3d3c commit 3d70836
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,12 @@ CHIP_ERROR EthernetDiagosticsAttrAccess::ReadIfSupported(CHIP_ERROR (Connectivit

bool emberAfEthernetNetworkDiagnosticsClusterResetCountsCallback(EndpointId endpoint, app::CommandHandler * commandObj)
{
EmberAfStatus status = EthernetNetworkDiagnostics::Attributes::PacketRxCount::Set(endpoint, 0);
EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS;

VerifyOrExit(DeviceLayer::ConnectivityMgr().ResetEthNetworkDiagnosticsCounts() == CHIP_NO_ERROR,
status = EMBER_ZCL_STATUS_FAILURE);

status = EthernetNetworkDiagnostics::Attributes::PacketRxCount::Set(endpoint, 0);
VerifyOrExit(status == EMBER_ZCL_STATUS_SUCCESS, ChipLogError(Zcl, "Failed to reset PacketRxCount attribute"));

status = EthernetNetworkDiagnostics::Attributes::PacketTxCount::Set(endpoint, 0);
Expand Down
6 changes: 6 additions & 0 deletions src/include/platform/ConnectivityManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ class ConnectivityManager
CHIP_ERROR GetEthTxErrCount(uint64_t & txErrCount);
CHIP_ERROR GetEthCollisionCount(uint64_t & collisionCount);
CHIP_ERROR GetEthOverrunCount(uint64_t & overrunCount);
CHIP_ERROR ResetEthNetworkDiagnosticsCounts();

// WiFi network diagnostics methods
CHIP_ERROR GetWiFiSecurityType(uint8_t & securityType);
Expand Down Expand Up @@ -410,6 +411,11 @@ inline CHIP_ERROR ConnectivityManager::GetEthOverrunCount(uint64_t & overrunCoun
return static_cast<ImplClass *>(this)->_GetEthOverrunCount(overrunCount);
}

inline CHIP_ERROR ConnectivityManager::ResetEthNetworkDiagnosticsCounts()
{
return static_cast<ImplClass *>(this)->_ResetEthNetworkDiagnosticsCounts();
}

inline CHIP_ERROR ConnectivityManager::GetWiFiSecurityType(uint8_t & securityType)
{
return static_cast<ImplClass *>(this)->_GetWiFiSecurityType(securityType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class GenericConnectivityManagerImpl
CHIP_ERROR _GetEthTxErrCount(uint64_t & txErrCount);
CHIP_ERROR _GetEthCollisionCount(uint64_t & collisionCount);
CHIP_ERROR _GetEthOverrunCount(uint64_t & overrunCount);
CHIP_ERROR _ResetEthNetworkDiagnosticsCounts();

private:
ImplClass * Impl() { return static_cast<ImplClass *>(this); }
Expand Down Expand Up @@ -107,6 +108,12 @@ inline CHIP_ERROR GenericConnectivityManagerImpl<ImplClass>::_GetEthOverrunCount
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
}

template <class ImplClass>
inline CHIP_ERROR GenericConnectivityManagerImpl<ImplClass>::_ResetEthNetworkDiagnosticsCounts()
{
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
}

} // namespace Internal
} // namespace DeviceLayer
} // namespace chip
100 changes: 95 additions & 5 deletions src/platform/Linux/ConnectivityManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,11 @@ CHIP_ERROR ConnectivityManagerImpl::_Init()
mWiFiStationMode = kWiFiStationMode_Disabled;
mWiFiStationReconnectIntervalMS = CHIP_DEVICE_CONFIG_WIFI_STATION_RECONNECT_INTERVAL;

if (ResetEthernetStatsCount() != CHIP_NO_ERROR)
{
ChipLogError(DeviceLayer, "Failed to reset Ethernet statistic counts");
}

// Initialize the generic base classes that require it.
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
GenericConnectivityManagerImpl_Thread<ConnectivityManagerImpl>::_Init();
Expand Down Expand Up @@ -1012,27 +1017,112 @@ CHIP_ERROR ConnectivityManagerImpl::ProvisionWiFiNetwork(const char * ssid, cons

CHIP_ERROR ConnectivityManagerImpl::_GetEthPacketRxCount(uint64_t & packetRxCount)
{
return GetEthernetStatsCount(EthernetStatsCountType::kEthPacketRxCount, packetRxCount);
uint64_t count;

ReturnErrorOnFailure(GetEthernetStatsCount(EthernetStatsCountType::kEthPacketRxCount, count));
VerifyOrReturnError(count >= mEthPacketRxCount, CHIP_ERROR_INVALID_INTEGER_VALUE);

packetRxCount = count - mEthPacketRxCount;

return CHIP_NO_ERROR;
}

CHIP_ERROR ConnectivityManagerImpl::_GetEthPacketTxCount(uint64_t & packetTxCount)
{
return GetEthernetStatsCount(EthernetStatsCountType::kEthPacketTxCount, packetTxCount);
uint64_t count;

ReturnErrorOnFailure(GetEthernetStatsCount(EthernetStatsCountType::kEthPacketTxCount, count));
VerifyOrReturnError(count >= mEthPacketTxCount, CHIP_ERROR_INVALID_INTEGER_VALUE);

packetTxCount = count - mEthPacketTxCount;

return CHIP_NO_ERROR;
}

CHIP_ERROR ConnectivityManagerImpl::_GetEthTxErrCount(uint64_t & txErrCount)
{
return GetEthernetStatsCount(EthernetStatsCountType::kEthTxErrCount, txErrCount);
uint64_t count;

ReturnErrorOnFailure(GetEthernetStatsCount(EthernetStatsCountType::kEthTxErrCount, count));
VerifyOrReturnError(count >= mEthTxErrCount, CHIP_ERROR_INVALID_INTEGER_VALUE);

txErrCount = count - mEthTxErrCount;

return CHIP_NO_ERROR;
}

CHIP_ERROR ConnectivityManagerImpl::_GetEthCollisionCount(uint64_t & collisionCount)
{
return GetEthernetStatsCount(EthernetStatsCountType::kEthCollisionCount, collisionCount);
uint64_t count;

ReturnErrorOnFailure(GetEthernetStatsCount(EthernetStatsCountType::kEthCollisionCount, count));
VerifyOrReturnError(count >= mEthCollisionCount, CHIP_ERROR_INVALID_INTEGER_VALUE);

collisionCount = count - mEthCollisionCount;

return CHIP_NO_ERROR;
}

CHIP_ERROR ConnectivityManagerImpl::_GetEthOverrunCount(uint64_t & overrunCount)
{
return GetEthernetStatsCount(EthernetStatsCountType::kEthOverrunCount, overrunCount);
uint64_t count;

ReturnErrorOnFailure(GetEthernetStatsCount(EthernetStatsCountType::kEthOverrunCount, count));
VerifyOrReturnError(count >= mEthOverrunCount, CHIP_ERROR_INVALID_INTEGER_VALUE);

overrunCount = count - mEthOverrunCount;

return CHIP_NO_ERROR;
}

CHIP_ERROR ConnectivityManagerImpl::_ResetEthNetworkDiagnosticsCounts()
{
return ResetEthernetStatsCount();
}

CHIP_ERROR ConnectivityManagerImpl::ResetEthernetStatsCount()
{
CHIP_ERROR ret = CHIP_ERROR_READ_FAILED;
struct ifaddrs * ifaddr = nullptr;

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::kConnectionEthernet)
{
ChipLogProgress(DeviceLayer, "Found the primary Ethernet 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;

mEthPacketRxCount = stats->rx_packets;
mEthPacketTxCount = stats->tx_packets;
mEthTxErrCount = stats->tx_errors;
mEthCollisionCount = stats->collisions;
mEthOverrunCount = stats->rx_over_errors;
ret = CHIP_NO_ERROR;
}
}

freeifaddrs(ifaddr);
}

return ret;
}

#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
Expand Down
9 changes: 9 additions & 0 deletions src/platform/Linux/ConnectivityManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ class ConnectivityManagerImpl final : public ConnectivityManager,
CHIP_ERROR _GetEthTxErrCount(uint64_t & txErrCount);
CHIP_ERROR _GetEthCollisionCount(uint64_t & collisionCount);
CHIP_ERROR _GetEthOverrunCount(uint64_t & overrunCount);
CHIP_ERROR _ResetEthNetworkDiagnosticsCounts();

#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
CHIP_ERROR _GetWiFiChannelNumber(uint16_t & channelNumber);
Expand All @@ -171,6 +172,8 @@ class ConnectivityManagerImpl final : public ConnectivityManager,

// ==================== ConnectivityManager Private Methods ====================

CHIP_ERROR ResetEthernetStatsCount();

#if CHIP_DEVICE_CONFIG_ENABLE_WPA
void DriveAPState();
CHIP_ERROR ConfigureWiFiAP();
Expand All @@ -187,6 +190,12 @@ class ConnectivityManagerImpl final : public ConnectivityManager,

// ===== Private members reserved for use by this class only.

uint64_t mEthPacketRxCount = 0;
uint64_t mEthPacketTxCount = 0;
uint64_t mEthTxErrCount = 0;
uint64_t mEthCollisionCount = 0;
uint64_t mEthOverrunCount = 0;

#if CHIP_DEVICE_CONFIG_ENABLE_WPA
ConnectivityManager::WiFiStationMode mWiFiStationMode;
ConnectivityManager::WiFiAPMode mWiFiAPMode;
Expand Down
19 changes: 11 additions & 8 deletions src/platform/Linux/ConnectivityUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,14 +257,17 @@ ConnectionType ConnectivityUtils::GetInterfaceConnectionType(const char * ifname
return ConnectionType::kConnectionWiFi;

// Test ethtool for CONNECTION_ETHERNET
struct ethtool_cmd ecmd = {};
ecmd.cmd = ETHTOOL_GSET;
struct ifreq ifr = {};
ifr.ifr_data = reinterpret_cast<char *>(&ecmd);
strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1);

if (ioctl(sock, SIOCETHTOOL, &ifr) != -1)
return ConnectionType::kConnectionEthernet;
if ((strncmp(ifname, "en", 2) == 0) || (strncmp(ifname, "eth", 3) == 0))
{
struct ethtool_cmd ecmd = {};
ecmd.cmd = ETHTOOL_GSET;
struct ifreq ifr = {};
ifr.ifr_data = reinterpret_cast<char *>(&ecmd);
strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1);

if (ioctl(sock, SIOCETHTOOL, &ifr) != -1)
return ConnectionType::kConnectionEthernet;
}

return ConnectionType::kConnectionUnknown;
}
Expand Down

0 comments on commit 3d70836

Please sign in to comment.