Skip to content

Commit

Permalink
samples: matter: Unified default Matter event handler
Browse files Browse the repository at this point in the history
Implemented common Matter event handler module that
includes the default handler and API to register user
provided handlers in the application code.

Added default Matter event handler for GPIO related operations
in the Board utility module, that can be registered
in the application.

Signed-off-by: Marcin Kajor <[email protected]>
  • Loading branch information
markaj-nordic authored and rlubos committed Jan 12, 2024
1 parent 4c18d11 commit a58ff6c
Show file tree
Hide file tree
Showing 31 changed files with 357 additions and 513 deletions.
1 change: 1 addition & 0 deletions applications/matter_bridge/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ target_sources(app PRIVATE
${COMMON_ROOT}/src/app/task_executor.cpp
${COMMON_ROOT}/src/board/board.cpp
${COMMON_ROOT}/src/app/matter_init.cpp
${COMMON_ROOT}/src/app/matter_event_handler.cpp
)

if(CONFIG_BRIDGED_DEVICE_BT)
Expand Down
80 changes: 26 additions & 54 deletions applications/matter_bridge/src/app_task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
#include "simulated_bridged_device_factory.h"
#endif /* CONFIG_BRIDGED_DEVICE_BT */

#include "app/matter_init.h"
#include "app/task_executor.h"
#include "board/board.h"
#include "bridge/bridge_manager.h"
#include "bridge/bridge_storage_manager.h"
#include "app/matter_init.h"
#include "app/task_executor.h"

#ifdef CONFIG_BRIDGED_DEVICE_BT
#include "bridge/ble_connectivity_manager.h"
Expand Down Expand Up @@ -52,37 +52,6 @@ static constexpr uint8_t kUuidServicesNumber = ARRAY_SIZE(sUuidServices);

} /* namespace */

void AppTask::MatterEventHandler(const ChipDeviceEvent *event, intptr_t /* arg */)
{
bool isNetworkProvisioned = false;

switch (event->Type) {
case DeviceEventType::kCHIPoBLEAdvertisingChange:
if (ConnectivityMgr().NumBLEConnections() != 0) {
Nrf::GetBoard().UpdateDeviceState(Nrf::DeviceState::DeviceConnectedBLE);
}
break;
#if defined(CONFIG_CHIP_WIFI)
case DeviceEventType::kWiFiConnectivityChange:
isNetworkProvisioned =
ConnectivityMgr().IsWiFiStationProvisioned() && ConnectivityMgr().IsWiFiStationEnabled();
#if CONFIG_CHIP_OTA_REQUESTOR
if (event->WiFiConnectivityChange.Result == kConnectivity_Established) {
Nrf::Matter::InitBasicOTARequestor();
}
#endif /* CONFIG_CHIP_OTA_REQUESTOR */
#endif
if (isNetworkProvisioned) {
Nrf::GetBoard().UpdateDeviceState(Nrf::DeviceState::DeviceProvisioned);
} else {
Nrf::GetBoard().UpdateDeviceState(Nrf::DeviceState::DeviceDisconnected);
}
break;
default:
break;
}
}

CHIP_ERROR AppTask::RestoreBridgedDevices()
{
uint8_t count;
Expand All @@ -94,8 +63,8 @@ CHIP_ERROR AppTask::RestoreBridgedDevices()
return CHIP_NO_ERROR;
}

if (!Nrf::BridgeStorageManager::Instance().LoadBridgedDevicesIndexes(indexes, Nrf::BridgeManager::kMaxBridgedDevices,
indexesCount)) {
if (!Nrf::BridgeStorageManager::Instance().LoadBridgedDevicesIndexes(
indexes, Nrf::BridgeManager::kMaxBridgedDevices, indexesCount)) {
return CHIP_NO_ERROR;
}

Expand All @@ -112,7 +81,7 @@ CHIP_ERROR AppTask::RestoreBridgedDevices()

/* Ignore an error, as node label is optional, so it may not be found. */
Nrf::BridgeStorageManager::Instance().LoadBridgedDeviceNodeLabel(label, sizeof(label), labelSize,
indexes[i]);
indexes[i]);

if (!Nrf::BridgeStorageManager::Instance().LoadBridgedDeviceType(deviceType, indexes[i])) {
return CHIP_ERROR_NOT_FOUND;
Expand All @@ -139,33 +108,36 @@ CHIP_ERROR AppTask::RestoreBridgedDevices()
CHIP_ERROR AppTask::Init()
{
/* Initialize Matter stack */
ReturnErrorOnFailure(Nrf::Matter::PrepareServer(
MatterEventHandler, Nrf::Matter::InitData{ .mPostServerInitClbk = [] {
ReturnErrorOnFailure(Nrf::Matter::PrepareServer(Nrf::Matter::InitData{ .mPostServerInitClbk = [] {
#ifdef CONFIG_BRIDGED_DEVICE_BT
/* Initialize BLE Connectivity Manager before the Bridge Manager, as it must be ready to recover
* devices loaded from persistent storage during the bridge init. */
CHIP_ERROR bleInitError =
Nrf::BLEConnectivityManager::Instance().Init(sUuidServices, kUuidServicesNumber);
if (bleInitError != CHIP_NO_ERROR) {
LOG_ERR("BLEConnectivityManager initialization failed");
return bleInitError;
}
/* Initialize BLE Connectivity Manager before the Bridge Manager, as it must be ready to recover
* devices loaded from persistent storage during the bridge init. */
CHIP_ERROR bleInitError =
Nrf::BLEConnectivityManager::Instance().Init(sUuidServices, kUuidServicesNumber);
if (bleInitError != CHIP_NO_ERROR) {
LOG_ERR("BLEConnectivityManager initialization failed");
return bleInitError;
}
#endif

/* Initialize bridge manager */
CHIP_ERROR bridgeMgrInitError = Nrf::BridgeManager::Instance().Init(RestoreBridgedDevices);
if (bridgeMgrInitError != CHIP_NO_ERROR) {
LOG_ERR("BridgeManager initialization failed");
return bridgeMgrInitError;
}
return CHIP_NO_ERROR;
} }));
/* Initialize bridge manager */
CHIP_ERROR bridgeMgrInitError = Nrf::BridgeManager::Instance().Init(RestoreBridgedDevices);
if (bridgeMgrInitError != CHIP_NO_ERROR) {
LOG_ERR("BridgeManager initialization failed");
return bridgeMgrInitError;
}
return CHIP_NO_ERROR;
} }));

if (!Nrf::GetBoard().Init()) {
LOG_ERR("User interface initialization failed.");
return CHIP_ERROR_INCORRECT_STATE;
}

/* Register Matter event handler that controls the connectivity status LED based on the captured Matter network
* state. */
ReturnErrorOnFailure(Nrf::Matter::RegisterEventHandler(Nrf::Board::DefaultMatterEventHandler, 0));

return Nrf::Matter::StartServer();
}

Expand Down
1 change: 0 additions & 1 deletion applications/matter_bridge/src/app_task.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,5 @@ class AppTask {
private:
CHIP_ERROR Init();

static void MatterEventHandler(const chip::DeviceLayer::ChipDeviceEvent *event, intptr_t arg);
static CHIP_ERROR RestoreBridgedDevices();
};
1 change: 1 addition & 0 deletions applications/matter_weather_station/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ target_sources(app PRIVATE
${COMMON_ROOT}/src/app/task_executor.cpp
${COMMON_ROOT}/src/board/board.cpp
${COMMON_ROOT}/src/app/matter_init.cpp
${COMMON_ROOT}/src/app/matter_event_handler.cpp
)

if(CONFIG_CHIP_OTA_REQUESTOR OR CONFIG_MCUMGR_TRANSPORT_BT)
Expand Down
69 changes: 10 additions & 59 deletions applications/matter_weather_station/src/app_task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
#include "battery.h"
#include "buzzer.h"

#include "board/board.h"
#include "app/matter_init.h"
#include "board/led_widget.h"
#include "app/task_executor.h"
#include "board/board.h"
#include "board/led_widget.h"

#ifdef CONFIG_CHIP_OTA_REQUESTOR
#include "dfu/ota/ota_util.h"
Expand Down Expand Up @@ -124,7 +124,8 @@ void AppTask::MeasurementsTimerHandler()

void AppTask::OnIdentifyStart(Identify *)
{
Nrf::PostTask([] { Nrf::GetBoard().GetLED(Nrf::DeviceLeds::LED2).Blink(Nrf::LedConsts::kIdentifyBlinkRate_ms); });
Nrf::PostTask(
[] { Nrf::GetBoard().GetLED(Nrf::DeviceLeds::LED2).Blink(Nrf::LedConsts::kIdentifyBlinkRate_ms); });
k_timer_start(&sIdentifyTimer, K_MSEC(kIdentifyTimerIntervalMs), K_MSEC(kIdentifyTimerIntervalMs));
}

Expand Down Expand Up @@ -320,59 +321,6 @@ void AppTask::UpdateClustersState()
UpdatePowerSourceClusterState();
}

void AppTask::MatterEventHandler(const ChipDeviceEvent *event, intptr_t /* arg */)
{
bool isNetworkProvisioned = false;

switch (event->Type) {
case DeviceEventType::kCHIPoBLEAdvertisingChange:
#ifdef CONFIG_CHIP_NFC_COMMISSIONING
if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Started) {
if (NFCMgr().IsTagEmulationStarted()) {
LOG_INF("NFC Tag emulation is already started");
} else {
ShareQRCodeOverNFC(
chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE));
}
} else if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Stopped) {
NFCMgr().StopTagEmulation();
}
#endif
if (ConnectivityMgr().NumBLEConnections() != 0) {
Nrf::GetBoard().UpdateDeviceState(Nrf::DeviceState::DeviceConnectedBLE);
} else if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Started) {
Nrf::GetBoard().UpdateDeviceState(Nrf::DeviceState::DeviceAdvertisingBLE);
} else {
Nrf::GetBoard().UpdateDeviceState(Nrf::DeviceState::DeviceDisconnected);
}
break;
#if defined(CONFIG_NET_L2_OPENTHREAD)
case DeviceEventType::kDnssdInitialized:
#if CONFIG_CHIP_OTA_REQUESTOR
Nrf::Matter::InitBasicOTARequestor();
#endif /* CONFIG_CHIP_OTA_REQUESTOR */
break;
case DeviceEventType::kThreadStateChange:
isNetworkProvisioned = ConnectivityMgr().IsThreadProvisioned() && ConnectivityMgr().IsThreadEnabled();
#elif defined(CONFIG_CHIP_WIFI)
case DeviceEventType::kWiFiConnectivityChange:
isNetworkProvisioned =
ConnectivityMgr().IsWiFiStationProvisioned() && ConnectivityMgr().IsWiFiStationEnabled();
#if CONFIG_CHIP_OTA_REQUESTOR
if (event->WiFiConnectivityChange.Result == kConnectivity_Established) {
Nrf::Matter::InitBasicOTARequestor();
}
#endif /* CONFIG_CHIP_OTA_REQUESTOR */
#endif
if (isNetworkProvisioned) {
Nrf::GetBoard().UpdateDeviceState(Nrf::DeviceState::DeviceProvisioned);
}
break;
default:
break;
}
}

void AppTask::UpdateLedState()
{
if (!Instance().mGreenLED || !Instance().mBlueLED || !Instance().mRedLED) {
Expand Down Expand Up @@ -410,7 +358,7 @@ CHIP_ERROR AppTask::Init()
#ifdef CONFIG_CHIP_FACTORY_DATA
initConfig.mPostServerInitClbk = CustomFactoryDataInit;
#endif
ReturnErrorOnFailure(Nrf::Matter::PrepareServer(MatterEventHandler, initConfig));
ReturnErrorOnFailure(Nrf::Matter::PrepareServer(initConfig));

/* Set references for RGB LED */
mRedLED = &Nrf::GetBoard().GetLED(Nrf::DeviceLeds::LED1);
Expand All @@ -422,6 +370,10 @@ CHIP_ERROR AppTask::Init()
return CHIP_ERROR_INCORRECT_STATE;
}

/* Register Matter event handler that controls the connectivity status LED based on the captured Matter network
* state. */
ReturnErrorOnFailure(Nrf::Matter::RegisterEventHandler(Nrf::Board::DefaultMatterEventHandler, 0));

if (!device_is_ready(sBme688SensorDev)) {
LOG_ERR("BME688 sensor device not ready");
return chip::System::MapErrorZephyr(-ENODEV);
Expand Down Expand Up @@ -453,8 +405,7 @@ CHIP_ERROR AppTask::Init()

/* Initialize timers */
k_timer_init(
&sMeasurementsTimer, [](k_timer *) { Nrf::PostTask([] { MeasurementsTimerHandler(); }); },
nullptr);
&sMeasurementsTimer, [](k_timer *) { Nrf::PostTask([] { MeasurementsTimerHandler(); }); }, nullptr);
k_timer_init(
&sIdentifyTimer, [](k_timer *) { Nrf::PostTask([] { IdentifyTimerHandler(); }); }, nullptr);
k_timer_start(&sMeasurementsTimer, K_MSEC(kMeasurementsIntervalMs), K_MSEC(kMeasurementsIntervalMs));
Expand Down
1 change: 0 additions & 1 deletion applications/matter_weather_station/src/app_task.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ class AppTask {

static void MeasurementsTimerHandler();
static void IdentifyTimerHandler();
static void MatterEventHandler(const chip::DeviceLayer::ChipDeviceEvent *event, intptr_t arg);

Nrf::LEDWidget *mRedLED;
Nrf::LEDWidget *mGreenLED;
Expand Down
77 changes: 77 additions & 0 deletions samples/matter/common/src/app/matter_event_handler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include "matter_event_handler.h"

#ifdef CONFIG_CHIP_OTA_REQUESTOR
#include "dfu/ota/ota_util.h"
#endif

#include <platform/ConnectivityManager.h>

#ifdef CONFIG_CHIP_NFC_COMMISSIONING
#include <app/server/OnboardingCodesUtil.h>
#include <platform/NFCManager.h>
#endif

#include <zephyr/logging/log.h>

LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL);

using namespace ::chip::DeviceLayer;

namespace Nrf::Matter
{
CHIP_ERROR RegisterEventHandler(PlatformManager::EventHandlerFunct handler, intptr_t arg)
{
StackLock lock;
return PlatformMgr().AddEventHandler(handler, arg);
}

void UnregisterEventHandler(PlatformManager::EventHandlerFunct handler, intptr_t arg)
{
StackLock lock;
PlatformMgr().RemoveEventHandler(handler, arg);
}

void DefaultEventHandler(const ChipDeviceEvent *event, intptr_t /* unused */)
{
switch (event->Type) {
case DeviceEventType::kCHIPoBLEAdvertisingChange:
#ifdef CONFIG_CHIP_NFC_COMMISSIONING
if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Started) {
if (NFCMgr().IsTagEmulationStarted()) {
LOG_INF("NFC Tag emulation is already started");
} else {
ShareQRCodeOverNFC(
chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE));
}
} else if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Stopped) {
NFCMgr().StopTagEmulation();
}
#endif
break;
#if defined(CONFIG_NET_L2_OPENTHREAD)
case DeviceEventType::kDnssdInitialized:
#if CONFIG_CHIP_OTA_REQUESTOR
InitBasicOTARequestor();
#endif /* CONFIG_CHIP_OTA_REQUESTOR */
break;
#elif defined(CONFIG_CHIP_WIFI)
case DeviceEventType::kWiFiConnectivityChange:
#if CONFIG_CHIP_OTA_REQUESTOR
if (event->WiFiConnectivityChange.Result == kConnectivity_Established) {
InitBasicOTARequestor();
}
#endif /* CONFIG_CHIP_OTA_REQUESTOR */
#endif /* CONFIG_NET_L2_OPENTHREAD */
break;
default:
break;
}
}

} // namespace Nrf::Matter
Loading

0 comments on commit a58ff6c

Please sign in to comment.