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

Te event triggers #15

Merged
merged 2 commits into from
Feb 7, 2024
Merged
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
1 change: 1 addition & 0 deletions samples/matter/common/src/Kconfig
Original file line number Diff line number Diff line change
@@ -41,3 +41,4 @@ config NCS_SAMPLE_MATTER_FACTORY_RESET_ON_KEY_MIGRATION_FAILURE
properly to PSA ITS storage.

rsource "diagnostic/Kconfig"
rsource "event_triggers/Kconfig"
19 changes: 19 additions & 0 deletions samples/matter/common/src/app/matter_init.cpp
Original file line number Diff line number Diff line change
@@ -21,6 +21,10 @@
#include "dfu/smp/dfu_over_smp.h"
#endif

#ifdef CONFIG_NCS_SAMPLE_MATTER_TEST_EVENT_TRIGGERS
#include "event_triggers/event_triggers.h"
#endif

#include <app/InteractionModelEngine.h>
#include <app/clusters/network-commissioning/network-commissioning.h>
#include <app/server/OnboardingCodesUtil.h>
@@ -162,6 +166,11 @@ void DoInitChipServer(intptr_t /* unused */)
Nrf::GetDFUOverSMP().ConfirmNewImage();
#endif

#ifdef CONFIG_NCS_SAMPLE_MATTER_TEST_EVENT_TRIGGERS
static Nrf::Matter::TestEventTrigger testEventTriggerDelegate;
sLocalInitData.mServerInitParams->testEventTriggerDelegate = &testEventTriggerDelegate;
#endif

/* Initialize CHIP server */
#if CONFIG_CHIP_FACTORY_DATA
if (sLocalInitData.mFactoryDataProvider) {
@@ -172,6 +181,16 @@ void DoInitChipServer(intptr_t /* unused */)
SetDeviceInstanceInfoProvider(sLocalInitData.mFactoryDataProvider);
SetDeviceAttestationCredentialsProvider(sLocalInitData.mFactoryDataProvider);
SetCommissionableDataProvider(sLocalInitData.mFactoryDataProvider);

#ifdef CONFIG_NCS_SAMPLE_MATTER_TEST_EVENT_TRIGGERS
// Read EnableKey from the factory data.
uint8_t enableKeyData[chip::TestEventTriggerDelegate::kEnableKeyLength];
MutableByteSpan enableKey(enableKeyData);
sInitResult = sLocalInitData.mFactoryDataProvider->GetEnableKey(enableKey);
VerifyInitResultOrReturn(sInitResult, "GetEnableKey() failed");
sInitResult = testEventTriggerDelegate.SetEnableKey(enableKey);
VerifyInitResultOrReturn(sInitResult, "SetEnableKey() failed");
#endif /* CONFIG_NCS_SAMPLE_MATTER_TEST_EVENT_TRIGGERS */
#else
SetDeviceInstanceInfoProvider(&DeviceInstanceInfoProviderMgrImpl());
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
10 changes: 10 additions & 0 deletions samples/matter/common/src/event_triggers/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#
# Copyright (c) 2024 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

menuconfig NCS_SAMPLE_MATTER_TEST_EVENT_TRIGGERS
bool "Test event triggers support"
help
Enables support for test event triggers for the specific use-cases.
85 changes: 85 additions & 0 deletions samples/matter/common/src/event_triggers/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
.. _matter_testing_events:

Matter testing events
#####################

.. contents::
:local:
:depth: 2

Matter testing events are a set of device's events that can be activated using triggers that have defined the activation codes.
You can use several events only if the specific Kconfig options are set to the specific values.

All event triggers requires the `enable key` that can be defined in the factory data.
The default `enable key` is set to ``00112233445566778899AABBCCDDEEFF``.

Requirements
************

To use the matter testing events you need the :ref:`Chip Tool application <ug_matter_gs_tools_chip>` to the send `test-event-trigger` commands of the general diagnostics cluster.
You need also a device that contains the `generaldiagnostics` cluster in its data model database.
To learn how to set the `generaldiagnostics` cluster see the :ref:`ug_matter_gs_adding_cluster` page.

To activate several triggers you need to have a specific accessory.
For example to use commands for the Door Lock cluster you need to have an accessory that contains that cluster and has set the appropriate product ID.

Available event triggers
************************

The following table lists available triggers and the activation codes:

.. list-table::
:widths: auto
:header-rows: 1

* - Name
- Requirements
- Description
- Activation code
* - Factory reset
- None
- Perform a factory reset of the device.
- `0xF000000000000000`
* - Reboot
- None
- Reboot the device.
- `0xF000000000000001`
* - Diagnostic logs crash
- The snippet `diagnostic-logs` attached (-S diagnostic-logs) or :kconfig:option:`CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS` = ``y`` & :kconfig:option:`CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_CRASH_LOGS` to ``y`` & `diagnostic logs` cluster
- Trigger a simple crash that rely on execution of the undefined instruction attempt.
- `0x1000000000000000`
* - OTA query
- :kconfig:option:`CONFIG_CHIP_OTA_REQUESTOR` = ``y``
- Trigger a OTA firmware update.
- `0x0100000000000100`
* - Door lock jammed
- :kconfig:option:`CONFIG_CHIP_DEVICE_PRODUCT_ID` = ``32774``
- Simulate the jammed lock state.
In this state the door lock
- `0x3277400000000000`

Setting the enable key
**********************

The `enable key` can be set to the specific value only if the :kconfig:option:`CONFIG_CHIP_FACTORY_DATA` Kconfig option is set to ``y``.
Otherwise the default value ``00112233445566778899AABBCCDDEEFF`` will be set.

To set the `enable key` using the build system set :kconfig:option:`CONFIG_CHIP_FACTORY_DATA_BUILD` Kconfig option to ``y`` and the :kconfig:option:`CONFIG_CHIP_DEVICE_ENABLE_KEY` to the hex string with length of 32 Bytes.

If the :kconfig:option:`CONFIG_CHIP_FACTORY_DATA_BUILD` is set to ``n`` you can use the Python script to generate the factory data set with the specific `enable key` value.
To learn how to do it read the :doc:`matter:nrfconnect_factory_data_configuration` guide in the Matter documentation.

Usage
*****

To trigger a specific event on the device, fill the `enable key`, `activation code`, and `node id` fields and run the following command:

.. code-block:: console

./chip-tool generaldiagnostics test-event-trigger hex:<enable key> <activation code> <node id> 0

An example for Matter Door Lock device which has a `node id` set to ``1``, using the default enable key:

.. code-block:: console

./chip-tool generaldiagnostics test-event-trigger hex:00112233445566778899AABBCCDDEEFF 0x3277400000000000 1 0
63 changes: 63 additions & 0 deletions samples/matter/common/src/event_triggers/event_triggers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include "event_triggers.h"

#include <app/server/Server.h>
#include <platform/nrfconnect/Reboot.h>

#if defined(CONFIG_CHIP_DEVICE_PRODUCT_ID) && CONFIG_CHIP_DEVICE_PRODUCT_ID == 32774
#include <app/clusters/door-lock-server/door-lock-server.h>

namespace
{
/* Ensure that the Lock endpoint is the same as in the app_task.cpp file */
constexpr uint16_t kLockEndpointId = 1;
} /* namespace */
#endif

using namespace Nrf::Matter;
using namespace chip;

bool TestEventTrigger::DoesEnableKeyMatch(const ByteSpan &enableKey) const
{
return !mEnableKey.empty() && mEnableKey.data_equal(enableKey);
}

CHIP_ERROR TestEventTrigger::HandleEventTrigger(uint64_t eventTrigger)
{
switch (eventTrigger) {
case EventTriggers::kFactoryReset:
Server::GetInstance().ScheduleFactoryReset();
break;
case EventTriggers::kReboot:
DeviceLayer::SystemLayer().ScheduleLambda(
[] { DeviceLayer::Reboot(DeviceLayer::SoftwareRebootReason::kOther); });
break;
case EventTriggers::kDiagnosticLogsCrash: {
/* Trigger the execute of the undefined instruction attempt */
DeviceLayer::SystemLayer().ScheduleLambda([] {
uint8_t *undefined = nullptr;
*undefined = 5;
});
} break;
#if defined(CONFIG_CHIP_DEVICE_PRODUCT_ID) && CONFIG_CHIP_DEVICE_PRODUCT_ID == 32774
case EventTriggers::kDoorLockJammed:
VerifyOrReturnError(DoorLockServer::Instance().SendLockAlarmEvent(kLockEndpointId,
AlarmCodeEnum::kLockJammed),
CHIP_ERROR_INTERNAL);
break;
#endif /* CHIP_DEVICE_PRODUCT_ID == 32774 */
#ifdef CONFIG_CHIP_OTA_REQUESTOR
case EventTriggers::kOtaStart:
mOtaTestEventTrigger.HandleEventTrigger(eventTrigger);
break;
#endif /* CONFIG_CHIP_OTA_REQUESTOR */
default:
return CHIP_ERROR_NOT_IMPLEMENTED;
}
return CHIP_NO_ERROR;
}
57 changes: 57 additions & 0 deletions samples/matter/common/src/event_triggers/event_triggers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#pragma once

#include <app/TestEventTriggerDelegate.h>
#include <app/clusters/ota-requestor/OTATestEventTriggerDelegate.h>

#include <cstdint>

namespace Nrf::Matter
{
class TestEventTrigger : public chip::TestEventTriggerDelegate {
public:
enum EventTriggerMask : uint64_t {
kSystem = 0xF000000000000000,
kDiagnostics = 0x1000000000000000,
kMatterStack = 0x0100000000000000,
kDoorLock = 0x3277400000000000,
};

enum EventTriggers : uint64_t {
/* System */
kFactoryReset = EventTriggerMask::kSystem,
kReboot = kFactoryReset + 1,
/* Diagnostic logs cluster */
kDiagnosticLogsCrash = EventTriggerMask::kDiagnostics,
/* Door lock cluster */
kDoorLockJammed = EventTriggerMask::kDoorLock,
/* OTA */
kOtaStart = chip::OTATestEventTriggerDelegate::kOtaQueryTrigger,
};

CHIP_ERROR SetEnableKey(const chip::ByteSpan &newEnableKey)
{
VerifyOrReturnError(newEnableKey.size() == chip::TestEventTriggerDelegate::kEnableKeyLength,
CHIP_ERROR_INVALID_ARGUMENT);
return CopySpanToMutableSpan(newEnableKey, mEnableKey);
}

explicit TestEventTrigger() : mOtaTestEventTrigger(mEnableKey) {}

/* TestEventTriggerDelegate implementation */
bool DoesEnableKeyMatch(const chip::ByteSpan &enableKey) const override;
CHIP_ERROR HandleEventTrigger(uint64_t eventTrigger) override;

private:
uint8_t mEnableKeyData[chip::TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb,
0xcc, 0xdd, 0xee, 0xff };
chip::MutableByteSpan mEnableKey{ mEnableKeyData };
chip::OTATestEventTriggerDelegate mOtaTestEventTrigger;
};
} /* namespace Nrf::Matter */
4 changes: 4 additions & 0 deletions samples/matter/lock/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -98,6 +98,10 @@ if(CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_CRASH_LOGS)
endif()
endif()

if(CONFIG_NCS_SAMPLE_MATTER_TEST_EVENT_TRIGGERS)
target_sources(app PRIVATE ${COMMON_ROOT}/src/event_triggers/event_triggers.cpp)
endif()

if(CONFIG_THREAD_WIFI_SWITCHING)
target_sources(app PRIVATE src/thread_wifi_switch.cpp)

1 change: 1 addition & 0 deletions samples/matter/lock/prj.conf
Original file line number Diff line number Diff line change
@@ -39,3 +39,4 @@ CONFIG_CHIP_FACTORY_DATA_BUILD=y

# TE Matter 1.3 Configurations
CONFIG_CHIP_CRYPTO_PSA=n
CONFIG_NCS_SAMPLE_MATTER_TEST_EVENT_TRIGGERS=y
Loading