Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the ResetEthNetworkDiagnosticsCounts method in ConnectivityManager #10122

Merged
merged 2 commits into from
Oct 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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