From 1713708cd89c39216e4b5499be769025ecc9ed3a Mon Sep 17 00:00:00 2001 From: Timothy Maes Date: Thu, 13 Jan 2022 22:50:03 +0100 Subject: [PATCH] Adding ota-requestor support in qpg lighting app (#13534) General: * Add ota-upgrade AnnounceOTAProvider handling to lighting-app .zap QPG: * Add OTA upgrade to QPG platform and lighting-app * Enable DNS client to resolve OTA provider Restyled by whitespace Restyled by clang-format Restyled by gn * Update to latest API for OTARequestor --- config/qpg/chip-gn/BUILD.gn | 2 - .../lighting-app/esp32/main/CMakeLists.txt | 1 + .../lighting-common/lighting-app.zap | 209 ++++++++++++++++- examples/lighting-app/mbed/CMakeLists.txt | 4 + examples/lighting-app/qpg/BUILD.gn | 10 +- examples/lighting-app/qpg/args.gni | 4 + examples/lighting-app/qpg/include/AppTask.h | 5 +- examples/lighting-app/qpg/src/AppTask.cpp | 45 ++-- examples/lighting-app/telink/CMakeLists.txt | 5 +- examples/lock-app/qpg/BUILD.gn | 5 +- examples/platform/qpg/ota/ota.cpp | 65 ++++++ .../qpg/{app/include/Service.h => ota/ota.h} | 9 +- .../qpg/project_include/OpenThreadConfig.h | 1 + src/platform/qpg/BUILD.gn | 1 + src/platform/qpg/CHIPDevicePlatformConfig.h | 7 +- src/platform/qpg/OTAImageProcessorImpl.cpp | 210 ++++++++++++++++++ src/platform/qpg/OTAImageProcessorImpl.h | 63 ++++++ .../zap-generated/IMClusterCommandHandler.cpp | 45 ++++ .../PluginApplicationCallbacks.h | 1 + .../zap-generated/callback-stub.cpp | 8 + .../zap-generated/endpoint_config.h | 68 +++--- .../lighting-app/zap-generated/gen_config.h | 6 + 22 files changed, 687 insertions(+), 87 deletions(-) create mode 100644 examples/platform/qpg/ota/ota.cpp rename examples/platform/qpg/{app/include/Service.h => ota/ota.h} (79%) create mode 100644 src/platform/qpg/OTAImageProcessorImpl.cpp create mode 100644 src/platform/qpg/OTAImageProcessorImpl.h diff --git a/config/qpg/chip-gn/BUILD.gn b/config/qpg/chip-gn/BUILD.gn index 1db20a55b9f9fa..8c3a56ea45c53b 100644 --- a/config/qpg/chip-gn/BUILD.gn +++ b/config/qpg/chip-gn/BUILD.gn @@ -26,8 +26,6 @@ declare_args() { examples_plat_dir = "//examples/platform/qpg" qpg_sdk("sdk") { - sources = [ "//examples/platform/qpg/app/include/Service.h" ] - include_dirs = [ "//src/platform/qpg", "${examples_plat_dir}/project_include", diff --git a/examples/lighting-app/esp32/main/CMakeLists.txt b/examples/lighting-app/esp32/main/CMakeLists.txt index fa544eadb52424..9f1b54cccfc3d6 100644 --- a/examples/lighting-app/esp32/main/CMakeLists.txt +++ b/examples/lighting-app/esp32/main/CMakeLists.txt @@ -48,6 +48,7 @@ idf_component_register(PRIV_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/occupancy-sensor-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/on-off-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/operational-credentials-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/ota-requestor" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/power-source-configuration-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/software-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/switch-server" diff --git a/examples/lighting-app/lighting-common/lighting-app.zap b/examples/lighting-app/lighting-common/lighting-app.zap index 1ba6d25d72e9d9..0fdfa137b28bc5 100644 --- a/examples/lighting-app/lighting-common/lighting-app.zap +++ b/examples/lighting-app/lighting-common/lighting-app.zap @@ -1305,14 +1305,14 @@ "code": 65533, "mfgCode": null, "side": "client", - "included": 0, + "included": 1, "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", - "reportable": 0, - "minInterval": 1, - "maxInterval": 65534, + "defaultValue": "0x0001", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, "reportableChange": 0 } ] @@ -1342,7 +1342,204 @@ "outgoing": 0 } ], - "attributes": [] + "attributes": [ + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0001", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "OTA Software Update Requestor", + "code": 42, + "mfgCode": null, + "define": "OTA_REQUESTOR_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "AnnounceOtaProvider", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "OTA Software Update Requestor", + "code": 42, + "mfgCode": null, + "define": "OTA_REQUESTOR_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [], + "attributes": [ + { + "name": "DefaultOtaProviders", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "UpdatePossible", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpdateState", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpdateStateProgress", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] }, { "name": "Localization Configuration", diff --git a/examples/lighting-app/mbed/CMakeLists.txt b/examples/lighting-app/mbed/CMakeLists.txt index f623512804b86a..5a4fdf42a2d176 100644 --- a/examples/lighting-app/mbed/CMakeLists.txt +++ b/examples/lighting-app/mbed/CMakeLists.txt @@ -42,6 +42,7 @@ target_include_directories(${APP_TARGET} PRIVATE ${CHIP_ROOT}/third_party/nlio/repo/include ) +# TODO - re-use chip_data_model.cmake to add cluster implementations. target_sources(${APP_TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/main/AppTask.cpp ${CMAKE_CURRENT_SOURCE_DIR}/main/LightingManager.cpp @@ -95,6 +96,9 @@ target_sources(${APP_TARGET} PRIVATE ${CHIP_ROOT}/src/app/clusters/occupancy-sensor-server/occupancy-sensor-server.cpp ${CHIP_ROOT}/src/app/clusters/network-commissioning-old/network-commissioning-ember.cpp ${CHIP_ROOT}/src/app/clusters/network-commissioning-old/network-commissioning-old.cpp + ${CHIP_ROOT}/src/app/clusters/ota-requestor/ota-requestor-server.cpp + ${CHIP_ROOT}/src/app/clusters/ota-requestor/BDXDownloader.cpp + ${CHIP_ROOT}/src/app/clusters/ota-requestor/OTARequestor.cpp ) target_link_libraries(${APP_TARGET} mbed-os-posix-socket mbed-os mbed-ble mbed-events mbed-netsocket mbed-storage mbed-storage-kv-global-api mbed-mbedtls mbed-emac chip) diff --git a/examples/lighting-app/qpg/BUILD.gn b/examples/lighting-app/qpg/BUILD.gn index b19eec5b3cc5f9..428931ffcd2cdc 100644 --- a/examples/lighting-app/qpg/BUILD.gn +++ b/examples/lighting-app/qpg/BUILD.gn @@ -27,10 +27,7 @@ qpg_project_dir = "${chip_root}/examples/lighting-app/qpg" examples_plat_dir = "${chip_root}/examples/platform/qpg" qpg_sdk("sdk") { - sources = [ - "${examples_plat_dir}/app/include/Service.h", - "${examples_plat_dir}/project_include/CHIPProjectConfig.h", - ] + sources = [ "${examples_plat_dir}/project_include/CHIPProjectConfig.h" ] include_dirs = [ "${chip_root}/src/platform/qpg", @@ -41,9 +38,12 @@ qpg_sdk("sdk") { qpg_executable("lighting_app") { output_name = "chip-${qpg_target_ic}-lighting-example.out" + include_dirs = [] + sources = [ "${chip_root}/examples/lighting-app/lighting-common/color_format/color_format.cpp", "${examples_plat_dir}/app/main.cpp", + "${examples_plat_dir}/ota/ota.cpp", "src/AppTask.cpp", "src/LightingManager.cpp", "src/ZclCallbacks.cpp", @@ -75,7 +75,7 @@ qpg_executable("lighting_app") { include_dirs = [ "${qpg_project_dir}/include/", "${examples_plat_dir}", - "${examples_plat_dir}/app/include", + "${examples_plat_dir}/ota", "${chip_root}/examples/lighting-app/lighting-common/color_format", ] diff --git a/examples/lighting-app/qpg/args.gni b/examples/lighting-app/qpg/args.gni index 8a90e0c6e66dbc..8f05dc6ace9362 100644 --- a/examples/lighting-app/qpg/args.gni +++ b/examples/lighting-app/qpg/args.gni @@ -16,3 +16,7 @@ import("//build_overrides/chip.gni") import("${chip_root}/examples/platform/qpg/args.gni") qpg_sdk_target = get_label_info(":sdk", "label_no_toolchain") + +declare_args() { + chip_enable_ota_requestor = true +} diff --git a/examples/lighting-app/qpg/include/AppTask.h b/examples/lighting-app/qpg/include/AppTask.h index b4f9e2fe86fb86..edc33a5f88a0c3 100644 --- a/examples/lighting-app/qpg/include/AppTask.h +++ b/examples/lighting-app/qpg/include/AppTask.h @@ -27,7 +27,6 @@ #include "FreeRTOS.h" #include "timers.h" // provides FreeRTOS timer support -#include #include #define APP_NAME "Lighting-app" @@ -68,8 +67,7 @@ class AppTask enum Function_t { kFunction_NoneSelected = 0, - kFunction_SoftwareUpdate = 0, - kFunction_Joiner = 1, + kFunction_SoftwareUpdate = 1, kFunction_FactoryReset = 2, kFunction_Invalid @@ -78,7 +76,6 @@ class AppTask Function_t mFunction; bool mFunctionTimerActive; bool mSyncClusterToButtonAction; - chip::Ble::BLEEndPoint * mBLEEndPoint; static AppTask sAppTask; }; diff --git a/examples/lighting-app/qpg/src/AppTask.cpp b/examples/lighting-app/qpg/src/AppTask.cpp index 2addad9a41f715..475cb8324f4325 100644 --- a/examples/lighting-app/qpg/src/AppTask.cpp +++ b/examples/lighting-app/qpg/src/AppTask.cpp @@ -21,6 +21,7 @@ #include "AppConfig.h" #include "AppEvent.h" #include "AppTask.h" +#include "ota.h" #include @@ -42,12 +43,6 @@ using namespace chip::Credentials; using namespace chip::DeviceLayer; #include -#if CHIP_ENABLE_OPENTHREAD -#include -#include -#include -#define JOINER_START_TRIGGER_TIMEOUT 1500 -#endif #define FACTORY_RESET_TRIGGER_TIMEOUT 3000 #define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 3000 @@ -121,6 +116,9 @@ CHIP_ERROR AppTask::Init() // Init ZCL Data Model chip::Server::GetInstance().Init(); + // Init OTA engine + InitializeOTARequestor(); + // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); @@ -290,17 +288,8 @@ void AppTask::FunctionTimerEventHandler(AppEvent * aEvent) // initiate factory reset if (sAppTask.mFunctionTimerActive && sAppTask.mFunction == kFunction_SoftwareUpdate) { -#if CHIP_ENABLE_OPENTHREAD - ChipLogProgress(NotSpecified, "Release button now to Start Thread Joiner"); - ChipLogProgress(NotSpecified, "Hold to trigger Factory Reset"); - sAppTask.mFunction = kFunction_Joiner; - sAppTask.StartTimer(FACTORY_RESET_TRIGGER_TIMEOUT); - } - else if (sAppTask.mFunctionTimerActive && sAppTask.mFunction == kFunction_Joiner) - { -#endif - ChipLogProgress(NotSpecified, "Factory Reset Triggered. Release button within %ums to cancel.", - FACTORY_RESET_CANCEL_WINDOW_TIMEOUT); + ChipLogProgress(NotSpecified, "[BTN] Factory Reset selected. Release within %us to cancel.", + FACTORY_RESET_CANCEL_WINDOW_TIMEOUT / 1000); // Start timer for FACTORY_RESET_CANCEL_WINDOW_TIMEOUT to allow user to // cancel, if required. @@ -340,11 +329,11 @@ void AppTask::FunctionHandler(AppEvent * aEvent) { if (!sAppTask.mFunctionTimerActive && sAppTask.mFunction == kFunction_NoneSelected) { -#if CHIP_ENABLE_OPENTHREAD - sAppTask.StartTimer(JOINER_START_TRIGGER_TIMEOUT); -#else + ChipLogProgress(NotSpecified, "[BTN] Hold to select function:"); + ChipLogProgress(NotSpecified, "[BTN] - Trigger OTA (0-3s)"); + ChipLogProgress(NotSpecified, "[BTN] - Factory Reset (>6s)"); + sAppTask.StartTimer(FACTORY_RESET_TRIGGER_TIMEOUT); -#endif sAppTask.mFunction = kFunction_SoftwareUpdate; } @@ -359,18 +348,10 @@ void AppTask::FunctionHandler(AppEvent * aEvent) sAppTask.mFunction = kFunction_NoneSelected; - ChipLogError(NotSpecified, "Software Update currently not supported."); - } -#if CHIP_ENABLE_OPENTHREAD - else if (sAppTask.mFunctionTimerActive && sAppTask.mFunction == kFunction_Joiner) - { - sAppTask.CancelTimer(); - sAppTask.mFunction = kFunction_NoneSelected; + ChipLogProgress(NotSpecified, "[BTN] Triggering OTA Query"); - CHIP_ERROR error = ThreadStackMgr().JoinerStart(); - ChipLogProgress(NotSpecified, "Thread joiner triggered: %s", chip::ErrorStr(error)); + TriggerOTAQuery(); } -#endif else if (sAppTask.mFunctionTimerActive && sAppTask.mFunction == kFunction_FactoryReset) { sAppTask.CancelTimer(); @@ -379,7 +360,7 @@ void AppTask::FunctionHandler(AppEvent * aEvent) // canceled. sAppTask.mFunction = kFunction_NoneSelected; - ChipLogProgress(NotSpecified, "Factory Reset has been Canceled"); + ChipLogProgress(NotSpecified, "[BTN] Factory Reset has been Canceled"); } } } diff --git a/examples/lighting-app/telink/CMakeLists.txt b/examples/lighting-app/telink/CMakeLists.txt index 2261a2e2823421..cabca3ee2eb539 100644 --- a/examples/lighting-app/telink/CMakeLists.txt +++ b/examples/lighting-app/telink/CMakeLists.txt @@ -39,7 +39,7 @@ target_include_directories(app PRIVATE ${NLIO_ROOT} ${TELINK_COMMON}/util/include ${TELINK_COMMON}/app/include) - +# TODO - re-use chip_data_model.cmake to add cluster implementations. target_sources(app PRIVATE src/AppTask.cpp src/LightingManager.cpp @@ -95,4 +95,7 @@ target_sources(app PRIVATE ${CHIP_ROOT}/src/app/clusters/occupancy-sensor-server/occupancy-sensor-server.cpp ${CHIP_ROOT}/src/app/clusters/network-commissioning-old/network-commissioning-ember.cpp ${CHIP_ROOT}/src/app/clusters/network-commissioning-old/network-commissioning-old.cpp + ${CHIP_ROOT}/src/app/clusters/ota-requestor/ota-requestor-server.cpp + ${CHIP_ROOT}/src/app/clusters/ota-requestor/BDXDownloader.cpp + ${CHIP_ROOT}/src/app/clusters/ota-requestor/OTARequestor.cpp ) diff --git a/examples/lock-app/qpg/BUILD.gn b/examples/lock-app/qpg/BUILD.gn index 08d4f5730ddf58..0ba2a9729c709f 100644 --- a/examples/lock-app/qpg/BUILD.gn +++ b/examples/lock-app/qpg/BUILD.gn @@ -28,10 +28,7 @@ qpg_project_dir = "${chip_root}/examples/lock-app/qpg" examples_plat_dir = "${chip_root}/examples/platform/qpg" qpg_sdk("sdk") { - sources = [ - "${examples_plat_dir}/app/include/Service.h", - "${examples_plat_dir}/project_include/CHIPProjectConfig.h", - ] + sources = [ "${examples_plat_dir}/project_include/CHIPProjectConfig.h" ] include_dirs = [ "${chip_root}/src/platform/qpg", diff --git a/examples/platform/qpg/ota/ota.cpp b/examples/platform/qpg/ota/ota.cpp new file mode 100644 index 00000000000000..ec8464ff1486f5 --- /dev/null +++ b/examples/platform/qpg/ota/ota.cpp @@ -0,0 +1,65 @@ +/* + * + * Copyright (c) 2021 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. + */ + +/** @file "ota.cpp" + * + * OTA handling for an application + */ + +/***************************************************************************** + * Includes Definitions + *****************************************************************************/ + +#include + +#include +#include +#include +#include + +using namespace chip; +using namespace chip::DeviceLayer; + +/***************************************************************************** + * Static Data Definitions + *****************************************************************************/ + +OTARequestor gRequestorCore; +GenericOTARequestorDriver gRequestorUser; +BDXDownloader gDownloader; +OTAImageProcessorImpl gImageProcessor; + +/***************************************************************************** + * Application Function Definitions + *****************************************************************************/ + +void InitializeOTARequestor(void) +{ + // Initialize and interconnect the Requestor and Image Processor objects + SetRequestorInstance(&gRequestorCore); + + gRequestorCore.Init(&Server::GetInstance(), &gRequestorUser, &gDownloader); + gImageProcessor.SetOTADownloader(&gDownloader); + gDownloader.SetImageProcessorDelegate(&gImageProcessor); + gRequestorUser.Init(&gRequestorCore, &gImageProcessor); +} + +void TriggerOTAQuery(void) +{ + GetRequestorInstance()->TriggerImmediateQuery(); +} diff --git a/examples/platform/qpg/app/include/Service.h b/examples/platform/qpg/ota/ota.h similarity index 79% rename from examples/platform/qpg/app/include/Service.h rename to examples/platform/qpg/ota/ota.h index 14abfb0e1d2189..0a56e93fe95c63 100644 --- a/examples/platform/qpg/app/include/Service.h +++ b/examples/platform/qpg/ota/ota.h @@ -1,6 +1,7 @@ /* * - * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2021 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. @@ -17,6 +18,6 @@ #pragma once -void SetDeviceName(const char * newDeviceName); -void PublishService(); -void StartDefaultThreadNetwork(void); +void InitializeOTARequestor(void); + +void TriggerOTAQuery(void); diff --git a/examples/platform/qpg/project_include/OpenThreadConfig.h b/examples/platform/qpg/project_include/OpenThreadConfig.h index d4c29a26b7c43d..460208fc6b9671 100644 --- a/examples/platform/qpg/project_include/OpenThreadConfig.h +++ b/examples/platform/qpg/project_include/OpenThreadConfig.h @@ -62,6 +62,7 @@ #define OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE 1 #define OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE 1 +#define OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE 1 #define OPENTHREAD_CONFIG_ECDSA_ENABLE 1 #define OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE 0 diff --git a/src/platform/qpg/BUILD.gn b/src/platform/qpg/BUILD.gn index 54596a15ea5f09..419f73030ed61a 100644 --- a/src/platform/qpg/BUILD.gn +++ b/src/platform/qpg/BUILD.gn @@ -42,6 +42,7 @@ static_library("qpg") { "DiagnosticDataProviderImpl.h", "InetPlatformConfig.h", "Logging.cpp", + "OTAImageProcessorImpl.cpp", "PlatformManagerImpl.cpp", "PlatformManagerImpl.h", "SystemPlatformConfig.h", diff --git a/src/platform/qpg/CHIPDevicePlatformConfig.h b/src/platform/qpg/CHIPDevicePlatformConfig.h index 81bcbcfa269419..ecbad8ade3443a 100644 --- a/src/platform/qpg/CHIPDevicePlatformConfig.h +++ b/src/platform/qpg/CHIPDevicePlatformConfig.h @@ -28,15 +28,18 @@ #define CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION 0 #define CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP 0 +#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1 + #if CHIP_ENABLE_OPENTHREAD #define CHIP_DEVICE_CONFIG_ENABLE_THREAD 1 #define CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT 1 -#define CHIP_DEVICE_CONFIG_THREAD_SRP_MAX_SERVICES 5 +#define CHIP_DEVICE_CONFIG_THREAD_SRP_MAX_SERVICES (CHIP_CONFIG_MAX_DEVICE_ADMINS + 1) +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT 1 +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_COMMISSIONABLE_DISCOVERY 1 #endif #define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 #define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONABLE_DISCOVERY 1 -#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1 #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 0 diff --git a/src/platform/qpg/OTAImageProcessorImpl.cpp b/src/platform/qpg/OTAImageProcessorImpl.cpp new file mode 100644 index 00000000000000..019c104daccb6e --- /dev/null +++ b/src/platform/qpg/OTAImageProcessorImpl.cpp @@ -0,0 +1,210 @@ +/* + * + * Copyright (c) 2021 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 + +#include "OTAImageProcessorImpl.h" + +namespace chip { + +CHIP_ERROR OTAImageProcessorImpl::PrepareDownload() +{ + + // Get OTA status - under what circumstances does prepared break? + // what happens if a prepare is pending and another one is invoked + // Should we store the state here and wait til we receive notification + + DeviceLayer::PlatformMgr().ScheduleWork(HandlePrepareDownload, reinterpret_cast(this)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::Finalize() +{ + DeviceLayer::PlatformMgr().ScheduleWork(HandleFinalize, reinterpret_cast(this)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::Apply() +{ + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::Abort() +{ + if (mParams.imageFile.empty()) + { + ChipLogError(SoftwareUpdate, "Invalid output image file supplied"); + return CHIP_ERROR_INTERNAL; + } + + DeviceLayer::PlatformMgr().ScheduleWork(HandleAbort, reinterpret_cast(this)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::ProcessBlock(ByteSpan & block) +{ + if (!1 /* What stops us processing a block?*/) + { + return CHIP_ERROR_INTERNAL; + } + + if ((block.data() == nullptr) || block.empty()) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + + // Store block data for HandleProcessBlock to access + CHIP_ERROR err = SetBlock(block); + if (err != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "Cannot set block data: %" CHIP_ERROR_FORMAT, err.Format()); + } + + DeviceLayer::PlatformMgr().ScheduleWork(HandleProcessBlock, reinterpret_cast(this)); + return CHIP_NO_ERROR; +} + +void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context) +{ + qvCHIP_OtaStatus_t status = qvCHIP_OtaStatusSuccess; + auto * imageProcessor = reinterpret_cast(context); + if (imageProcessor == nullptr) + { + ChipLogError(SoftwareUpdate, "ImageProcessor context is null"); + return; + } + else if (imageProcessor->mDownloader == nullptr) + { + ChipLogError(SoftwareUpdate, "mDownloader is null"); + return; + } + + // running this in a thread so won't block main event loop + ChipLogProgress(SoftwareUpdate, "Q: HandlePrepareDownload"); + + qvCHIP_OtaEraseArea(); + qvCHIP_OtaStartWrite(); + + imageProcessor->mDownloader->OnPreparedForDownload(CHIP_NO_ERROR); +} + +void OTAImageProcessorImpl::HandleFinalize(intptr_t context) +{ + qvCHIP_OtaStatus_t status = qvCHIP_OtaStatusSuccess; + auto * imageProcessor = reinterpret_cast(context); + if (imageProcessor == nullptr) + { + return; + } + + ChipLogProgress(SoftwareUpdate, "Q: HandleFinalize"); + + // FIXME - Versions need to be filled in + qvCHIP_OtaSetPendingImage(imageProcessor->mSwVer /*swVer*/, imageProcessor->mHwVer /*hwVer*/, qvCHIP_OtaGetAreaStartAddress(), + static_cast(imageProcessor->mParams.downloadedBytes) /*imgSz*/); + + imageProcessor->ReleaseBlock(); +} + +void OTAImageProcessorImpl::HandleAbort(intptr_t context) +{ + auto * imageProcessor = reinterpret_cast(context); + if (imageProcessor == nullptr) + { + return; + } + + // TODO: What do we do when we abort? + ChipLogProgress(SoftwareUpdate, "Q: HandleAbort"); + + remove(imageProcessor->mParams.imageFile.data()); + imageProcessor->ReleaseBlock(); +} + +void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context) +{ + qvCHIP_OtaStatus_t status = qvCHIP_OtaStatusSuccess; + auto * imageProcessor = reinterpret_cast(context); + if (imageProcessor == nullptr) + { + ChipLogError(SoftwareUpdate, "ImageProcessor context is null"); + return; + } + else if (imageProcessor->mDownloader == nullptr) + { + ChipLogError(SoftwareUpdate, "mDownloader is null"); + return; + } + + ChipLogProgress(SoftwareUpdate, "Q: HandleProcessBlock"); + // TODO: Process block header if any + + status = qvCHIP_OtaWriteChunk(qvCHIP_OtaGetAreaStartAddress() + imageProcessor->mParams.downloadedBytes, + static_cast(imageProcessor->mBlock.size()), + reinterpret_cast(imageProcessor->mBlock.data())); + + if (status != qvCHIP_OtaStatusSuccess) + { + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); + return; + } + + imageProcessor->mParams.downloadedBytes += imageProcessor->mBlock.size(); + imageProcessor->mDownloader->FetchNextData(); +} + +CHIP_ERROR OTAImageProcessorImpl::SetBlock(ByteSpan & block) +{ + if ((block.data() == nullptr) || block.empty()) + { + return CHIP_NO_ERROR; + } + + // Allocate memory for block data if it has not been done yet + if (mBlock.empty()) + { + mBlock = MutableByteSpan(static_cast(chip::Platform::MemoryAlloc(block.size())), block.size()); + if (mBlock.data() == nullptr) + { + return CHIP_ERROR_NO_MEMORY; + } + } + + // Store the actual block data + CHIP_ERROR err = CopySpanToMutableSpan(block, mBlock); + if (err != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "Cannot copy block data: %" CHIP_ERROR_FORMAT, err.Format()); + return err; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::ReleaseBlock() +{ + if (mBlock.data() != nullptr) + { + chip::Platform::MemoryFree(mBlock.data()); + } + + mBlock = MutableByteSpan(); + return CHIP_NO_ERROR; +} + +} // namespace chip diff --git a/src/platform/qpg/OTAImageProcessorImpl.h b/src/platform/qpg/OTAImageProcessorImpl.h new file mode 100644 index 00000000000000..ee8c3175536315 --- /dev/null +++ b/src/platform/qpg/OTAImageProcessorImpl.h @@ -0,0 +1,63 @@ +/* + * + * Copyright (c) 2021 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 +#include +#include + +namespace chip { + +class OTAImageProcessorImpl : public OTAImageProcessorInterface +{ +public: + //////////// OTAImageProcessorInterface Implementation /////////////// + CHIP_ERROR PrepareDownload() override; + CHIP_ERROR Finalize() override; + CHIP_ERROR Apply() override; + CHIP_ERROR Abort() override; + CHIP_ERROR ProcessBlock(ByteSpan & block) override; + + void SetOTADownloader(OTADownloader * downloader) { mDownloader = downloader; } + +private: + //////////// Actual handlers for the OTAImageProcessorInterface /////////////// + static void HandlePrepareDownload(intptr_t context); + static void HandleFinalize(intptr_t context); + static void HandleAbort(intptr_t context); + static void HandleProcessBlock(intptr_t context); + + /** + * Called to allocate memory for mBlock if necessary and set it to block + */ + CHIP_ERROR SetBlock(ByteSpan & block); + + /** + * Called to release allocated memory for mBlock + */ + CHIP_ERROR ReleaseBlock(); + + std::uint32_t mSwVer; + std::uint32_t mHwVer; + + MutableByteSpan mBlock; + OTADownloader * mDownloader; +}; + +} // namespace chip diff --git a/zzz_generated/lighting-app/zap-generated/IMClusterCommandHandler.cpp b/zzz_generated/lighting-app/zap-generated/IMClusterCommandHandler.cpp index b12fb475dacee5..f471a3a899d02d 100644 --- a/zzz_generated/lighting-app/zap-generated/IMClusterCommandHandler.cpp +++ b/zzz_generated/lighting-app/zap-generated/IMClusterCommandHandler.cpp @@ -889,6 +889,48 @@ void DispatchClientCommand(CommandSender * apCommandObj, const ConcreteCommandPa } // namespace OtaSoftwareUpdateProvider +namespace OtaSoftwareUpdateRequestor { + +void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) +{ + // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV + // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error. + // Any error value TLVUnpackError means we have received an illegal value. + // The following variables are used for all commands to save code size. + CHIP_ERROR TLVError = CHIP_NO_ERROR; + bool wasHandled = false; + { + switch (aCommandPath.mCommandId) + { + case Commands::AnnounceOtaProvider::Id: { + Commands::AnnounceOtaProvider::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = + emberAfOtaSoftwareUpdateRequestorClusterAnnounceOtaProviderCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI, + ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId)); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || !wasHandled) + { + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::InvalidCommand); + ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format()); + } +} + +} // namespace OtaSoftwareUpdateRequestor + namespace OnOff { void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) @@ -1247,6 +1289,9 @@ void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, TLV: case Clusters::NetworkCommissioning::Id: Clusters::NetworkCommissioning::DispatchServerCommand(apCommandObj, aCommandPath, aReader); break; + case Clusters::OtaSoftwareUpdateRequestor::Id: + Clusters::OtaSoftwareUpdateRequestor::DispatchServerCommand(apCommandObj, aCommandPath, aReader); + break; case Clusters::OnOff::Id: Clusters::OnOff::DispatchServerCommand(apCommandObj, aCommandPath, aReader); break; diff --git a/zzz_generated/lighting-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/lighting-app/zap-generated/PluginApplicationCallbacks.h index a1fb371ae0b6b7..7ef58a6f6b5776 100644 --- a/zzz_generated/lighting-app/zap-generated/PluginApplicationCallbacks.h +++ b/zzz_generated/lighting-app/zap-generated/PluginApplicationCallbacks.h @@ -36,6 +36,7 @@ MatterLocalizationConfigurationPluginServerInitCallback(); \ MatterNetworkCommissioningPluginServerInitCallback(); \ MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ + MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ MatterOccupancySensingPluginServerInitCallback(); \ MatterOnOffPluginClientInitCallback(); \ MatterOnOffPluginServerInitCallback(); \ diff --git a/zzz_generated/lighting-app/zap-generated/callback-stub.cpp b/zzz_generated/lighting-app/zap-generated/callback-stub.cpp index ccb5454a214c2c..978e166c1c419c 100644 --- a/zzz_generated/lighting-app/zap-generated/callback-stub.cpp +++ b/zzz_generated/lighting-app/zap-generated/callback-stub.cpp @@ -71,6 +71,9 @@ void emberAfClusterInitCallback(EndpointId endpoint, ClusterId clusterId) case ZCL_OTA_PROVIDER_CLUSTER_ID: emberAfOtaSoftwareUpdateProviderClusterInitCallback(endpoint); break; + case ZCL_OTA_REQUESTOR_CLUSTER_ID: + emberAfOtaSoftwareUpdateRequestorClusterInitCallback(endpoint); + break; case ZCL_OCCUPANCY_SENSING_CLUSTER_ID: emberAfOccupancySensingClusterInitCallback(endpoint); break; @@ -174,6 +177,11 @@ void __attribute__((weak)) emberAfOtaSoftwareUpdateProviderClusterInitCallback(E // To prevent warning (void) endpoint; } +void __attribute__((weak)) emberAfOtaSoftwareUpdateRequestorClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} void __attribute__((weak)) emberAfOccupancySensingClusterInitCallback(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 e32b52b850391d..3ec287cc36faa6 100644 --- a/zzz_generated/lighting-app/zap-generated/endpoint_config.h +++ b/zzz_generated/lighting-app/zap-generated/endpoint_config.h @@ -577,7 +577,7 @@ #define ZAP_ATTRIBUTE_MASK(mask) ATTRIBUTE_MASK_##mask // This is an array of EmberAfAttributeMetadata structures. -#define GENERATED_ATTRIBUTE_COUNT 223 +#define GENERATED_ATTRIBUTE_COUNT 229 #define GENERATED_ATTRIBUTES \ { \ \ @@ -613,6 +613,17 @@ { 0x0012, ZAP_TYPE(CHAR_STRING), 33, ZAP_ATTRIBUTE_MASK(SINGLETON), ZAP_EMPTY_DEFAULT() }, /* UniqueID */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(SINGLETON), ZAP_SIMPLE_DEFAULT(3) }, /* ClusterRevision */ \ \ + /* Endpoint: 0, Cluster: OTA Software Update Provider (client) */ \ + { 0xFFFD, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(CLIENT), ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ + \ + /* Endpoint: 0, Cluster: OTA Software Update Requestor (server) */ \ + { 0x0000, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(WRITABLE), \ + ZAP_SIMPLE_DEFAULT(0) }, /* DefaultOtaProviders */ \ + { 0x0001, ZAP_TYPE(BOOLEAN), 1, 0, ZAP_SIMPLE_DEFAULT(1) }, /* UpdatePossible */ \ + { 0x0002, ZAP_TYPE(ENUM8), 1, 0, ZAP_SIMPLE_DEFAULT(0) }, /* UpdateState */ \ + { 0x0003, ZAP_TYPE(INT8U), 1, ZAP_ATTRIBUTE_MASK(NULLABLE), ZAP_SIMPLE_DEFAULT(0) }, /* UpdateStateProgress */ \ + { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ /* Endpoint: 0, Cluster: Localization Configuration (server) */ \ { 0x0001, ZAP_TYPE(CHAR_STRING), 36, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_EMPTY_DEFAULT() }, /* ActiveLocale */ \ { 0x0002, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* SupportedLocales */ \ @@ -893,7 +904,7 @@ }; #define ZAP_CLUSTER_MASK(mask) CLUSTER_MASK_##mask -#define GENERATED_CLUSTER_COUNT 25 +#define GENERATED_CLUSTER_COUNT 26 #define GENERATED_CLUSTERS \ { \ { 0x001D, ZAP_ATTRIBUTE_INDEX(0), 5, 0, ZAP_CLUSTER_MASK(SERVER), NULL }, /* Endpoint: 0, Cluster: Descriptor (server) */ \ @@ -904,88 +915,91 @@ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ chipFuncArrayBasicServer }, /* Endpoint: 0, Cluster: Basic (server) */ \ { \ - 0x0029, ZAP_ATTRIBUTE_INDEX(25), 0, 0, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0029, ZAP_ATTRIBUTE_INDEX(25), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 0, Cluster: OTA Software Update Provider (client) */ \ { \ - 0x002B, ZAP_ATTRIBUTE_INDEX(25), 2, 36, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x002A, ZAP_ATTRIBUTE_INDEX(26), 5, 5, ZAP_CLUSTER_MASK(SERVER), NULL \ + }, /* Endpoint: 0, Cluster: OTA Software Update Requestor (server) */ \ + { \ + 0x002B, ZAP_ATTRIBUTE_INDEX(31), 2, 36, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Localization Configuration (server) */ \ { \ - 0x0030, ZAP_ATTRIBUTE_INDEX(27), 6, 270, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0030, ZAP_ATTRIBUTE_INDEX(33), 6, 270, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: General Commissioning (server) */ \ { \ - 0x0031, ZAP_ATTRIBUTE_INDEX(33), 10, 60, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0031, ZAP_ATTRIBUTE_INDEX(39), 10, 60, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Network Commissioning (server) */ \ { \ - 0x0032, ZAP_ATTRIBUTE_INDEX(43), 0, 0, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0032, ZAP_ATTRIBUTE_INDEX(49), 0, 0, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Diagnostic Logs (server) */ \ { \ - 0x0033, ZAP_ATTRIBUTE_INDEX(43), 9, 17, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0033, ZAP_ATTRIBUTE_INDEX(49), 9, 17, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: General Diagnostics (server) */ \ { \ - 0x0034, ZAP_ATTRIBUTE_INDEX(52), 6, 30, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0034, ZAP_ATTRIBUTE_INDEX(58), 6, 30, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Software Diagnostics (server) */ \ { \ - 0x0035, ZAP_ATTRIBUTE_INDEX(58), 65, 247, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0035, ZAP_ATTRIBUTE_INDEX(64), 65, 247, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Thread Network Diagnostics (server) */ \ { \ - 0x0036, ZAP_ATTRIBUTE_INDEX(123), 15, 58, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0036, ZAP_ATTRIBUTE_INDEX(129), 15, 58, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: WiFi Network Diagnostics (server) */ \ { \ - 0x0037, ZAP_ATTRIBUTE_INDEX(138), 11, 57, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0037, ZAP_ATTRIBUTE_INDEX(144), 11, 57, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Ethernet Network Diagnostics (server) */ \ { \ - 0x003B, ZAP_ATTRIBUTE_INDEX(149), 0, 0, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x003B, ZAP_ATTRIBUTE_INDEX(155), 0, 0, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Switch (server) */ \ { \ - 0x003C, ZAP_ATTRIBUTE_INDEX(149), 4, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x003C, ZAP_ATTRIBUTE_INDEX(155), 4, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: AdministratorCommissioning (server) */ \ { \ - 0x003E, ZAP_ATTRIBUTE_INDEX(153), 6, 4, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x003E, ZAP_ATTRIBUTE_INDEX(159), 6, 4, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Operational Credentials (server) */ \ { \ - 0x0040, ZAP_ATTRIBUTE_INDEX(159), 2, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0040, ZAP_ATTRIBUTE_INDEX(165), 2, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Fixed Label (server) */ \ { \ - 0x0041, ZAP_ATTRIBUTE_INDEX(161), 2, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0041, ZAP_ATTRIBUTE_INDEX(167), 2, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: User Label (server) */ \ { 0x0003, \ - ZAP_ATTRIBUTE_INDEX(163), \ + ZAP_ATTRIBUTE_INDEX(169), \ 3, \ 5, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(ATTRIBUTE_CHANGED_FUNCTION), \ chipFuncArrayIdentifyServer }, /* Endpoint: 1, Cluster: Identify (server) */ \ { 0x0006, \ - ZAP_ATTRIBUTE_INDEX(166), \ + ZAP_ATTRIBUTE_INDEX(172), \ 7, \ 13, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ chipFuncArrayOnOffServer }, /* Endpoint: 1, Cluster: On/Off (server) */ \ { 0x0008, \ - ZAP_ATTRIBUTE_INDEX(173), \ + ZAP_ATTRIBUTE_INDEX(179), \ 15, \ 23, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ chipFuncArrayLevelControlServer }, /* Endpoint: 1, Cluster: Level Control (server) */ \ { \ - 0x001D, ZAP_ATTRIBUTE_INDEX(188), 5, 0, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x001D, ZAP_ATTRIBUTE_INDEX(194), 5, 0, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Descriptor (server) */ \ { 0x0300, \ - ZAP_ATTRIBUTE_INDEX(193), \ + ZAP_ATTRIBUTE_INDEX(199), \ 22, \ 36, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ chipFuncArrayColorControlServer }, /* Endpoint: 1, Cluster: Color Control (server) */ \ { 0x0406, \ - ZAP_ATTRIBUTE_INDEX(215), \ + ZAP_ATTRIBUTE_INDEX(221), \ 4, \ 5, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ chipFuncArrayOccupancySensingServer }, /* Endpoint: 1, Cluster: Occupancy Sensing (server) */ \ { \ - 0x0006, ZAP_ATTRIBUTE_INDEX(219), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0006, ZAP_ATTRIBUTE_INDEX(225), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 2, Cluster: On/Off (client) */ \ { \ - 0x0007, ZAP_ATTRIBUTE_INDEX(220), 3, 4, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0007, ZAP_ATTRIBUTE_INDEX(226), 3, 4, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 2, Cluster: On/off Switch Configuration (server) */ \ } @@ -994,7 +1008,7 @@ // This is an array of EmberAfEndpointType structures. #define GENERATED_ENDPOINT_TYPES \ { \ - { ZAP_CLUSTER_INDEX(0), 17, 1472 }, { ZAP_CLUSTER_INDEX(17), 6, 82 }, { ZAP_CLUSTER_INDEX(23), 2, 6 }, \ + { ZAP_CLUSTER_INDEX(0), 18, 1479 }, { ZAP_CLUSTER_INDEX(18), 6, 82 }, { ZAP_CLUSTER_INDEX(24), 2, 6 }, \ } // Largest attribute size is needed for various buffers @@ -1004,7 +1018,7 @@ #define ATTRIBUTE_SINGLETONS_SIZE (687) // Total size of attribute storage -#define ATTRIBUTE_MAX_SIZE (1560) +#define ATTRIBUTE_MAX_SIZE (1567) // Number of fixed endpoints #define FIXED_ENDPOINT_COUNT (3) diff --git a/zzz_generated/lighting-app/zap-generated/gen_config.h b/zzz_generated/lighting-app/zap-generated/gen_config.h index 053035a8d0e6cc..e801337b0acc11 100644 --- a/zzz_generated/lighting-app/zap-generated/gen_config.h +++ b/zzz_generated/lighting-app/zap-generated/gen_config.h @@ -43,6 +43,7 @@ #define EMBER_AF_LOCALIZATION_CONFIGURATION_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_NETWORK_COMMISSIONING_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_OTA_PROVIDER_CLUSTER_CLIENT_ENDPOINT_COUNT (1) +#define EMBER_AF_OTA_REQUESTOR_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_OCCUPANCY_SENSING_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_ON_OFF_CLUSTER_CLIENT_ENDPOINT_COUNT (1) #define EMBER_AF_ON_OFF_CLUSTER_SERVER_ENDPOINT_COUNT (1) @@ -133,6 +134,11 @@ #define ZCL_USING_OTA_PROVIDER_CLUSTER_CLIENT #define EMBER_AF_PLUGIN_OTA_SOFTWARE_UPDATE_PROVIDER_CLIENT +// Use this macro to check if the server side of the OTA Software Update Requestor cluster is included +#define ZCL_USING_OTA_REQUESTOR_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_OTA_SOFTWARE_UPDATE_REQUESTOR_SERVER +#define EMBER_AF_PLUGIN_OTA_SOFTWARE_UPDATE_REQUESTOR + // Use this macro to check if the server side of the Occupancy Sensing cluster is included #define ZCL_USING_OCCUPANCY_SENSING_CLUSTER_SERVER #define EMBER_AF_PLUGIN_OCCUPANCY_SENSING_SERVER