diff --git a/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn b/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn index 02cce50f266eb1..3e1ac42eacf61b 100644 --- a/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn +++ b/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn @@ -168,7 +168,6 @@ rt_executable("all_cluster_app") { "${common_example_dir}/device_manager/source/CHIPDeviceManager.cpp", "${common_example_dir}/icd/source/ICDUtil.cpp", "${common_example_dir}/matter_button/source/AppMatterButtonEmpty.cpp", - "${common_example_dir}/matter_cli/source/AppMatterCli.cpp", ] deps = [ "${chip_root}/examples/${app_common_folder}" ] @@ -185,6 +184,10 @@ rt_executable("all_cluster_app") { "${chip_root}/examples/shell/shell_common:shell_common", "${chip_root}/src/lib/shell:shell", ] + sources += [ + "${common_example_dir}/matter_cli/source/AppCLIBase.cpp", + "${common_example_dir}/matter_cli/source/AppCLIFreeRTOS.cpp", + ] } if (chip_enable_ota_requestor) { diff --git a/examples/laundry-washer-app/nxp/common/main/AppTask.cpp b/examples/laundry-washer-app/nxp/common/main/AppTask.cpp index 1137db82338b6f..fb37f4f13a78f5 100644 --- a/examples/laundry-washer-app/nxp/common/main/AppTask.cpp +++ b/examples/laundry-washer-app/nxp/common/main/AppTask.cpp @@ -29,8 +29,9 @@ #ifdef ENABLE_CHIP_SHELL #include - +#include using namespace chip::Shell; +#define MATTER_CLI_LOG(message) (streamer_printf(streamer_get(), message)) #endif /* ENABLE_CHIP_SHELL */ using namespace chip; @@ -38,71 +39,77 @@ using namespace chip::app::Clusters; app::Clusters::TemperatureControl::AppSupportedTemperatureLevelsDelegate sAppSupportedTemperatureLevelsDelegate; -CHIP_ERROR cliOpState(int argc, char * argv[]) +#ifdef ENABLE_CHIP_SHELL +const static std::map map_cmd_errstate{ + { "no_error", (uint8_t) OperationalState::ErrorStateEnum::kNoError }, + { "unable_to_start_or_resume", (uint8_t) OperationalState::ErrorStateEnum::kUnableToStartOrResume }, + { "unable_to_complete_operation", (uint8_t) OperationalState::ErrorStateEnum::kUnableToCompleteOperation }, + { "command_invalid_in_state", (uint8_t) OperationalState::ErrorStateEnum::kCommandInvalidInState } +}; + +const static std::map map_cmd_opstate{ { "stop", (uint8_t) OperationalState::OperationalStateEnum::kStopped }, + { "run", (uint8_t) OperationalState::OperationalStateEnum::kRunning }, + { "pause", (uint8_t) OperationalState::OperationalStateEnum::kPaused }, + { "error", + (uint8_t) OperationalState::OperationalStateEnum::kError } }; + +static void InvalidStateHandler(void) { - if ((argc != 1) && (argc != 2)) - { - ChipLogError(Shell, "Target State is missing"); - return CHIP_ERROR_INVALID_ARGUMENT; - } - if (!strcmp(argv[0], "stop")) + ChipLogError(Shell, "Invalid State/Error to set"); + MATTER_CLI_LOG("Invalid. Supported commands are:\n"); + for (auto const & it : map_cmd_opstate) { - ChipLogDetail(Shell, "OpSState : Set to %s state", argv[0]); - OperationalState::GetOperationalStateInstance()->SetOperationalState( - to_underlying(OperationalState::OperationalStateEnum::kStopped)); + MATTER_CLI_LOG(("\t opstate " + it.first + "\n").c_str()); } - else if (!strcmp(argv[0], "run")) + for (auto const & it : map_cmd_errstate) { - ChipLogDetail(Shell, "OpSState : Set to %s state", argv[0]); - OperationalState::GetOperationalStateInstance()->SetOperationalState( - to_underlying(OperationalState::OperationalStateEnum::kRunning)); + MATTER_CLI_LOG(("\t opstate error " + it.first + "\n").c_str()); } - else if (!strcmp(argv[0], "pause")) +} + +static CHIP_ERROR cliOpState(int argc, char * argv[]) +{ + bool inputErr = false; + if ((argc != 1) && (argc != 2)) { - ChipLogDetail(Shell, "OpSState : Set to %s state", argv[0]); - OperationalState::GetOperationalStateInstance()->SetOperationalState( - to_underlying(OperationalState::OperationalStateEnum::kPaused)); + inputErr = true; + goto exit; } - else if (!strcmp(argv[0], "error")) + + if (map_cmd_opstate.find(argv[0]) != map_cmd_opstate.end()) { - OperationalState::Structs::ErrorStateStruct::Type err; + OperationalState::GetOperationalStateInstance()->SetOperationalState(map_cmd_opstate.at(argv[0])); ChipLogDetail(Shell, "OpSState : Set to %s state", argv[0]); - if (!strcmp(argv[1], "no_error")) - { - ChipLogDetail(Shell, "OpSState_error : Error: %s state", argv[1]); - err.errorStateID = (uint8_t) OperationalState::ErrorStateEnum::kNoError; - } - else if (!strcmp(argv[1], "unable_to_start_or_resume")) - { - ChipLogDetail(Shell, "OpSState_error : Error: %s state", argv[1]); - err.errorStateID = (uint8_t) OperationalState::ErrorStateEnum::kUnableToStartOrResume; - } - else if (!strcmp(argv[1], "unable_to_complete_operation")) - { - ChipLogDetail(Shell, "OpSState_error : Error: %s state", argv[1]); - err.errorStateID = (uint8_t) OperationalState::ErrorStateEnum::kUnableToCompleteOperation; - } - else if (!strcmp(argv[1], "command_invalid_in_state")) - { - ChipLogDetail(Shell, "OpSState_error : Error: %s state", argv[1]); - err.errorStateID = (uint8_t) OperationalState::ErrorStateEnum::kCommandInvalidInState; - } - else + if (!strcmp(argv[0], "error") && argc == 2) { - ChipLogError(Shell, "Invalid Error State to set"); - return CHIP_ERROR_INVALID_ARGUMENT; + OperationalState::Structs::ErrorStateStruct::Type err; + if (map_cmd_errstate.find(argv[1]) != map_cmd_errstate.end()) + { + ChipLogDetail(Shell, "OpSState_error : Set to %s state", argv[1]); + err.errorStateID = map_cmd_errstate.at(argv[1]); + OperationalState::GetOperationalStateInstance()->OnOperationalErrorDetected(err); + } + else + { + inputErr = true; + goto exit; + } } - OperationalState::GetOperationalStateInstance()->OnOperationalErrorDetected(err); - OperationalState::GetOperationalStateInstance()->SetOperationalState( - to_underlying(OperationalState::OperationalStateEnum::kError)); } else { - ChipLogError(Shell, "Invalid State to set"); + inputErr = true; + } +exit: + if (inputErr) + { + InvalidStateHandler(); return CHIP_ERROR_INVALID_ARGUMENT; } + return CHIP_NO_ERROR; } +#endif /* ENABLE_CHIP_SHELL */ void LaundryWasherApp::AppTask::PreInitMatterStack() { @@ -121,7 +128,9 @@ void LaundryWasherApp::AppTask::AppMatter_RegisterCustomCliCommands() #ifdef ENABLE_CHIP_SHELL /* Register application commands */ static const shell_command_t kCommands[] = { - { .cmd_func = cliOpState, .cmd_name = "opstate", .cmd_help = "Set the Operational State" }, + { .cmd_func = cliOpState, + .cmd_name = "opstate", + .cmd_help = "Set the Operational State. Usage:[stop|run|pause|dock|error 'state'] " }, }; Engine::Root().RegisterCommands(kCommands, sizeof(kCommands) / sizeof(kCommands[0])); #endif diff --git a/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn b/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn index 1a0e8f39d9c9a3..a9840f74f20d0f 100644 --- a/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn +++ b/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn @@ -169,7 +169,6 @@ rt_executable("laundry-washer") { "${common_example_dir}/device_manager/source/CHIPDeviceManager.cpp", "${common_example_dir}/icd/source/ICDUtil.cpp", "${common_example_dir}/matter_button/source/AppMatterButtonEmpty.cpp", - "${common_example_dir}/matter_cli/source/AppMatterCli.cpp", ] deps = [ "${chip_root}/examples/${app_common_folder}" ] @@ -190,6 +189,10 @@ rt_executable("laundry-washer") { "${chip_root}/examples/shell/shell_common:shell_common", "${chip_root}/src/lib/shell:shell", ] + sources += [ + "${common_example_dir}/matter_cli/source/AppCLIBase.cpp", + "${common_example_dir}/matter_cli/source/AppCLIFreeRTOS.cpp", + ] } if (chip_enable_ota_requestor) { diff --git a/examples/platform/nxp/common/app_task/include/AppTaskBase.h b/examples/platform/nxp/common/app_task/include/AppTaskBase.h index 02fdf513eb6679..98cec56832b705 100644 --- a/examples/platform/nxp/common/app_task/include/AppTaskBase.h +++ b/examples/platform/nxp/common/app_task/include/AppTaskBase.h @@ -130,14 +130,22 @@ class AppTaskBase */ static void InitServer(intptr_t arg); - /* Commissioning handlers */ - virtual void StartCommissioningHandler(void){}; - virtual void StopCommissioningHandler(void){}; - virtual void SwitchCommissioningStateHandler(void){}; - virtual void FactoryResetHandler(void){}; + /** + * Commissioning handlers + * Generic implementation is provided within this class + * Can be overridden by a child class + */ + virtual void StartCommissioningHandler(void); + virtual void StopCommissioningHandler(void); + virtual void SwitchCommissioningStateHandler(void); + virtual void FactoryResetHandler(void); private: inline static chip::CommonCaseDeviceServerInitParams initParams; + /* Functions used by the public commisioning handlers */ + static void StartCommissioning(intptr_t arg); + static void StopCommissioning(intptr_t arg); + static void SwitchCommissioningState(intptr_t arg); }; /** diff --git a/examples/platform/nxp/common/app_task/include/AppTaskFreeRTOS.h b/examples/platform/nxp/common/app_task/include/AppTaskFreeRTOS.h index 9fbaf8063df8b7..7ebc4a7430ccaf 100644 --- a/examples/platform/nxp/common/app_task/include/AppTaskFreeRTOS.h +++ b/examples/platform/nxp/common/app_task/include/AppTaskFreeRTOS.h @@ -65,26 +65,13 @@ class AppTaskFreeRTOS : public AppTaskBase #endif /** - * \brief This function register matter CLI and button features. + * \brief This function registers custom matter CLI and button features. * * \return CHIP_ERROR * */ virtual CHIP_ERROR AppMatter_Register(void) override; - /* Functions that would be called in the Matter task context */ - static void StartCommissioning(intptr_t arg); - static void StopCommissioning(intptr_t arg); - static void SwitchCommissioningState(intptr_t arg); - - /* Commissioning handlers */ - virtual void StartCommissioningHandler(void) override; - virtual void StopCommissioningHandler(void) override; - virtual void SwitchCommissioningStateHandler(void) override; - - /* FactoryResetHandler */ - virtual void FactoryResetHandler(void) override; - private: void DispatchEvent(const AppEvent & event); }; diff --git a/examples/platform/nxp/common/app_task/include/AppTaskZephyr.h b/examples/platform/nxp/common/app_task/include/AppTaskZephyr.h index 163e3e76a9d87c..77cfaa0e468ccf 100644 --- a/examples/platform/nxp/common/app_task/include/AppTaskZephyr.h +++ b/examples/platform/nxp/common/app_task/include/AppTaskZephyr.h @@ -54,6 +54,14 @@ class AppTaskZephyr : public AppTaskBase virtual chip::DeviceLayer::NetworkCommissioning::WiFiDriver * GetWifiDriverInstance(void) override; #endif + /** + * \brief This function registers applicative features such as custom CLI commands + * + * \return CHIP_ERROR + * + */ + virtual CHIP_ERROR AppMatter_Register(void) override; + private: void DispatchEvent(const AppEvent & event); }; diff --git a/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp b/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp index 2b70fcb4c070c7..9ba90e6c146b74 100644 --- a/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp +++ b/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp @@ -172,6 +172,12 @@ CHIP_ERROR chip::NXP::App::AppTaskBase::Init() ChipLogError(DeviceLayer, "CHIPDeviceManager.Init() failed: %s", ErrorStr(err)); goto exit; } + /* Make sure to initialize the Matter CLI which will include the ot-cli first. + * In fact it is mandatory to enable first the ot-cli before initializing the Matter openthread layer + * which would modify some contexts of the openthread instance. + */ + err = AppMatter_Register(); + VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(DeviceLayer, "Error during APP features registration")); #if CONFIG_NET_L2_OPENTHREAD err = ThreadStackMgr().InitThreadStack(); @@ -218,12 +224,6 @@ CHIP_ERROR chip::NXP::App::AppTaskBase::Init() } #endif - err = AppMatter_Register(); - if (err != CHIP_NO_ERROR) - { - goto exit; - } - ConfigurationMgr().LogDeviceConfig(); // QR code will be used with CHIP Tool @@ -257,3 +257,79 @@ CHIP_ERROR chip::NXP::App::AppTaskBase::Init() exit: return err; } + +void chip::NXP::App::AppTaskBase::StartCommissioning(intptr_t arg) +{ + /* Check the status of the commissioning */ + if (ConfigurationMgr().IsFullyProvisioned()) + { + ChipLogProgress(DeviceLayer, "Device already commissioned"); + } + else if (chip::Server::GetInstance().GetCommissioningWindowManager().IsCommissioningWindowOpen()) + { + ChipLogProgress(DeviceLayer, "Commissioning window already opened"); + } + else + { + chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow(); + } +} + +void chip::NXP::App::AppTaskBase::StopCommissioning(intptr_t arg) +{ + /* Check the status of the commissioning */ + if (ConfigurationMgr().IsFullyProvisioned()) + { + ChipLogProgress(DeviceLayer, "Device already commissioned"); + } + else if (!chip::Server::GetInstance().GetCommissioningWindowManager().IsCommissioningWindowOpen()) + { + ChipLogProgress(DeviceLayer, "Commissioning window not opened"); + } + else + { + chip::Server::GetInstance().GetCommissioningWindowManager().CloseCommissioningWindow(); + } +} + +void chip::NXP::App::AppTaskBase::SwitchCommissioningState(intptr_t arg) +{ + /* Check the status of the commissioning */ + if (ConfigurationMgr().IsFullyProvisioned()) + { + ChipLogProgress(DeviceLayer, "Device already commissioned"); + } + else if (!chip::Server::GetInstance().GetCommissioningWindowManager().IsCommissioningWindowOpen()) + { + chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow(); + } + else + { + chip::Server::GetInstance().GetCommissioningWindowManager().CloseCommissioningWindow(); + } +} + +void chip::NXP::App::AppTaskBase::StartCommissioningHandler(void) +{ + /* Publish an event to the Matter task to always set the commissioning state in the Matter task context */ + PlatformMgr().ScheduleWork(StartCommissioning, 0); +} + +void chip::NXP::App::AppTaskBase::StopCommissioningHandler(void) +{ + /* Publish an event to the Matter task to always set the commissioning state in the Matter task context */ + PlatformMgr().ScheduleWork(StopCommissioning, 0); +} + +void chip::NXP::App::AppTaskBase::SwitchCommissioningStateHandler(void) +{ + /* Publish an event to the Matter task to always set the commissioning state in the Matter task context */ + PlatformMgr().ScheduleWork(SwitchCommissioningState, 0); +} + +void chip::NXP::App::AppTaskBase::FactoryResetHandler(void) +{ + /* Emit the ShutDown event before factory reset */ + chip::Server::GetInstance().GenerateShutDownEvent(); + chip::Server::GetInstance().ScheduleFactoryReset(); +} diff --git a/examples/platform/nxp/common/app_task/source/AppTaskFreeRTOS.cpp b/examples/platform/nxp/common/app_task/source/AppTaskFreeRTOS.cpp index 8508884b672b23..c48894ed6467cf 100644 --- a/examples/platform/nxp/common/app_task/source/AppTaskFreeRTOS.cpp +++ b/examples/platform/nxp/common/app_task/source/AppTaskFreeRTOS.cpp @@ -22,7 +22,6 @@ #include #include "AppMatterButton.h" -#include "AppMatterCli.h" #include "CHIPDeviceManager.h" #include @@ -31,6 +30,10 @@ #include #endif // CHIP_DEVICE_CONFIG_ENABLE_WPA +#ifdef ENABLE_CHIP_SHELL +#include "AppCLIBase.h" +#endif + #include #include @@ -69,14 +72,11 @@ CHIP_ERROR chip::NXP::App::AppTaskFreeRTOS::AppMatter_Register() { CHIP_ERROR err = CHIP_NO_ERROR; /* Register Matter CLI cmds */ - err = AppMatterCli_RegisterCommands(); +#ifdef ENABLE_CHIP_SHELL + err = chip::NXP::App::GetAppCLI().Init(); + VerifyOrReturnError(err == CHIP_NO_ERROR, err, ChipLogError(DeviceLayer, "Error during CLI init")); AppMatter_RegisterCustomCliCommands(); - AppMatterCli_StartTask(); - if (err != CHIP_NO_ERROR) - { - ChipLogError(DeviceLayer, "Error during AppMatterCli_RegisterCommands"); - return err; - } +#endif /* Register Matter buttons */ err = AppMatterButton_registerButtons(); if (err != CHIP_NO_ERROR) @@ -162,79 +162,3 @@ void chip::NXP::App::AppTaskFreeRTOS::DispatchEvent(const AppEvent & event) ChipLogProgress(DeviceLayer, "Event received with no handler. Dropping event."); } } - -void chip::NXP::App::AppTaskFreeRTOS::StartCommissioning(intptr_t arg) -{ - /* Check the status of the commissioning */ - if (ConfigurationMgr().IsFullyProvisioned()) - { - ChipLogProgress(DeviceLayer, "Device already commissioned"); - } - else if (chip::Server::GetInstance().GetCommissioningWindowManager().IsCommissioningWindowOpen()) - { - ChipLogProgress(DeviceLayer, "Commissioning window already opened"); - } - else - { - chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow(); - } -} - -void chip::NXP::App::AppTaskFreeRTOS::StopCommissioning(intptr_t arg) -{ - /* Check the status of the commissioning */ - if (ConfigurationMgr().IsFullyProvisioned()) - { - ChipLogProgress(DeviceLayer, "Device already commissioned"); - } - else if (!chip::Server::GetInstance().GetCommissioningWindowManager().IsCommissioningWindowOpen()) - { - ChipLogProgress(DeviceLayer, "Commissioning window not opened"); - } - else - { - chip::Server::GetInstance().GetCommissioningWindowManager().CloseCommissioningWindow(); - } -} - -void chip::NXP::App::AppTaskFreeRTOS::SwitchCommissioningState(intptr_t arg) -{ - /* Check the status of the commissioning */ - if (ConfigurationMgr().IsFullyProvisioned()) - { - ChipLogProgress(DeviceLayer, "Device already commissioned"); - } - else if (!chip::Server::GetInstance().GetCommissioningWindowManager().IsCommissioningWindowOpen()) - { - chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow(); - } - else - { - chip::Server::GetInstance().GetCommissioningWindowManager().CloseCommissioningWindow(); - } -} - -void chip::NXP::App::AppTaskFreeRTOS::StartCommissioningHandler(void) -{ - /* Publish an event to the Matter task to always set the commissioning state in the Matter task context */ - PlatformMgr().ScheduleWork(StartCommissioning, 0); -} - -void chip::NXP::App::AppTaskFreeRTOS::StopCommissioningHandler(void) -{ - /* Publish an event to the Matter task to always set the commissioning state in the Matter task context */ - PlatformMgr().ScheduleWork(StopCommissioning, 0); -} - -void chip::NXP::App::AppTaskFreeRTOS::SwitchCommissioningStateHandler(void) -{ - /* Publish an event to the Matter task to always set the commissioning state in the Matter task context */ - PlatformMgr().ScheduleWork(SwitchCommissioningState, 0); -} - -void chip::NXP::App::AppTaskFreeRTOS::FactoryResetHandler(void) -{ - /* Emit the ShutDown event before factory reset */ - chip::Server::GetInstance().GenerateShutDownEvent(); - chip::Server::GetInstance().ScheduleFactoryReset(); -} diff --git a/examples/platform/nxp/common/app_task/source/AppTaskZephyr.cpp b/examples/platform/nxp/common/app_task/source/AppTaskZephyr.cpp index 05257c3a88c190..00554d8ee1a48c 100644 --- a/examples/platform/nxp/common/app_task/source/AppTaskZephyr.cpp +++ b/examples/platform/nxp/common/app_task/source/AppTaskZephyr.cpp @@ -32,6 +32,10 @@ #include #endif +#ifdef ENABLE_CHIP_SHELL +#include "AppCLIBase.h" +#endif + #if CONFIG_CHIP_FACTORY_DATA #include #else @@ -67,6 +71,18 @@ chip::DeviceLayer::NetworkCommissioning::WiFiDriver * chip::NXP::App::AppTaskZep } #endif // CONFIG_CHIP_WIFI +CHIP_ERROR chip::NXP::App::AppTaskZephyr::AppMatter_Register() +{ + CHIP_ERROR err = CHIP_NO_ERROR; +#ifdef ENABLE_CHIP_SHELL + /* Register Matter CLI cmds */ + err = chip::NXP::App::GetAppCLI().Init(); + VerifyOrReturnError(err == CHIP_NO_ERROR, err, ChipLogError(DeviceLayer, "Error during CLI init")); + AppMatter_RegisterCustomCliCommands(); +#endif + return err; +} + CHIP_ERROR chip::NXP::App::AppTaskZephyr::Start() { PreInitMatterStack(); diff --git a/examples/platform/nxp/common/matter_cli/include/AppCLIBase.h b/examples/platform/nxp/common/matter_cli/include/AppCLIBase.h new file mode 100644 index 00000000000000..c3be97e755431b --- /dev/null +++ b/examples/platform/nxp/common/matter_cli/include/AppCLIBase.h @@ -0,0 +1,53 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace chip { +namespace NXP { +namespace App { + +class AppCLIBase +{ +public: + virtual ~AppCLIBase() = default; + /** + * \brief API allowing to initialize the CLI + * + * This API can also register some common commands + */ + virtual CHIP_ERROR Init(void) = 0; + + /** + * \brief Registers common CLI commands used by application + */ + void RegisterDefaultCommands(void); + + /** + * \brief Handles CLI Reset command + * + * Abstract function since implementation could be different for each child class. + */ + virtual void ResetCmdHandle(void) = 0; +}; +extern AppCLIBase & GetAppCLI(); +} // namespace App +} // namespace NXP +} // namespace chip diff --git a/examples/platform/nxp/common/matter_cli/include/AppCLIFreeRTOS.h b/examples/platform/nxp/common/matter_cli/include/AppCLIFreeRTOS.h new file mode 100644 index 00000000000000..9a60d7ebbfb6b8 --- /dev/null +++ b/examples/platform/nxp/common/matter_cli/include/AppCLIFreeRTOS.h @@ -0,0 +1,44 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "AppCLIBase.h" + +namespace chip { +namespace NXP { +namespace App { + +class AppCLIFreeRTOS : public AppCLIBase +{ +public: + virtual ~AppCLIFreeRTOS() = default; + + virtual CHIP_ERROR Init(void) override; + + virtual void ResetCmdHandle(void) override; + + static AppCLIFreeRTOS & GetDefaultInstance(); + +private: + bool isShellInitialized = false; +}; +AppCLIBase & GetAppCLI(); +} // namespace App +} // namespace NXP +} // namespace chip diff --git a/examples/platform/nxp/common/matter_cli/include/AppCLIZephyr.h b/examples/platform/nxp/common/matter_cli/include/AppCLIZephyr.h new file mode 100644 index 00000000000000..403bd0d3d4dcdf --- /dev/null +++ b/examples/platform/nxp/common/matter_cli/include/AppCLIZephyr.h @@ -0,0 +1,44 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "AppCLIBase.h" + +namespace chip { +namespace NXP { +namespace App { + +class AppCLIZephyr : public AppCLIBase +{ +public: + virtual ~AppCLIZephyr() = default; + + virtual CHIP_ERROR Init(void) override; + + virtual void ResetCmdHandle(void) override; + + static AppCLIZephyr & GetDefaultInstance(); + +private: + bool isShellInitialized = false; +}; +AppCLIBase & GetAppCLI(); +} // namespace App +} // namespace NXP +} // namespace chip diff --git a/examples/platform/nxp/common/matter_cli/include/AppMatterCli.h b/examples/platform/nxp/common/matter_cli/include/AppMatterCli.h deleted file mode 100644 index 68f24fc8fcbfdc..00000000000000 --- a/examples/platform/nxp/common/matter_cli/include/AppMatterCli.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2022-2024 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef _MATTER_CLI_H_ -#define _MATTER_CLI_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -namespace chip { -namespace NXP { -namespace App { -/** - * API allowing to register matter cli command - */ -CHIP_ERROR AppMatterCli_RegisterCommands(void); -/** - * API allowing to start matter cli task - */ -CHIP_ERROR AppMatterCli_StartTask(void); - -} // namespace App -} // namespace NXP -} // namespace chip - -#ifdef __cplusplus -} -#endif - -#endif /* _MATTER_CLI_H_ */ diff --git a/examples/platform/nxp/common/matter_cli/source/AppCLIBase.cpp b/examples/platform/nxp/common/matter_cli/source/AppCLIBase.cpp new file mode 100644 index 00000000000000..9bd53ff21cbd4a --- /dev/null +++ b/examples/platform/nxp/common/matter_cli/source/AppCLIBase.cpp @@ -0,0 +1,87 @@ +/* + * + * Copyright (c) 2022-2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppCLIBase.h" +#include "AppTaskBase.h" +#include +#include +#include +#include +#include + +#define MATTER_CLI_LOG(message) (chip::Shell::streamer_printf(chip::Shell::streamer_get(), message)) + +static CHIP_ERROR commissioningManager(int argc, char * argv[]) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + if (strncmp(argv[0], "on", 2) == 0) + { + chip::NXP::App::GetAppTask().StartCommissioningHandler(); + } + else if (strncmp(argv[0], "off", 3) == 0) + { + chip::NXP::App::GetAppTask().StopCommissioningHandler(); + } + else + { + MATTER_CLI_LOG("wrong args should be either \"mattercommissioning on\" or \"mattercommissioning off\""); + error = CHIP_ERROR_INVALID_ARGUMENT; + } + return error; +} + +static CHIP_ERROR cliFactoryReset(int argc, char * argv[]) +{ + chip::NXP::App::GetAppTask().FactoryResetHandler(); + return CHIP_NO_ERROR; +} + +static CHIP_ERROR cliReset(int argc, char * argv[]) +{ + chip::NXP::App::GetAppCLI().ResetCmdHandle(); + return CHIP_NO_ERROR; +} + +void chip::NXP::App::AppCLIBase::RegisterDefaultCommands(void) +{ + static const chip::Shell::shell_command_t kCommands[] = { + { + .cmd_func = commissioningManager, + .cmd_name = "mattercommissioning", + .cmd_help = "Open/close the commissioning window. Usage : mattercommissioning [on|off]", + }, + { + .cmd_func = cliFactoryReset, + .cmd_name = "matterfactoryreset", + .cmd_help = "Perform a factory reset on the device", + }, + { + .cmd_func = cliReset, + .cmd_name = "matterreset", + .cmd_help = "Reset the device", + } + }; + + /* Register common shell commands */ + cmd_misc_init(); + cmd_otcli_init(); +#if CHIP_SHELL_ENABLE_CMD_SERVER + cmd_app_server_init(); +#endif /* CHIP_SHELL_ENABLE_CMD_SERVER */ + chip::Shell::Engine::Root().RegisterCommands(kCommands, sizeof(kCommands) / sizeof(kCommands[0])); +} diff --git a/examples/platform/nxp/common/matter_cli/source/AppCLIFreeRTOS.cpp b/examples/platform/nxp/common/matter_cli/source/AppCLIFreeRTOS.cpp new file mode 100644 index 00000000000000..1a2f840edc2e27 --- /dev/null +++ b/examples/platform/nxp/common/matter_cli/source/AppCLIFreeRTOS.cpp @@ -0,0 +1,80 @@ +/* + * + * Copyright (c) 2022-2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppCLIFreeRTOS.h" +#include "AppTaskBase.h" +#include +#include +#include + +#define MATTER_CLI_TASK_SIZE ((configSTACK_DEPTH_TYPE) 2048 / sizeof(portSTACK_TYPE)) + +TaskHandle_t AppMatterCliTaskHandle; + +void AppMatterCliTask(void * args) +{ + chip::Shell::Engine::Root().RunMainLoop(); +} + +// This returns an instance of this class. +chip::NXP::App::AppCLIFreeRTOS & chip::NXP::App::AppCLIFreeRTOS::GetDefaultInstance() +{ + static chip::NXP::App::AppCLIFreeRTOS sAppCLI; + return sAppCLI; +} + +chip::NXP::App::AppCLIBase & chip::NXP::App::GetAppCLI() +{ + return chip::NXP::App::AppCLIFreeRTOS::GetDefaultInstance(); +} + +void chip::NXP::App::AppCLIFreeRTOS::ResetCmdHandle(void) +{ + /* + Shutdown device before reboot, + this emits the ShutDown event, handles the server shutting down, + and stores in flash the total-operational-hours value. + */ + chip::DeviceLayer::PlatformMgr().Shutdown(); + chip::DeviceLayer::PlatformMgrImpl().ScheduleResetInIdle(); +} + +CHIP_ERROR chip::NXP::App::AppCLIFreeRTOS::Init(void) +{ + if (!isShellInitialized) + { + int error = chip::Shell::Engine::Root().Init(); + + if (error != 0) + { + ChipLogError(Shell, "Streamer initialization failed: %d", error); + return CHIP_ERROR_INTERNAL; + } + + RegisterDefaultCommands(); + + if (xTaskCreate(&AppMatterCliTask, "AppMatterCli_task", MATTER_CLI_TASK_SIZE, NULL, 1, &AppMatterCliTaskHandle) != pdPASS) + { + ChipLogError(Shell, "Failed to start Matter CLI task"); + return CHIP_ERROR_INTERNAL; + } + + isShellInitialized = true; + } + return CHIP_NO_ERROR; +} diff --git a/examples/platform/nxp/common/matter_cli/source/AppCLIZephyr.cpp b/examples/platform/nxp/common/matter_cli/source/AppCLIZephyr.cpp new file mode 100644 index 00000000000000..1e64a91a3ab848 --- /dev/null +++ b/examples/platform/nxp/common/matter_cli/source/AppCLIZephyr.cpp @@ -0,0 +1,49 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppCLIZephyr.h" +#include "AppTaskBase.h" +#include + +void chip::NXP::App::AppCLIZephyr::ResetCmdHandle(void) +{ + chip::DeviceLayer::PlatformMgr().Shutdown(); +} + +// This returns an instance of this class. +chip::NXP::App::AppCLIZephyr & chip::NXP::App::AppCLIZephyr::GetDefaultInstance() +{ + static chip::NXP::App::AppCLIZephyr sAppCLI; + return sAppCLI; +} + +chip::NXP::App::AppCLIBase & chip::NXP::App::GetAppCLI() +{ + return chip::NXP::App::AppCLIZephyr::GetDefaultInstance(); +} + +CHIP_ERROR chip::NXP::App::AppCLIZephyr::Init(void) +{ + if (!isShellInitialized) + { + RegisterDefaultCommands(); + + isShellInitialized = true; + } + return CHIP_NO_ERROR; +} diff --git a/examples/platform/nxp/common/matter_cli/source/AppMatterCli.cpp b/examples/platform/nxp/common/matter_cli/source/AppMatterCli.cpp deleted file mode 100644 index e206ad0a2d4127..00000000000000 --- a/examples/platform/nxp/common/matter_cli/source/AppMatterCli.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* - * - * Copyright (c) 2022 Project CHIP Authors - * Copyright 2023-2024 NXP - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "AppMatterCli.h" -#include "AppTaskBase.h" -#include -#include -#include - -#ifdef CONFIG_CHIP_APP_DEVICE_TYPE_LAUNDRY_WASHER -#include -#endif /* CONFIG_CHIP_APP_DEVICE_TYPE_LAUNDRY_WASHER */ - -#ifdef ENABLE_CHIP_SHELL -#include "task.h" -#include -#include - -#define MATTER_CLI_TASK_SIZE ((configSTACK_DEPTH_TYPE) 2048 / sizeof(portSTACK_TYPE)) -#define MATTER_CLI_LOG(message) (streamer_printf(streamer_get(), message)) - -using namespace chip::Shell; -TaskHandle_t AppMatterCliTaskHandle; -static bool isShellInitialized = false; -#else -#define MATTER_CLI_LOG(...) -#endif /* ENABLE_CHIP_SHELL */ - -using namespace chip; -using namespace chip::app::Clusters; - -void AppMatterCliTask(void * args) -{ -#ifdef ENABLE_CHIP_SHELL - Engine::Root().RunMainLoop(); -#endif /* ENABLE_CHIP_SHELL */ -} - -/* Application Matter CLI commands */ - -CHIP_ERROR commissioningManager(int argc, char * argv[]) -{ - CHIP_ERROR error = CHIP_NO_ERROR; - if (strncmp(argv[0], "on", 2) == 0) - { - chip::NXP::App::GetAppTask().StartCommissioningHandler(); - } - else if (strncmp(argv[0], "off", 3) == 0) - { - chip::NXP::App::GetAppTask().StopCommissioningHandler(); - } - else - { - MATTER_CLI_LOG("wrong args should be either \"mattercommissioning on\" or \"mattercommissioning off\""); - error = CHIP_ERROR_INVALID_ARGUMENT; - } - return error; -} - -CHIP_ERROR cliFactoryReset(int argc, char * argv[]) -{ - chip::NXP::App::GetAppTask().FactoryResetHandler(); - return CHIP_NO_ERROR; -} - -CHIP_ERROR cliReset(int argc, char * argv[]) -{ - /* - Shutdown device before reboot, - this emits the ShutDown event, handles the server shutting down, - and stores in flash the total-operational-hours value. - */ - chip::DeviceLayer::PlatformMgr().Shutdown(); - chip::DeviceLayer::PlatformMgrImpl().ScheduleResetInIdle(); - return CHIP_NO_ERROR; -} - -CHIP_ERROR chip::NXP::App::AppMatterCli_RegisterCommands(void) -{ -#ifdef ENABLE_CHIP_SHELL - if (!isShellInitialized) - { - int error = Engine::Root().Init(); - if (error != 0) - { - ChipLogError(Shell, "Streamer initialization failed: %d", error); - return CHIP_ERROR_INTERNAL; - } - - /* Register common shell commands */ - cmd_misc_init(); - cmd_otcli_init(); -#if CHIP_SHELL_ENABLE_CMD_SERVER - cmd_app_server_init(); -#endif /* CHIP_SHELL_ENABLE_CMD_SERVER */ - - /* Register application commands */ - static const shell_command_t kCommands[] = { - { - .cmd_func = commissioningManager, - .cmd_name = "mattercommissioning", - .cmd_help = "Open/close the commissioning window. Usage : mattercommissioning [on|off]", - }, - { - .cmd_func = cliFactoryReset, - .cmd_name = "matterfactoryreset", - .cmd_help = "Perform a factory reset on the device", - }, - { - .cmd_func = cliReset, - .cmd_name = "matterreset", - .cmd_help = "Reset the device", - }, - }; - - Engine::Root().RegisterCommands(kCommands, sizeof(kCommands) / sizeof(kCommands[0])); - isShellInitialized = true; - } -#endif /* ENABLE_CHIP_SHELL */ - - return CHIP_NO_ERROR; -} - -CHIP_ERROR chip::NXP::App::AppMatterCli_StartTask() -{ -#ifdef ENABLE_CHIP_SHELL - if (xTaskCreate(&AppMatterCliTask, "AppMatterCli_task", MATTER_CLI_TASK_SIZE, NULL, 1, &AppMatterCliTaskHandle) != pdPASS) - { - ChipLogError(Shell, "Failed to start Matter CLI task"); - return CHIP_ERROR_INTERNAL; - } -#endif /* ENABLE_CHIP_SHELL */ - return CHIP_NO_ERROR; -} diff --git a/examples/thermostat/nxp/rt/rw61x/BUILD.gn b/examples/thermostat/nxp/rt/rw61x/BUILD.gn index 76610146809bca..dbd1bda583dea6 100644 --- a/examples/thermostat/nxp/rt/rw61x/BUILD.gn +++ b/examples/thermostat/nxp/rt/rw61x/BUILD.gn @@ -165,7 +165,6 @@ rt_executable("thermostat") { "${common_example_dir}/device_manager/source/CHIPDeviceManager.cpp", "${common_example_dir}/icd/source/ICDUtil.cpp", "${common_example_dir}/matter_button/source/AppMatterButtonEmpty.cpp", - "${common_example_dir}/matter_cli/source/AppMatterCli.cpp", ] deps = [ "${chip_root}/examples/${app_common_folder}" ] @@ -176,6 +175,10 @@ rt_executable("thermostat") { "${chip_root}/examples/shell/shell_common:shell_common", "${chip_root}/src/lib/shell:shell", ] + sources += [ + "${common_example_dir}/matter_cli/source/AppCLIBase.cpp", + "${common_example_dir}/matter_cli/source/AppCLIFreeRTOS.cpp", + ] } if (chip_enable_ota_requestor) { diff --git a/src/platform/nxp/common/ThreadStackManagerImpl.cpp b/src/platform/nxp/common/ThreadStackManagerImpl.cpp index c7f8ce7a5f0538..b15ad60f0e9578 100644 --- a/src/platform/nxp/common/ThreadStackManagerImpl.cpp +++ b/src/platform/nxp/common/ThreadStackManagerImpl.cpp @@ -39,8 +39,6 @@ #include "openthread-system.h" #include "ot_platform_common.h" -extern "C" CHIP_ERROR AppMatterCli_RegisterCommands(void); - /* * Empty content for otPlatCliUartProcess, as the openthread CLI * is managed by the matter cli if enabled. @@ -66,12 +64,6 @@ CHIP_ERROR ThreadStackManagerImpl::_InitThreadStack(void) */ otPlatAlarmInit(); - /* Make sure to initialize the Matter CLI which will include the ot-cli first. - * In fact it is mandatory to enable first the ot-cli before initializing the Matter openthread layer - * which would modify some contexts of the openthread instance. - */ - AppMatterCli_RegisterCommands(); - // Initialize the generic implementation base classes. err = GenericThreadStackManagerImpl_FreeRTOS::DoInit(); SuccessOrExit(err); diff --git a/third_party/openthread/ot-nxp b/third_party/openthread/ot-nxp index 2128e8dbe8af40..b8471857ab7b2c 160000 --- a/third_party/openthread/ot-nxp +++ b/third_party/openthread/ot-nxp @@ -1 +1 @@ -Subproject commit 2128e8dbe8af40d0cce55fc514a39a0b1376a95b +Subproject commit b8471857ab7b2c843c9ec5bc5d7e7711b2cd30a4