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