diff --git a/src/app/clusters/general_diagnostics_server/general_diagnostics_server.cpp b/src/app/clusters/general_diagnostics_server/general_diagnostics_server.cpp index 35495a16f5df82..ced518d665f14d 100644 --- a/src/app/clusters/general_diagnostics_server/general_diagnostics_server.cpp +++ b/src/app/clusters/general_diagnostics_server/general_diagnostics_server.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -29,7 +30,7 @@ using namespace chip::app; using namespace chip::app::Clusters; using namespace chip::app::Clusters::GeneralDiagnostics::Attributes; using chip::DeviceLayer::ConnectivityMgr; -using chip::DeviceLayer::PlatformManager; +using chip::DeviceLayer::PlatformMgr; namespace { @@ -43,12 +44,12 @@ class GeneralDiagosticsAttrAccess : public AttributeAccessInterface private: template - CHIP_ERROR ReadIfSupported(CHIP_ERROR (PlatformManager::*getter)(T &), AttributeValueEncoder & aEncoder); + CHIP_ERROR ReadIfSupported(CHIP_ERROR (DeviceLayer::PlatformManager::*getter)(T &), AttributeValueEncoder & aEncoder); CHIP_ERROR ReadNetworkInterfaces(AttributeValueEncoder & aEncoder); }; template -CHIP_ERROR GeneralDiagosticsAttrAccess::ReadIfSupported(CHIP_ERROR (PlatformManager::*getter)(T &), +CHIP_ERROR GeneralDiagosticsAttrAccess::ReadIfSupported(CHIP_ERROR (DeviceLayer::PlatformManager::*getter)(T &), AttributeValueEncoder & aEncoder) { T data; @@ -107,16 +108,16 @@ CHIP_ERROR GeneralDiagosticsAttrAccess::Read(const ConcreteAttributePath & aPath return ReadNetworkInterfaces(aEncoder); } case RebootCount::Id: { - return ReadIfSupported(&PlatformManager::GetRebootCount, aEncoder); + return ReadIfSupported(&DeviceLayer::PlatformManager::GetRebootCount, aEncoder); } case UpTime::Id: { - return ReadIfSupported(&PlatformManager::GetUpTime, aEncoder); + return ReadIfSupported(&DeviceLayer::PlatformManager::GetUpTime, aEncoder); } case TotalOperationalHours::Id: { - return ReadIfSupported(&PlatformManager::GetTotalOperationalHours, aEncoder); + return ReadIfSupported(&DeviceLayer::PlatformManager::GetTotalOperationalHours, aEncoder); } case BootReasons::Id: { - return ReadIfSupported(&PlatformManager::GetBootReasons, aEncoder); + return ReadIfSupported(&DeviceLayer::PlatformManager::GetBootReasons, aEncoder); } default: { break; @@ -124,9 +125,65 @@ CHIP_ERROR GeneralDiagosticsAttrAccess::Read(const ConcreteAttributePath & aPath } return CHIP_NO_ERROR; } + +class GeneralDiagnosticDelegate : public DeviceLayer::ConnectivityManagerDelegate, public DeviceLayer::PlatformManagerDelegate +{ + + // Gets called when any network interface on the Node is updated. + void OnNetworkInfoChanged() override + { + ChipLogProgress(Zcl, "GeneralDiagnosticDelegate: OnNetworkInfoChanged"); + + for (uint16_t index = 0; index < emberAfEndpointCount(); index++) + { + if (emberAfEndpointIndexIsEnabled(index)) + { + EndpointId endpointId = emberAfEndpointFromIndex(index); + if (endpointId == 0) + continue; + + if (emberAfContainsServer(endpointId, GeneralDiagnostics::Id)) + { + // If General Diagnostics cluster is implemented on this endpoint + MatterReportingAttributeChangeCallback(endpointId, GeneralDiagnostics::Id, + GeneralDiagnostics::Attributes::NetworkInterfaces::Id); + } + } + } + } + + // Gets called when the device has been rebooted. + void OnDeviceRebooted() override + { + ChipLogProgress(Zcl, "GeneralDiagnosticDelegate: OnDeviceRebooted"); + + for (uint16_t index = 0; index < emberAfEndpointCount(); index++) + { + if (emberAfEndpointIndexIsEnabled(index)) + { + EndpointId endpointId = emberAfEndpointFromIndex(index); + + if (emberAfContainsServer(endpointId, GeneralDiagnostics::Id)) + { + // If General Diagnostics cluster is implemented on this endpoint + MatterReportingAttributeChangeCallback(endpointId, GeneralDiagnostics::Id, + GeneralDiagnostics::Attributes::RebootCount::Id); + MatterReportingAttributeChangeCallback(endpointId, GeneralDiagnostics::Id, + GeneralDiagnostics::Attributes::BootReasons::Id); + } + } + } + } +}; + +GeneralDiagnosticDelegate gDiagnosticDelegate; + } // anonymous namespace void MatterGeneralDiagnosticsPluginServerInitCallback() { registerAttributeAccessOverride(&gAttrAccess); + + PlatformMgr().SetDelegate(&gDiagnosticDelegate); + ConnectivityMgr().SetDelegate(&gDiagnosticDelegate); } diff --git a/src/include/platform/ConnectivityManager.h b/src/include/platform/ConnectivityManager.h index 61e5e015cf7273..dd757590187a00 100644 --- a/src/include/platform/ConnectivityManager.h +++ b/src/include/platform/ConnectivityManager.h @@ -60,8 +60,25 @@ struct NetworkInterface : public app::Clusters::GeneralDiagnostics::Structs::Net NetworkInterface * Next; /* Pointer to the next structure. */ }; +class ConnectivityManager; class ConnectivityManagerImpl; +/** + * Defines the delegate class of Connectivity Manager to notify connectivity updates. + */ +class ConnectivityManagerDelegate +{ +public: + virtual ~ConnectivityManagerDelegate() {} + + /** + * @brief + * Called when any network interface on the Node is changed + * + */ + virtual void OnNetworkInfoChanged() {} +}; + /** * Provides control of network connectivity for a chip device. */ @@ -140,6 +157,9 @@ class ConnectivityManager struct ThreadPollingConfig; + void SetDelegate(ConnectivityManagerDelegate * delegate) { mDelegate = delegate; } + ConnectivityManagerDelegate * GetDelegate() const { return mDelegate; } + // WiFi station methods WiFiStationMode GetWiFiStationMode(); CHIP_ERROR SetWiFiStationMode(WiFiStationMode val); @@ -241,6 +261,8 @@ class ConnectivityManager static const char * CHIPoBLEServiceModeToStr(CHIPoBLEServiceMode mode); private: + ConnectivityManagerDelegate * mDelegate = nullptr; + // ===== Members for internal use by the following friends. friend class PlatformManagerImpl; diff --git a/src/include/platform/PlatformManager.h b/src/include/platform/PlatformManager.h index 966d3e033c7874..5bbb68c9adf2cc 100644 --- a/src/include/platform/PlatformManager.h +++ b/src/include/platform/PlatformManager.h @@ -66,6 +66,23 @@ template class GenericThreadStackManagerImpl_OpenThread_LwIP; } // namespace Internal +class PlatformManager; + +/** + * Defines the delegate class of Platform Manager to notify platform updates. + */ +class PlatformManagerDelegate +{ +public: + virtual ~PlatformManagerDelegate() {} + + /** + * @brief + * Called after the current device is rebooted + */ + virtual void OnDeviceRebooted() {} +}; + /** * Provides features for initializing and interacting with the chip network * stack on a chip-enabled device. @@ -88,6 +105,8 @@ class PlatformManager CHIP_ERROR InitChipStack(); CHIP_ERROR AddEventHandler(EventHandlerFunct handler, intptr_t arg = 0); void RemoveEventHandler(EventHandlerFunct handler, intptr_t arg = 0); + void SetDelegate(PlatformManagerDelegate * delegate) { mDelegate = delegate; } + PlatformManagerDelegate * GetDelegate() const { return mDelegate; } /** * ScheduleWork can be called after InitChipStack has been called. Calls @@ -171,7 +190,9 @@ class PlatformManager #endif private: - bool mInitialized = false; + bool mInitialized = false; + PlatformManagerDelegate * mDelegate = nullptr; + // ===== Members for internal use by the following friends. friend class PlatformManagerImpl; diff --git a/src/platform/Linux/PlatformManagerImpl.cpp b/src/platform/Linux/PlatformManagerImpl.cpp index 93943f8d186b4d..a4231fa396d4b6 100644 --- a/src/platform/Linux/PlatformManagerImpl.cpp +++ b/src/platform/Linux/PlatformManagerImpl.cpp @@ -216,6 +216,8 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack() mStartTime = System::SystemClock().GetMonotonicTimestamp(); + ScheduleWork(HandleDeviceRebooted, 0); + exit: return err; } @@ -343,6 +345,16 @@ CHIP_ERROR PlatformManagerImpl::_GetBootReasons(uint8_t & bootReasons) return err; } +void PlatformManagerImpl::HandleDeviceRebooted(intptr_t arg) +{ + PlatformManagerDelegate * delegate = PlatformMgr().GetDelegate(); + + if (delegate != nullptr) + { + delegate->OnDeviceRebooted(); + } +} + #if CHIP_WITH_GIO GDBusConnection * PlatformManagerImpl::GetGDBusConnection() { diff --git a/src/platform/Linux/PlatformManagerImpl.h b/src/platform/Linux/PlatformManagerImpl.h index 7a4bdb9e05601c..7cfd51e4c79621 100644 --- a/src/platform/Linux/PlatformManagerImpl.h +++ b/src/platform/Linux/PlatformManagerImpl.h @@ -83,6 +83,7 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener // The temporary hack for getting IP address change on linux for network provisioning in the rendezvous session. // This should be removed or find a better place once we depercate the rendezvous session. static void WiFIIPChangeListener(); + static void HandleDeviceRebooted(intptr_t arg); #if CHIP_WITH_GIO struct GDBusConnectionDeleter