From 57fb2e1793c3a08e29be02b0e6089cd2eb81b1d9 Mon Sep 17 00:00:00 2001 From: Marius Tache <102153746+marius-alex-tache@users.noreply.github.com> Date: Tue, 1 Oct 2024 21:35:43 +0300 Subject: [PATCH 01/15] [NXP] App button manager rework (#35859) * [nxp][examples][common] Rework button manager Create an abstraction over SDK buttons. If an app needs a custom behavior for a specific button: - it can implement the Button interface, similar to the ButtonDefault implementation - it can implement a ButtonWithTimer derived class, to also have access to timer behavior, such as scheduling a delay for a specific action (e.g. factory reset after 6s) The ButtonManager is responsible with registering Button instances. The button callback is common across all buttons because it delegates the proper action handling to the button itself through the provided Button::Handle* API. The ButtonRegistration header provides an API that can be used by other components (e.g. AppTask) to initialize the ButtonManager and register buttons. A default implementation is provided. Some button examples are implemented: - ButtonApp - ButtonBle - ButtonDefault Check the corresponding header for a description of actions. Signed-off-by: marius-alex-tache * [nxp][examples][common] Update register buttons API usage Update AppEvent structure for some apps to take into account a way to pass extra args to App event processing. Signed-off-by: marius-alex-tache * [nxp][examples][mcxw71_k32w1] Rework button manager Update build system files for all impacted applications. Signed-off-by: marius-alex-tache * [nxp][examples][rw61x] Update empty button registration path Signed-off-by: marius-alex-tache * [nxp][examples][common] Add double click button action for ButtonBle Double clicking the ButtonBle will trigger a toggle of SIT mode request through the DSLS mechanism. Signed-off-by: marius-alex-tache * Restyled by gn * Restyled by prettier-markdown --------- Signed-off-by: marius-alex-tache Co-authored-by: Restyled.io --- .../all-clusters-app/nxp/rt/rw61x/BUILD.gn | 2 +- .../nxp/common/include/AppEvent.h | 1 + .../contact-sensor-app/nxp/k32w1/BUILD.gn | 10 +- .../contact-sensor-app/nxp/mcxw71/BUILD.gn | 10 +- .../laundry-washer-app/nxp/rt/rw61x/BUILD.gn | 2 +- .../nxp/common/include/AppEvent.h | 1 + examples/lighting-app/nxp/k32w1/BUILD.gn | 10 +- examples/lighting-app/nxp/k32w1/README.md | 4 +- examples/lighting-app/nxp/mcxw71/BUILD.gn | 10 +- .../nxp/common/main/include/AppEvent.h | 1 + examples/lock-app/nxp/k32w1/BUILD.gn | 10 +- examples/lock-app/nxp/mcxw71/BUILD.gn | 10 +- .../app_task/source/AppTaskFreeRTOS.cpp | 6 +- .../nxp/common/matter_button/include/Button.h | 52 ++++ .../common/matter_button/include/ButtonApp.h | 44 ++++ .../common/matter_button/include/ButtonBle.h | 48 ++++ .../matter_button/include/ButtonDefault.h | 43 +++ .../matter_button/include/ButtonManager.h | 58 ++++ ...AppMatterButton.h => ButtonRegistration.h} | 29 +- .../matter_button/include/ButtonWithTimer.h | 50 ++++ .../matter_button/source/AppMatterButton.cpp | 81 ------ .../common/matter_button/source/ButtonApp.cpp | 57 ++++ .../common/matter_button/source/ButtonBle.cpp | 142 ++++++++++ .../matter_button/source/ButtonDefault.cpp | 48 ++++ .../matter_button/source/ButtonManager.cpp | 67 +++++ .../source/ButtonRegistrationAppAndBle.cpp | 37 +++ .../source/ButtonRegistrationDefault.cpp | 33 +++ ...nEmpty.cpp => ButtonRegistrationEmpty.cpp} | 11 +- .../matter_button/source/ButtonWithTimer.cpp | 86 ++++++ .../nxp/mcxw71_k32w1/button/ButtonManager.cpp | 247 ------------------ .../nxp/mcxw71_k32w1/button/ButtonManager.h | 118 --------- .../platform/nxp/mcxw71_k32w1/rpc/AppRpc.cpp | 15 +- examples/thermostat/nxp/rt/rw61x/BUILD.gn | 2 +- 33 files changed, 837 insertions(+), 508 deletions(-) create mode 100644 examples/platform/nxp/common/matter_button/include/Button.h create mode 100644 examples/platform/nxp/common/matter_button/include/ButtonApp.h create mode 100644 examples/platform/nxp/common/matter_button/include/ButtonBle.h create mode 100644 examples/platform/nxp/common/matter_button/include/ButtonDefault.h create mode 100644 examples/platform/nxp/common/matter_button/include/ButtonManager.h rename examples/platform/nxp/common/matter_button/include/{AppMatterButton.h => ButtonRegistration.h} (60%) create mode 100644 examples/platform/nxp/common/matter_button/include/ButtonWithTimer.h delete mode 100644 examples/platform/nxp/common/matter_button/source/AppMatterButton.cpp create mode 100644 examples/platform/nxp/common/matter_button/source/ButtonApp.cpp create mode 100644 examples/platform/nxp/common/matter_button/source/ButtonBle.cpp create mode 100644 examples/platform/nxp/common/matter_button/source/ButtonDefault.cpp create mode 100644 examples/platform/nxp/common/matter_button/source/ButtonManager.cpp create mode 100644 examples/platform/nxp/common/matter_button/source/ButtonRegistrationAppAndBle.cpp create mode 100644 examples/platform/nxp/common/matter_button/source/ButtonRegistrationDefault.cpp rename examples/platform/nxp/common/matter_button/source/{AppMatterButtonEmpty.cpp => ButtonRegistrationEmpty.cpp} (77%) create mode 100644 examples/platform/nxp/common/matter_button/source/ButtonWithTimer.cpp delete mode 100644 examples/platform/nxp/mcxw71_k32w1/button/ButtonManager.cpp delete mode 100644 examples/platform/nxp/mcxw71_k32w1/button/ButtonManager.h diff --git a/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn b/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn index bdc878cc0f5250..19fa822ec24688 100644 --- a/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn +++ b/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn @@ -170,7 +170,7 @@ rt_executable("all_cluster_app") { "${common_example_dir}/device_callbacks/source/CommonDeviceCallbacks.cpp", "${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_button/source/ButtonRegistrationEmpty.cpp", ] deps = [ diff --git a/examples/contact-sensor-app/nxp/common/include/AppEvent.h b/examples/contact-sensor-app/nxp/common/include/AppEvent.h index b292afaddf8c18..562c0b4df66dcb 100644 --- a/examples/contact-sensor-app/nxp/common/include/AppEvent.h +++ b/examples/contact-sensor-app/nxp/common/include/AppEvent.h @@ -24,4 +24,5 @@ typedef void (*EventHandler)(const AppEvent &); struct AppEvent { EventHandler Handler; + void * extra; }; diff --git a/examples/contact-sensor-app/nxp/k32w1/BUILD.gn b/examples/contact-sensor-app/nxp/k32w1/BUILD.gn index 8e215d4c7d6517..1b57e5f3cf9061 100644 --- a/examples/contact-sensor-app/nxp/k32w1/BUILD.gn +++ b/examples/contact-sensor-app/nxp/k32w1/BUILD.gn @@ -149,6 +149,11 @@ mcxw71_k32w1_executable("contact_sensor_app") { "${common_example_dir}/clusters/source/ZclCallbacks.cpp", "${common_example_dir}/device_callbacks/source/CommonDeviceCallbacks.cpp", "${common_example_dir}/device_manager/source/CHIPDeviceManager.cpp", + "${common_example_dir}/matter_button/source/ButtonApp.cpp", + "${common_example_dir}/matter_button/source/ButtonBle.cpp", + "${common_example_dir}/matter_button/source/ButtonManager.cpp", + "${common_example_dir}/matter_button/source/ButtonRegistrationAppAndBle.cpp", + "${common_example_dir}/matter_button/source/ButtonWithTimer.cpp", "${common_example_dir}/operational_keystore/source/OperationalKeystoreS200.cpp", "${example_platform_dir}/factory_data/source/AppFactoryDataExample.cpp", ] @@ -193,10 +198,7 @@ mcxw71_k32w1_executable("contact_sensor_app") { "${example_platform_dir}/button", ] - sources += [ - "${example_platform_dir}/button/ButtonManager.cpp", - "${example_platform_dir}/clusters/Identify.cpp", - ] + sources += [ "${example_platform_dir}/clusters/Identify.cpp" ] if (chip_enable_ota_requestor) { sources += [ "${example_platform_dir}/ota/OtaUtils.cpp" ] diff --git a/examples/contact-sensor-app/nxp/mcxw71/BUILD.gn b/examples/contact-sensor-app/nxp/mcxw71/BUILD.gn index cf22ec5c658509..8bba2393f8fc43 100644 --- a/examples/contact-sensor-app/nxp/mcxw71/BUILD.gn +++ b/examples/contact-sensor-app/nxp/mcxw71/BUILD.gn @@ -148,6 +148,11 @@ mcxw71_k32w1_executable("contact_sensor_app") { "${common_example_dir}/clusters/source/ZclCallbacks.cpp", "${common_example_dir}/device_callbacks/source/CommonDeviceCallbacks.cpp", "${common_example_dir}/device_manager/source/CHIPDeviceManager.cpp", + "${common_example_dir}/matter_button/source/ButtonApp.cpp", + "${common_example_dir}/matter_button/source/ButtonBle.cpp", + "${common_example_dir}/matter_button/source/ButtonManager.cpp", + "${common_example_dir}/matter_button/source/ButtonRegistrationAppAndBle.cpp", + "${common_example_dir}/matter_button/source/ButtonWithTimer.cpp", "${common_example_dir}/operational_keystore/source/OperationalKeystoreS200.cpp", "${example_platform_dir}/factory_data/source/AppFactoryDataExample.cpp", ] @@ -192,10 +197,7 @@ mcxw71_k32w1_executable("contact_sensor_app") { "${example_platform_dir}/button", ] - sources += [ - "${example_platform_dir}/button/ButtonManager.cpp", - "${example_platform_dir}/clusters/Identify.cpp", - ] + sources += [ "${example_platform_dir}/clusters/Identify.cpp" ] if (chip_enable_ota_requestor) { sources += [ "${example_platform_dir}/ota/OtaUtils.cpp" ] diff --git a/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn b/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn index cb0b7ba0a96439..7f22eca6b2c085 100644 --- a/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn +++ b/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn @@ -171,7 +171,7 @@ rt_executable("laundry-washer") { "${common_example_dir}/device_callbacks/source/CommonDeviceCallbacks.cpp", "${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_button/source/ButtonRegistrationEmpty.cpp", ] deps = [ diff --git a/examples/lighting-app/nxp/common/include/AppEvent.h b/examples/lighting-app/nxp/common/include/AppEvent.h index b292afaddf8c18..562c0b4df66dcb 100644 --- a/examples/lighting-app/nxp/common/include/AppEvent.h +++ b/examples/lighting-app/nxp/common/include/AppEvent.h @@ -24,4 +24,5 @@ typedef void (*EventHandler)(const AppEvent &); struct AppEvent { EventHandler Handler; + void * extra; }; diff --git a/examples/lighting-app/nxp/k32w1/BUILD.gn b/examples/lighting-app/nxp/k32w1/BUILD.gn index 54030a789763ea..57a1b7921fcaf9 100644 --- a/examples/lighting-app/nxp/k32w1/BUILD.gn +++ b/examples/lighting-app/nxp/k32w1/BUILD.gn @@ -156,6 +156,11 @@ mcxw71_k32w1_executable("light_app") { "${common_example_dir}/clusters/source/ZclCallbacks.cpp", "${common_example_dir}/device_callbacks/source/CommonDeviceCallbacks.cpp", "${common_example_dir}/device_manager/source/CHIPDeviceManager.cpp", + "${common_example_dir}/matter_button/source/ButtonApp.cpp", + "${common_example_dir}/matter_button/source/ButtonBle.cpp", + "${common_example_dir}/matter_button/source/ButtonManager.cpp", + "${common_example_dir}/matter_button/source/ButtonRegistrationAppAndBle.cpp", + "${common_example_dir}/matter_button/source/ButtonWithTimer.cpp", "${common_example_dir}/operational_keystore/source/OperationalKeystoreS200.cpp", "${example_platform_dir}/factory_data/source/AppFactoryDataExample.cpp", ] @@ -180,10 +185,7 @@ mcxw71_k32w1_executable("light_app") { "${example_platform_dir}/button", ] - sources += [ - "${example_platform_dir}/button/ButtonManager.cpp", - "${example_platform_dir}/clusters/Identify.cpp", - ] + sources += [ "${example_platform_dir}/clusters/Identify.cpp" ] if (chip_enable_ota_requestor) { sources += [ "${example_platform_dir}/ota/OtaUtils.cpp" ] diff --git a/examples/lighting-app/nxp/k32w1/README.md b/examples/lighting-app/nxp/k32w1/README.md index c47449bf249490..d61ab1e42431d4 100644 --- a/examples/lighting-app/nxp/k32w1/README.md +++ b/examples/lighting-app/nxp/k32w1/README.md @@ -220,8 +220,8 @@ by running: The console should have already been installed in the virtual environment. From the `chip-console`, a user can send specific commands to the device. -For button commands, please run `rpcs.chip.rpc.Button.Event(index)` based on the -table below: +For button commands, please run `rpcs.chip.rpc.Button.Event(idx=index)` based on +the table below: | index | action | | ----- | --------------------------------------------- | diff --git a/examples/lighting-app/nxp/mcxw71/BUILD.gn b/examples/lighting-app/nxp/mcxw71/BUILD.gn index efd3af6fd5e19a..f7e9c42b6e752c 100644 --- a/examples/lighting-app/nxp/mcxw71/BUILD.gn +++ b/examples/lighting-app/nxp/mcxw71/BUILD.gn @@ -156,6 +156,11 @@ mcxw71_k32w1_executable("light_app") { "${common_example_dir}/clusters/source/ZclCallbacks.cpp", "${common_example_dir}/device_callbacks/source/CommonDeviceCallbacks.cpp", "${common_example_dir}/device_manager/source/CHIPDeviceManager.cpp", + "${common_example_dir}/matter_button/source/ButtonApp.cpp", + "${common_example_dir}/matter_button/source/ButtonBle.cpp", + "${common_example_dir}/matter_button/source/ButtonManager.cpp", + "${common_example_dir}/matter_button/source/ButtonRegistrationAppAndBle.cpp", + "${common_example_dir}/matter_button/source/ButtonWithTimer.cpp", "${common_example_dir}/operational_keystore/source/OperationalKeystoreS200.cpp", "${example_platform_dir}/factory_data/source/AppFactoryDataExample.cpp", ] @@ -183,10 +188,7 @@ mcxw71_k32w1_executable("light_app") { "${example_platform_dir}/button", ] - sources += [ - "${example_platform_dir}/button/ButtonManager.cpp", - "${example_platform_dir}/clusters/Identify.cpp", - ] + sources += [ "${example_platform_dir}/clusters/Identify.cpp" ] if (chip_enable_ota_requestor) { sources += [ "${example_platform_dir}/ota/OtaUtils.cpp" ] diff --git a/examples/lock-app/nxp/common/main/include/AppEvent.h b/examples/lock-app/nxp/common/main/include/AppEvent.h index 065078a52e7a72..06522efbee9f70 100644 --- a/examples/lock-app/nxp/common/main/include/AppEvent.h +++ b/examples/lock-app/nxp/common/main/include/AppEvent.h @@ -48,4 +48,5 @@ struct AppEvent }; EventHandler Handler; + void * extra; }; diff --git a/examples/lock-app/nxp/k32w1/BUILD.gn b/examples/lock-app/nxp/k32w1/BUILD.gn index 602398e0d604b4..c10cc05475ffee 100644 --- a/examples/lock-app/nxp/k32w1/BUILD.gn +++ b/examples/lock-app/nxp/k32w1/BUILD.gn @@ -154,6 +154,11 @@ mcxw71_k32w1_executable("lock_app") { sources += [ "${common_example_dir}/app_task/source/AppTaskBase.cpp", "${common_example_dir}/app_task/source/AppTaskFreeRTOS.cpp", + "${common_example_dir}/matter_button/source/ButtonApp.cpp", + "${common_example_dir}/matter_button/source/ButtonBle.cpp", + "${common_example_dir}/matter_button/source/ButtonManager.cpp", + "${common_example_dir}/matter_button/source/ButtonRegistrationAppAndBle.cpp", + "${common_example_dir}/matter_button/source/ButtonWithTimer.cpp", #"${common_example_dir}/clusters/source/ZclCallbacks.cpp", "${common_example_dir}/device_callbacks/source/CommonDeviceCallbacks.cpp", @@ -221,10 +226,7 @@ mcxw71_k32w1_executable("lock_app") { "${example_platform_dir}/button", ] - sources += [ - "${example_platform_dir}/button/ButtonManager.cpp", - "${example_platform_dir}/clusters/Identify.cpp", - ] + sources += [ "${example_platform_dir}/clusters/Identify.cpp" ] if (chip_enable_ota_requestor) { sources += [ "${example_platform_dir}/ota/OtaUtils.cpp" ] diff --git a/examples/lock-app/nxp/mcxw71/BUILD.gn b/examples/lock-app/nxp/mcxw71/BUILD.gn index 6d105f16ffd163..0c34d3d8083a20 100644 --- a/examples/lock-app/nxp/mcxw71/BUILD.gn +++ b/examples/lock-app/nxp/mcxw71/BUILD.gn @@ -154,6 +154,11 @@ mcxw71_k32w1_executable("lock_app") { sources += [ "${common_example_dir}/app_task/source/AppTaskBase.cpp", "${common_example_dir}/app_task/source/AppTaskFreeRTOS.cpp", + "${common_example_dir}/matter_button/source/ButtonApp.cpp", + "${common_example_dir}/matter_button/source/ButtonBle.cpp", + "${common_example_dir}/matter_button/source/ButtonManager.cpp", + "${common_example_dir}/matter_button/source/ButtonRegistrationAppAndBle.cpp", + "${common_example_dir}/matter_button/source/ButtonWithTimer.cpp", #"${common_example_dir}/clusters/source/ZclCallbacks.cpp", "${common_example_dir}/device_callbacks/source/CommonDeviceCallbacks.cpp", @@ -221,10 +226,7 @@ mcxw71_k32w1_executable("lock_app") { "${example_platform_dir}/button", ] - sources += [ - "${example_platform_dir}/button/ButtonManager.cpp", - "${example_platform_dir}/clusters/Identify.cpp", - ] + sources += [ "${example_platform_dir}/clusters/Identify.cpp" ] if (chip_enable_ota_requestor) { sources += [ "${example_platform_dir}/ota/OtaUtils.cpp" ] diff --git a/examples/platform/nxp/common/app_task/source/AppTaskFreeRTOS.cpp b/examples/platform/nxp/common/app_task/source/AppTaskFreeRTOS.cpp index 5b8e3eab70be40..ec394b4ac40fc4 100644 --- a/examples/platform/nxp/common/app_task/source/AppTaskFreeRTOS.cpp +++ b/examples/platform/nxp/common/app_task/source/AppTaskFreeRTOS.cpp @@ -21,7 +21,7 @@ #include #include -#include "AppMatterButton.h" +#include "ButtonRegistration.h" #include "CHIPDeviceManager.h" #include @@ -98,10 +98,10 @@ CHIP_ERROR chip::NXP::App::AppTaskFreeRTOS::AppMatter_Register() #endif /* Register Matter buttons */ - err = AppMatterButton_registerButtons(); + err = chip::NXP::App::RegisterButtons(); if (err != CHIP_NO_ERROR) { - ChipLogError(DeviceLayer, "Error during AppMatterButton_registerButtons"); + ChipLogError(DeviceLayer, "Error during button registration"); return err; } return err; diff --git a/examples/platform/nxp/common/matter_button/include/Button.h b/examples/platform/nxp/common/matter_button/include/Button.h new file mode 100644 index 00000000000000..7485cf9bd88f76 --- /dev/null +++ b/examples/platform/nxp/common/matter_button/include/Button.h @@ -0,0 +1,52 @@ +/* + * + * 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 "fsl_component_button.h" + +#include + +namespace chip::NXP::App { + +/** + * @brief This class is an abstraction over an SDK button. + * + */ +class Button +{ +public: + using Callback = button_status_t (*)(void * handle, button_callback_message_t * message, void * param); + + virtual ~Button() = default; + + virtual CHIP_ERROR Init() = 0; + virtual void HandleShortPress() = 0; + virtual void HandleLongPress() = 0; + virtual void HandleDoubleClick() = 0; + + /** + * @brief This is an SDK handle for a button. + * + * It should be set in the Init method, based on a newly defined + * handle or an already defined handle owned by the SDK. + */ + button_handle_t handle = nullptr; +}; + +} // namespace chip::NXP::App diff --git a/examples/platform/nxp/common/matter_button/include/ButtonApp.h b/examples/platform/nxp/common/matter_button/include/ButtonApp.h new file mode 100644 index 00000000000000..3ace28f30a4094 --- /dev/null +++ b/examples/platform/nxp/common/matter_button/include/ButtonApp.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 "Button.h" + +namespace chip::NXP::App { +/** + * @brief This class implements a custom app button behavior. + * + * | Action | Effect | + * | ------------ | --------------------------------- | + * | Short press | Switch a cluster attribute state | + * | Long press | Schedule a soft reset taking into | + * | | account Matter shutdown mechanism | + * | Double click | Do nothing | + * + */ +class ButtonApp : public Button +{ +public: + virtual CHIP_ERROR Init() override; + virtual void HandleShortPress() override; + virtual void HandleLongPress() override; + virtual void HandleDoubleClick() override; +}; + +} // namespace chip::NXP::App diff --git a/examples/platform/nxp/common/matter_button/include/ButtonBle.h b/examples/platform/nxp/common/matter_button/include/ButtonBle.h new file mode 100644 index 00000000000000..75b35f25d355f1 --- /dev/null +++ b/examples/platform/nxp/common/matter_button/include/ButtonBle.h @@ -0,0 +1,48 @@ +/* + * + * 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 "ButtonWithTimer.h" + +namespace chip::NXP::App { + +/** + * @brief This class implements a customized default button behavior. + * + * | Action | Effect | + * | ------------ | -------------------------------------------------- | + * | Short press | If a factory reset is scheduled, cancel it. | + * | | Else if the device is commissioned and a factory | + * | | reset is not scheduled, switch to ICD active mode. | + * | | Otherwise, switch commissioning state. | + * | Long press | Schedule a factory reset | + * | Double click | Toggle SIT mode request through DSLS mechanism | + * + */ +class ButtonBle : public ButtonWithTimer +{ +public: + virtual CHIP_ERROR Init() override; + virtual void HandleShortPress() override; + virtual void HandleLongPress() override; + virtual void HandleDoubleClick() override; + virtual void HandleTimerExpire() override; +}; + +} // namespace chip::NXP::App diff --git a/examples/platform/nxp/common/matter_button/include/ButtonDefault.h b/examples/platform/nxp/common/matter_button/include/ButtonDefault.h new file mode 100644 index 00000000000000..4241f0465acf25 --- /dev/null +++ b/examples/platform/nxp/common/matter_button/include/ButtonDefault.h @@ -0,0 +1,43 @@ +/* + * + * 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 "Button.h" + +namespace chip::NXP::App { +/** + * @brief This class implements a default button behavior. + * + * | Action | Effect | + * | ------------ | -------------------------- | + * | Short press | Switch commissioning state | + * | Long press | Schedule a factory reset | + * | Double click | Do nothing | + * + */ +class ButtonDefault : public Button +{ +public: + virtual CHIP_ERROR Init() override; + virtual void HandleShortPress() override; + virtual void HandleLongPress() override; + virtual void HandleDoubleClick() override; +}; + +} // namespace chip::NXP::App diff --git a/examples/platform/nxp/common/matter_button/include/ButtonManager.h b/examples/platform/nxp/common/matter_button/include/ButtonManager.h new file mode 100644 index 00000000000000..44ad191e2eef12 --- /dev/null +++ b/examples/platform/nxp/common/matter_button/include/ButtonManager.h @@ -0,0 +1,58 @@ +/* + * + * 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 "Button.h" + +#include + +namespace chip::NXP::App { + +/** + * @brief This class describes a manager over Button operations. + * + */ +class ButtonManager +{ +public: + static ButtonManager sInstance; + + CHIP_ERROR Init(); + + /** + * @brief API for registering a Button object. + * + */ + CHIP_ERROR RegisterButton(Button & button); + + /** + * @brief Generic callback for all registered buttons. + * + * Event handling is delegated to Button objects. + * + */ + static button_status_t HandleCallbacks(void * buttonHandle, button_callback_message_t * message, void * callbackParam); +}; + +inline ButtonManager & ButtonMgr() +{ + return ButtonManager::sInstance; +} + +} // namespace chip::NXP::App diff --git a/examples/platform/nxp/common/matter_button/include/AppMatterButton.h b/examples/platform/nxp/common/matter_button/include/ButtonRegistration.h similarity index 60% rename from examples/platform/nxp/common/matter_button/include/AppMatterButton.h rename to examples/platform/nxp/common/matter_button/include/ButtonRegistration.h index dd00a5c80d719f..c47eeba7acbddc 100644 --- a/examples/platform/nxp/common/matter_button/include/AppMatterButton.h +++ b/examples/platform/nxp/common/matter_button/include/ButtonRegistration.h @@ -1,7 +1,6 @@ /* * - * Copyright (c) 2022 Project CHIP Authors - * Copyright 2023-2024 NXP + * Copyright (c) 2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,29 +16,17 @@ * limitations under the License. */ -#ifndef _MATTER_BUTTON_H_ -#define _MATTER_BUTTON_H_ +#pragma once #include -#ifdef __cplusplus -extern "C" { -#endif +namespace chip::NXP::App { -namespace chip { -namespace NXP { -namespace App { /** - * API allowing to register matter buttons + * @brief API used by app task to register buttons. + * + * The default implementation will register a single ButtonDefault instance. */ -CHIP_ERROR AppMatterButton_registerButtons(void); - -} // namespace App -} // namespace NXP -} // namespace chip - -#ifdef __cplusplus -} -#endif +CHIP_ERROR RegisterButtons(); -#endif /* _MATTER_BUTTON_H_ */ +} // namespace chip::NXP::App diff --git a/examples/platform/nxp/common/matter_button/include/ButtonWithTimer.h b/examples/platform/nxp/common/matter_button/include/ButtonWithTimer.h new file mode 100644 index 00000000000000..6620bae9ec0288 --- /dev/null +++ b/examples/platform/nxp/common/matter_button/include/ButtonWithTimer.h @@ -0,0 +1,50 @@ +/* + * + * 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 "Button.h" +#include "FreeRTOS.h" +#include "timers.h" + +namespace chip::NXP::App { +/** + * @brief This class implements a default button with timer behavior. + * + * This class provides an API for starting/cancelling the timer. It can + * be used by derived classes to define their own timer handler behavior. + */ +class ButtonWithTimer : public Button +{ +public: + ButtonWithTimer(); + + virtual CHIP_ERROR Init() override; + virtual void HandleShortPress() override; + virtual void HandleLongPress() override; + virtual void HandleDoubleClick() override; + + virtual void HandleTimerExpire(); + + void CancelTimer(); + void StartTimer(uint32_t aTimeoutInMs); + + TimerHandle_t timer; +}; + +} // namespace chip::NXP::App diff --git a/examples/platform/nxp/common/matter_button/source/AppMatterButton.cpp b/examples/platform/nxp/common/matter_button/source/AppMatterButton.cpp deleted file mode 100644 index be5adc975c2f79..00000000000000 --- a/examples/platform/nxp/common/matter_button/source/AppMatterButton.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * - * Copyright (c) 2022 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 "AppMatterButton.h" -#include "AppTaskBase.h" -#include "board_comp.h" -#include "fsl_component_timer_manager.h" -#include "fwk_platform.h" -#include - -static BUTTON_HANDLE_DEFINE(sdkButtonHandle); - -static button_status_t AppMatterButton_ButtonCallback(void * buttonHandle, button_callback_message_t * message, - void * callbackParam) -{ - switch (message->event) - { - case kBUTTON_EventShortPress: - case kBUTTON_EventOneClick: - chip::NXP::App::GetAppTask().SwitchCommissioningStateHandler(); - break; - case kBUTTON_EventLongPress: - chip::NXP::App::GetAppTask().FactoryResetHandler(); - break; - default: - break; - } - return kStatus_BUTTON_Success; -} - -CHIP_ERROR chip::NXP::App::AppMatterButton_registerButtons(void) -{ - button_config_t buttonConfig; - button_status_t bStatus; - CHIP_ERROR err = CHIP_NO_ERROR; - - do - { - /* Init the Platform Timer Manager */ - if (PLATFORM_InitTimerManager() != 0) - { - err = CHIP_ERROR_UNEXPECTED_EVENT; - ChipLogError(DeviceLayer, "tmr init error"); - break; - } - - /* Init board buttons */ - bStatus = BOARD_InitButton((button_handle_t) sdkButtonHandle); - if (bStatus != kStatus_BUTTON_Success) - { - err = CHIP_ERROR_UNEXPECTED_EVENT; - ChipLogError(DeviceLayer, "button init error"); - break; - } - bStatus = BUTTON_InstallCallback((button_handle_t) sdkButtonHandle, AppMatterButton_ButtonCallback, NULL); - - if (bStatus != kStatus_BUTTON_Success) - { - err = CHIP_ERROR_UNEXPECTED_EVENT; - ChipLogError(DeviceLayer, "button init error"); - break; - } - } while (0); - - return err; -} diff --git a/examples/platform/nxp/common/matter_button/source/ButtonApp.cpp b/examples/platform/nxp/common/matter_button/source/ButtonApp.cpp new file mode 100644 index 00000000000000..3b03b413ec2a93 --- /dev/null +++ b/examples/platform/nxp/common/matter_button/source/ButtonApp.cpp @@ -0,0 +1,57 @@ +/* + * + * 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 "ButtonApp.h" +#include "AppTaskBase.h" + +extern "C" { +#include "app.h" +#include "board_comp.h" +} + +CHIP_ERROR chip::NXP::App::ButtonApp::Init() +{ + // Button is initialized in otSysInit, when APP_InitServices is called. + // Overwrite the handle to reference the SDK handle. + handle = &g_buttonHandle[1]; + + return CHIP_NO_ERROR; +} + +void chip::NXP::App::ButtonApp::HandleShortPress() +{ + chip::DeviceLayer::PlatformMgr().ScheduleWork( + [](intptr_t arg) { + auto status = chip::NXP::App::GetAppTask().ProcessSetStateClusterHandler(); + if (status != CHIP_NO_ERROR) + { + ChipLogProgress(DeviceLayer, "Error when updating cluster attribute"); + } + }, + (intptr_t) nullptr); +} + +void chip::NXP::App::ButtonApp::HandleLongPress() +{ + chip::DeviceLayer::PlatformMgrImpl().CleanReset(); +} + +void chip::NXP::App::ButtonApp::HandleDoubleClick() +{ + /* Currently not mapped to any action */ +} diff --git a/examples/platform/nxp/common/matter_button/source/ButtonBle.cpp b/examples/platform/nxp/common/matter_button/source/ButtonBle.cpp new file mode 100644 index 00000000000000..447b0b04529825 --- /dev/null +++ b/examples/platform/nxp/common/matter_button/source/ButtonBle.cpp @@ -0,0 +1,142 @@ +/* + * + * 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 "ButtonBle.h" +#include "AppTaskBase.h" +#include "BLEApplicationManager.h" +#include "UserInterfaceFeedback.h" + +extern "C" { +#include "app.h" +#include "board_comp.h" +} + +#include + +/** + * @brief Timeout (ms) for factory data reset action. + * + * During this timeout, the factory reset action can be cancelled by pressing a button. + */ +#ifndef BLE_BUTTON_FACTORY_RESET_TIMEOUT_MS +#define BLE_BUTTON_FACTORY_RESET_TIMEOUT_MS 6000 +#endif + +static void BleHandleLongPress(const AppEvent & event) +{ + auto & button = *static_cast(event.extra); + + if (xTimerIsTimerActive(button.timer)) + { + button.CancelTimer(); +#if CONFIG_ENABLE_FEEDBACK + FeedbackMgr().RestoreState(); +#endif + ChipLogProgress(DeviceLayer, "Factory Reset was cancelled!"); + } + else + { + uint32_t resetTimeout = BLE_BUTTON_FACTORY_RESET_TIMEOUT_MS; + ChipLogProgress(DeviceLayer, "Factory Reset Triggered. Push the RESET button within %lu ms to cancel!", resetTimeout); + +#if CONFIG_ENABLE_FEEDBACK + FeedbackMgr().DisplayOnAction(UserInterfaceFeedback::Action::kFactoryReset); +#endif + button.StartTimer(resetTimeout); + } +} + +static void BleHandleShortPress(const AppEvent & event) +{ + auto & button = *static_cast(event.extra); + if (xTimerIsTimerActive(button.timer)) + { + // If a factory reset is scheduled, pressing the BLE button will cancel it. + BleHandleLongPress(event); + return; + } + +#if CHIP_CONFIG_ENABLE_ICD_LIT + if (chip::DeviceLayer::ConfigurationMgr().IsFullyProvisioned()) + { + // If the device is commissioned and a factory reset is not scheduled, switch to active mode. + chip::DeviceLayer::PlatformMgr().ScheduleWork( + [](intptr_t arg) { chip::app::ICDNotifier::GetInstance().NotifyNetworkActivityNotification(); }, 0); + return; + } +#endif + + chip::NXP::App::GetAppTask().SwitchCommissioningStateHandler(); + chip::NXP::App::BleAppMgr().EnableMultipleConnectionsHandler(); +} + +CHIP_ERROR chip::NXP::App::ButtonBle::Init() +{ + // Button is initialized in otSysInit, when APP_InitServices is called. + // Overwrite the handle to reference the SDK handle. + handle = &g_buttonHandle[0]; + + return CHIP_NO_ERROR; +} + +void chip::NXP::App::ButtonBle::HandleShortPress() +{ + AppEvent event; + event.Handler = BleHandleShortPress; + event.extra = this; + chip::NXP::App::GetAppTask().PostEvent(event); +} + +void chip::NXP::App::ButtonBle::HandleLongPress() +{ + AppEvent event; + event.Handler = BleHandleLongPress; + event.extra = this; + chip::NXP::App::GetAppTask().PostEvent(event); +} + +void chip::NXP::App::ButtonBle::HandleDoubleClick() +{ +#if (CHIP_CONFIG_ENABLE_ICD_LIT && CHIP_CONFIG_ENABLE_ICD_DSLS) + static bool sitModeRequested = false; + + if (chip::DeviceLayer::ConfigurationMgr().IsFullyProvisioned()) + { + if (!sitModeRequested) + { + chip::DeviceLayer::PlatformMgr().ScheduleWork( + [](intptr_t arg) { chip::app::ICDNotifier::GetInstance().NotifySITModeRequestNotification(); }, 0); + sitModeRequested = true; + } + else + { + chip::DeviceLayer::PlatformMgr().ScheduleWork( + [](intptr_t arg) { chip::app::ICDNotifier::GetInstance().NotifySITModeRequestWithdrawal(); }, 0); + sitModeRequested = false; + } + } +#endif +} + +void chip::NXP::App::ButtonBle::HandleTimerExpire() +{ + ChipLogProgress(DeviceLayer, "Device will factory reset..."); + + // Actually trigger Factory Reset + chip::Server::GetInstance().ScheduleFactoryReset(); +} diff --git a/examples/platform/nxp/common/matter_button/source/ButtonDefault.cpp b/examples/platform/nxp/common/matter_button/source/ButtonDefault.cpp new file mode 100644 index 00000000000000..526bcd3e8bd5a3 --- /dev/null +++ b/examples/platform/nxp/common/matter_button/source/ButtonDefault.cpp @@ -0,0 +1,48 @@ +/* + * + * 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 "ButtonDefault.h" +#include "AppTaskBase.h" +#include "board_comp.h" + +BUTTON_HANDLE_DEFINE(sHandle); + +CHIP_ERROR chip::NXP::App::ButtonDefault::Init() +{ + handle = sHandle; + + auto status = BOARD_InitButton(handle); + VerifyOrReturnError(status == kStatus_BUTTON_Success, CHIP_ERROR_UNEXPECTED_EVENT); + + return CHIP_NO_ERROR; +} + +void chip::NXP::App::ButtonDefault::HandleShortPress() +{ + chip::NXP::App::GetAppTask().SwitchCommissioningStateHandler(); +} + +void chip::NXP::App::ButtonDefault::HandleLongPress() +{ + chip::NXP::App::GetAppTask().FactoryResetHandler(); +} + +void chip::NXP::App::ButtonDefault::HandleDoubleClick() +{ + /* Currently not mapped to any action */ +} diff --git a/examples/platform/nxp/common/matter_button/source/ButtonManager.cpp b/examples/platform/nxp/common/matter_button/source/ButtonManager.cpp new file mode 100644 index 00000000000000..046337397a3c3c --- /dev/null +++ b/examples/platform/nxp/common/matter_button/source/ButtonManager.cpp @@ -0,0 +1,67 @@ +/* + * + * 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 "ButtonManager.h" +#include "fwk_platform.h" + +#include +#include + +chip::NXP::App::ButtonManager chip::NXP::App::ButtonManager::sInstance; + +CHIP_ERROR chip::NXP::App::ButtonManager::Init() +{ + VerifyOrReturnError(PLATFORM_InitTimerManager() >= 0, CHIP_ERROR_UNEXPECTED_EVENT); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR chip::NXP::App::ButtonManager::RegisterButton(Button & button) +{ + ReturnErrorOnFailure(button.Init()); + VerifyOrReturnError(button.handle != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + + auto status = BUTTON_InstallCallback(button.handle, ButtonManager::HandleCallbacks, &button); + VerifyOrReturnError(status == kStatus_BUTTON_Success, CHIP_ERROR_UNEXPECTED_EVENT); + + return CHIP_NO_ERROR; +} + +button_status_t chip::NXP::App::ButtonManager::HandleCallbacks(void * buttonHandle, button_callback_message_t * message, + void * callbackParam) +{ + auto * button = static_cast