Skip to content

Commit

Permalink
[zephyr] Added support for getting GeneralDiagnostics attributes
Browse files Browse the repository at this point in the history
nrfconnect/Zephyr platform doesn't support get methods for
GeneralDiagnostics attributes

* Added methods for getting RebootCount, NetworkInterfaces
and BootReasons
* Added to the InetIterator methods allowing to get interface
type and hardware address using Zephyr API
* Added BootReasonType to the DiagnosticDataProvider to remove
dependency between platform and auto-generated code
  • Loading branch information
kkasperczyk-no committed Dec 3, 2021
1 parent 70af2c4 commit 7ca45e1
Show file tree
Hide file tree
Showing 17 changed files with 280 additions and 30 deletions.
3 changes: 3 additions & 0 deletions config/nrfconnect/app/sample-defaults.conf
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ CONFIG_ASSERT=y
CONFIG_HW_STACK_PROTECTION=y
CONFIG_SHELL=y

# Enable getting reboot reasons information
CONFIG_HWINFO=y

# Generic networking options
CONFIG_NETWORKING=y
CONFIG_NET_SOCKETS=y
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ using chip::DeviceLayer::ConnectivityMgr;
using chip::DeviceLayer::DiagnosticDataProvider;
using chip::DeviceLayer::GetDiagnosticDataProvider;

static_assert(sizeof(DiagnosticDataProvider::BootReasonType) == sizeof(EmberAfBootReasonType),
"BootReasonType size doesn't match EmberAfBootReasonType size");
static_assert(static_cast<uint8_t>(DiagnosticDataProvider::BootReasonType::Unspecified) == EMBER_ZCL_BOOT_REASON_TYPE_UNSPECIFIED &&
static_cast<uint8_t>(DiagnosticDataProvider::BootReasonType::SoftwareReset) ==
EMBER_ZCL_BOOT_REASON_TYPE_SOFTWARE_RESET,
"BootReasonType and EmberAfBootReasonType values does not match.");

namespace {

class GeneralDiagosticsAttrAccess : public AttributeAccessInterface
Expand Down
11 changes: 11 additions & 0 deletions src/include/platform/DiagnosticDataProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,17 @@ class WiFiDiagnosticsDelegate
class DiagnosticDataProvider
{
public:
enum BootReasonType : uint8_t
{
Unspecified = 0,
PowerOnReboot = 1,
BrownOutReset = 2,
SoftwareWatchdogReset = 3,
HardwareWatchdogReset = 4,
SoftwareUpdateCompleted = 5,
SoftwareReset = 6,
};

void SetGeneralDiagnosticsDelegate(GeneralDiagnosticsDelegate * delegate) { mGeneralDiagnosticsDelegate = delegate; }
GeneralDiagnosticsDelegate * GetGeneralDiagnosticsDelegate() const { return mGeneralDiagnosticsDelegate; }

Expand Down
37 changes: 37 additions & 0 deletions src/inet/InetInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,43 @@ bool InterfaceIterator::HasBroadcastAddress()
return HasCurrent() && INET_CONFIG_ENABLE_IPV4;
}

InterfaceType InterfaceIterator::GetInterfaceType() const
{
const net_linkaddr * linkAddr = net_if_get_link_addr(mCurrentInterface);
if (!linkAddr)
return InterfaceType::Unknown;

// Do not consider other than WiFi and Thread for now.
if (linkAddr->type == NET_LINK_IEEE802154)
{
return InterfaceType::Thread;
}
// Zephyr doesn't define WiFi address type, so it shares the same type as Ethernet.
else if (linkAddr->type == NET_LINK_ETHERNET)
{
return InterfaceType::WiFi;
}
else
{
return InterfaceType::Unknown;
}
}

CHIP_ERROR InterfaceIterator::GetHardwareAddress(uint8_t * addressBuffer, uint8_t & addressSize, uint8_t addressBufferSize) const
{
const net_linkaddr * linkAddr = net_if_get_link_addr(mCurrentInterface);
if (!linkAddr)
return CHIP_ERROR_INCORRECT_STATE;

if (linkAddr->len > addressBufferSize)
return CHIP_ERROR_INVALID_ARGUMENT;

addressSize = linkAddr->len;
memcpy(addressBuffer, linkAddr->addr, linkAddr->len);

return CHIP_NO_ERROR;
}

InterfaceAddressIterator::InterfaceAddressIterator() = default;

bool InterfaceAddressIterator::HasCurrent()
Expand Down
28 changes: 28 additions & 0 deletions src/inet/InetInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,18 @@ namespace Inet {
class IPAddress;
class IPPrefix;

/**
* Data type describing interface type.
*/
enum class InterfaceType
{
Unknown = 0,
WiFi = 1,
Ethernet = 2,
Cellular = 3,
Thread = 4,
};

/**
* Indicator for system network interfaces.
*/
Expand Down Expand Up @@ -299,6 +311,22 @@ class InterfaceIterator
*/
bool HasBroadcastAddress();

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
/**
* Returns interface type of the current network interface.
*/
InterfaceType GetInterfaceType() const;

/**
* Get the hardware address of the current network interface
*
* @param[in] addressBuffer Region of memory to write the hardware address.
* @param[in] addressSize Size of the address saved to a buffer.
* @param[in] addressBufferSize Maximum size of a buffer to save data.
*/
CHIP_ERROR GetHardwareAddress(uint8_t * addressBuffer, uint8_t & addressSize, uint8_t addressBufferSize) const;
#endif

protected:
#if CHIP_SYSTEM_CONFIG_USE_LWIP
struct netif * mCurNetif;
Expand Down
3 changes: 2 additions & 1 deletion src/platform/Ameba/ConfigurationManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
/* this file behaves like a config.h, comes first */
#include <platform/internal/CHIPDeviceLayerInternal.h>

#include <DiagnosticDataProvider.h>
#include <platform/Ameba/AmebaConfig.h>
#include <platform/ConfigurationManager.h>
#include <platform/internal/GenericConfigurationManagerImpl.cpp>
Expand Down Expand Up @@ -79,7 +80,7 @@ CHIP_ERROR ConfigurationManagerImpl::Init()

if (!AmebaConfig::ConfigValueExists(AmebaConfig::kCounterKey_BootReason))
{
err = StoreBootReason(EMBER_ZCL_BOOT_REASON_TYPE_UNSPECIFIED);
err = StoreBootReason(DiagnosticDataProvider::BootReasonType::Unspecified);
SuccessOrExit(err);
}

Expand Down
23 changes: 12 additions & 11 deletions src/platform/EFR32/ConfigurationManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include <platform/internal/GenericConfigurationManagerImpl.cpp>

#include <DiagnosticDataProvider.h>
#include <platform/ConfigurationManager.h>
#include <platform/EFR32/EFR32Config.h>

Expand Down Expand Up @@ -106,50 +107,50 @@ uint32_t ConfigurationManagerImpl::GetBootReason(void)
#if defined(_SILICON_LABS_32B_SERIES_1)
if (rebootCause & RMU_RSTCAUSE_PORST || rebootCause & RMU_RSTCAUSE_EXTRST) // PowerOn or External pin reset
{
matterBootCause = EMBER_ZCL_BOOT_REASON_TYPE_POWER_ON_REBOOT;
matterBootCause = DiagnosticDataProvider::BootReasonType::PowerOnReboot;
}
else if (rebootCause & RMU_RSTCAUSE_AVDDBOD || rebootCause & RMU_RSTCAUSE_DVDDBOD || rebootCause & RMU_RSTCAUSE_DECBOD)
{
matterBootCause = EMBER_ZCL_BOOT_REASON_TYPE_BROWN_OUT_RESET;
matterBootCause = DiagnosticDataProvider::BootReasonType::BrownOutReset;
}
else if (rebootCause & RMU_RSTCAUSE_SYSREQRST)
{
matterBootCause = EMBER_ZCL_BOOT_REASON_TYPE_SOFTWARE_RESET;
matterBootCause = DiagnosticDataProvider::BootReasonType::SoftwareReset;
}
else if (rebootCause & RMU_RSTCAUSE_WDOGRST)
{
matterBootCause = EMBER_ZCL_BOOT_REASON_TYPE_SOFTWARE_WATCHDOG_RESET;
matterBootCause = DiagnosticDataProvider::BootReasonType::SoftwareWatchdogReset;
}
else
{
matterBootCause = EMBER_ZCL_BOOT_REASON_TYPE_UNSPECIFIED;
matterBootCause = DiagnosticDataProvider::BootReasonType::Unspecified;
}
// Not tracked HARDWARE_WATCHDOG_RESET && SOFTWARE_UPDATE_COMPLETED
#elif defined(_SILICON_LABS_32B_SERIES_2)
if (rebootCause & EMU_RSTCAUSE_POR || rebootCause & EMU_RSTCAUSE_PIN) // PowerOn or External pin reset
{
matterBootCause = EMBER_ZCL_BOOT_REASON_TYPE_POWER_ON_REBOOT;
matterBootCause = DiagnosticDataProvider::BootReasonType::PowerOnReboot;
}
else if (rebootCause & EMU_RSTCAUSE_AVDDBOD || rebootCause & EMU_RSTCAUSE_DVDDBOD || rebootCause & EMU_RSTCAUSE_DECBOD ||
rebootCause & EMU_RSTCAUSE_VREGIN || rebootCause & EMU_RSTCAUSE_IOVDD0BOD || rebootCause & EMU_RSTCAUSE_DVDDLEBOD)
{
matterBootCause = EMBER_ZCL_BOOT_REASON_TYPE_BROWN_OUT_RESET;
matterBootCause = DiagnosticDataProvider::BootReasonType::BrownOutReset;
}
else if (rebootCause & EMU_RSTCAUSE_SYSREQ)
{
matterBootCause = EMBER_ZCL_BOOT_REASON_TYPE_SOFTWARE_RESET;
matterBootCause = DiagnosticDataProvider::BootReasonType::SoftwareReset;
}
else if (rebootCause & EMU_RSTCAUSE_WDOG0 || rebootCause & EMU_RSTCAUSE_WDOG1)
{
matterBootCause = EMBER_ZCL_BOOT_REASON_TYPE_SOFTWARE_WATCHDOG_RESET;
matterBootCause = DiagnosticDataProvider::BootReasonType::SoftwareWatchdogReset;
}
else
{
matterBootCause = EMBER_ZCL_BOOT_REASON_TYPE_UNSPECIFIED;
matterBootCause = DiagnosticDataProvider::BootReasonType::Unspecified;
}
// Not tracked HARDWARE_WATCHDOG_RESET && SOFTWARE_UPDATE_COMPLETED
#else
matterBootCause = EMBER_ZCL_BOOT_REASON_TYPE_UNSPECIFIED;
matterBootCause = DiagnosticDataProvider::BootReasonType::Unspecified;
#endif

return matterBootCause;
Expand Down
12 changes: 6 additions & 6 deletions src/platform/ESP32/DiagnosticDataProviderImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,28 +167,28 @@ CHIP_ERROR DiagnosticDataProviderImpl::GetTotalOperationalHours(uint32_t & total

CHIP_ERROR DiagnosticDataProviderImpl::GetBootReason(uint8_t & bootReason)
{
bootReason = EMBER_ZCL_BOOT_REASON_TYPE_UNSPECIFIED;
bootReason = BootReasonType::Unspecified;
uint8_t reason;
reason = static_cast<uint8_t>(esp_reset_reason());
if (reason == ESP_RST_UNKNOWN)
{
bootReason = EMBER_ZCL_BOOT_REASON_TYPE_UNSPECIFIED;
bootReason = BootReasonType::Unspecified;
}
else if (reason == ESP_RST_POWERON)
{
bootReason = EMBER_ZCL_BOOT_REASON_TYPE_POWER_ON_REBOOT;
bootReason = BootReasonType::PowerOnReboot;
}
else if (reason == ESP_RST_BROWNOUT)
{
bootReason = EMBER_ZCL_BOOT_REASON_TYPE_BROWN_OUT_RESET;
bootReason = BootReasonType::BrownOutReset;
}
else if (reason == ESP_RST_SW)
{
bootReason = EMBER_ZCL_BOOT_REASON_TYPE_SOFTWARE_RESET;
bootReason = BootReasonType::SoftwareReset;
}
else if (reason == ESP_RST_INT_WDT)
{
bootReason = EMBER_ZCL_BOOT_REASON_TYPE_SOFTWARE_WATCHDOG_RESET;
bootReason = BootReasonType::SoftwareWatchdogReset;
/* Reboot can be due to hardware or software watchdog*/
}
return CHIP_NO_ERROR;
Expand Down
3 changes: 2 additions & 1 deletion src/platform/Linux/ConfigurationManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include <platform/internal/CHIPDeviceLayerInternal.h>

#include <DiagnosticDataProvider.h>
#include <app-common/zap-generated/enums.h>
#include <ifaddrs.h>
#include <lib/core/CHIPVendorIdentifiers.hpp>
Expand Down Expand Up @@ -87,7 +88,7 @@ CHIP_ERROR ConfigurationManagerImpl::Init()

if (!PosixConfig::ConfigValueExists(PosixConfig::kCounterKey_BootReason))
{
err = StoreBootReason(EMBER_ZCL_BOOT_REASON_TYPE_UNSPECIFIED);
err = StoreBootReason(DiagnosticDataProvider::BootReasonType::Unspecified);
SuccessOrExit(err);
}

Expand Down
12 changes: 6 additions & 6 deletions src/platform/Linux/PlatformManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,27 +63,27 @@ void SignalHandler(int signum)
switch (signum)
{
case SIGINT:
ConfigurationMgr().StoreBootReason(EMBER_ZCL_BOOT_REASON_TYPE_SOFTWARE_RESET);
ConfigurationMgr().StoreBootReason(DiagnosticDataProvider::BootReasonType::SoftwareReset);
err = CHIP_ERROR_REBOOT_SIGNAL_RECEIVED;
break;
case SIGHUP:
ConfigurationMgr().StoreBootReason(EMBER_ZCL_BOOT_REASON_TYPE_BROWN_OUT_RESET);
ConfigurationMgr().StoreBootReason(DiagnosticDataProvider::BootReasonType::BrownOutReset);
err = CHIP_ERROR_REBOOT_SIGNAL_RECEIVED;
break;
case SIGTERM:
ConfigurationMgr().StoreBootReason(EMBER_ZCL_BOOT_REASON_TYPE_POWER_ON_REBOOT);
ConfigurationMgr().StoreBootReason(DiagnosticDataProvider::BootReasonType::PowerOnReboot);
err = CHIP_ERROR_REBOOT_SIGNAL_RECEIVED;
break;
case SIGUSR1:
ConfigurationMgr().StoreBootReason(EMBER_ZCL_BOOT_REASON_TYPE_HARDWARE_WATCHDOG_RESET);
ConfigurationMgr().StoreBootReason(DiagnosticDataProvider::BootReasonType::HardwareWatchdogReset);
err = CHIP_ERROR_REBOOT_SIGNAL_RECEIVED;
break;
case SIGUSR2:
ConfigurationMgr().StoreBootReason(EMBER_ZCL_BOOT_REASON_TYPE_SOFTWARE_WATCHDOG_RESET);
ConfigurationMgr().StoreBootReason(DiagnosticDataProvider::BootReasonType::SoftwareWatchdogReset);
err = CHIP_ERROR_REBOOT_SIGNAL_RECEIVED;
break;
case SIGTSTP:
ConfigurationMgr().StoreBootReason(EMBER_ZCL_BOOT_REASON_TYPE_SOFTWARE_UPDATE_COMPLETED);
ConfigurationMgr().StoreBootReason(DiagnosticDataProvider::BootReasonType::SoftwareUpdateCompleted);
err = CHIP_ERROR_REBOOT_SIGNAL_RECEIVED;
break;
case SIGTRAP:
Expand Down
10 changes: 5 additions & 5 deletions src/platform/P6/DiagnosticDataProviderImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,23 +119,23 @@ CHIP_ERROR DiagnosticDataProviderImpl::GetBootReason(uint8_t & bootReason)
cyhal_reset_reason_t reset_reason = cyhal_system_get_reset_reason();
if (reset_reason == CYHAL_SYSTEM_RESET_NONE)
{
bootReason = EMBER_ZCL_BOOT_REASON_TYPE_POWER_ON_REBOOT;
bootReason = BootReasonType::PowerOnReboot;
}
else if (reset_reason == CYHAL_SYSTEM_RESET_WDT)
{
bootReason = EMBER_ZCL_BOOT_REASON_TYPE_SOFTWARE_WATCHDOG_RESET;
bootReason = BootReasonType::SoftwareWatchdogReset;
}
else if (reset_reason == CYHAL_SYSTEM_RESET_SOFT)
{
bootReason = EMBER_ZCL_BOOT_REASON_TYPE_SOFTWARE_RESET;
bootReason = BootReasonType::SoftwareReset;
}
else if (reset_reason == CYHAL_SYSTEM_RESET_HIB_WAKEUP)
{
bootReason = EMBER_ZCL_BOOT_REASON_TYPE_HARDWARE_WATCHDOG_RESET;
bootReason = BootReasonType::HardwareWatchdogReset;
}
else
{
bootReason = EMBER_ZCL_BOOT_REASON_TYPE_UNSPECIFIED;
bootReason = BootReasonType::Unspecified;
}
return CHIP_NO_ERROR;
}
Expand Down
26 changes: 26 additions & 0 deletions src/platform/Zephyr/ConfigurationManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ ConfigurationManagerImpl & ConfigurationManagerImpl::GetDefaultInstance()
CHIP_ERROR ConfigurationManagerImpl::Init()
{
CHIP_ERROR err;
uint32_t rebootCount;
bool failSafeArmed;

// Initialize the generic implementation base class.
Expand All @@ -71,6 +72,21 @@ CHIP_ERROR ConfigurationManagerImpl::Init()
}
#endif // CHIP_DEVICE_CONFIG_ENABLE_FACTORY_PROVISIONING

if (ZephyrConfig::ConfigValueExists(ZephyrConfig::kCounterKey_RebootCount))
{
err = GetRebootCount(rebootCount);
SuccessOrExit(err);

err = StoreRebootCount(rebootCount + 1);
SuccessOrExit(err);
}
else
{
// The first boot after factory reset of the Node.
err = StoreRebootCount(1);
SuccessOrExit(err);
}

// If the fail-safe was armed when the device last shutdown, initiate a factory reset.
if (GetFailSafeArmed(failSafeArmed) == CHIP_NO_ERROR && failSafeArmed)
{
Expand All @@ -84,6 +100,16 @@ CHIP_ERROR ConfigurationManagerImpl::Init()
return err;
}

CHIP_ERROR ConfigurationManagerImpl::GetRebootCount(uint32_t & rebootCount)
{
return ReadConfigValue(ZephyrConfig::kCounterKey_RebootCount, rebootCount);
}

CHIP_ERROR ConfigurationManagerImpl::StoreRebootCount(uint32_t rebootCount)
{
return WriteConfigValue(ZephyrConfig::kCounterKey_RebootCount, rebootCount);
}

void ConfigurationManagerImpl::InitiateFactoryReset()
{
PlatformMgr().ScheduleWork(DoFactoryReset);
Expand Down
2 changes: 2 additions & 0 deletions src/platform/Zephyr/ConfigurationManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ namespace DeviceLayer {
class ConfigurationManagerImpl : public Internal::GenericConfigurationManagerImpl<Internal::ZephyrConfig>
{
public:
CHIP_ERROR GetRebootCount(uint32_t & rebootCount) override;
CHIP_ERROR StoreRebootCount(uint32_t rebootCount) override;
// This returns an instance of this class.
static ConfigurationManagerImpl & GetDefaultInstance();

Expand Down
Loading

0 comments on commit 7ca45e1

Please sign in to comment.