diff --git a/examples/lock-app/nrfconnect/CMakeLists.txt b/examples/lock-app/nrfconnect/CMakeLists.txt index 675d9914f1f92b..bb49b8798ed1e8 100644 --- a/examples/lock-app/nrfconnect/CMakeLists.txt +++ b/examples/lock-app/nrfconnect/CMakeLists.txt @@ -29,16 +29,29 @@ if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD}.conf) list(APPEND CONF_FILE boards/${BOARD}.conf) endif() -option(BUILD_WITH_DFU "Build target with Device Firmware Upgrade support" OFF) -if(BUILD_WITH_DFU) - if(${BOARD} STREQUAL "nrf5340dk_nrf5340_cpuapp") - list(INSERT OVERLAY_CONFIG 0 ${CHIP_ROOT}/config/nrfconnect/app/overlay-multi_image_smp_dfu_support.conf) +set(BUILD_WITH_DFU "MATTER" CACHE STRING "Build target with Device Firmware Upgrade support") + +if(NOT BUILD_WITH_DFU STREQUAL "OFF") + if(BUILD_WITH_DFU STREQUAL "BLE") + if(BOARD STREQUAL "nrf5340dk_nrf5340_cpuapp") + list(INSERT OVERLAY_CONFIG 0 ${CHIP_ROOT}/config/nrfconnect/app/overlay-multi_image_smp_dfu_support.conf) + else() + list(INSERT OVERLAY_CONFIG 0 ${CHIP_ROOT}/config/nrfconnect/app/overlay-single_image_smp_dfu_support.conf) + endif() + elseif(NOT BUILD_WITH_DFU STREQUAL "MATTER") + message(FATAL_ERROR "Selected invalid BUILD_WITH_DFU value: ${BUILD_WITH_DFU}") + endif() + + list(INSERT OVERLAY_CONFIG 0 ${CHIP_ROOT}/config/nrfconnect/app/overlay-mcuboot_qspi_nor_support.conf) + list(INSERT OVERLAY_CONFIG 0 ${CHIP_ROOT}/config/nrfconnect/app/overlay-ota_requestor.conf) + + if(BOARD STREQUAL "nrf5340dk_nrf5340_cpuapp") + # DFU over Matter doesn't support multi-image update yet, but using this configs should not harm it anyway. set(mcuboot_OVERLAY_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/configuration/mcuboot_multi_image_dfu.conf CACHE INTERNAL "") else() - list(INSERT OVERLAY_CONFIG 0 ${CHIP_ROOT}/config/nrfconnect/app/overlay-single_image_smp_dfu_support.conf) set(mcuboot_OVERLAY_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/configuration/mcuboot_single_image_dfu.conf CACHE INTERNAL "") endif() - list(INSERT OVERLAY_CONFIG 0 ${CHIP_ROOT}/config/nrfconnect/app/overlay-mcuboot_qspi_nor_support.conf) + set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static.yml) endif() @@ -80,6 +93,6 @@ chip_configure_data_model(app ZAP_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../lock-common/lock-app.zap ) -if(BUILD_WITH_DFU) +if(BUILD_WITH_DFU STREQUAL "BLE") target_sources(app PRIVATE ${NRFCONNECT_COMMON}/util/DFUOverSMP.cpp) endif() diff --git a/examples/lock-app/nrfconnect/README.md b/examples/lock-app/nrfconnect/README.md index ed19cf8b5c4e7d..4ad73a8b7d4f90 100644 --- a/examples/lock-app/nrfconnect/README.md +++ b/examples/lock-app/nrfconnect/README.md @@ -95,28 +95,31 @@ with other Thread devices in the network. ### Device Firmware Upgrade -The example allows enabling the over-the-air Device Firmware Upgrade feature. In -this process, the device hosting new firmware image sends the image to the -Matter device using Bluetooth LE transport and -[Simple Management Protocol](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/guides/device_mgmt/index.html#device-mgmt). -The +The example supports over-the-air (OTA) device firmware upgrade (DFU) using one +of the two available methods: + +- Matter OTA update that is mandatory for Matter-compliant devices and enabled + by default +- [Simple Management Protocol](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/guides/device_mgmt/index.html#device-mgmt) + over Bluetooth LE, an optional proprietary method that can be enabled to + work alongside the default Matter OTA update. Note that this protocol is not + a part of the Matter specification. + +For both methods, the [MCUboot](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/mcuboot/index.html) -bootloader solution then replaces the old firmware image with the new one. +bootloader solution is used to replace the old firmware image with the new one. -#### Bootloader +#### Matter Over-the-Air Update -MCUboot is a secure bootloader used for swapping firmware images of different -versions and generating proper build output files that can be used in the device -firmware upgrade process. +The Matter over-the-air update distinguishes two types of nodes: OTA Provider +and OTA Requestor. -The bootloader solution requires an area of flash memory to swap application -images during the firmware upgrade. The Nordic devices use an external memory -chip for this purpose. The memory chip communicates with the microcontroller -through the QSPI bus. +An OTA Provider is a node that hosts a new firmware image and is able to respond +on an OTA Requestor's queries regarding availability of new firmware images or +requests to start sending the update packages. -See the -[Building with Device Firmware Upgrade support](#building-with-device-firmware-upgrade-support) -section to learn how to change MCUboot and flash configuration in this example. +An OTA Requestor is a node that wants to download a new firmware image and sends +requests to an OTA Provider to start the update process. #### Simple Management Protocol @@ -132,6 +135,21 @@ See the section to learn how to enable SMP and use it for the DFU purpose in this example. +#### Bootloader + +MCUboot is a secure bootloader used for swapping firmware images of different +versions and generating proper build output files that can be used in the device +firmware upgrade process. + +The bootloader solution requires an area of flash memory to swap application +images during the firmware upgrade. Nordic Semiconductor devices use an external +memory chip for this purpose. The memory chip communicates with the +microcontroller through the QSPI bus. + +See the +[Building with Device Firmware Upgrade support](#building-with-device-firmware-upgrade-support) +section to learn how to change MCUboot and flash configuration in this example. +
@@ -380,11 +398,19 @@ For example, use the following command for `nrf52840dk_nrf52840`: ### Building with Device Firmware Upgrade support -To build the example with configuration that enables DFU, run the following -command with _build-target_ replaced with the build target name of the Nordic -Semiconductor's kit you own (for example `nrf52840dk_nrf52840`): +Support for DFU using Matter OTA is enabled by default. + +To enable DFU over Bluetooth LE, run the following command with _build-target_ +replaced with the build target name of the Nordic Semiconductor kit you are +using (for example `nrf52840dk_nrf52840`): + + $ west build -b build-target -- -DBUILD_WITH_DFU=BLE + +To completely disable support for both DFU methods, run the following command +with _build-target_ replaced with the build target name of the Nordic +Semiconductor kit you are using (for example `nrf52840dk_nrf52840`): - $ west build -b build-target -- -DBUILD_WITH_DFU=1 + $ west build -b build-target -- -DBUILD_WITH_DFU=OFF > **Note**: > @@ -397,15 +423,16 @@ Semiconductor's kit you own (for example `nrf52840dk_nrf52840`): #### Changing Device Firmware Upgrade configuration -To change the default DFU configuration, edit some of the following overlay -files depending on selected configuration: +To change the default DFU configuration, edit the following overlay files +corresponding to the selected configuration: -- `overlay-mcuboot_qspi_nor_support.conf` - generic file enabling MCUboot and +- `overlay-mcuboot_qspi_nor_support.conf` - general file enabling MCUboot and QSPI NOR support, used by all DFU configurations - `overlay-single_image_smp_dfu_support.conf` - file enabling single-image DFU over Bluetooth LE using SMP - `overlay-multi_image_smp_dfu_support.conf` - file enabling multi-image DFU over Bluetooth LE using SMP +- `overlay-ota_requestor.conf` - file enabling Matter OTA Requestor support. The files are located in the `config/nrfconnect/app` directory. You can also define the desired options in your example's `prj.conf` file. diff --git a/examples/lock-app/nrfconnect/main/AppTask.cpp b/examples/lock-app/nrfconnect/main/AppTask.cpp index 3e59a98ae637ff..b5ab85ff54c7ff 100644 --- a/examples/lock-app/nrfconnect/main/AppTask.cpp +++ b/examples/lock-app/nrfconnect/main/AppTask.cpp @@ -35,6 +35,13 @@ #include #include +#if CONFIG_CHIP_OTA_REQUESTOR +#include +#include +#include +#include +#endif + #include #include #include @@ -49,21 +56,31 @@ using namespace ::chip::DeviceLayer; #define APP_EVENT_QUEUE_SIZE 10 #define BUTTON_PUSH_EVENT 1 #define BUTTON_RELEASE_EVENT 0 + +namespace { constexpr EndpointId kLockEndpointId = 1; LOG_MODULE_DECLARE(app); K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), APP_EVENT_QUEUE_SIZE, alignof(AppEvent)); +k_timer sFunctionTimer; + +LEDWidget sStatusLED; +LEDWidget sLockLED; +LEDWidget sUnusedLED; +LEDWidget sUnusedLED_1; + +bool sIsThreadProvisioned = false; +bool sIsThreadEnabled = false; +bool sHaveBLEConnections = false; + +#if CONFIG_CHIP_OTA_REQUESTOR +GenericOTARequestorDriver sOTARequestorDriver; +OTAImageProcessorImpl sOTAImageProcessor; +chip::BDXDownloader sBDXDownloader; +chip::OTARequestor sOTARequestor; +#endif -static LEDWidget sStatusLED; -static LEDWidget sLockLED; -static LEDWidget sUnusedLED; -static LEDWidget sUnusedLED_1; - -static bool sIsThreadProvisioned = false; -static bool sIsThreadEnabled = false; -static bool sHaveBLEConnections = false; - -static k_timer sFunctionTimer; +} // namespace AppTask AppTask::sAppTask; @@ -140,6 +157,7 @@ CHIP_ERROR AppTask::Init() // Initialize CHIP server SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); + InitOTARequestor(); ReturnErrorOnFailure(chip::Server::GetInstance().Init()); ConfigurationMgr().LogDeviceConfig(); PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); @@ -158,6 +176,17 @@ CHIP_ERROR AppTask::Init() return err; } +void AppTask::InitOTARequestor() +{ +#if CONFIG_CHIP_OTA_REQUESTOR + sOTAImageProcessor.SetOTADownloader(&sBDXDownloader); + sBDXDownloader.SetImageProcessorDelegate(&sOTAImageProcessor); + sOTARequestorDriver.Init(&sOTARequestor, &sOTAImageProcessor); + sOTARequestor.Init(&chip::Server::GetInstance(), &sOTARequestorDriver, &sBDXDownloader); + chip::SetRequestorInstance(&sOTARequestor); +#endif +} + CHIP_ERROR AppTask::StartApp() { ReturnErrorOnFailure(Init()); diff --git a/examples/lock-app/nrfconnect/main/include/AppTask.h b/examples/lock-app/nrfconnect/main/include/AppTask.h index 2789d15a41e229..1106723152b261 100644 --- a/examples/lock-app/nrfconnect/main/include/AppTask.h +++ b/examples/lock-app/nrfconnect/main/include/AppTask.h @@ -44,6 +44,7 @@ class AppTask friend AppTask & GetAppTask(void); CHIP_ERROR Init(); + void InitOTARequestor(); static void ActionInitiated(BoltLockManager::Action_t aAction, int32_t aActor); static void ActionCompleted(BoltLockManager::Action_t aAction, int32_t aActor); diff --git a/examples/pump-app/nrfconnect/CMakeLists.txt b/examples/pump-app/nrfconnect/CMakeLists.txt index 95ea01f58afafc..3471a1f63fa94b 100644 --- a/examples/pump-app/nrfconnect/CMakeLists.txt +++ b/examples/pump-app/nrfconnect/CMakeLists.txt @@ -29,16 +29,29 @@ if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD}.conf) list(APPEND CONF_FILE boards/${BOARD}.conf) endif() -option(BUILD_WITH_DFU "Build target with Device Firmware Upgrade support" OFF) -if(BUILD_WITH_DFU) - if(${BOARD} STREQUAL "nrf5340dk_nrf5340_cpuapp") +set(BUILD_WITH_DFU "MATTER" CACHE STRING "Build target with Device Firmware Upgrade support") + +if(NOT BUILD_WITH_DFU STREQUAL "OFF") + if(BUILD_WITH_DFU STREQUAL "BLE") + if(BOARD STREQUAL "nrf5340dk_nrf5340_cpuapp") list(INSERT OVERLAY_CONFIG 0 ${CHIP_ROOT}/config/nrfconnect/app/overlay-multi_image_smp_dfu_support.conf) + else() + list(INSERT OVERLAY_CONFIG 0 ${CHIP_ROOT}/config/nrfconnect/app/overlay-single_image_smp_dfu_support.conf) + endif() + elseif(NOT BUILD_WITH_DFU STREQUAL "MATTER") + message(FATAL_ERROR "Selected invalid BUILD_WITH_DFU value: ${BUILD_WITH_DFU}") + endif() + + list(INSERT OVERLAY_CONFIG 0 ${CHIP_ROOT}/config/nrfconnect/app/overlay-mcuboot_qspi_nor_support.conf) + list(INSERT OVERLAY_CONFIG 0 ${CHIP_ROOT}/config/nrfconnect/app/overlay-ota_requestor.conf) + + if(BOARD STREQUAL "nrf5340dk_nrf5340_cpuapp") + # DFU over Matter doesn't support multi-image update yet, but using this configs should not harm it anyway. set(mcuboot_OVERLAY_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/configuration/mcuboot_multi_image_dfu.conf CACHE INTERNAL "") else() - list(INSERT OVERLAY_CONFIG 0 ${CHIP_ROOT}/config/nrfconnect/app/overlay-single_image_smp_dfu_support.conf) set(mcuboot_OVERLAY_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/configuration/mcuboot_single_image_dfu.conf CACHE INTERNAL "") endif() - list(INSERT OVERLAY_CONFIG 0 ${CHIP_ROOT}/config/nrfconnect/app/overlay-mcuboot_qspi_nor_support.conf) + set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static.yml) endif() @@ -80,6 +93,6 @@ chip_configure_data_model(app ZAP_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../pump-common/pump-app.zap ) -if(BUILD_WITH_DFU) +if(BUILD_WITH_DFU STREQUAL "BLE") target_sources(app PRIVATE ${NRFCONNECT_COMMON}/util/DFUOverSMP.cpp) endif() diff --git a/examples/pump-app/nrfconnect/README.md b/examples/pump-app/nrfconnect/README.md index 857c7909cd241e..c9dbacc8ee7f6f 100644 --- a/examples/pump-app/nrfconnect/README.md +++ b/examples/pump-app/nrfconnect/README.md @@ -24,6 +24,7 @@ into an existing Matter network and can be controlled by this network. - [Overview](#overview) - [Bluetooth LE advertising](#bluetooth-le-advertising) - [Bluetooth LE rendezvous](#bluetooth-le-rendezvous) + - [Device Firmware Upgrade](#device-firmware-upgrade) - [Requirements](#requirements) - [Supported devices](#supported_devices) - [Device UI](#device-ui) @@ -60,6 +61,9 @@ default settings by pressing button manually. However, this mode does not guarantee that the device will be able to communicate with the Matter controller and other devices. +The example can be configured to use the secure bootloader and utilize it for +performing over-the-air Device Firmware Upgrade using Bluetooth LE. + ### Bluetooth LE advertising In this example, to commission the device onto a Matter network, it must be @@ -85,6 +89,63 @@ sending the Thread network credentials from the Matter controller to the Matter device. As a result, device is able to join the Thread network and communicate with other Thread devices in the network. +### Device Firmware Upgrade + +The example supports over-the-air (OTA) device firmware upgrade (DFU) using one +of the two available methods: + +- Matter OTA update that is mandatory for Matter-compliant devices and enabled + by default +- [Simple Management Protocol](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/guides/device_mgmt/index.html#device-mgmt) + over Bluetooth LE, an optional proprietary method that can be enabled to + work alongside the default Matter OTA update. Note that this protocol is not + a part of the Matter specification. + +For both methods, the +[MCUboot](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/mcuboot/index.html) +bootloader solution is used to replace the old firmware image with the new one. + +#### Matter Over-the-Air Update + +The Matter over-the-air update distinguishes two types of nodes: OTA Provider +and OTA Requestor. + +An OTA Provider is a node that hosts a new firmware image and is able to respond +on an OTA Requestor's queries regarding availability of new firmware images or +requests to start sending the update packages. + +An OTA Requestor is a node that wants to download a new firmware image and sends +requests to an OTA Provider to start the update process. + +#### Simple Management Protocol + +Simple Management Protocol (SMP) is a basic transfer encoding that is used for +device management purposes, including application image management. SMP supports +using different transports, such as Bluetooth LE, UDP, or serial USB/UART. + +In this example, the Matter device runs the SMP Server to download the +application update image using the Bluetooth LE transport. + +See the +[Building with Device Firmware Upgrade support](#building-with-device-firmware-upgrade-support) +section to learn how to enable SMP and use it for the DFU purpose in this +example. + +#### Bootloader + +MCUboot is a secure bootloader used for swapping firmware images of different +versions and generating proper build output files that can be used in the device +firmware upgrade process. + +The bootloader solution requires an area of flash memory to swap application +images during the firmware upgrade. Nordic Semiconductor devices use an external +memory chip for this purpose. The memory chip communicates with the +microcontroller through the QSPI bus. + +See the +[Building with Device Firmware Upgrade support](#building-with-device-firmware-upgrade-support) +section to learn how to change MCUboot and flash configuration in this example. +
@@ -312,6 +373,76 @@ features like logs and command-line interface, run the following command: Remember to replace _build-target_ with the build target name of the Nordic Semiconductor's kit you own. +### Building with Device Firmware Upgrade support + +Support for DFU using Matter OTA is enabled by default. + +To enable DFU over Bluetooth LE, run the following command with _build-target_ +replaced with the build target name of the Nordic Semiconductor kit you are +using (for example `nrf52840dk_nrf52840`): + + $ west build -b build-target -- -DBUILD_WITH_DFU=BLE + +To completely disable support for both DFU methods, run the following command +with _build-target_ replaced with the build target name of the Nordic +Semiconductor kit you are using (for example `nrf52840dk_nrf52840`): + + $ west build -b build-target -- -DBUILD_WITH_DFU=OFF + +> **Note**: +> +> There are two types of Device Firmware Upgrade modes: single-image DFU and +> multi-image DFU. Single-image mode supports upgrading only one firmware image, +> the application image, and should be used for single-core nRF52840 DK devices. +> Multi-image mode allows to upgrade more firmware images and is suitable for +> upgrading the application core and network core firmware in two-core nRF5340 +> DK devices. +> +> Currently the multi-image mode is only available for the DFU over Bluetooth LE +> method. + +#### Changing Device Firmware Upgrade configuration + +To change the default DFU configuration, edit the following overlay files +corresponding to the selected configuration: + +- `overlay-mcuboot_qspi_nor_support.conf` - general file enabling MCUboot and + QSPI NOR support, used by all DFU configurations +- `overlay-single_image_smp_dfu_support.conf` - file enabling single-image DFU + over Bluetooth LE using SMP +- `overlay-multi_image_smp_dfu_support.conf` - file enabling multi-image DFU + over Bluetooth LE using SMP +- `overlay-ota_requestor.conf` - file enabling Matter OTA Requestor support. + +The files are located in the `config/nrfconnect/app` directory. You can also +define the desired options in your example's `prj.conf` file. + +#### Changing bootloader configuration + +To change the default MCUboot configuration, edit the +`mcuboot_single_image_dfu.conf` or `mcuboot_multi_image_dfu.conf` overlay files +depending on whether the build target device supports multi-image DFU (nRF5340 +DK) or single-image DFU (nRF52840 DK). The files are located in the +`configuration` directory. + +Make sure to keep the configuration consistent with changes made to the +application configuration. This is necessary for the configuration to work, as +the bootloader image is a separate application from the user application and it +has its own configuration file. + +#### Changing flash memory settings + +In the default configuration, the MCUboot uses the +[Partition Manager](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/scripts/partition_manager/partition_manager.html#partition-manager) +to configure flash partitions used for the bootloader application image slot +purposes. You can change these settings by defining +[static partitions](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/scripts/partition_manager/partition_manager.html#ug-pm-static). +This example uses this option to define using an external flash. + +To modify the flash settings of your board (that is, your _build-target_, for +example `nrf52840dk_nrf52840`), edit the `pm_static.yml` file located in the +`configuration/build-target/` directory. +
@@ -344,7 +475,7 @@ page. To flash the application to the device, use the west tool and run the following command from the example directory: - $ west flash + $ west flash --erase If you have multiple development kits connected, west will prompt you to pick the correct one. diff --git a/examples/pump-app/nrfconnect/configuration/mcuboot_multi_image_dfu.conf b/examples/pump-app/nrfconnect/configuration/mcuboot_multi_image_dfu.conf index de4023efbc3c52..4daff546711a62 100644 --- a/examples/pump-app/nrfconnect/configuration/mcuboot_multi_image_dfu.conf +++ b/examples/pump-app/nrfconnect/configuration/mcuboot_multi_image_dfu.conf @@ -19,7 +19,6 @@ CONFIG_NORDIC_QSPI_NOR=y CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 -CONFIG_MULTITHREADING=y CONFIG_BOOT_MAX_IMG_SECTORS=256 # The following configurations are required to support simultaneous multi image update @@ -35,3 +34,19 @@ CONFIG_FLASH_SIMULATOR_STATS=n # Enable custom command to erase settings partition. CONFIG_ENABLE_MGMT_PERUSER=y CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE=y + +# bootloader size optimization +CONFIG_LOG=n +CONFIG_GPIO=n +CONFIG_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_BOOT_BANNER=n +CONFIG_TIMESLICING=n +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_MULTITHREADING=n +CONFIG_TICKLESS_KERNEL=n +CONFIG_TIMEOUT_64BIT=n +CONFIG_USE_SEGGER_RTT=n +CONFIG_NRF_ENABLE_ICACHE=n diff --git a/examples/pump-app/nrfconnect/configuration/mcuboot_single_image_dfu.conf b/examples/pump-app/nrfconnect/configuration/mcuboot_single_image_dfu.conf index 09e708c4e4dfff..4bd385555cf1b4 100644 --- a/examples/pump-app/nrfconnect/configuration/mcuboot_single_image_dfu.conf +++ b/examples/pump-app/nrfconnect/configuration/mcuboot_single_image_dfu.conf @@ -19,5 +19,20 @@ CONFIG_NORDIC_QSPI_NOR=y CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 -CONFIG_MULTITHREADING=y CONFIG_BOOT_MAX_IMG_SECTORS=256 + +# bootloader size optimization +CONFIG_LOG=n +CONFIG_GPIO=n +CONFIG_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_BOOT_BANNER=n +CONFIG_TIMESLICING=n +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_MULTITHREADING=n +CONFIG_TICKLESS_KERNEL=n +CONFIG_TIMEOUT_64BIT=n +CONFIG_USE_SEGGER_RTT=n +CONFIG_NRF_ENABLE_ICACHE=n diff --git a/examples/pump-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static.yml b/examples/pump-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static.yml index 372da532303458..9c26550c0902be 100644 --- a/examples/pump-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static.yml +++ b/examples/pump-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static.yml @@ -1,38 +1,38 @@ mcuboot: address: 0x0 - size: 0xc000 + size: 0x7000 region: flash_primary mcuboot_pad: - address: 0xc000 + address: 0x7000 size: 0x200 app: - address: 0xc200 - size: 0xebe00 + address: 0x7200 + size: 0xf0e00 mcuboot_primary: orig_span: &id001 - mcuboot_pad - app span: *id001 - address: 0xc000 - size: 0xec000 + address: 0x7000 + size: 0xf1000 region: flash_primary mcuboot_primary_app: orig_span: &id002 - app span: *id002 - address: 0xc200 - size: 0xebe00 + address: 0x7200 + size: 0xf0e00 settings_storage: address: 0xf8000 size: 0x8000 region: flash_primary mcuboot_secondary: address: 0x0 - size: 0xec000 + size: 0xf1000 device: MX25R64 region: external_flash external_flash: - address: 0xec000 - size: 0x714000 + address: 0xf1000 + size: 0x70f000 device: MX25R64 region: external_flash diff --git a/examples/pump-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static.yml b/examples/pump-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static.yml index d92415a16db549..9f9f677d8af4fc 100644 --- a/examples/pump-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static.yml +++ b/examples/pump-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static.yml @@ -1,27 +1,27 @@ mcuboot: address: 0x0 - size: 0x10000 + size: 0xC000 region: flash_primary mcuboot_pad: - address: 0x10000 + address: 0xC000 size: 0x200 app: - address: 0x10200 - size: 0xe7e00 + address: 0xC200 + size: 0xebe00 mcuboot_primary: orig_span: &id001 - mcuboot_pad - app span: *id001 - address: 0x10000 - size: 0xe8000 + address: 0xC000 + size: 0xec000 region: flash_primary mcuboot_primary_app: orig_span: &id002 - app span: *id002 - address: 0x10200 - size: 0xe7e00 + address: 0xC200 + size: 0xebe00 settings_storage: address: 0xf8000 size: 0x8000 @@ -33,17 +33,17 @@ mcuboot_primary_1: region: ram_flash mcuboot_secondary: address: 0x0 - size: 0xe8000 + size: 0xec000 device: MX25R64 region: external_flash mcuboot_secondary_1: - address: 0xe8000 + address: 0xec000 size: 0x40000 device: MX25R64 region: external_flash external_flash: - address: 0x128000 - size: 0x6d8000 + address: 0x12C000 + size: 0x6D4000 device: MX25R64 region: external_flash pcd_sram: diff --git a/examples/pump-app/nrfconnect/main/AppTask.cpp b/examples/pump-app/nrfconnect/main/AppTask.cpp index 832b103a68cac9..dc9d6b739a654b 100644 --- a/examples/pump-app/nrfconnect/main/AppTask.cpp +++ b/examples/pump-app/nrfconnect/main/AppTask.cpp @@ -36,10 +36,22 @@ #include #include +#if CONFIG_CHIP_OTA_REQUESTOR +#include +#include +#include +#include +#endif + #include #include #include +using namespace ::chip; +using namespace ::chip::app::Clusters; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; + #define FACTORY_RESET_TRIGGER_TIMEOUT 3000 #define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 3000 #define APP_EVENT_QUEUE_SIZE 10 @@ -49,23 +61,29 @@ #define PCC_CLUSTER_ENDPOINT 1 #define ONOFF_CLUSTER_ENDPOINT 1 +namespace { + LOG_MODULE_DECLARE(app); K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), APP_EVENT_QUEUE_SIZE, alignof(AppEvent)); +k_timer sFunctionTimer; + +LEDWidget sStatusLED; +LEDWidget sPumpStateLED; +LEDWidget sUnusedLED; +LEDWidget sUnusedLED_1; + +bool sIsThreadProvisioned = false; +bool sIsThreadEnabled = false; +bool sHaveBLEConnections = false; + +#if CONFIG_CHIP_OTA_REQUESTOR +GenericOTARequestorDriver sOTARequestorDriver; +OTAImageProcessorImpl sOTAImageProcessor; +chip::BDXDownloader sBDXDownloader; +chip::OTARequestor sOTARequestor; +#endif -static LEDWidget sStatusLED; -static LEDWidget sPumpStateLED; -static LEDWidget sUnusedLED; -static LEDWidget sUnusedLED_1; - -static bool sIsThreadProvisioned = false; -static bool sIsThreadEnabled = false; -static bool sHaveBLEConnections = false; - -static k_timer sFunctionTimer; - -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; -using namespace ::chip::app::Clusters; +} // namespace AppTask AppTask::sAppTask; @@ -138,6 +156,7 @@ CHIP_ERROR AppTask::Init() // Initialize CHIP server SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); + InitOTARequestor(); ReturnErrorOnFailure(chip::Server::GetInstance().Init()); ConfigurationMgr().LogDeviceConfig(); PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); @@ -156,6 +175,17 @@ CHIP_ERROR AppTask::Init() return err; } +void AppTask::InitOTARequestor() +{ +#if CONFIG_CHIP_OTA_REQUESTOR + sOTAImageProcessor.SetOTADownloader(&sBDXDownloader); + sBDXDownloader.SetImageProcessorDelegate(&sOTAImageProcessor); + sOTARequestorDriver.Init(&sOTARequestor, &sOTAImageProcessor); + sOTARequestor.Init(&chip::Server::GetInstance(), &sOTARequestorDriver, &sBDXDownloader); + chip::SetRequestorInstance(&sOTARequestor); +#endif +} + CHIP_ERROR AppTask::StartApp() { ReturnErrorOnFailure(Init()); diff --git a/examples/pump-app/nrfconnect/main/include/AppTask.h b/examples/pump-app/nrfconnect/main/include/AppTask.h index 7ca19cdc923f5c..42efbc747020f6 100644 --- a/examples/pump-app/nrfconnect/main/include/AppTask.h +++ b/examples/pump-app/nrfconnect/main/include/AppTask.h @@ -44,6 +44,7 @@ class AppTask friend AppTask & GetAppTask(void); CHIP_ERROR Init(); + void InitOTARequestor(); static void ActionInitiated(PumpManager::Action_t aAction, int32_t aActor); static void ActionCompleted(PumpManager::Action_t aAction, int32_t aActor); diff --git a/examples/pump-controller-app/nrfconnect/CMakeLists.txt b/examples/pump-controller-app/nrfconnect/CMakeLists.txt index 44b2c3b921d178..7cdf8f9ef9e1ce 100644 --- a/examples/pump-controller-app/nrfconnect/CMakeLists.txt +++ b/examples/pump-controller-app/nrfconnect/CMakeLists.txt @@ -29,16 +29,29 @@ if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD}.conf) list(APPEND CONF_FILE boards/${BOARD}.conf) endif() -option(BUILD_WITH_DFU "Build target with Device Firmware Upgrade support" OFF) -if(BUILD_WITH_DFU) - if(${BOARD} STREQUAL "nrf5340dk_nrf5340_cpuapp") +set(BUILD_WITH_DFU "MATTER" CACHE STRING "Build target with Device Firmware Upgrade support") + +if(NOT BUILD_WITH_DFU STREQUAL "OFF") + if(BUILD_WITH_DFU STREQUAL "BLE") + if(BOARD STREQUAL "nrf5340dk_nrf5340_cpuapp") list(INSERT OVERLAY_CONFIG 0 ${CHIP_ROOT}/config/nrfconnect/app/overlay-multi_image_smp_dfu_support.conf) + else() + list(INSERT OVERLAY_CONFIG 0 ${CHIP_ROOT}/config/nrfconnect/app/overlay-single_image_smp_dfu_support.conf) + endif() + elseif(NOT BUILD_WITH_DFU STREQUAL "MATTER") + message(FATAL_ERROR "Selected invalid BUILD_WITH_DFU value: ${BUILD_WITH_DFU}") + endif() + + list(INSERT OVERLAY_CONFIG 0 ${CHIP_ROOT}/config/nrfconnect/app/overlay-mcuboot_qspi_nor_support.conf) + list(INSERT OVERLAY_CONFIG 0 ${CHIP_ROOT}/config/nrfconnect/app/overlay-ota_requestor.conf) + + if(BOARD STREQUAL "nrf5340dk_nrf5340_cpuapp") + # DFU over Matter doesn't support multi-image update yet, but using this configs should not harm it anyway. set(mcuboot_OVERLAY_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/configuration/mcuboot_multi_image_dfu.conf CACHE INTERNAL "") else() - list(INSERT OVERLAY_CONFIG 0 ${CHIP_ROOT}/config/nrfconnect/app/overlay-single_image_smp_dfu_support.conf) set(mcuboot_OVERLAY_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/configuration/mcuboot_single_image_dfu.conf CACHE INTERNAL "") endif() - list(INSERT OVERLAY_CONFIG 0 ${CHIP_ROOT}/config/nrfconnect/app/overlay-mcuboot_qspi_nor_support.conf) + set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static.yml) endif() @@ -80,6 +93,6 @@ chip_configure_data_model(app ZAP_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../pump-controller-common/pump-controller-app.zap ) -if(BUILD_WITH_DFU) +if(BUILD_WITH_DFU STREQUAL "BLE") target_sources(app PRIVATE ${NRFCONNECT_COMMON}/util/DFUOverSMP.cpp) endif() diff --git a/examples/pump-controller-app/nrfconnect/README.md b/examples/pump-controller-app/nrfconnect/README.md index 7328417c1948c5..bfe847869c5cda 100644 --- a/examples/pump-controller-app/nrfconnect/README.md +++ b/examples/pump-controller-app/nrfconnect/README.md @@ -25,6 +25,7 @@ into an existing Matter network and can be controlled by this network. - [Overview](#overview) - [Bluetooth LE advertising](#bluetooth-le-advertising) - [Bluetooth LE rendezvous](#bluetooth-le-rendezvous) + - [Device Firmware Upgrade](#device-firmware-upgrade) - [Requirements](#requirements) - [Supported devices](#supported_devices) - [Device UI](#device-ui) @@ -61,6 +62,9 @@ default settings by pressing button manually. However, this mode does not guarantee that the device will be able to communicate with the Matter controller and other devices. +The example can be configured to use the secure bootloader and utilize it for +performing over-the-air Device Firmware Upgrade using Bluetooth LE. + ### Bluetooth LE advertising In this example, to commission the device onto a Matter network, it must be @@ -86,6 +90,63 @@ sending the Thread network credentials from the Matter controller to the Matter device. As a result, device is able to join the Thread network and communicate with other Thread devices in the network. +### Device Firmware Upgrade + +The example supports over-the-air (OTA) device firmware upgrade (DFU) using one +of the two available methods: + +- Matter OTA update that is mandatory for Matter-compliant devices and enabled + by default +- [Simple Management Protocol](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/guides/device_mgmt/index.html#device-mgmt) + over Bluetooth LE, an optional proprietary method that can be enabled to + work alongside the default Matter OTA update. Note that this protocol is not + a part of the Matter specification. + +For both methods, the +[MCUboot](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/mcuboot/index.html) +bootloader solution is used to replace the old firmware image with the new one. + +#### Matter Over-the-Air Update + +The Matter over-the-air update distinguishes two types of nodes: OTA Provider +and OTA Requestor. + +An OTA Provider is a node that hosts a new firmware image and is able to respond +on an OTA Requestor's queries regarding availability of new firmware images or +requests to start sending the update packages. + +An OTA Requestor is a node that wants to download a new firmware image and sends +requests to an OTA Provider to start the update process. + +#### Simple Management Protocol + +Simple Management Protocol (SMP) is a basic transfer encoding that is used for +device management purposes, including application image management. SMP supports +using different transports, such as Bluetooth LE, UDP, or serial USB/UART. + +In this example, the Matter device runs the SMP Server to download the +application update image using the Bluetooth LE transport. + +See the +[Building with Device Firmware Upgrade support](#building-with-device-firmware-upgrade-support) +section to learn how to enable SMP and use it for the DFU purpose in this +example. + +#### Bootloader + +MCUboot is a secure bootloader used for swapping firmware images of different +versions and generating proper build output files that can be used in the device +firmware upgrade process. + +The bootloader solution requires an area of flash memory to swap application +images during the firmware upgrade. Nordic Semiconductor devices use an external +memory chip for this purpose. The memory chip communicates with the +microcontroller through the QSPI bus. + +See the +[Building with Device Firmware Upgrade support](#building-with-device-firmware-upgrade-support) +section to learn how to change MCUboot and flash configuration in this example. +
@@ -312,6 +373,76 @@ features like logs and command-line interface, run the following command: Remember to replace _build-target_ with the build target name of the Nordic Semiconductor's kit you own. +### Building with Device Firmware Upgrade support + +Support for DFU using Matter OTA is enabled by default. + +To enable DFU over Bluetooth LE, run the following command with _build-target_ +replaced with the build target name of the Nordic Semiconductor kit you are +using (for example `nrf52840dk_nrf52840`): + + $ west build -b build-target -- -DBUILD_WITH_DFU=BLE + +To completely disable support for both DFU methods, run the following command +with _build-target_ replaced with the build target name of the Nordic +Semiconductor kit you are using (for example `nrf52840dk_nrf52840`): + + $ west build -b build-target -- -DBUILD_WITH_DFU=OFF + +> **Note**: +> +> There are two types of Device Firmware Upgrade modes: single-image DFU and +> multi-image DFU. Single-image mode supports upgrading only one firmware image, +> the application image, and should be used for single-core nRF52840 DK devices. +> Multi-image mode allows to upgrade more firmware images and is suitable for +> upgrading the application core and network core firmware in two-core nRF5340 +> DK devices. +> +> Currently the multi-image mode is only available for the DFU over Bluetooth LE +> method. + +#### Changing Device Firmware Upgrade configuration + +To change the default DFU configuration, edit the following overlay files +corresponding to the selected configuration: + +- `overlay-mcuboot_qspi_nor_support.conf` - general file enabling MCUboot and + QSPI NOR support, used by all DFU configurations +- `overlay-single_image_smp_dfu_support.conf` - file enabling single-image DFU + over Bluetooth LE using SMP +- `overlay-multi_image_smp_dfu_support.conf` - file enabling multi-image DFU + over Bluetooth LE using SMP +- `overlay-ota_requestor.conf` - file enabling Matter OTA Requestor support. + +The files are located in the `config/nrfconnect/app` directory. You can also +define the desired options in your example's `prj.conf` file. + +#### Changing bootloader configuration + +To change the default MCUboot configuration, edit the +`mcuboot_single_image_dfu.conf` or `mcuboot_multi_image_dfu.conf` overlay files +depending on whether the build target device supports multi-image DFU (nRF5340 +DK) or single-image DFU (nRF52840 DK). The files are located in the +`configuration` directory. + +Make sure to keep the configuration consistent with changes made to the +application configuration. This is necessary for the configuration to work, as +the bootloader image is a separate application from the user application and it +has its own configuration file. + +#### Changing flash memory settings + +In the default configuration, the MCUboot uses the +[Partition Manager](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/scripts/partition_manager/partition_manager.html#partition-manager) +to configure flash partitions used for the bootloader application image slot +purposes. You can change these settings by defining +[static partitions](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/scripts/partition_manager/partition_manager.html#ug-pm-static). +This example uses this option to define using an external flash. + +To modify the flash settings of your board (that is, your _build-target_, for +example `nrf52840dk_nrf52840`), edit the `pm_static.yml` file located in the +`configuration/build-target/` directory. +
diff --git a/examples/pump-controller-app/nrfconnect/configuration/mcuboot_multi_image_dfu.conf b/examples/pump-controller-app/nrfconnect/configuration/mcuboot_multi_image_dfu.conf index de4023efbc3c52..ccc69439f449f0 100644 --- a/examples/pump-controller-app/nrfconnect/configuration/mcuboot_multi_image_dfu.conf +++ b/examples/pump-controller-app/nrfconnect/configuration/mcuboot_multi_image_dfu.conf @@ -19,7 +19,6 @@ CONFIG_NORDIC_QSPI_NOR=y CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 -CONFIG_MULTITHREADING=y CONFIG_BOOT_MAX_IMG_SECTORS=256 # The following configurations are required to support simultaneous multi image update @@ -35,3 +34,19 @@ CONFIG_FLASH_SIMULATOR_STATS=n # Enable custom command to erase settings partition. CONFIG_ENABLE_MGMT_PERUSER=y CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE=y + +# bootloader size optimization +CONFIG_LOG=n +CONFIG_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_BOOT_BANNER=n +CONFIG_TIMESLICING=n +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_MULTITHREADING=n +CONFIG_TICKLESS_KERNEL=n +CONFIG_TIMEOUT_64BIT=n +CONFIG_USE_SEGGER_RTT=n +CONFIG_GPIO=n +CONFIG_NRF_ENABLE_ICACHE=n diff --git a/examples/pump-controller-app/nrfconnect/configuration/mcuboot_single_image_dfu.conf b/examples/pump-controller-app/nrfconnect/configuration/mcuboot_single_image_dfu.conf index 09e708c4e4dfff..807ba68b805796 100644 --- a/examples/pump-controller-app/nrfconnect/configuration/mcuboot_single_image_dfu.conf +++ b/examples/pump-controller-app/nrfconnect/configuration/mcuboot_single_image_dfu.conf @@ -19,5 +19,20 @@ CONFIG_NORDIC_QSPI_NOR=y CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 -CONFIG_MULTITHREADING=y CONFIG_BOOT_MAX_IMG_SECTORS=256 + +# bootloader size optimization +CONFIG_LOG=n +CONFIG_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_BOOT_BANNER=n +CONFIG_TIMESLICING=n +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_MULTITHREADING=n +CONFIG_TICKLESS_KERNEL=n +CONFIG_TIMEOUT_64BIT=n +CONFIG_USE_SEGGER_RTT=n +CONFIG_GPIO=n +CONFIG_NRF_ENABLE_ICACHE=n diff --git a/examples/pump-controller-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static.yml b/examples/pump-controller-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static.yml index 372da532303458..9c26550c0902be 100644 --- a/examples/pump-controller-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static.yml +++ b/examples/pump-controller-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static.yml @@ -1,38 +1,38 @@ mcuboot: address: 0x0 - size: 0xc000 + size: 0x7000 region: flash_primary mcuboot_pad: - address: 0xc000 + address: 0x7000 size: 0x200 app: - address: 0xc200 - size: 0xebe00 + address: 0x7200 + size: 0xf0e00 mcuboot_primary: orig_span: &id001 - mcuboot_pad - app span: *id001 - address: 0xc000 - size: 0xec000 + address: 0x7000 + size: 0xf1000 region: flash_primary mcuboot_primary_app: orig_span: &id002 - app span: *id002 - address: 0xc200 - size: 0xebe00 + address: 0x7200 + size: 0xf0e00 settings_storage: address: 0xf8000 size: 0x8000 region: flash_primary mcuboot_secondary: address: 0x0 - size: 0xec000 + size: 0xf1000 device: MX25R64 region: external_flash external_flash: - address: 0xec000 - size: 0x714000 + address: 0xf1000 + size: 0x70f000 device: MX25R64 region: external_flash diff --git a/examples/pump-controller-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static.yml b/examples/pump-controller-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static.yml index d92415a16db549..9f9f677d8af4fc 100644 --- a/examples/pump-controller-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static.yml +++ b/examples/pump-controller-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static.yml @@ -1,27 +1,27 @@ mcuboot: address: 0x0 - size: 0x10000 + size: 0xC000 region: flash_primary mcuboot_pad: - address: 0x10000 + address: 0xC000 size: 0x200 app: - address: 0x10200 - size: 0xe7e00 + address: 0xC200 + size: 0xebe00 mcuboot_primary: orig_span: &id001 - mcuboot_pad - app span: *id001 - address: 0x10000 - size: 0xe8000 + address: 0xC000 + size: 0xec000 region: flash_primary mcuboot_primary_app: orig_span: &id002 - app span: *id002 - address: 0x10200 - size: 0xe7e00 + address: 0xC200 + size: 0xebe00 settings_storage: address: 0xf8000 size: 0x8000 @@ -33,17 +33,17 @@ mcuboot_primary_1: region: ram_flash mcuboot_secondary: address: 0x0 - size: 0xe8000 + size: 0xec000 device: MX25R64 region: external_flash mcuboot_secondary_1: - address: 0xe8000 + address: 0xec000 size: 0x40000 device: MX25R64 region: external_flash external_flash: - address: 0x128000 - size: 0x6d8000 + address: 0x12C000 + size: 0x6D4000 device: MX25R64 region: external_flash pcd_sram: diff --git a/examples/pump-controller-app/nrfconnect/main/AppTask.cpp b/examples/pump-controller-app/nrfconnect/main/AppTask.cpp index 1d8d85b3955921..d46659748df911 100644 --- a/examples/pump-controller-app/nrfconnect/main/AppTask.cpp +++ b/examples/pump-controller-app/nrfconnect/main/AppTask.cpp @@ -36,32 +36,51 @@ #include #include +#if CONFIG_CHIP_OTA_REQUESTOR +#include +#include +#include +#include +#endif + #include #include #include +using namespace ::chip; +using namespace ::chip::app; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; + #define FACTORY_RESET_TRIGGER_TIMEOUT 3000 #define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 3000 #define APP_EVENT_QUEUE_SIZE 10 #define BUTTON_PUSH_EVENT 1 #define BUTTON_RELEASE_EVENT 0 +namespace { + LOG_MODULE_DECLARE(app); K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), APP_EVENT_QUEUE_SIZE, alignof(AppEvent)); +k_timer sFunctionTimer; + +LEDWidget sStatusLED; +LEDWidget sPumpStateLED; +LEDWidget sUnusedLED; +LEDWidget sUnusedLED_1; + +bool sIsThreadProvisioned = false; +bool sIsThreadEnabled = false; +bool sHaveBLEConnections = false; + +#if CONFIG_CHIP_OTA_REQUESTOR +GenericOTARequestorDriver sOTARequestorDriver; +OTAImageProcessorImpl sOTAImageProcessor; +chip::BDXDownloader sBDXDownloader; +chip::OTARequestor sOTARequestor; +#endif -static LEDWidget sStatusLED; -static LEDWidget sPumpStateLED; -static LEDWidget sUnusedLED; -static LEDWidget sUnusedLED_1; - -static bool sIsThreadProvisioned = false; -static bool sIsThreadEnabled = false; -static bool sHaveBLEConnections = false; - -static k_timer sFunctionTimer; - -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; +} // namespace AppTask AppTask::sAppTask; @@ -134,6 +153,7 @@ CHIP_ERROR AppTask::Init() // Initialize CHIP server SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); + InitOTARequestor(); ReturnErrorOnFailure(chip::Server::GetInstance().Init()); ConfigurationMgr().LogDeviceConfig(); PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); @@ -152,6 +172,17 @@ CHIP_ERROR AppTask::Init() return err; } +void AppTask::InitOTARequestor() +{ +#if CONFIG_CHIP_OTA_REQUESTOR + sOTAImageProcessor.SetOTADownloader(&sBDXDownloader); + sBDXDownloader.SetImageProcessorDelegate(&sOTAImageProcessor); + sOTARequestorDriver.Init(&sOTARequestor, &sOTAImageProcessor); + sOTARequestor.Init(&chip::Server::GetInstance(), &sOTARequestorDriver, &sBDXDownloader); + chip::SetRequestorInstance(&sOTARequestor); +#endif +} + CHIP_ERROR AppTask::StartApp() { ReturnErrorOnFailure(Init()); diff --git a/examples/pump-controller-app/nrfconnect/main/include/AppTask.h b/examples/pump-controller-app/nrfconnect/main/include/AppTask.h index 7ca19cdc923f5c..42efbc747020f6 100644 --- a/examples/pump-controller-app/nrfconnect/main/include/AppTask.h +++ b/examples/pump-controller-app/nrfconnect/main/include/AppTask.h @@ -44,6 +44,7 @@ class AppTask friend AppTask & GetAppTask(void); CHIP_ERROR Init(); + void InitOTARequestor(); static void ActionInitiated(PumpManager::Action_t aAction, int32_t aActor); static void ActionCompleted(PumpManager::Action_t aAction, int32_t aActor); diff --git a/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter b/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter index 7640967e7bddb7..1c99965aa42a62 100644 --- a/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter +++ b/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter @@ -577,6 +577,141 @@ server cluster NetworkCommissioning = 49 { command ScanNetworks(ScanNetworksRequest): ScanNetworksResponse = 0; } +client cluster OtaSoftwareUpdateProvider = 41 { + enum OTAApplyUpdateAction : ENUM8 { + kProceed = 0; + kAwaitNextAction = 1; + kDiscontinue = 2; + } + + enum OTADownloadProtocol : ENUM8 { + kBDXSynchronous = 0; + kBDXAsynchronous = 1; + kHttps = 2; + kVendorSpecific = 3; + } + + enum OTAQueryStatus : ENUM8 { + kUpdateAvailable = 0; + kBusy = 1; + kNotAvailable = 2; + kDownloadProtocolNotSupported = 3; + } + + + request struct ApplyUpdateRequestRequest { + OCTET_STRING updateToken = 0; + INT32U newVersion = 1; + } + + request struct NotifyUpdateAppliedRequest { + OCTET_STRING updateToken = 0; + INT32U softwareVersion = 1; + } + + request struct QueryImageRequest { + vendor_id vendorId = 0; + INT16U productId = 1; + INT32U softwareVersion = 2; + OTADownloadProtocol protocolsSupported[] = 3; + optional INT16U hardwareVersion = 4; + optional CHAR_STRING location = 5; + optional BOOLEAN requestorCanConsent = 6; + optional OCTET_STRING metadataForProvider = 7; + } + + response struct ApplyUpdateResponse { + OTAApplyUpdateAction action = 0; + INT32U delayedActionTime = 1; + } + + response struct QueryImageResponse { + OTAQueryStatus status = 0; + optional INT32U delayedActionTime = 1; + optional CHAR_STRING imageURI = 2; + optional INT32U softwareVersion = 3; + optional CHAR_STRING softwareVersionString = 4; + optional OCTET_STRING updateToken = 5; + optional BOOLEAN userConsentNeeded = 6; + optional OCTET_STRING metadataForRequestor = 7; + } + + command ApplyUpdateRequest(ApplyUpdateRequestRequest): ApplyUpdateResponse = 2; + command NotifyUpdateApplied(NotifyUpdateAppliedRequest): DefaultSuccess = 4; + command QueryImage(QueryImageRequest): QueryImageResponse = 0; +} + +server cluster OtaSoftwareUpdateRequestor = 42 { + enum OTAAnnouncementReason : ENUM8 { + kSimpleAnnouncement = 0; + kUpdateAvailable = 1; + kUrgentUpdateAvailable = 2; + } + + enum OTAChangeReasonEnum : ENUM8 { + kUnknown = 0; + kSuccess = 1; + kFailure = 2; + kTimeOut = 3; + kDelayByProvider = 4; + } + + enum OTAUpdateStateEnum : ENUM8 { + kUnknown = 0; + kIdle = 1; + kQuerying = 2; + kDelayedOnQuery = 3; + kDownloading = 4; + kApplying = 5; + kDelayedOnApply = 6; + kRollingBack = 7; + kDelayedOnUserConsent = 8; + } + + struct ProviderLocation { + fabric_idx fabricIndex = 0; + node_id providerNodeID = 1; + endpoint_no endpoint = 2; + } + + info event StateTransition = 0 { + OTAUpdateStateEnum previousState = 0; + OTAUpdateStateEnum newState = 1; + OTAChangeReasonEnum reason = 2; + nullable INT32U targetSoftwareVersion = 3; + } + + critical event VersionApplied = 1 { + INT32U softwareVersion = 0; + INT16U productID = 1; + } + + info event DownloadError = 2 { + INT32U softwareVersion = 0; + INT64U bytesDownloaded = 1; + nullable INT8U progressPercent = 2; + nullable INT64S platformCode = 3; + } + + attribute ProviderLocation defaultOtaProviders[] = 0; + readonly attribute boolean updatePossible = 1; + readonly attribute OTAUpdateStateEnum updateState = 2; + readonly attribute nullable int8u updateStateProgress = 3; + readonly global attribute command_id serverGeneratedCommandList[] = 65528; + readonly global attribute command_id clientGeneratedCommandList[] = 65529; + readonly global attribute int16u clusterRevision = 65533; + + request struct AnnounceOtaProviderRequest { + node_id providerNodeId = 0; + vendor_id vendorId = 1; + OTAAnnouncementReason announcementReason = 2; + optional OCTET_STRING metadataForNode = 3; + endpoint_no endpoint = 4; + } + + command AnnounceOtaProvider(AnnounceOtaProviderRequest): DefaultSuccess = 0; +} + client cluster OnOff = 6 { enum OnOffDelayedAllOffEffectVariant : enum8 { kFadeToOffIn0p8Seconds = 0; @@ -1121,6 +1256,8 @@ endpoint 0 { binding cluster LevelControl; server cluster LocalizationConfiguration; server cluster NetworkCommissioning; + binding cluster OtaSoftwareUpdateProvider; + server cluster OtaSoftwareUpdateRequestor; server cluster OperationalCredentials; server cluster SoftwareDiagnostics; server cluster ThreadNetworkDiagnostics; diff --git a/examples/pump-controller-app/pump-controller-common/pump-controller-app.zap b/examples/pump-controller-app/pump-controller-common/pump-controller-app.zap index b58fcefd651427..748cacf90639a0 100644 --- a/examples/pump-controller-app/pump-controller-common/pump-controller-app.zap +++ b/examples/pump-controller-app/pump-controller-common/pump-controller-app.zap @@ -1265,6 +1265,264 @@ } ] }, + { + "name": "OTA Software Update Provider", + "code": 41, + "mfgCode": null, + "define": "OTA_PROVIDER_CLUSTER", + "side": "client", + "enabled": 1, + "commands": [ + { + "name": "QueryImage", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "ApplyUpdateRequest", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "NotifyUpdateApplied", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 0, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "client", + "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": "client", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "OTA Software Update Provider", + "code": 41, + "mfgCode": null, + "define": "OTA_PROVIDER_CLUSTER", + "side": "server", + "enabled": 0, + "commands": [ + { + "name": "QueryImageResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "ApplyUpdateResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [] + }, + { + "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": "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": "", + "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": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "UpdateState", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "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": "ServerGeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientGeneratedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "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": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, { "name": "Localization Configuration", "code": 43, @@ -1785,7 +2043,7 @@ "mfgCode": null, "side": "server", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, "defaultValue": "", @@ -1890,7 +2148,7 @@ "mfgCode": null, "side": "server", "included": 0, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, "defaultValue": "", @@ -4031,7 +4289,7 @@ "reportableChange": 0 }, { - "name": "fabrics list", + "name": "Fabrics", "code": 1, "mfgCode": null, "side": "server", @@ -6478,5 +6736,6 @@ "endpointVersion": 1, "deviceIdentifier": 772 } - ] -} \ No newline at end of file + ], + "log": [] +} diff --git a/zzz_generated/pump-controller-app/zap-generated/CHIPClusters.h b/zzz_generated/pump-controller-app/zap-generated/CHIPClusters.h index 89278b783a8d78..ac67a86ce8e939 100644 --- a/zzz_generated/pump-controller-app/zap-generated/CHIPClusters.h +++ b/zzz_generated/pump-controller-app/zap-generated/CHIPClusters.h @@ -44,6 +44,13 @@ class DLL_EXPORT LevelControlCluster : public ClusterBase ~LevelControlCluster() {} }; +class DLL_EXPORT OtaSoftwareUpdateProviderCluster : public ClusterBase +{ +public: + OtaSoftwareUpdateProviderCluster() : ClusterBase(app::Clusters::OtaSoftwareUpdateProvider::Id) {} + ~OtaSoftwareUpdateProviderCluster() {} +}; + class DLL_EXPORT OnOffCluster : public ClusterBase { public: diff --git a/zzz_generated/pump-controller-app/zap-generated/IMClusterCommandHandler.cpp b/zzz_generated/pump-controller-app/zap-generated/IMClusterCommandHandler.cpp index 2e1a0e8e8c9a00..9587f7e6315da4 100644 --- a/zzz_generated/pump-controller-app/zap-generated/IMClusterCommandHandler.cpp +++ b/zzz_generated/pump-controller-app/zap-generated/IMClusterCommandHandler.cpp @@ -276,6 +276,44 @@ void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandP } // namespace NetworkCommissioning +namespace OtaSoftwareUpdateRequestor { + +void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) +{ + 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 OperationalCredentials { void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) @@ -409,6 +447,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::OperationalCredentials::Id: Clusters::OperationalCredentials::DispatchServerCommand(apCommandObj, aCommandPath, aReader); break; diff --git a/zzz_generated/pump-controller-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/pump-controller-app/zap-generated/PluginApplicationCallbacks.h index 9847c0f8007d71..3b3c191b1d97ca 100644 --- a/zzz_generated/pump-controller-app/zap-generated/PluginApplicationCallbacks.h +++ b/zzz_generated/pump-controller-app/zap-generated/PluginApplicationCallbacks.h @@ -35,6 +35,8 @@ MatterLevelControlPluginClientInitCallback(); \ MatterLocalizationConfigurationPluginServerInitCallback(); \ MatterNetworkCommissioningPluginServerInitCallback(); \ + MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ + MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ MatterOnOffPluginClientInitCallback(); \ MatterOperationalCredentialsPluginServerInitCallback(); \ MatterPressureMeasurementPluginClientInitCallback(); \ diff --git a/zzz_generated/pump-controller-app/zap-generated/callback-stub.cpp b/zzz_generated/pump-controller-app/zap-generated/callback-stub.cpp index 0ba195be460f15..b066afad83848a 100644 --- a/zzz_generated/pump-controller-app/zap-generated/callback-stub.cpp +++ b/zzz_generated/pump-controller-app/zap-generated/callback-stub.cpp @@ -68,6 +68,12 @@ void emberAfClusterInitCallback(EndpointId endpoint, ClusterId clusterId) case ZCL_NETWORK_COMMISSIONING_CLUSTER_ID: emberAfNetworkCommissioningClusterInitCallback(endpoint); break; + case ZCL_OTA_PROVIDER_CLUSTER_ID: + emberAfOtaSoftwareUpdateProviderClusterInitCallback(endpoint); + break; + case ZCL_OTA_REQUESTOR_CLUSTER_ID: + emberAfOtaSoftwareUpdateRequestorClusterInitCallback(endpoint); + break; case ZCL_ON_OFF_CLUSTER_ID: emberAfOnOffClusterInitCallback(endpoint); break; @@ -172,6 +178,16 @@ void __attribute__((weak)) emberAfNetworkCommissioningClusterInitCallback(Endpoi // To prevent warning (void) endpoint; } +void __attribute__((weak)) emberAfOtaSoftwareUpdateProviderClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfOtaSoftwareUpdateRequestorClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} void __attribute__((weak)) emberAfOnOffClusterInitCallback(EndpointId endpoint) { // To prevent warning diff --git a/zzz_generated/pump-controller-app/zap-generated/endpoint_config.h b/zzz_generated/pump-controller-app/zap-generated/endpoint_config.h index 2bf3b05744ca15..0725d0323d3b5c 100644 --- a/zzz_generated/pump-controller-app/zap-generated/endpoint_config.h +++ b/zzz_generated/pump-controller-app/zap-generated/endpoint_config.h @@ -532,7 +532,7 @@ #define ZAP_ATTRIBUTE_MASK(mask) ATTRIBUTE_MASK_##mask // This is an array of EmberAfAttributeMetadata structures. -#define GENERATED_ATTRIBUTE_COUNT 180 +#define GENERATED_ATTRIBUTE_COUNT 185 #define GENERATED_ATTRIBUTES \ { \ \ @@ -592,6 +592,14 @@ ZAP_EMPTY_DEFAULT() }, /* UniqueID */ \ { 0x0000FFFD, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(SINGLETON), ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ \ + /* Endpoint: 0, Cluster: OTA Software Update Requestor (server) */ \ + { 0x00000000, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(WRITABLE), \ + ZAP_EMPTY_DEFAULT() }, /* DefaultOtaProviders */ \ + { 0x00000001, ZAP_TYPE(BOOLEAN), 1, 0, ZAP_SIMPLE_DEFAULT(1) }, /* UpdatePossible */ \ + { 0x00000002, ZAP_TYPE(ENUM8), 1, 0, ZAP_SIMPLE_DEFAULT(0) }, /* UpdateState */ \ + { 0x00000003, ZAP_TYPE(INT8U), 1, ZAP_ATTRIBUTE_MASK(NULLABLE), ZAP_SIMPLE_DEFAULT(0) }, /* UpdateStateProgress */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ /* Endpoint: 0, Cluster: Localization Configuration (server) */ \ { 0x00000001, ZAP_TYPE(CHAR_STRING), 36, ZAP_ATTRIBUTE_MASK(TOKENIZE) | ZAP_ATTRIBUTE_MASK(WRITABLE), \ ZAP_LONG_DEFAULTS_INDEX(0) }, /* ActiveLocale */ \ @@ -812,6 +820,10 @@ // clang-format off #define GENERATED_COMMANDS { \ + /* Endpoint: 0, Cluster: OTA Software Update Requestor (server) */\ + /* client_generated */ \ + 0x00000000 /* AnnounceOtaProvider */, \ + chip::kInvalidCommandId /* end of list */, \ /* Endpoint: 0, Cluster: General Commissioning (server) */\ /* client_generated */ \ 0x00000000 /* ArmFailSafe */, \ @@ -876,7 +888,7 @@ // clang-format on #define ZAP_CLUSTER_MASK(mask) CLUSTER_MASK_##mask -#define GENERATED_CLUSTER_COUNT 25 +#define GENERATED_CLUSTER_COUNT 27 // clang-format off #define GENERATED_CLUSTERS { \ @@ -924,10 +936,32 @@ .clientGeneratedCommandList = nullptr ,\ .serverGeneratedCommandList = nullptr ,\ },\ + { \ + /* Endpoint: 0, Cluster: OTA Software Update Provider (client) */ \ + .clusterId = 0x00000029, \ + .attributes = ZAP_ATTRIBUTE_INDEX(28), \ + .attributeCount = 0, \ + .clusterSize = 0, \ + .mask = ZAP_CLUSTER_MASK(CLIENT), \ + .functions = NULL, \ + .clientGeneratedCommandList = nullptr ,\ + .serverGeneratedCommandList = nullptr ,\ + },\ + { \ + /* Endpoint: 0, Cluster: OTA Software Update Requestor (server) */ \ + .clusterId = 0x0000002A, \ + .attributes = ZAP_ATTRIBUTE_INDEX(28), \ + .attributeCount = 5, \ + .clusterSize = 5, \ + .mask = ZAP_CLUSTER_MASK(SERVER), \ + .functions = NULL, \ + .clientGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 0 ) ,\ + .serverGeneratedCommandList = nullptr ,\ + },\ { \ /* Endpoint: 0, Cluster: Localization Configuration (server) */ \ .clusterId = 0x0000002B, \ - .attributes = ZAP_ATTRIBUTE_INDEX(28), \ + .attributes = ZAP_ATTRIBUTE_INDEX(33), \ .attributeCount = 3, \ .clusterSize = 38, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(PRE_ATTRIBUTE_CHANGED_FUNCTION), \ @@ -938,7 +972,7 @@ { \ /* Endpoint: 0, Cluster: Time Format Localization (server) */ \ .clusterId = 0x0000002C, \ - .attributes = ZAP_ATTRIBUTE_INDEX(31), \ + .attributes = ZAP_ATTRIBUTE_INDEX(36), \ .attributeCount = 4, \ .clusterSize = 4, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(PRE_ATTRIBUTE_CHANGED_FUNCTION), \ @@ -949,7 +983,7 @@ { \ /* Endpoint: 0, Cluster: Unit Localization (server) */ \ .clusterId = 0x0000002D, \ - .attributes = ZAP_ATTRIBUTE_INDEX(35), \ + .attributes = ZAP_ATTRIBUTE_INDEX(40), \ .attributeCount = 3, \ .clusterSize = 7, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -960,40 +994,40 @@ { \ /* Endpoint: 0, Cluster: General Commissioning (server) */ \ .clusterId = 0x00000030, \ - .attributes = ZAP_ATTRIBUTE_INDEX(38), \ + .attributes = ZAP_ATTRIBUTE_INDEX(43), \ .attributeCount = 6, \ .clusterSize = 16, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ .functions = NULL, \ - .clientGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 0 ) ,\ - .serverGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 4 ) ,\ + .clientGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 2 ) ,\ + .serverGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 6 ) ,\ },\ { \ /* Endpoint: 0, Cluster: Network Commissioning (server) */ \ .clusterId = 0x00000031, \ - .attributes = ZAP_ATTRIBUTE_INDEX(44), \ + .attributes = ZAP_ATTRIBUTE_INDEX(49), \ .attributeCount = 10, \ .clusterSize = 48, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ .functions = NULL, \ - .clientGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 7 ) ,\ - .serverGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 14 ) ,\ + .clientGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 9 ) ,\ + .serverGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 16 ) ,\ },\ { \ /* Endpoint: 0, Cluster: Diagnostic Logs (server) */ \ .clusterId = 0x00000032, \ - .attributes = ZAP_ATTRIBUTE_INDEX(54), \ + .attributes = ZAP_ATTRIBUTE_INDEX(59), \ .attributeCount = 0, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ .functions = NULL, \ - .clientGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 17 ) ,\ + .clientGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 19 ) ,\ .serverGeneratedCommandList = nullptr ,\ },\ { \ /* Endpoint: 0, Cluster: General Diagnostics (server) */ \ .clusterId = 0x00000033, \ - .attributes = ZAP_ATTRIBUTE_INDEX(54), \ + .attributes = ZAP_ATTRIBUTE_INDEX(59), \ .attributeCount = 9, \ .clusterSize = 17, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -1004,18 +1038,18 @@ { \ /* Endpoint: 0, Cluster: Software Diagnostics (server) */ \ .clusterId = 0x00000034, \ - .attributes = ZAP_ATTRIBUTE_INDEX(63), \ + .attributes = ZAP_ATTRIBUTE_INDEX(68), \ .attributeCount = 6, \ .clusterSize = 30, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ .functions = NULL, \ - .clientGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 19 ) ,\ + .clientGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 21 ) ,\ .serverGeneratedCommandList = nullptr ,\ },\ { \ /* Endpoint: 0, Cluster: Thread Network Diagnostics (server) */ \ .clusterId = 0x00000035, \ - .attributes = ZAP_ATTRIBUTE_INDEX(69), \ + .attributes = ZAP_ATTRIBUTE_INDEX(74), \ .attributeCount = 65, \ .clusterSize = 247, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -1026,7 +1060,7 @@ { \ /* Endpoint: 0, Cluster: WiFi Network Diagnostics (server) */ \ .clusterId = 0x00000036, \ - .attributes = ZAP_ATTRIBUTE_INDEX(134), \ + .attributes = ZAP_ATTRIBUTE_INDEX(139), \ .attributeCount = 15, \ .clusterSize = 58, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -1037,40 +1071,40 @@ { \ /* Endpoint: 0, Cluster: Ethernet Network Diagnostics (server) */ \ .clusterId = 0x00000037, \ - .attributes = ZAP_ATTRIBUTE_INDEX(149), \ + .attributes = ZAP_ATTRIBUTE_INDEX(154), \ .attributeCount = 11, \ .clusterSize = 57, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ .functions = NULL, \ - .clientGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 21 ) ,\ + .clientGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 23 ) ,\ .serverGeneratedCommandList = nullptr ,\ },\ { \ /* Endpoint: 0, Cluster: AdministratorCommissioning (server) */ \ .clusterId = 0x0000003C, \ - .attributes = ZAP_ATTRIBUTE_INDEX(160), \ + .attributes = ZAP_ATTRIBUTE_INDEX(165), \ .attributeCount = 4, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ .functions = NULL, \ - .clientGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 23 ) ,\ + .clientGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 25 ) ,\ .serverGeneratedCommandList = nullptr ,\ },\ { \ /* Endpoint: 0, Cluster: Operational Credentials (server) */ \ .clusterId = 0x0000003E, \ - .attributes = ZAP_ATTRIBUTE_INDEX(164), \ + .attributes = ZAP_ATTRIBUTE_INDEX(169), \ .attributeCount = 7, \ .clusterSize = 4, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ .functions = NULL, \ - .clientGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 27 ) ,\ - .serverGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 37 ) ,\ + .clientGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 29 ) ,\ + .serverGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 39 ) ,\ },\ { \ /* Endpoint: 0, Cluster: Fixed Label (server) */ \ .clusterId = 0x00000040, \ - .attributes = ZAP_ATTRIBUTE_INDEX(171), \ + .attributes = ZAP_ATTRIBUTE_INDEX(176), \ .attributeCount = 2, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -1081,7 +1115,7 @@ { \ /* Endpoint: 0, Cluster: User Label (server) */ \ .clusterId = 0x00000041, \ - .attributes = ZAP_ATTRIBUTE_INDEX(173), \ + .attributes = ZAP_ATTRIBUTE_INDEX(178), \ .attributeCount = 2, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -1092,7 +1126,7 @@ { \ /* Endpoint: 1, Cluster: On/Off (client) */ \ .clusterId = 0x00000006, \ - .attributes = ZAP_ATTRIBUTE_INDEX(175), \ + .attributes = ZAP_ATTRIBUTE_INDEX(180), \ .attributeCount = 0, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(CLIENT), \ @@ -1103,7 +1137,7 @@ { \ /* Endpoint: 1, Cluster: Descriptor (server) */ \ .clusterId = 0x0000001D, \ - .attributes = ZAP_ATTRIBUTE_INDEX(175), \ + .attributes = ZAP_ATTRIBUTE_INDEX(180), \ .attributeCount = 5, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -1114,7 +1148,7 @@ { \ /* Endpoint: 1, Cluster: Pump Configuration and Control (client) */ \ .clusterId = 0x00000200, \ - .attributes = ZAP_ATTRIBUTE_INDEX(180), \ + .attributes = ZAP_ATTRIBUTE_INDEX(185), \ .attributeCount = 0, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(CLIENT), \ @@ -1125,7 +1159,7 @@ { \ /* Endpoint: 1, Cluster: Temperature Measurement (client) */ \ .clusterId = 0x00000402, \ - .attributes = ZAP_ATTRIBUTE_INDEX(180), \ + .attributes = ZAP_ATTRIBUTE_INDEX(185), \ .attributeCount = 0, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(CLIENT), \ @@ -1136,7 +1170,7 @@ { \ /* Endpoint: 1, Cluster: Pressure Measurement (client) */ \ .clusterId = 0x00000403, \ - .attributes = ZAP_ATTRIBUTE_INDEX(180), \ + .attributes = ZAP_ATTRIBUTE_INDEX(185), \ .attributeCount = 0, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(CLIENT), \ @@ -1147,7 +1181,7 @@ { \ /* Endpoint: 1, Cluster: Flow Measurement (client) */ \ .clusterId = 0x00000404, \ - .attributes = ZAP_ATTRIBUTE_INDEX(180), \ + .attributes = ZAP_ATTRIBUTE_INDEX(185), \ .attributeCount = 0, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(CLIENT), \ @@ -1161,12 +1195,12 @@ #define ZAP_CLUSTER_INDEX(index) (&generatedClusters[index]) -#define ZAP_FIXED_ENDPOINT_DATA_VERSION_COUNT 19 +#define ZAP_FIXED_ENDPOINT_DATA_VERSION_COUNT 20 // This is an array of EmberAfEndpointType structures. #define GENERATED_ENDPOINT_TYPES \ { \ - { ZAP_CLUSTER_INDEX(0), 19, 573 }, { ZAP_CLUSTER_INDEX(19), 6, 0 }, \ + { ZAP_CLUSTER_INDEX(0), 21, 578 }, { ZAP_CLUSTER_INDEX(21), 6, 0 }, \ } // Largest attribute size is needed for various buffers @@ -1178,7 +1212,7 @@ static_assert(ATTRIBUTE_LARGEST <= CHIP_CONFIG_MAX_ATTRIBUTE_STORE_ELEMENT_SIZE, #define ATTRIBUTE_SINGLETONS_SIZE (39) // Total size of attribute storage -#define ATTRIBUTE_MAX_SIZE (573) +#define ATTRIBUTE_MAX_SIZE (578) // Number of fixed endpoints #define FIXED_ENDPOINT_COUNT (2) diff --git a/zzz_generated/pump-controller-app/zap-generated/gen_config.h b/zzz_generated/pump-controller-app/zap-generated/gen_config.h index 169c25017ac914..ff37239ff303ba 100644 --- a/zzz_generated/pump-controller-app/zap-generated/gen_config.h +++ b/zzz_generated/pump-controller-app/zap-generated/gen_config.h @@ -42,6 +42,8 @@ #define EMBER_AF_LEVEL_CONTROL_CLUSTER_CLIENT_ENDPOINT_COUNT (1) #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_ON_OFF_CLUSTER_CLIENT_ENDPOINT_COUNT (1) #define EMBER_AF_OPERATIONAL_CREDENTIALS_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_PRESSURE_MEASUREMENT_CLUSTER_CLIENT_ENDPOINT_COUNT (1) @@ -119,6 +121,15 @@ #define EMBER_AF_PLUGIN_NETWORK_COMMISSIONING_SERVER #define EMBER_AF_PLUGIN_NETWORK_COMMISSIONING +// Use this macro to check if the client side of the OTA Software Update Provider cluster is included +#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 client side of the On/Off cluster is included #define ZCL_USING_ON_OFF_CLUSTER_CLIENT #define EMBER_AF_PLUGIN_ON_OFF_CLIENT