diff --git a/samples/matter/common/cmake/source_common.cmake b/samples/matter/common/cmake/source_common.cmake index d2396fe52f56..a4ee2739e530 100644 --- a/samples/matter/common/cmake/source_common.cmake +++ b/samples/matter/common/cmake/source_common.cmake @@ -80,3 +80,7 @@ if(CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS) endif() endif() endif() + +if(CONFIG_NCS_SAMPLE_MATTER_TEST_SHELL) + target_sources(app PRIVATE ${MATTER_COMMONS_SRC_DIR}/test/test_shell.cpp) +endif() diff --git a/samples/matter/common/src/Kconfig b/samples/matter/common/src/Kconfig index ae0787639435..04cc2f1e7d55 100644 --- a/samples/matter/common/src/Kconfig +++ b/samples/matter/common/src/Kconfig @@ -83,6 +83,12 @@ config NCS_SAMPLE_MATTER_TEST_EVENT_TRIGGERS_MAX_TRIGGERS_DELEGATES Defines the maximum number for the TestEventTriggerDelegate implementations to be registered in the nRF test event triggers class. +config NCS_SAMPLE_MATTER_TEST_SHELL + bool "Test - specific shell commands support for Matter samples" + depends on CHIP_LIB_SHELL + help + Enables support for test - specific shell commands in Matter samples. + config NCS_SAMPLE_MATTER_PERSISTENT_STORAGE bool "Persistent storage support for Matter samples" help diff --git a/samples/matter/common/src/app/matter_init.cpp b/samples/matter/common/src/app/matter_init.cpp index a7f7c62f7b1e..b5d65162d226 100644 --- a/samples/matter/common/src/app/matter_init.cpp +++ b/samples/matter/common/src/app/matter_init.cpp @@ -38,6 +38,10 @@ #include "watchdog/watchdog.h" #endif +#ifdef CONFIG_NCS_SAMPLE_MATTER_TEST_SHELL +#include "test/test_shell.h" +#endif + #include #include #include @@ -329,6 +333,10 @@ CHIP_ERROR PrepareServer(const InitData &initData) err = PlatformMgr().InitChipStack(); VerifyInitResultOrReturnError(err, "PlatformMgr().InitChipStack() failed"); +#ifdef CONFIG_NCS_SAMPLE_MATTER_TEST_SHELL + Nrf::RegisterTestCommands(); +#endif + /* Schedule all CHIP initializations to the CHIP thread for better synchronization. */ return PlatformMgr().ScheduleWork(DoInitChipServer, 0); } diff --git a/samples/matter/common/src/test/test_shell.cpp b/samples/matter/common/src/test/test_shell.cpp new file mode 100644 index 000000000000..976eb73d0709 --- /dev/null +++ b/samples/matter/common/src/test/test_shell.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include "test_shell.h" + +#include +#include + +using namespace chip; +using namespace chip::app; + +namespace Nrf +{ +using Shell::Engine; +using Shell::shell_command_t; +using Shell::streamer_get; +using Shell::streamer_printf; + +Engine sShellTestSubCommands; +Engine sShellResumptionStorageSubCommands; + +static CHIP_ERROR TestHelpHandler(int argc, char **argv) +{ + sShellTestSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + +static CHIP_ERROR TestCommandHandler(int argc, char **argv) +{ + if (argc == 0) { + return TestHelpHandler(argc, argv); + } + return sShellTestSubCommands.ExecCommand(argc, argv); +} + + +static CHIP_ERROR ResumptionStorageHelpHandler(int argc, char **argv) +{ + sShellResumptionStorageSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + +static CHIP_ERROR ResumptionStorageHandler(int argc, char **argv) +{ + if (argc == 0) { + return ResumptionStorageHelpHandler(argc, argv); + } + return sShellResumptionStorageSubCommands.ExecCommand(argc, argv); +} + +static CHIP_ERROR ClearResumptionStorageHandler(int argc, char ** argv) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + FabricId fabricId = kUndefinedFabricId; + SessionResumptionStorage * storage = Server::GetInstance().GetSessionResumptionStorage(); + + VerifyOrExit(storage != nullptr, error = CHIP_ERROR_INCORRECT_STATE); + VerifyOrExit(argc < 2, error = CHIP_ERROR_INVALID_ARGUMENT); + + if (argc == 1) + { + char *endptr; + + fabricId = static_cast(strtoull(argv[0], &endptr, 0)); + VerifyOrExit(*endptr == '\0', error = CHIP_ERROR_INVALID_ARGUMENT); + } + + streamer_printf(streamer_get(), "Clearing resumption storage.\r\n"); + + for (auto & fabricInfo : Server::GetInstance().GetFabricTable()) { + if (argc == 0 || fabricInfo.GetFabricId() == fabricId) { + SuccessOrExit(error = storage->DeleteAll(fabricInfo.GetFabricIndex())); + + if (fabricInfo.GetFabricId() == fabricId) { + ExitNow(); + } + } + } + +exit: + return error; +} + +void RegisterTestCommands() +{ + static const shell_command_t sTestSubCommands[] = { + { &TestHelpHandler, "help", "Test - specific commands" }, + { &ResumptionStorageHandler, "restorage", "Resumption storage commands." }, + }; + + static const shell_command_t sResumptionStorageSubCommands[] = { + { &ResumptionStorageHelpHandler, "help", "Resumption storage commands. " + "Usage : test restorage " }, + { &ClearResumptionStorageHandler, "clear", "Clears resumption storage for fabric-id. If fabric-id is " + "not specified, clears resumption storage for all fabrics. " + "Usage : test restorage clear [fabric-id]" }, + }; + + static const shell_command_t sTestCommand = { &TestCommandHandler, "test", "Test - specific commands" }; + + sShellTestSubCommands.RegisterCommands(sTestSubCommands, ArraySize(sTestSubCommands)); + sShellResumptionStorageSubCommands.RegisterCommands(sResumptionStorageSubCommands, + ArraySize(sResumptionStorageSubCommands)); + + Engine::Root().RegisterCommands(&sTestCommand, 1); +} + +} /* namespace Nrf */ diff --git a/samples/matter/common/src/test/test_shell.h b/samples/matter/common/src/test/test_shell.h new file mode 100644 index 000000000000..7ab8400a1870 --- /dev/null +++ b/samples/matter/common/src/test/test_shell.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#pragma once + +#include +#include +#include + +namespace Nrf +{ +void RegisterTestCommands(); + +} /* namespace Nrf */ diff --git a/samples/matter/template/sample.yaml b/samples/matter/template/sample.yaml index 58d45597fc7a..1ba339f2824f 100644 --- a/samples/matter/template/sample.yaml +++ b/samples/matter/template/sample.yaml @@ -79,3 +79,16 @@ tests: - nrf54h20dk/nrf54h20/cpuapp platform_allow: nrf54h20dk/nrf54h20/cpuapp tags: sysbuild ci_samples_matter + sample.matter.template.test_shell: + sysbuild: true + build_only: true + extra_args: CONFIG_NCS_SAMPLE_MATTER_TEST_SHELL=y + integration_platforms: + - nrf52840dk/nrf52840 + - nrf5340dk/nrf5340/cpuapp + - nrf7002dk/nrf5340/cpuapp + - nrf54l15pdk/nrf54l15/cpuapp + - nrf54h20dk/nrf54h20/cpuapp + platform_allow: nrf52840dk/nrf52840 nrf5340dk/nrf5340/cpuapp nrf7002dk/nrf5340/cpuapp + nrf54l15pdk/nrf54l15/cpuapp nrf54h20dk/nrf54h20/cpuapp + tags: sysbuild ci_samples_matter diff --git a/scripts/quarantine_integration.yaml b/scripts/quarantine_integration.yaml index 690bec6334ad..23c70d87cebb 100644 --- a/scripts/quarantine_integration.yaml +++ b/scripts/quarantine_integration.yaml @@ -19,6 +19,7 @@ - sample.matter.window_cover.lto - sample.matter.thermostat.ext_temp - sample.matter.light_bulb.memory_profiling + - sample.matter.template.test_shell platforms: - nrf52840dk/nrf52840 comment: "Configurations excluded to limit resources usage in integration builds" @@ -41,6 +42,7 @@ - sample.matter.window_cover.lto - sample.matter.thermostat.ext_temp - sample.matter.light_bulb.memory_profiling + - sample.matter.template.test_shell platforms: - nrf5340dk/nrf5340/cpuapp comment: "Configurations excluded to limit resources usage in integration builds"