From 112499921f27ef866820518b3fef3d42d354d0e6 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Wed, 15 Dec 2021 11:28:14 -0800 Subject: [PATCH] Implement event support for switch cluster (#13036) --- .../esp32/main/CMakeLists.txt | 1 + examples/all-clusters-app/mbed/CMakeLists.txt | 1 + examples/bridge-app/esp32/main/CMakeLists.txt | 1 + .../lighting-common/lighting-app.zap | 20 ++ examples/lighting-app/mbed/CMakeLists.txt | 1 + examples/lighting-app/telink/CMakeLists.txt | 1 + examples/lock-app/esp32/main/CMakeLists.txt | 2 + examples/lock-app/mbed/CMakeLists.txt | 1 + .../esp32/main/CMakeLists.txt | 1 + .../esp32/main/CMakeLists.txt | 1 + .../esp32/main/CMakeLists.txt | 1 + .../general-commissioning-server.cpp | 9 +- .../network-commissioning.cpp | 4 +- .../clusters/switch-server/switch-server.cpp | 200 ++++++++++++++++++ src/app/util/util.cpp | 1 - src/app/zap_cluster_list.py | 2 +- .../{internal => }/DeviceControlServer.h | 61 +++++- src/include/platform/PlatformManager.h | 4 +- src/include/platform/ThreadStackManager.h | 4 +- src/platform/BUILD.gn | 2 +- src/platform/DeviceControlServer.cpp | 4 +- src/platform/Linux/PlatformManagerImpl.cpp | 87 ++++++++ src/platform/Linux/PlatformManagerImpl.h | 1 + .../PluginApplicationCallbacks.h | 1 + .../zap-generated/callback-stub.cpp | 8 + .../zap-generated/endpoint_config.h | 7 +- .../lighting-app/zap-generated/gen_config.h | 6 + 27 files changed, 411 insertions(+), 21 deletions(-) create mode 100644 src/app/clusters/switch-server/switch-server.cpp rename src/include/platform/{internal => }/DeviceControlServer.h (52%) diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt index 8f8e523cf1e430..49c8bc19a2db46 100644 --- a/examples/all-clusters-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt @@ -66,6 +66,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/tv-channel-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/scenes" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/software-diagnostics-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/switch-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/general-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/basic" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/bindings" diff --git a/examples/all-clusters-app/mbed/CMakeLists.txt b/examples/all-clusters-app/mbed/CMakeLists.txt index cb3fec04753396..2b7e0ccb0183e5 100644 --- a/examples/all-clusters-app/mbed/CMakeLists.txt +++ b/examples/all-clusters-app/mbed/CMakeLists.txt @@ -118,6 +118,7 @@ target_sources(${APP_TARGET} PRIVATE ${APP_CLUSTERS}/on-off-server/on-off-server.cpp ${APP_CLUSTERS}/ota-provider/ota-provider.cpp ${APP_CLUSTERS}/scenes/scenes.cpp + ${APP_CLUSTERS}/switch-server/switch-server.cpp ${APP_CLUSTERS}/target-navigator-server/target-navigator-server.cpp ${APP_CLUSTERS}/thermostat-server/thermostat-server.cpp ${APP_CLUSTERS}/thermostat-user-interface-configuration-server/thermostat-user-interface-configuration-server.cpp diff --git a/examples/bridge-app/esp32/main/CMakeLists.txt b/examples/bridge-app/esp32/main/CMakeLists.txt index 4587054f593b5c..66fa70ee9a23f4 100644 --- a/examples/bridge-app/esp32/main/CMakeLists.txt +++ b/examples/bridge-app/esp32/main/CMakeLists.txt @@ -35,6 +35,7 @@ idf_component_register(PRIV_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/thread-network-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/wifi-network-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/software-diagnostics-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/switch-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/general-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/descriptor" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/network-commissioning" diff --git a/examples/lighting-app/lighting-common/lighting-app.zap b/examples/lighting-app/lighting-common/lighting-app.zap index 9816b0fee7511b..02a63c25e1094b 100644 --- a/examples/lighting-app/lighting-common/lighting-app.zap +++ b/examples/lighting-app/lighting-common/lighting-app.zap @@ -3612,6 +3612,26 @@ } ] }, + { + "name": "Switch", + "code": 59, + "mfgCode": null, + "define": "SWITCH_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [], + "attributes": [] + }, + { + "name": "Switch", + "code": 59, + "mfgCode": null, + "define": "SWITCH_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [], + "attributes": [] + }, { "name": "AdministratorCommissioning", "code": 60, diff --git a/examples/lighting-app/mbed/CMakeLists.txt b/examples/lighting-app/mbed/CMakeLists.txt index bc11cc1b1e0e07..20a8878e93c4a9 100644 --- a/examples/lighting-app/mbed/CMakeLists.txt +++ b/examples/lighting-app/mbed/CMakeLists.txt @@ -85,6 +85,7 @@ target_sources(${APP_TARGET} PRIVATE ${CHIP_ROOT}/src/app/clusters/thread-network-diagnostics-server/thread-network-diagnostics-server.cpp ${CHIP_ROOT}/src/app/clusters/wifi-network-diagnostics-server/wifi-network-diagnostics-server.cpp ${CHIP_ROOT}/src/app/clusters/software-diagnostics-server/software-diagnostics-server.cpp + ${CHIP_ROOT}/src/app/clusters/switch-server/switch-server.cpp ${CHIP_ROOT}/src/app/clusters/general-diagnostics-server/general-diagnostics-server.cpp ${CHIP_ROOT}/src/app/clusters/general-commissioning-server/general-commissioning-server.cpp ${CHIP_ROOT}/src/app/clusters/on-off-server/on-off-server.cpp diff --git a/examples/lighting-app/telink/CMakeLists.txt b/examples/lighting-app/telink/CMakeLists.txt index e1a2865c22ebe0..d3b4e08f646bd2 100644 --- a/examples/lighting-app/telink/CMakeLists.txt +++ b/examples/lighting-app/telink/CMakeLists.txt @@ -85,6 +85,7 @@ target_sources(app PRIVATE ${CHIP_ROOT}/src/app/clusters/thread-network-diagnostics-server/thread-network-diagnostics-server.cpp ${CHIP_ROOT}/src/app/clusters/wifi-network-diagnostics-server/wifi-network-diagnostics-server.cpp ${CHIP_ROOT}/src/app/clusters/software-diagnostics-server/software-diagnostics-server.cpp + ${CHIP_ROOT}/src/app/clusters/switch-server/switch-server.cpp ${CHIP_ROOT}/src/app/clusters/general-diagnostics-server/general-diagnostics-server.cpp ${CHIP_ROOT}/src/app/clusters/general-commissioning-server/general-commissioning-server.cpp ${CHIP_ROOT}/src/app/clusters/on-off-server/on-off-server.cpp diff --git a/examples/lock-app/esp32/main/CMakeLists.txt b/examples/lock-app/esp32/main/CMakeLists.txt index fbca6b270d9315..2525e67b1f7b4a 100644 --- a/examples/lock-app/esp32/main/CMakeLists.txt +++ b/examples/lock-app/esp32/main/CMakeLists.txt @@ -53,6 +53,7 @@ idf_component_register(INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/thread-network-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/wifi-network-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/software-diagnostics-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/switch-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/general-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/power-source-configuration-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/user-label-server" @@ -141,6 +142,7 @@ idf_component_register(PRIV_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/thread-network-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/wifi-network-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/software-diagnostics-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/switch-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/general-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/network-commissioning" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/on-off-server" diff --git a/examples/lock-app/mbed/CMakeLists.txt b/examples/lock-app/mbed/CMakeLists.txt index 30b0e3651e9e16..71915eb01b071d 100644 --- a/examples/lock-app/mbed/CMakeLists.txt +++ b/examples/lock-app/mbed/CMakeLists.txt @@ -82,6 +82,7 @@ target_sources(${APP_TARGET} PRIVATE ${CHIP_ROOT}/src/app/clusters/thread-network-diagnostics-server/thread-network-diagnostics-server.cpp ${CHIP_ROOT}/src/app/clusters/wifi-network-diagnostics-server/wifi-network-diagnostics-server.cpp ${CHIP_ROOT}/src/app/clusters/software-diagnostics-server/software-diagnostics-server.cpp + ${CHIP_ROOT}/src/app/clusters/switch-server/switch-server.cpp ${CHIP_ROOT}/src/app/clusters/general-diagnostics-server/general-diagnostics-server.cpp ${CHIP_ROOT}/src/app/clusters/general-commissioning-server/general-commissioning-server.cpp ${CHIP_ROOT}/src/app/clusters/network-commissioning/network-commissioning-ember.cpp diff --git a/examples/ota-provider-app/esp32/main/CMakeLists.txt b/examples/ota-provider-app/esp32/main/CMakeLists.txt index a25dde36db364e..777e87a07ecf3e 100644 --- a/examples/ota-provider-app/esp32/main/CMakeLists.txt +++ b/examples/ota-provider-app/esp32/main/CMakeLists.txt @@ -39,6 +39,7 @@ idf_component_register(PRIV_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/thread-network-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/wifi-network-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/software-diagnostics-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/switch-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/general-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/general-commissioning-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/network-commissioning" diff --git a/examples/ota-requestor-app/esp32/main/CMakeLists.txt b/examples/ota-requestor-app/esp32/main/CMakeLists.txt index 8fb4bddfe2c230..156ef5f8cb9a04 100644 --- a/examples/ota-requestor-app/esp32/main/CMakeLists.txt +++ b/examples/ota-requestor-app/esp32/main/CMakeLists.txt @@ -39,6 +39,7 @@ idf_component_register(PRIV_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/thread-network-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/wifi-network-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/software-diagnostics-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/switch-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/general-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/general-commissioning-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/network-commissioning" diff --git a/examples/temperature-measurement-app/esp32/main/CMakeLists.txt b/examples/temperature-measurement-app/esp32/main/CMakeLists.txt index 6d8637cd18caf2..d9f4e09f30d1ae 100644 --- a/examples/temperature-measurement-app/esp32/main/CMakeLists.txt +++ b/examples/temperature-measurement-app/esp32/main/CMakeLists.txt @@ -39,6 +39,7 @@ idf_component_register(PRIV_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/thread-network-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/wifi-network-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/software-diagnostics-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/switch-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/general-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/general-commissioning-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/network-commissioning" diff --git a/src/app/clusters/general-commissioning-server/general-commissioning-server.cpp b/src/app/clusters/general-commissioning-server/general-commissioning-server.cpp index 7a0d08fe73779f..d2808d9544a774 100644 --- a/src/app/clusters/general-commissioning-server/general-commissioning-server.cpp +++ b/src/app/clusters/general-commissioning-server/general-commissioning-server.cpp @@ -31,7 +31,7 @@ #include #include #include -#include +#include using namespace chip; using namespace chip::app; @@ -104,7 +104,7 @@ bool emberAfGeneralCommissioningClusterArmFailSafeCallback(app::CommandHandler * { auto expiryLengthSeconds = System::Clock::Seconds16(commandData.expiryLengthSeconds); - CHIP_ERROR err = DeviceLayer::Internal::DeviceControlServer::DeviceControlSvr().ArmFailSafe(expiryLengthSeconds); + CHIP_ERROR err = DeviceLayer::DeviceControlServer::DeviceControlSvr().ArmFailSafe(expiryLengthSeconds); emberAfSendImmediateDefaultResponse(err == CHIP_NO_ERROR ? EMBER_ZCL_STATUS_SUCCESS : EMBER_ZCL_STATUS_FAILURE); return true; @@ -114,7 +114,7 @@ bool emberAfGeneralCommissioningClusterCommissioningCompleteCallback( app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, const Commands::CommissioningComplete::DecodableType & commandData) { - CHIP_ERROR err = DeviceLayer::Internal::DeviceControlServer::DeviceControlSvr().CommissioningComplete(); + CHIP_ERROR err = DeviceLayer::DeviceControlServer::DeviceControlSvr().CommissioningComplete(); emberAfSendImmediateDefaultResponse(err == CHIP_NO_ERROR ? EMBER_ZCL_STATUS_SUCCESS : EMBER_ZCL_STATUS_FAILURE); return true; @@ -128,8 +128,7 @@ bool emberAfGeneralCommissioningClusterSetRegulatoryConfigCallback(app::CommandH auto & countryCode = commandData.countryCode; auto & breadcrumb = commandData.breadcrumb; - CHIP_ERROR err = - DeviceLayer::Internal::DeviceControlServer::DeviceControlSvr().SetRegulatoryConfig(location, countryCode, breadcrumb); + CHIP_ERROR err = DeviceLayer::DeviceControlServer::DeviceControlSvr().SetRegulatoryConfig(location, countryCode, breadcrumb); emberAfSendImmediateDefaultResponse(err == CHIP_NO_ERROR ? EMBER_ZCL_STATUS_SUCCESS : EMBER_ZCL_STATUS_FAILURE); diff --git a/src/app/clusters/network-commissioning/network-commissioning.cpp b/src/app/clusters/network-commissioning/network-commissioning.cpp index 14e3cd54575c47..3ecdbda015eeed 100644 --- a/src/app/clusters/network-commissioning/network-commissioning.cpp +++ b/src/app/clusters/network-commissioning/network-commissioning.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include @@ -281,7 +281,7 @@ void OnConnectNetworkCommandCallbackInternal(app::CommandHandler * apCommandHand exit: if (err == NetworkCommissioningStatus::kSuccess) { - DeviceLayer::Internal::DeviceControlServer::DeviceControlSvr().ConnectNetworkForOperational(networkID); + DeviceLayer::DeviceControlServer::DeviceControlSvr().ConnectNetworkForOperational(networkID); } response.networkingStatus = err; apCommandHandler->AddResponseData(commandPath, response); diff --git a/src/app/clusters/switch-server/switch-server.cpp b/src/app/clusters/switch-server/switch-server.cpp new file mode 100644 index 00000000000000..2cab1043dd50d9 --- /dev/null +++ b/src/app/clusters/switch-server/switch-server.cpp @@ -0,0 +1,200 @@ +/** + * + * Copyright (c) 2021 Project CHIP Authors + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::Switch; +using namespace chip::app::Clusters::Switch::Attributes; +using chip::DeviceLayer::DeviceControlServer; + +namespace { + +class SwitchDelegate : public DeviceLayer::SwitchDeviceControlDelegate +{ + /** + * @brief + * Called when the latching switch is moved to a new position. + */ + void OnSwitchLatched(uint8_t newPosition) override + { + ChipLogProgress(Zcl, "SwitchDelegate: OnSwitchLatched"); + + for (auto endpointId : EnabledEndpointsWithServerCluster(Switch::Id)) + { + // Record SwitchLatched event + EventNumber eventNumber; + Events::SwitchLatched::Type event{ newPosition }; + + if (CHIP_NO_ERROR != LogEvent(event, endpointId, eventNumber)) + { + ChipLogError(Zcl, "SwitchDelegate: Failed to record SwitchLatched event"); + } + } + } + + /** + * @brief + * Called when the momentary switch starts to be pressed. + */ + void OnInitialPressed(uint8_t newPosition) override + { + ChipLogProgress(Zcl, "SwitchDelegate: OnInitialPressed"); + + for (auto endpointId : EnabledEndpointsWithServerCluster(Switch::Id)) + { + // Record InitialPress event + EventNumber eventNumber; + Events::InitialPress::Type event{ newPosition }; + + if (CHIP_NO_ERROR != LogEvent(event, endpointId, eventNumber)) + { + ChipLogError(Zcl, "SwitchDelegate: Failed to record InitialPress event"); + } + } + } + + /** + * @brief + * Called when the momentary switch has been pressed for a "long" time. + */ + void OnLongPressed(uint8_t newPosition) override + { + ChipLogProgress(Zcl, "SwitchDelegate: OnLongPressed"); + + for (auto endpointId : EnabledEndpointsWithServerCluster(Switch::Id)) + { + // Record LongPress event + EventNumber eventNumber; + Events::LongPress::Type event{ newPosition }; + + if (CHIP_NO_ERROR != LogEvent(event, endpointId, eventNumber)) + { + ChipLogError(Zcl, "SwitchDelegate: Failed to record LongPress event"); + } + } + } + + /** + * @brief + * Called when the momentary switch has been released. + */ + void OnShortReleased(uint8_t previousPosition) override + { + ChipLogProgress(Zcl, "SwitchDelegate: OnShortReleased"); + + for (auto endpointId : EnabledEndpointsWithServerCluster(Switch::Id)) + { + // Record ShortRelease event + EventNumber eventNumber; + Events::ShortRelease::Type event{ previousPosition }; + + if (CHIP_NO_ERROR != LogEvent(event, endpointId, eventNumber)) + { + ChipLogError(Zcl, "SwitchDelegate: Failed to record ShortRelease event"); + } + } + } + + /** + * @brief + * Called when the momentary switch has been released (after debouncing) + * and after having been pressed for a long time. + */ + void OnLongReleased(uint8_t previousPosition) override + { + ChipLogProgress(Zcl, "SwitchDelegate: OnLongReleased"); + + for (auto endpointId : EnabledEndpointsWithServerCluster(Switch::Id)) + { + // Record LongRelease event + EventNumber eventNumber; + Events::LongRelease::Type event{ previousPosition }; + + if (CHIP_NO_ERROR != LogEvent(event, endpointId, eventNumber)) + { + ChipLogError(Zcl, "SwitchDelegate: Failed to record LongRelease event"); + } + } + } + + /** + * @brief + * Called to indicate how many times the momentary switch has been pressed + * in a multi-press sequence, during that sequence. + */ + void OnMultiPressOngoing(uint8_t newPosition, uint8_t count) override + { + ChipLogProgress(Zcl, "SwitchDelegate: OnMultiPressOngoing"); + + for (auto endpointId : EnabledEndpointsWithServerCluster(Switch::Id)) + { + // Record MultiPressOngoing event + EventNumber eventNumber; + Events::MultiPressOngoing::Type event{ newPosition, count }; + + if (CHIP_NO_ERROR != LogEvent(event, endpointId, eventNumber)) + { + ChipLogError(Zcl, "SwitchDelegate: Failed to record MultiPressOngoing event"); + } + } + } + + /** + * @brief + * Called to indicate how many times the momentary switch has been pressed + * in a multi-press sequence, after it has been detected that the sequence has ended. + */ + void OnMultiPressComplete(uint8_t newPosition, uint8_t count) override + { + ChipLogProgress(Zcl, "SwitchDelegate: OnMultiPressComplete"); + + for (auto endpointId : EnabledEndpointsWithServerCluster(Switch::Id)) + { + // Record MultiPressComplete event + EventNumber eventNumber; + Events::MultiPressComplete::Type event{ newPosition, count }; + + if (CHIP_NO_ERROR != LogEvent(event, endpointId, eventNumber)) + { + ChipLogError(Zcl, "SwitchDelegate: Failed to record MultiPressComplete event"); + } + } + } +}; + +SwitchDelegate gSwitchDelegate; + +} // anonymous namespace + +void MatterSwitchPluginServerInitCallback() +{ + DeviceControlServer::DeviceControlSvr().SetSwitchDelegate(&gSwitchDelegate); +} diff --git a/src/app/util/util.cpp b/src/app/util/util.cpp index 4f44413a853b4d..d82283c909f802 100644 --- a/src/app/util/util.cpp +++ b/src/app/util/util.cpp @@ -297,7 +297,6 @@ void MatterElectricalMeasurementPluginServerInitCallback() {} void MatterOtaSoftwareUpdateRequestorPluginServerInitCallback() {} void MatterGroupKeyManagementPluginServerInitCallback() {} void MatterRelativeHumidityMeasurementPluginServerInitCallback() {} -void MatterSwitchPluginServerInitCallback() {} void MatterIlluminanceMeasurementPluginServerInitCallback() {} void MatterBinaryInputBasicPluginServerInitCallback() {} void MatterPressureMeasurementPluginServerInitCallback() {} diff --git a/src/app/zap_cluster_list.py b/src/app/zap_cluster_list.py index 990d882af6dae9..0e77cf7d61e54e 100755 --- a/src/app/zap_cluster_list.py +++ b/src/app/zap_cluster_list.py @@ -72,7 +72,7 @@ 'RELATIVE_HUMIDITY_MEASUREMENT_CLUSTER': [], 'SCENES_CLUSTER': ['scenes'], 'SOFTWARE_DIAGNOSTICS_CLUSTER': ['software-diagnostics-server'], - 'SWITCH_CLUSTER': [], + 'SWITCH_CLUSTER': ['switch-server'], 'TARGET_NAVIGATOR_CLUSTER': ['target-navigator-server'], 'TEMP_MEASUREMENT_CLUSTER': [], 'TEST_CLUSTER': ['test-cluster-server'], diff --git a/src/include/platform/internal/DeviceControlServer.h b/src/include/platform/DeviceControlServer.h similarity index 52% rename from src/include/platform/internal/DeviceControlServer.h rename to src/include/platform/DeviceControlServer.h index c5dee52839ba47..c5c98ee7e6728c 100644 --- a/src/include/platform/internal/DeviceControlServer.h +++ b/src/include/platform/DeviceControlServer.h @@ -27,7 +27,60 @@ namespace chip { namespace DeviceLayer { -namespace Internal { + +/** + * Defines the Swtich Device Control Delegate class to notify platform events. + */ +class SwitchDeviceControlDelegate +{ +public: + virtual ~SwitchDeviceControlDelegate() {} + + /** + * @brief + * Called when the latching switch is moved to a new position. + */ + virtual void OnSwitchLatched(uint8_t newPosition) {} + + /** + * @brief + * Called when the momentary switch starts to be pressed. + */ + virtual void OnInitialPressed(uint8_t newPosition) {} + + /** + * @brief + * Called when the momentary switch has been pressed for a "long" time. + */ + virtual void OnLongPressed(uint8_t newPosition) {} + + /** + * @brief + * Called when the momentary switch has been released. + */ + virtual void OnShortReleased(uint8_t previousPosition) {} + + /** + * @brief + * Called when the momentary switch has been released (after debouncing) + * and after having been pressed for a long time. + */ + virtual void OnLongReleased(uint8_t previousPosition) {} + + /** + * @brief + * Called to indicate how many times the momentary switch has been pressed + * in a multi-press sequence, during that sequence. + */ + virtual void OnMultiPressOngoing(uint8_t newPosition, uint8_t count) {} + + /** + * @brief + * Called to indicate how many times the momentary switch has been pressed + * in a multi-press sequence, after it has been detected that the sequence has ended. + */ + virtual void OnMultiPressComplete(uint8_t newPosition, uint8_t count) {} +}; class DeviceControlServer final { @@ -41,11 +94,16 @@ class DeviceControlServer final CHIP_ERROR ConnectNetworkForOperational(ByteSpan networkID); + void SetSwitchDelegate(SwitchDeviceControlDelegate * delegate) { mSwitchDelegate = delegate; } + SwitchDeviceControlDelegate * GetSwitchDelegate() const { return mSwitchDelegate; } + static DeviceControlServer & DeviceControlSvr(); private: // ===== Members for internal use by the following friends. static DeviceControlServer sInstance; + SwitchDeviceControlDelegate * mSwitchDelegate = nullptr; + friend void HandleArmFailSafe(System::Layer * layer, void * aAppState); void CommissioningFailedTimerComplete(); @@ -60,6 +118,5 @@ class DeviceControlServer final DeviceControlServer & operator=(const DeviceControlServer &) = delete; }; -} // namespace Internal } // namespace DeviceLayer } // namespace chip diff --git a/src/include/platform/PlatformManager.h b/src/include/platform/PlatformManager.h index b90a6098939bb3..f9f0cf9e136dd0 100644 --- a/src/include/platform/PlatformManager.h +++ b/src/include/platform/PlatformManager.h @@ -40,12 +40,12 @@ namespace DeviceLayer { class PlatformManagerImpl; class ConnectivityManagerImpl; class ConfigurationManagerImpl; +class DeviceControlServer; class TraitManager; class ThreadStackManagerImpl; class TimeSyncManager; namespace Internal { -class DeviceControlServer; class FabricProvisioningServer; class ServiceProvisioningServer; class BLEManagerImpl; @@ -194,11 +194,11 @@ class PlatformManager friend class PlatformManagerImpl; friend class ConnectivityManagerImpl; friend class ConfigurationManagerImpl; + friend class DeviceControlServer; friend class Dnssd::DiscoveryImplPlatform; friend class TraitManager; friend class ThreadStackManagerImpl; friend class TimeSyncManager; - friend class Internal::DeviceControlServer; friend class Internal::FabricProvisioningServer; friend class Internal::ServiceProvisioningServer; friend class Internal::BLEManagerImpl; diff --git a/src/include/platform/ThreadStackManager.h b/src/include/platform/ThreadStackManager.h index 75d6dfe58d5a8c..b9b3c49145018a 100644 --- a/src/include/platform/ThreadStackManager.h +++ b/src/include/platform/ThreadStackManager.h @@ -40,9 +40,9 @@ namespace DeviceLayer { class PlatformManagerImpl; class ThreadStackManagerImpl; class ConfigurationManagerImpl; +class DeviceControlServer; namespace Internal { -class DeviceControlServer; class BLEManagerImpl; template class GenericPlatformManagerImpl; @@ -124,10 +124,10 @@ class ThreadStackManager friend class PlatformManagerImpl; friend class ConfigurationManagerImpl; + friend class DeviceControlServer; #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE friend class Internal::BLEManagerImpl; #endif - friend class Internal::DeviceControlServer; template friend class Internal::GenericPlatformManagerImpl; template diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn index 1dd684ec06e330..cd12ba5da998df 100644 --- a/src/platform/BUILD.gn +++ b/src/platform/BUILD.gn @@ -263,6 +263,7 @@ if (chip_device_platform != "none") { "../include/platform/CHIPDeviceLayer.h", "../include/platform/ConfigurationManager.h", "../include/platform/ConnectivityManager.h", + "../include/platform/DeviceControlServer.h", "../include/platform/GeneralUtils.h", "../include/platform/KeyValueStoreManager.h", "../include/platform/PersistedStorage.h", @@ -270,7 +271,6 @@ if (chip_device_platform != "none") { "../include/platform/ThreadStackManager.h", "../include/platform/internal/BLEManager.h", "../include/platform/internal/CHIPDeviceLayerInternal.h", - "../include/platform/internal/DeviceControlServer.h", "../include/platform/internal/DeviceNetworkInfo.h", "../include/platform/internal/DeviceNetworkProvisioning.h", "../include/platform/internal/EventLogging.h", diff --git a/src/platform/DeviceControlServer.cpp b/src/platform/DeviceControlServer.cpp index e14069fde5e0d1..9509a3edfdc590 100644 --- a/src/platform/DeviceControlServer.cpp +++ b/src/platform/DeviceControlServer.cpp @@ -20,13 +20,12 @@ * Provides the implementation of the DeviceControlServer object. */ -#include +#include #include namespace chip { namespace DeviceLayer { -namespace Internal { void HandleArmFailSafe(System::Layer * layer, void * aAppState) { @@ -108,6 +107,5 @@ CHIP_ERROR DeviceControlServer::ConnectNetworkForOperational(ByteSpan networkID) return CHIP_NO_ERROR; } -} // namespace Internal } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/Linux/PlatformManagerImpl.cpp b/src/platform/Linux/PlatformManagerImpl.cpp index 574a8ce58fd632..bed1e41d0e6d26 100644 --- a/src/platform/Linux/PlatformManagerImpl.cpp +++ b/src/platform/Linux/PlatformManagerImpl.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -98,6 +99,9 @@ void SignalHandler(int signum) case SIGVTALRM: PlatformMgrImpl().HandleGeneralFault(GeneralDiagnostics::Events::NetworkFaultChange::kEventId); break; + case SIGIO: + PlatformMgrImpl().HandleSwitchEvent(Switch::Events::SwitchLatched::kEventId); + break; default: break; } @@ -432,6 +436,89 @@ void PlatformManagerImpl::HandleSoftwareFault(uint32_t EventId) } } +void PlatformManagerImpl::HandleSwitchEvent(uint32_t EventId) +{ + SwitchDeviceControlDelegate * delegate = DeviceControlServer::DeviceControlSvr().GetSwitchDelegate(); + + if (delegate == nullptr) + { + ChipLogError(DeviceLayer, "No delegate registered to handle Switch event"); + return; + } + + if (EventId == Switch::Events::SwitchLatched::kEventId) + { + uint8_t newPosition = 0; + +#if CHIP_CONFIG_TEST + newPosition = 100; +#endif + delegate->OnSwitchLatched(newPosition); + } + else if (EventId == Switch::Events::InitialPress::kEventId) + { + uint8_t newPosition = 0; + +#if CHIP_CONFIG_TEST + newPosition = 100; +#endif + delegate->OnInitialPressed(newPosition); + } + else if (EventId == Switch::Events::LongPress::kEventId) + { + uint8_t newPosition = 0; + +#if CHIP_CONFIG_TEST + newPosition = 100; +#endif + delegate->OnLongPressed(newPosition); + } + else if (EventId == Switch::Events::ShortRelease::kEventId) + { + uint8_t previousPosition = 0; + +#if CHIP_CONFIG_TEST + previousPosition = 50; +#endif + delegate->OnShortReleased(previousPosition); + } + else if (EventId == Switch::Events::LongRelease::kEventId) + { + uint8_t previousPosition = 0; + +#if CHIP_CONFIG_TEST + previousPosition = 50; +#endif + delegate->OnLongReleased(previousPosition); + } + else if (EventId == Switch::Events::MultiPressOngoing::kEventId) + { + uint8_t newPosition = 0; + uint8_t currentNumberOfPressesCounted = 0; + +#if CHIP_CONFIG_TEST + newPosition = 10; + currentNumberOfPressesCounted = 5; +#endif + delegate->OnMultiPressOngoing(newPosition, currentNumberOfPressesCounted); + } + else if (EventId == Switch::Events::MultiPressComplete::kEventId) + { + uint8_t newPosition = 0; + uint8_t totalNumberOfPressesCounted = 0; + +#if CHIP_CONFIG_TEST + newPosition = 10; + totalNumberOfPressesCounted = 5; +#endif + delegate->OnMultiPressComplete(newPosition, totalNumberOfPressesCounted); + } + else + { + ChipLogError(DeviceLayer, "Unknow event ID:%d", EventId); + } +} + #if CHIP_WITH_GIO GDBusConnection * PlatformManagerImpl::GetGDBusConnection() { diff --git a/src/platform/Linux/PlatformManagerImpl.h b/src/platform/Linux/PlatformManagerImpl.h index a3017e97029c5b..5d77ad2c8809b9 100644 --- a/src/platform/Linux/PlatformManagerImpl.h +++ b/src/platform/Linux/PlatformManagerImpl.h @@ -58,6 +58,7 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener void HandleGeneralFault(uint32_t EventId); void HandleSoftwareFault(uint32_t EventId); + void HandleSwitchEvent(uint32_t EventId); private: // ===== Methods that implement the PlatformManager abstract interface. diff --git a/zzz_generated/lighting-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/lighting-app/zap-generated/PluginApplicationCallbacks.h index 7a742884d6430e..ac93a15a8550c2 100644 --- a/zzz_generated/lighting-app/zap-generated/PluginApplicationCallbacks.h +++ b/zzz_generated/lighting-app/zap-generated/PluginApplicationCallbacks.h @@ -41,6 +41,7 @@ MatterOnOffSwitchConfigurationPluginServerInitCallback(); \ MatterOperationalCredentialsPluginServerInitCallback(); \ MatterSoftwareDiagnosticsPluginServerInitCallback(); \ + MatterSwitchPluginServerInitCallback(); \ MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ MatterUserLabelPluginServerInitCallback(); \ MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); diff --git a/zzz_generated/lighting-app/zap-generated/callback-stub.cpp b/zzz_generated/lighting-app/zap-generated/callback-stub.cpp index 68b30d16f6b810..ff219206cbe828 100644 --- a/zzz_generated/lighting-app/zap-generated/callback-stub.cpp +++ b/zzz_generated/lighting-app/zap-generated/callback-stub.cpp @@ -83,6 +83,9 @@ void emberAfClusterInitCallback(EndpointId endpoint, ClusterId clusterId) case ZCL_SOFTWARE_DIAGNOSTICS_CLUSTER_ID: emberAfSoftwareDiagnosticsClusterInitCallback(endpoint); break; + case ZCL_SWITCH_CLUSTER_ID: + emberAfSwitchClusterInitCallback(endpoint); + break; case ZCL_THREAD_NETWORK_DIAGNOSTICS_CLUSTER_ID: emberAfThreadNetworkDiagnosticsClusterInitCallback(endpoint); break; @@ -188,6 +191,11 @@ void __attribute__((weak)) emberAfSoftwareDiagnosticsClusterInitCallback(Endpoin // To prevent warning (void) endpoint; } +void __attribute__((weak)) emberAfSwitchClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} void __attribute__((weak)) emberAfThreadNetworkDiagnosticsClusterInitCallback(EndpointId endpoint) { // To prevent warning diff --git a/zzz_generated/lighting-app/zap-generated/endpoint_config.h b/zzz_generated/lighting-app/zap-generated/endpoint_config.h index d908e4422a0922..25f19168153af7 100644 --- a/zzz_generated/lighting-app/zap-generated/endpoint_config.h +++ b/zzz_generated/lighting-app/zap-generated/endpoint_config.h @@ -888,7 +888,7 @@ }; #define ZAP_CLUSTER_MASK(mask) CLUSTER_MASK_##mask -#define GENERATED_CLUSTER_COUNT 23 +#define GENERATED_CLUSTER_COUNT 24 #define GENERATED_CLUSTERS \ { \ { 0x001D, ZAP_ATTRIBUTE_INDEX(0), 5, 0, ZAP_CLUSTER_MASK(SERVER), NULL }, /* Endpoint: 0, Cluster: Descriptor (server) */ \ @@ -925,6 +925,9 @@ { \ 0x0037, ZAP_ATTRIBUTE_INDEX(136), 11, 57, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Ethernet Network Diagnostics (server) */ \ + { \ + 0x003B, ZAP_ATTRIBUTE_INDEX(147), 0, 0, ZAP_CLUSTER_MASK(SERVER), NULL \ + }, /* Endpoint: 0, Cluster: Switch (server) */ \ { \ 0x003C, ZAP_ATTRIBUTE_INDEX(147), 4, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: AdministratorCommissioning (server) */ \ @@ -983,7 +986,7 @@ // This is an array of EmberAfEndpointType structures. #define GENERATED_ENDPOINT_TYPES \ { \ - { ZAP_CLUSTER_INDEX(0), 15, 1436 }, { ZAP_CLUSTER_INDEX(15), 6, 82 }, { ZAP_CLUSTER_INDEX(21), 2, 6 }, \ + { ZAP_CLUSTER_INDEX(0), 16, 1436 }, { ZAP_CLUSTER_INDEX(16), 6, 82 }, { ZAP_CLUSTER_INDEX(22), 2, 6 }, \ } // Largest attribute size is needed for various buffers diff --git a/zzz_generated/lighting-app/zap-generated/gen_config.h b/zzz_generated/lighting-app/zap-generated/gen_config.h index 1b3c5edabc2bc0..1ce9f36f46e1aa 100644 --- a/zzz_generated/lighting-app/zap-generated/gen_config.h +++ b/zzz_generated/lighting-app/zap-generated/gen_config.h @@ -48,6 +48,7 @@ #define EMBER_AF_ON_OFF_SWITCH_CONFIG_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_OPERATIONAL_CREDENTIALS_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_SOFTWARE_DIAGNOSTICS_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_SWITCH_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_THREAD_NETWORK_DIAGNOSTICS_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_USER_LABEL_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_WIFI_NETWORK_DIAGNOSTICS_CLUSTER_SERVER_ENDPOINT_COUNT (1) @@ -155,6 +156,11 @@ #define EMBER_AF_PLUGIN_SOFTWARE_DIAGNOSTICS_SERVER #define EMBER_AF_PLUGIN_SOFTWARE_DIAGNOSTICS +// Use this macro to check if the server side of the Switch cluster is included +#define ZCL_USING_SWITCH_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_SWITCH_SERVER +#define EMBER_AF_PLUGIN_SWITCH + // Use this macro to check if the server side of the Thread Network Diagnostics cluster is included #define ZCL_USING_THREAD_NETWORK_DIAGNOSTICS_CLUSTER_SERVER #define EMBER_AF_PLUGIN_THREAD_NETWORK_DIAGNOSTICS_SERVER