Skip to content

Commit

Permalink
ESP32: Read Generic Diagnostics cluster attribute at runtime (#10314)
Browse files Browse the repository at this point in the history
  • Loading branch information
sweetymhaiske authored and pull[bot] committed Nov 25, 2021
1 parent ecf2ec1 commit 5252188
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 1 deletion.
42 changes: 42 additions & 0 deletions src/platform/ESP32/ConfigurationManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ ConfigurationManagerImpl ConfigurationManagerImpl::sInstance;
CHIP_ERROR ConfigurationManagerImpl::_Init()
{
CHIP_ERROR err;
uint32_t rebootCount;
bool failSafeArmed;

// Force initialization of NVS namespaces if they doesn't already exist.
Expand All @@ -67,6 +68,27 @@ CHIP_ERROR ConfigurationManagerImpl::_Init()
err = EnsureNamespace(kConfigNamespace_ChipCounters);
SuccessOrExit(err);

if (ConfigValueExists(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 (!ConfigValueExists(kCounterKey_TotalOperationalHours))
{
err = StoreTotalOperationalHours(0);
SuccessOrExit(err);
}

// Initialize the generic implementation base class.
err = Internal::GenericConfigurationManagerImpl<ConfigurationManagerImpl>::_Init();
SuccessOrExit(err);
Expand Down Expand Up @@ -100,6 +122,26 @@ CHIP_ERROR ConfigurationManagerImpl::_Init()
return err;
}

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

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

CHIP_ERROR ConfigurationManagerImpl::GetTotalOperationalHours(uint32_t & totalOperationalHours)
{
return ReadConfigValue(kCounterKey_TotalOperationalHours, totalOperationalHours);
}

CHIP_ERROR ConfigurationManagerImpl::StoreTotalOperationalHours(uint32_t totalOperationalHours)
{
return WriteConfigValue(kCounterKey_TotalOperationalHours, totalOperationalHours);
}

CHIP_ERROR ConfigurationManagerImpl::_GetPrimaryWiFiMACAddress(uint8_t * buf)
{
#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
Expand Down
8 changes: 7 additions & 1 deletion src/platform/ESP32/ConfigurationManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ class ConfigurationManagerImpl final : public ConfigurationManager,
#endif
private Internal::ESP32Config
{
public:
CHIP_ERROR GetRebootCount(uint32_t & rebootCount);
CHIP_ERROR StoreRebootCount(uint32_t rebootCount);
CHIP_ERROR GetTotalOperationalHours(uint32_t & totalOperationalHours);
CHIP_ERROR StoreTotalOperationalHours(uint32_t totalOperationalHours);

private:
// Allow the ConfigurationManager interface class to delegate method calls to
// the implementation methods provided by this class.
friend class ConfigurationManager;
Expand All @@ -60,7 +67,6 @@ class ConfigurationManagerImpl final : public ConfigurationManager,
friend class Internal::GenericConfigurationManagerImpl<ConfigurationManagerImpl>;
#endif

private:
// ===== Members that implement the ConfigurationManager public interface.

CHIP_ERROR _Init(void);
Expand Down
5 changes: 5 additions & 0 deletions src/platform/ESP32/ESP32Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ const ESP32Config::Key ESP32Config::kConfigKey_RegulatoryLocation = { kConfigNam
const ESP32Config::Key ESP32Config::kConfigKey_CountryCode = { kConfigNamespace_ChipConfig, "country-code" };
const ESP32Config::Key ESP32Config::kConfigKey_Breadcrumb = { kConfigNamespace_ChipConfig, "breadcrumb" };

// Keys stored in the Chip-counters namespace
const ESP32Config::Key ESP32Config::kCounterKey_RebootCount = { kConfigNamespace_ChipCounters, "reboot-count" };
const ESP32Config::Key ESP32Config::kCounterKey_UpTime = { kConfigNamespace_ChipCounters, "up-time" };
const ESP32Config::Key ESP32Config::kCounterKey_TotalOperationalHours = { kConfigNamespace_ChipCounters, "total-hours" };

// Prefix used for NVS keys that contain Chip group encryption keys.
const char ESP32Config::kGroupKeyNamePrefix[] = "gk-";

Expand Down
3 changes: 3 additions & 0 deletions src/platform/ESP32/ESP32Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ class ESP32Config
static const Key kConfigKey_RegulatoryLocation;
static const Key kConfigKey_CountryCode;
static const Key kConfigKey_Breadcrumb;
static const Key kCounterKey_RebootCount;
static const Key kCounterKey_UpTime;
static const Key kCounterKey_TotalOperationalHours;

static const char kGroupKeyNamePrefix[];

Expand Down
102 changes: 102 additions & 0 deletions src/platform/ESP32/PlatformManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
/* this file behaves like a config.h, comes first */
#include <platform/internal/CHIPDeviceLayerInternal.h>

#include <app-common/zap-generated/enums.h>
#include <crypto/CHIPCryptoPAL.h>
#include <platform/ESP32/ESP32Utils.h>
#include <platform/PlatformManager.h>
Expand Down Expand Up @@ -85,6 +86,7 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack(void)

esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, PlatformManagerImpl::HandleESPSystemEvent, NULL);
esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, PlatformManagerImpl::HandleESPSystemEvent, NULL);
mStartTimeMilliseconds = System::SystemClock().GetMonotonicMilliseconds();

// Initialize the ESP WiFi layer.
cfg = WIFI_INIT_CONFIG_DEFAULT();
Expand Down Expand Up @@ -118,6 +120,31 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack(void)
return chip::DeviceLayer::Internal::ESP32Utils::MapError(err);
}

CHIP_ERROR PlatformManagerImpl::_Shutdown()
{
uint64_t upTime = 0;

if (_GetUpTime(upTime) == CHIP_NO_ERROR)
{
uint32_t totalOperationalHours = 0;

if (ConfigurationMgrImpl().GetTotalOperationalHours(totalOperationalHours) == CHIP_NO_ERROR)
{
ConfigurationMgrImpl().StoreTotalOperationalHours(totalOperationalHours + static_cast<uint32_t>(upTime / 3600));
}
else
{
ChipLogError(DeviceLayer, "Failed to get total operational hours of the Node");
}
}
else
{
ChipLogError(DeviceLayer, "Failed to get current uptime since the Node’s last reboot");
}

return Internal::GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>::_Shutdown();
}

CHIP_ERROR PlatformManagerImpl::_GetCurrentHeapFree(uint64_t & currentHeapFree)
{
currentHeapFree = esp_get_free_heap_size();
Expand All @@ -136,6 +163,81 @@ CHIP_ERROR PlatformManagerImpl::_GetCurrentHeapHighWatermark(uint64_t & currentH
return CHIP_NO_ERROR;
}

CHIP_ERROR PlatformManagerImpl::_GetRebootCount(uint16_t & rebootCount)
{
uint32_t count = 0;

CHIP_ERROR err = ConfigurationMgrImpl().GetRebootCount(count);

if (err == CHIP_NO_ERROR)
{
VerifyOrReturnError(count <= UINT16_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE);
rebootCount = static_cast<uint16_t>(count);
}

return err;
}

CHIP_ERROR PlatformManagerImpl::_GetUpTime(uint64_t & upTime)
{
uint64_t currentTimeMilliseconds = System::SystemClock().GetMonotonicMilliseconds();

if (currentTimeMilliseconds >= mStartTimeMilliseconds)
{
upTime = (currentTimeMilliseconds - mStartTimeMilliseconds) / 1000;
return CHIP_NO_ERROR;
}

return CHIP_ERROR_INVALID_TIME;
}

CHIP_ERROR PlatformManagerImpl::_GetTotalOperationalHours(uint32_t & totalOperationalHours)
{
uint64_t upTime = 0;

if (_GetUpTime(upTime) == CHIP_NO_ERROR)
{
uint32_t totalHours = 0;
if (ConfigurationMgrImpl().GetTotalOperationalHours(totalHours) == CHIP_NO_ERROR)
{
VerifyOrReturnError(upTime / 3600 <= UINT32_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE);
totalOperationalHours = totalHours + static_cast<uint32_t>(upTime / 3600);
return CHIP_NO_ERROR;
}
}

return CHIP_ERROR_INVALID_TIME;
}

CHIP_ERROR PlatformManagerImpl::_GetBootReasons(uint8_t & bootReason)
{
bootReason = EMBER_ZCL_BOOT_REASON_TYPE_UNSPECIFIED;
uint8_t reason;
reason = static_cast<uint8_t>(esp_reset_reason());
if (reason == ESP_RST_UNKNOWN)
{
bootReason = EMBER_ZCL_BOOT_REASON_TYPE_UNSPECIFIED;
}
else if (reason == ESP_RST_POWERON)
{
bootReason = EMBER_ZCL_BOOT_REASON_TYPE_POWER_ON_REBOOT;
}
else if (reason == ESP_RST_BROWNOUT)
{
bootReason = EMBER_ZCL_BOOT_REASON_TYPE_BROWN_OUT_RESET;
}
else if (reason == ESP_RST_SW)
{
bootReason = EMBER_ZCL_BOOT_REASON_TYPE_SOFTWARE_RESET;
}
else if (reason == ESP_RST_INT_WDT)
{
bootReason = EMBER_ZCL_BOOT_REASON_TYPE_SOFTWARE_WATCHDOG_RESET;
/* Reboot can be due to hardware or software watchdog*/
}
return CHIP_NO_ERROR;
}

CHIP_ERROR PlatformManagerImpl::InitLwIPCoreLock(void)
{
return Internal::InitLwIPCoreLock();
Expand Down
7 changes: 7 additions & 0 deletions src/platform/ESP32/PlatformManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,22 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener
// ===== Methods that implement the PlatformManager abstract interface.

CHIP_ERROR _InitChipStack(void);
CHIP_ERROR _Shutdown();
CHIP_ERROR _GetCurrentHeapFree(uint64_t & currentHeapFree);
CHIP_ERROR _GetCurrentHeapUsed(uint64_t & currentHeapUsed);
CHIP_ERROR _GetCurrentHeapHighWatermark(uint64_t & currentHeapHighWatermark);

CHIP_ERROR _GetRebootCount(uint16_t & rebootCount);
CHIP_ERROR _GetUpTime(uint64_t & upTime);
CHIP_ERROR _GetTotalOperationalHours(uint32_t & totalOperationalHours);
CHIP_ERROR _GetBootReasons(uint8_t & bootReasons);
// ===== Members for internal use by the following friends.

friend PlatformManager & PlatformMgr(void);
friend PlatformManagerImpl & PlatformMgrImpl(void);

uint64_t mStartTimeMilliseconds = 0;

static PlatformManagerImpl sInstance;
};

Expand Down

0 comments on commit 5252188

Please sign in to comment.