From fbf8bab0533807813f2f2f0356d93c2f90ef1127 Mon Sep 17 00:00:00 2001 From: Artur Tynecki <77382963+ATmobica@users.noreply.github.com> Date: Wed, 16 Feb 2022 06:36:17 +0100 Subject: [PATCH] [Mbed] DFU support to all Mbed examples applications (#14883) * Use MBED_CONF_STORAGE_DEFAULT_KV insted of hardcoded definition for CHIP_CONFIG_KV_STORE_PARTITION * Remove hack on confirmation from mbed_app.json files Remvoe hack from BLE manager - add note * Add Mbed OTA requestor driver implementation * Add software version string to update description * Move all generated sources from common Mbed cmake to OTA requestor app cmake * Add common Mbed DFU Manager - class to manage the firmware update * Add DFU support to all examples: lighting-app - OTA and boot lock-app - only boot all-clusters-app - OTA and boot pigweed-app - only boot shell - OTA and boot ota-requestor-app - OTA and boot * Add auto-restart device after update apply * Change log type in OTAImageProcessorImpl * Add server command to shell example * Add confirm and reject user repsone to buttons service Add user response to OTA udpate available and apply functions Docs update * Implement OTA list image generator Add python script to generate OTA list image Change working directory and add APP_DIRECTORY path Add generating OTA list image step for upgrade image build Set vendor id and product id from mbed_app.json level * Changes restyle * Update vendor and product IDs for mbed examples Cleanup data model configuration in cmake files * Fix data parsing in OTA list image generator --- config/mbed/CMakeLists.txt | 68 +-- examples/all-clusters-app/mbed/.gitignore | 1 + examples/all-clusters-app/mbed/CMakeLists.txt | 131 ++---- examples/all-clusters-app/mbed/config.in | 3 +- .../all-clusters-app/mbed/main/AppTask.cpp | 19 +- .../mbed/main/LowPowerManager.cpp | 25 - .../mbed/main/include/LowPowerManager.h | 27 -- examples/all-clusters-app/mbed/mbed_app.json | 27 +- examples/lighting-app/mbed/.gitignore | 1 + examples/lighting-app/mbed/CMakeLists.txt | 17 +- examples/lighting-app/mbed/config.in | 3 +- examples/lighting-app/mbed/main/AppTask.cpp | 52 ++- .../lighting-app/mbed/main/include/AppTask.h | 1 + examples/lighting-app/mbed/mbed_app.json | 27 +- examples/lock-app/mbed/.gitignore | 1 + examples/lock-app/mbed/CMakeLists.txt | 15 +- examples/lock-app/mbed/config.in | 3 +- examples/lock-app/mbed/main/AppTask.cpp | 43 +- examples/lock-app/mbed/main/include/AppTask.h | 1 + examples/lock-app/mbed/mbed_app.json | 31 +- .../ota-requestor-app/mbed/CMakeLists.txt | 16 +- examples/ota-requestor-app/mbed/README.md | 15 +- .../ota-requestor-app/mbed/main/AppTask.cpp | 426 +++++++++++------- .../mbed/main/include/AppEvent.h | 9 +- .../mbed/main/include/AppTask.h | 65 ++- .../mbed/main/include/CHIPProjectConfig.h | 8 - examples/ota-requestor-app/mbed/main/main.cpp | 18 - examples/ota-requestor-app/mbed/mbed_app.json | 40 +- examples/pigweed-app/mbed/.gitignore | 1 + examples/pigweed-app/mbed/CMakeLists.txt | 21 +- examples/pigweed-app/mbed/config.in | 3 +- .../mbed/main/include/CHIPProjectConfig.h | 8 + examples/pigweed-app/mbed/main/main.cpp | 19 +- examples/pigweed-app/mbed/mbed_app.json | 25 +- .../platform/mbed/bootloader/mbed_app.json | 6 +- .../mbed/ota/generate_ota_list_image.py | 85 ++++ examples/platform/mbed/util/DFUManager.cpp | 91 ++++ .../platform/mbed/util/include/DFUManager.h | 75 +++ examples/shell/mbed/.gitignore | 1 + examples/shell/mbed/CMakeLists.txt | 39 +- examples/shell/mbed/config.in | 1 + examples/shell/mbed/main/main.cpp | 10 + examples/shell/mbed/mbed_app.json | 25 +- scripts/examples/mbed_example.sh | 19 +- .../clusters/ota-requestor/OTARequestor.cpp | 3 +- src/include/platform/OTARequestorDriver.h | 1 + src/platform/GenericOTARequestorDriver.h | 2 +- src/platform/mbed/BLEManagerImpl.cpp | 7 +- src/platform/mbed/CHIPDevicePlatformConfig.h | 28 +- src/platform/mbed/MbedConfig.cpp | 4 +- src/platform/mbed/OTAImageProcessorImpl.cpp | 83 ++-- src/platform/mbed/OTARequestorDriverImpl.cpp | 62 +++ src/platform/mbed/OTARequestorDriverImpl.h | 66 +++ src/test_driver/mbed/unit_tests/mbed_app.json | 14 +- 54 files changed, 1230 insertions(+), 562 deletions(-) delete mode 100644 examples/all-clusters-app/mbed/main/LowPowerManager.cpp delete mode 100644 examples/all-clusters-app/mbed/main/include/LowPowerManager.h create mode 100644 examples/platform/mbed/ota/generate_ota_list_image.py create mode 100644 examples/platform/mbed/util/DFUManager.cpp create mode 100644 examples/platform/mbed/util/include/DFUManager.h create mode 100644 src/platform/mbed/OTARequestorDriverImpl.cpp create mode 100644 src/platform/mbed/OTARequestorDriverImpl.h diff --git a/config/mbed/CMakeLists.txt b/config/mbed/CMakeLists.txt index 5e7a6fa8bbc517..795dc68366a651 100644 --- a/config/mbed/CMakeLists.txt +++ b/config/mbed/CMakeLists.txt @@ -47,7 +47,7 @@ string(APPEND CHIP_GN_ARGS) # C/C++ compiler flags which should not be forwarded to CHIP # build system (e.g. because CHIP configures them on its own) -set(CHIP_CFLAG_EXCLUDES +set(CHIP_CFLAG_EXCLUDES "-fno-asynchronous-unwind-tables" "-fno-common" "-fno-defer-pop" @@ -149,7 +149,7 @@ list(APPEND CHIP_CFLAGS_CC ${CMAKE_CXX_FLAGS_INIT}) mbed_get_target_common_compile_flags(CHIP_MBEDCMSISCM_CFLAGS mbed-cmsis-cortex-m) list(APPEND CHIP_CFLAGS ${CHIP_MBEDCMSISCM_CFLAGS}) if(MBED_TARGET STREQUAL "CY8CPROTO_062_4343W") - mbed_get_target_common_compile_flags(CHIP_MBEDCMSISCY8_CFLAGS mbed-cy8cproto-062-4343w) + mbed_get_target_common_compile_flags(CHIP_MBEDCMSISCY8_CFLAGS mbed-cy8cproto-062-4343w) list(APPEND CHIP_CFLAGS ${CHIP_MBEDCMSISCY8_CFLAGS}) mbed_get_target_common_compile_flags(CHIP_MBEDPSOC6_CFLAGS mbed-psoc6) list(APPEND CHIP_CFLAGS ${CHIP_MBEDPSOC6_CFLAGS}) @@ -159,7 +159,7 @@ if(MBED_TARGET STREQUAL "CY8CPROTO_062_4343W") list(APPEND CHIP_CFLAGS ${CHIP_MBEDCMSISCY8MODUS_CFLAGS}) endif() -# Add support for Mbed Posix Socket +# Add support for Mbed Posix Socket mbed_get_target_common_compile_flags(CHIP_MBEDPOSIXSOCKET_CFLAGS mbed-os-posix-socket) list(APPEND CHIP_CFLAGS ${CHIP_MBEDPOSIXSOCKET_CFLAGS}) @@ -167,7 +167,7 @@ list(APPEND CHIP_CFLAGS ${CHIP_MBEDPOSIXSOCKET_CFLAGS}) mbed_get_target_common_compile_flags(CHIP_MBEDBLE_CFLAGS mbed-ble) list(APPEND CHIP_CFLAGS ${CHIP_MBEDBLE_CFLAGS}) -# Add support for Mbed event +# Add support for Mbed event mbed_get_target_common_compile_flags(CHIP_MBEDEVENTS_CFLAGS mbed-events) list(APPEND CHIP_CFLAGS ${CHIP_MBEDEVENTS_CFLAGS}) @@ -179,7 +179,7 @@ list(APPEND CHIP_CFLAGS ${CHIP_MBEDRTOS_CFLAGS}) mbed_get_target_common_compile_flags(CHIP_MBEDSTORAGE_CFLAGS mbed-storage-kv-global-api) list(APPEND CHIP_CFLAGS ${CHIP_MBEDSTORAGE_CFLAGS}) -# Add support for Mbed Socket +# Add support for Mbed Socket mbed_get_target_common_compile_flags(CHIP_MBEDNETSOCKET_CFLAGS mbed-netsocket) list(APPEND CHIP_CFLAGS ${CHIP_MBEDNETSOCKET_CFLAGS}) @@ -190,12 +190,12 @@ endif() mbed_get_gnu_cpp_standard(CHIP_CFLAGS_CC) -list(APPEND CHIP_CFLAGS +list(APPEND CHIP_CFLAGS \"-D__LINUX_ERRNO_EXTENSIONS__=1\" ) if (CONFIG_MBED_BSD_SOCKET_TRACE) - list(APPEND CHIP_CFLAGS + list(APPEND CHIP_CFLAGS \"-DMBED_BSD_SOCKET_TRACE=1\" ) endif() @@ -240,7 +240,7 @@ set(CHIP_DEFAULT_CONFIG_FILE "<${CHIP_ROOT}/config/mbed/CHIPProjectConfig.h>") set(CHIP_PROJECT_CONFIG ${CHIP_DEFAULT_CONFIG_FILE}) if (CONFIG_CHIP_PROJECT_CONFIG) - get_filename_component(CHIP_PROJECT_CONFIG + get_filename_component(CHIP_PROJECT_CONFIG ${CONFIG_CHIP_PROJECT_CONFIG} REALPATH BASE_DIR ${CMAKE_SOURCE_DIR} @@ -298,7 +298,7 @@ ExternalProject_Add( BUILD_COMMAND ninja INSTALL_COMMAND "" BUILD_BYPRODUCTS ${CHIP_LIBRARIES} - CONFIGURE_ALWAYS TRUE + CONFIGURE_ALWAYS TRUE BUILD_ALWAYS TRUE USES_TERMINAL_CONFIGURE TRUE USES_TERMINAL_BUILD TRUE @@ -335,23 +335,23 @@ if("capsense" IN_LIST MBED_TARGET_LABELS) target_link_libraries(${APP_TARGET} capsense) endif() -list(APPEND CHIP_INCLUDES +list(APPEND CHIP_INCLUDES ${CHIP_ROOT}/config/mbed/mbedtls ) -list(APPEND CHIP_DEFINES +list(APPEND CHIP_DEFINES __LINUX_ERRNO_EXTENSIONS__=1 ) if (CONFIG_MBED_BSD_SOCKET_TRACE) - list(APPEND CHIP_DEFINES + list(APPEND CHIP_DEFINES MBED_BSD_SOCKET_TRACE=1 ) endif() if (CONFIG_CHIP_PW_RPC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17" PARENT_SCOPE) - list(APPEND CHIP_DEFINES + list(APPEND CHIP_DEFINES CHIP_PW_RPC=1 ) endif() @@ -412,7 +412,7 @@ if (CONFIG_CHIP_PW_RPC_ECHO_PROTO) ${CMAKE_CURRENT_BINARY_DIR}/protocol_buffer/gen/third_party/connectedhomeip/third_party/pigweed/repo/pw_rpc/protos.proto_library/nanopb_rpc ${CMAKE_CURRENT_BINARY_DIR}/protocol_buffer/gen/third_party/connectedhomeip/third_party/pigweed/repo/pw_rpc/protos.proto_library/nanopb ) - list(APPEND CHIP_DEFINES + list(APPEND CHIP_DEFINES CHIP_PW_RPC_ECHO_PROTO=1 ) endif(CONFIG_CHIP_PW_RPC_ECHO_PROTO) @@ -425,7 +425,7 @@ if (CONFIG_CHIP_PW_RPC_COMMON_PROTO) ${CMAKE_CURRENT_BINARY_DIR}/protocol_buffer/gen/third_party/connectedhomeip/examples/common/pigweed/device_service.proto_library/nanopb ${CMAKE_CURRENT_BINARY_DIR}/protocol_buffer/gen/third_party/connectedhomeip/examples/common/pigweed/device_service.proto_library/nanopb_rpc ) - list(APPEND CHIP_DEFINES + list(APPEND CHIP_DEFINES CHIP_PW_RPC_COMMON_PROTO=1 ) endif(CONFIG_CHIP_PW_RPC_COMMON_PROTO) @@ -435,7 +435,7 @@ if (CONFIG_CHIP_PW_RPC_LIGHTING_PROTO) ${CMAKE_CURRENT_BINARY_DIR}/protocol_buffer/gen/third_party/connectedhomeip/examples/common/pigweed/lighting_service.proto_library/nanopb ${CMAKE_CURRENT_BINARY_DIR}/protocol_buffer/gen/third_party/connectedhomeip/examples/common/pigweed/lighting_service.proto_library/nanopb_rpc ) - list(APPEND CHIP_DEFINES + list(APPEND CHIP_DEFINES CHIP_PW_RPC_LIGHTING_PROTO=1 ) endif(CONFIG_CHIP_PW_RPC_LIGHTING_PROTO) @@ -445,7 +445,7 @@ if (CONFIG_CHIP_PW_RPC_LOCKING_PROTO) ${CMAKE_CURRENT_BINARY_DIR}/protocol_buffer/gen/third_party/connectedhomeip/examples/common/pigweed/locking_service.proto_library/nanopb ${CMAKE_CURRENT_BINARY_DIR}/protocol_buffer/gen/third_party/connectedhomeip/examples/common/pigweed/locking_service.proto_library/nanopb_rpc ) - list(APPEND CHIP_DEFINES + list(APPEND CHIP_DEFINES CHIP_PW_RPC_LOCKING_PROTO=1 ) endif(CONFIG_CHIP_PW_RPC_LOCKING_PROTO) @@ -454,7 +454,6 @@ endif(CONFIG_CHIP_PW_RPC) if (CONFIG_CHIP_OTA_REQUESTOR) target_include_directories(${APP_TARGET} PRIVATE - ${CHIP_ROOT}/zzz_generated/ota-requestor-app ${CHIP_ROOT}/src/app/clusters/ota-requestor ${CHIP_ROOT}/src/platform ${CHIP_ROOT}/src/platform/mbed @@ -462,17 +461,32 @@ if (CONFIG_CHIP_OTA_REQUESTOR) ) target_sources(${APP_TARGET} PRIVATE - ${CHIP_ROOT}/zzz_generated/ota-requestor-app/zap-generated/callback-stub.cpp - ${CHIP_ROOT}/zzz_generated/ota-requestor-app/zap-generated/IMClusterCommandHandler.cpp - ${CHIP_ROOT}/src/app/clusters/ota-requestor/OTARequestor.cpp ${CHIP_ROOT}/src/app/clusters/ota-requestor/BDXDownloader.cpp - ${CHIP_ROOT}/src/app/clusters/ota-requestor/ota-requestor-server.cpp - ${CHIP_ROOT}/src/platform/mbed/OTAImageProcessorImpl.cpp + ${CHIP_ROOT}/src/platform/mbed/OTARequestorDriverImpl.cpp + ) + +if (NOT ${APP_TARGET} MATCHES "shell") + target_sources(${APP_TARGET} PRIVATE + ${CHIP_ROOT}/src/app/clusters/ota-requestor/ota-requestor-server.cpp ) +else() + include(${CHIP_ROOT}/src/app/chip_data_model.cmake) + chip_configure_data_model(${APP_TARGET} + ZAP_FILE ${CHIP_ROOT}/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap + GEN_DIR ${CHIP_ROOT}/zzz_generated/ota-requestor-app/zap-generated + ) + target_include_directories(${APP_TARGET} PRIVATE + ${GEN_DIR}/ota-requestor-app + ) + target_sources(${APP_TARGET} PRIVATE + ${GEN_DIR}//ota-requestor-app/zap-generated/callback-stub.cpp + ${GEN_DIR}/ota-requestor-app/zap-generated/IMClusterCommandHandler.cpp + ) +endif() - list(APPEND CHIP_DEFINES + list(APPEND CHIP_DEFINES CHIP_OTA_REQUESTOR=1 ) endif(CONFIG_CHIP_OTA_REQUESTOR) @@ -507,16 +521,16 @@ if(BOOT_ENABLED) "-DMBED_APP_SIZE=${APP_SIZE}" ) - list(APPEND CHIP_DEFINES + list(APPEND CHIP_DEFINES BOOT_ENABLED=1 ) endif() -target_include_directories(${APP_TARGET} PRIVATE +target_include_directories(${APP_TARGET} PRIVATE ${CHIP_INCLUDES} ) target_compile_definitions(${APP_TARGET} PRIVATE - ${CHIP_DEFINES} + ${CHIP_DEFINES} ) diff --git a/examples/all-clusters-app/mbed/.gitignore b/examples/all-clusters-app/mbed/.gitignore index 414487d53eb835..ef564644de9016 100644 --- a/examples/all-clusters-app/mbed/.gitignore +++ b/examples/all-clusters-app/mbed/.gitignore @@ -1 +1,2 @@ build-*/ +mcuboot diff --git a/examples/all-clusters-app/mbed/CMakeLists.txt b/examples/all-clusters-app/mbed/CMakeLists.txt index a28dd60017e677..aa9baf89abfe5c 100644 --- a/examples/all-clusters-app/mbed/CMakeLists.txt +++ b/examples/all-clusters-app/mbed/CMakeLists.txt @@ -4,11 +4,10 @@ cmake_minimum_required(VERSION 3.19.0) get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../.. REALPATH) -get_filename_component(APP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/.. REALPATH) get_filename_component(MBED_COMMON ${CHIP_ROOT}/examples/platform/mbed REALPATH) -get_filename_component(APP_UTIL ${CHIP_ROOT}/src/app/util REALPATH) -get_filename_component(APP_CLUSTERS ${CHIP_ROOT}/src/app/clusters REALPATH) get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) +get_filename_component(ALL_CLUSTERS_COMMON ${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common REALPATH) +get_filename_component(NLIO_ROOT ${CHIP_ROOT}/third_party/nlio/repo/include REALPATH) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/config.in @@ -18,9 +17,22 @@ configure_file( set(MBED_PATH ${MBED_OS_PATH} CACHE INTERNAL "") set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") +set(MCUBOOT_PATH ${MBED_MCU_BOOT_PATH} CACHE INTERNAL "") +set(APP_PATH ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "") +set(APP_TYPE ${MBED_APP_TYPE} CACHE INTERNAL "") +set(BOOT_ENABLED FALSE) set(APP_TARGET chip-mbed-all-clusters-app-example) +if(APP_TYPE STREQUAL "boot" OR APP_TYPE STREQUAL "upgrade") + set(BOOT_ENABLED TRUE) +endif() + include(${MBED_PATH}/tools/cmake/app.cmake) +if(MBED_TARGET STREQUAL "CY8CPROTO_062_4343W" AND BOOT_ENABLED) + list(REMOVE_ITEM MBED_TARGET_LABELS CM0P_SLEEP) + list(REMOVE_ITEM MBED_TARGET_DEFINITIONS COMPONENT_CM0P_SLEEP=1) +endif() +include(${CHIP_ROOT}/src/app/chip_data_model.cmake) project(${APP_TARGET}) @@ -34,111 +46,28 @@ add_subdirectory(${CHIP_ROOT}/config/mbed ./chip_build) mbed_configure_app_target(${APP_TARGET}) target_include_directories(${APP_TARGET} PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/main/include/ - ${APP_ROOT}/all-clusters-common - ${APP_ROOT}/all-clusters-common/include - ${APP_CLUSTERS} + main/include/ ${MBED_COMMON}/util/include - ${CHIP_ROOT}/src/app - ${CHIP_ROOT}/third_party/nlio/repo/include - ${GEN_DIR}/all-clusters-app + ${ALL_CLUSTERS_COMMON}/include ${GEN_DIR}/app-common + ${GEN_DIR}/all-clusters-app + ${NLIO_ROOT} ) target_sources(${APP_TARGET} PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/main/main.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/main/AppTask.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/main/LowPowerManager.cpp - - ${MBED_COMMON}/util/LEDWidget.cpp - + main/main.cpp + main/AppTask.cpp ${GEN_DIR}/all-clusters-app/zap-generated/callback-stub.cpp ${GEN_DIR}/all-clusters-app/zap-generated/IMClusterCommandHandler.cpp - ${GEN_DIR}/app-common/app-common/zap-generated/attributes/Accessors.cpp - ${GEN_DIR}/app-common/app-common/zap-generated/cluster-objects.cpp - - ${CHIP_ROOT}/src/app/server/EchoHandler.cpp - ${CHIP_ROOT}/src/app/server/Dnssd.cpp - ${CHIP_ROOT}/src/app/server/OnboardingCodesUtil.cpp - ${CHIP_ROOT}/src/app/server/Server.cpp - ${CHIP_ROOT}/src/app/server/CommissioningWindowManager.cpp - - ${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp - ${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp - - ${APP_UTIL}/DataModelHandler.cpp - ${APP_UTIL}/af-event.cpp - ${APP_UTIL}/attribute-storage.cpp - ${APP_UTIL}/attribute-table.cpp - ${APP_UTIL}/attribute-size-util.cpp - ${APP_UTIL}/binding-table.cpp - ${APP_UTIL}/client-api.cpp - ${APP_UTIL}/ember-print.cpp - ${APP_UTIL}/ember-compatibility-functions.cpp - ${APP_UTIL}/message.cpp - ${APP_UTIL}/util.cpp - ${APP_UTIL}/error-mapping.cpp - - ${APP_CLUSTERS}/application-basic-server/application-basic-server.cpp - ${APP_CLUSTERS}/basic/basic.cpp - ${APP_CLUSTERS}/bindings/BindingManager.cpp - ${APP_CLUSTERS}/bindings/bindings.cpp - ${APP_CLUSTERS}/bindings/PendingNotificationMap.cpp - ${APP_CLUSTERS}/on-off-server/on-off-server.cpp - ${APP_CLUSTERS}/access-control-server/access-control-server.cpp - ${APP_CLUSTERS}/account-login-server/account-login-server.cpp - ${APP_CLUSTERS}/application-launcher-server/application-launcher-server.cpp - ${APP_CLUSTERS}/audio-output-server/audio-output-server.cpp - ${APP_CLUSTERS}/barrier-control-server/barrier-control-server.cpp - ${APP_CLUSTERS}/basic/basic.cpp - ${APP_CLUSTERS}/bindings/bindings.cpp - ${APP_CLUSTERS}/color-control-server/color-control-server.cpp - ${APP_CLUSTERS}/content-launch-server/content-launch-server.cpp - ${APP_CLUSTERS}/descriptor/descriptor.cpp - ${APP_CLUSTERS}/door-lock-server/door-lock-server.cpp - ${APP_CLUSTERS}/fixed-label-server/fixed-label-server.cpp - ${APP_CLUSTERS}/user-label-server/user-label-server.cpp - ${APP_CLUSTERS}/general-commissioning-server/general-commissioning-server.cpp - ${APP_CLUSTERS}/groups-server/groups-server.cpp - ${APP_CLUSTERS}/ias-zone-server/ias-zone-server.cpp - ${APP_CLUSTERS}/keypad-input-server/keypad-input-server.cpp - ${APP_CLUSTERS}/level-control/level-control.cpp - ${APP_CLUSTERS}/low-power-server/low-power-server.cpp - ${APP_CLUSTERS}/localization-configuration-server/localization-configuration-server.cpp - ${APP_CLUSTERS}/time-format-localization-server/time-format-localization-server.cpp - ${APP_CLUSTERS}/media-input-server/media-input-server.cpp - ${APP_CLUSTERS}/media-playback-server/media-playback-server.cpp - ${APP_CLUSTERS}/mode-select-server/mode-select-server.cpp - ${APP_CLUSTERS}/network-commissioning-old/network-commissioning-ember.cpp - ${APP_CLUSTERS}/network-commissioning-old/network-commissioning-old.cpp - ${APP_CLUSTERS}/on-off-server/on-off-server.cpp - ${APP_CLUSTERS}/scenes/scenes.cpp - ${APP_CLUSTERS}/switch-server/switch-server.cpp - ${APP_CLUSTERS}/target-navigator-server/target-navigator-server.cpp - ${APP_CLUSTERS}/thermostat-server/thermostat-server.cpp - ${APP_CLUSTERS}/thermostat-user-interface-configuration-server/thermostat-user-interface-configuration-server.cpp - ${APP_CLUSTERS}/channel-server/channel-server.cpp - ${APP_CLUSTERS}/operational-credentials-server/operational-credentials-server.cpp - ${APP_CLUSTERS}/test-cluster-server/test-cluster-server.cpp - ${APP_CLUSTERS}/occupancy-sensor-server/occupancy-sensor-server.cpp - ${APP_CLUSTERS}/diagnostic-logs-server/diagnostic-logs-server.cpp - ${APP_CLUSTERS}/ethernet-network-diagnostics-server/ethernet-network-diagnostics-server.cpp - ${APP_CLUSTERS}/software-diagnostics-server/software-diagnostics-server.cpp - ${APP_CLUSTERS}/thread-network-diagnostics-server/thread-network-diagnostics-server.cpp - ${APP_CLUSTERS}/wake-on-lan-server/wake-on-lan-server.cpp - ${APP_CLUSTERS}/wifi-network-diagnostics-server/wifi-network-diagnostics-server.cpp - ${APP_CLUSTERS}/pump-configuration-and-control-server/pump-configuration-and-control-server.cpp - ${APP_CLUSTERS}/administrator-commissioning-server/administrator-commissioning-server.cpp - ${APP_CLUSTERS}/identify-server/identify-server.cpp - ${APP_CLUSTERS}/window-covering-server/window-covering-server.cpp - ${APP_CLUSTERS}/general-diagnostics-server/general-diagnostics-server.cpp - ${APP_CLUSTERS}/group-key-mgmt-server/group-key-mgmt-server.cpp - ${APP_CLUSTERS}/power-source-configuration-server/power-source-configuration-server.cpp - ${APP_CLUSTERS}/power-source-server/power-source-server.cpp - ${APP_CLUSTERS}/ota-requestor/ota-requestor-server.cpp - ${APP_CLUSTERS}/ota-requestor/BDXDownloader.cpp - ${APP_CLUSTERS}/ota-requestor/OTARequestor.cpp + ${MBED_COMMON}/util/LEDWidget.cpp + ${MBED_COMMON}/util/DFUManager.cpp + ${ALL_CLUSTERS_COMMON}/src/bridged-actions-stub.cpp + ${ALL_CLUSTERS_COMMON}/src/static-supported-modes-manager.cpp +) + +chip_configure_data_model(${APP_TARGET} + INCLUDE_SERVER + ZAP_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../all-clusters-common/all-clusters-app.zap ) target_link_libraries(${APP_TARGET} mbed-os-posix-socket mbed-os mbed-ble mbed-events mbed-netsocket mbed-storage mbed-storage-kv-global-api mbed-mbedtls mbed-emac chip) diff --git a/examples/all-clusters-app/mbed/config.in b/examples/all-clusters-app/mbed/config.in index 2542a38c16f4c3..262822b1ca58df 100644 --- a/examples/all-clusters-app/mbed/config.in +++ b/examples/all-clusters-app/mbed/config.in @@ -2,4 +2,5 @@ CONFIG_CHIP_BUILD_TESTS=n CONFIG_CHIP_WITH_EXTERNAL_MBEDTLS=y CONFIG_CHIP_PROJECT_CONFIG=main/include/CHIPProjectConfig.h CONFIG_CHIP_BYPASS_RENDEZVOUS=n -CONFIG_MBED_BSD_SOCKET_TRACE=n \ No newline at end of file +CONFIG_MBED_BSD_SOCKET_TRACE=n +CONFIG_CHIP_OTA_REQUESTOR=y \ No newline at end of file diff --git a/examples/all-clusters-app/mbed/main/AppTask.cpp b/examples/all-clusters-app/mbed/main/AppTask.cpp index 6952a360aa82d9..fdbeb2ea884260 100644 --- a/examples/all-clusters-app/mbed/main/AppTask.cpp +++ b/examples/all-clusters-app/mbed/main/AppTask.cpp @@ -18,6 +18,7 @@ #include "AppTask.h" #include "LEDWidget.h" +#include #include #include @@ -37,6 +38,7 @@ static bool sHaveBLEConnections = false; static events::EventQueue sAppEventQueue; +using namespace ::chip; using namespace ::chip::DeviceLayer; using namespace ::chip::Credentials; @@ -44,6 +46,7 @@ AppTask AppTask::sAppTask; int AppTask::Init() { + CHIP_ERROR error; // Register the callback to init the MDNS server when connectivity is available PlatformMgr().AddEventHandler( [](const ChipDeviceEvent * event, intptr_t arg) { @@ -59,10 +62,15 @@ int AppTask::Init() }, 0); - chip::DeviceLayer::ConnectivityMgrImpl().StartWiFiManagement(); + ConnectivityMgrImpl().StartWiFiManagement(); // Init ZCL Data Model and start server - chip::Server::GetInstance().Init(); + error = Server::GetInstance().Init(); + if (error != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Server initialization failed: %s", error.AsString()); + return EXIT_FAILURE; + } // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); @@ -70,6 +78,13 @@ int AppTask::Init() // QR code will be used with CHIP Tool PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); + error = GetDFUManager().Init(); + if (error != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "DFU manager initialization failed: %s", error.AsString()); + return EXIT_FAILURE; + } + return 0; } diff --git a/examples/all-clusters-app/mbed/main/LowPowerManager.cpp b/examples/all-clusters-app/mbed/main/LowPowerManager.cpp deleted file mode 100644 index 57399c0ba1de5c..00000000000000 --- a/examples/all-clusters-app/mbed/main/LowPowerManager.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "LowPowerManager.h" - -bool LowPowerManager::HandleSleep() -{ - // TODO: Insert code here - return true; -} diff --git a/examples/all-clusters-app/mbed/main/include/LowPowerManager.h b/examples/all-clusters-app/mbed/main/include/LowPowerManager.h deleted file mode 100644 index 92bb1417be514d..00000000000000 --- a/examples/all-clusters-app/mbed/main/include/LowPowerManager.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -class LowPowerManager : public chip::app::Clusters::LowPower::Delegate -{ -public: - bool HandleSleep() override; -}; diff --git a/examples/all-clusters-app/mbed/mbed_app.json b/examples/all-clusters-app/mbed/mbed_app.json index 154bf4dccfcbf6..8c167bfcb84c19 100644 --- a/examples/all-clusters-app/mbed/mbed_app.json +++ b/examples/all-clusters-app/mbed/mbed_app.json @@ -11,7 +11,10 @@ "nsapi.default-wifi-password": "\"YOUR_PASSWORD\"", "mbed-trace.max-level": "TRACE_LEVEL_DEBUG", "mbed-trace.enable": true, - "target.printf_lib": "std" + "target.printf_lib": "std", + "mcuboot.bootloader-build": false, + "mcuboot.log-enable": true, + "mcuboot.log-level": "MCUBOOT_LOG_LEVEL_ERROR" }, "CY8CPROTO_062_4343W": { "target.network-default-interface-type": "WIFI", @@ -20,7 +23,13 @@ "NL_ASSERT_LOG=NL_ASSERT_LOG_DEFAULT", "NL_ASSERT_EXPECT_FLAGS=NL_ASSERT_FLAG_LOG", "WHD_PRINT_DISABLE" - ] + ], + "mcuboot.primary-slot-address": "0x10022000", + "mcuboot.slot-size": "0x180000", + "mcuboot.scratch-address": "0x101A2000", + "mcuboot.scratch-size": "0x40000", + "mcuboot.max-img-sectors": "0xC00", + "mcuboot.header-size": "0x400" } }, "config": { @@ -36,9 +45,17 @@ "help": "Name used for BLE advertising.", "value": "\"MBED-clusters\"" }, - "use-gatt-indication-ack-hack": { - "help": "Fake a TX transfer confirmation. Send a 'kCHIPoBLEIndicateConfirm' event as soon as data is sent, without waiting for the actual ACK from the GATT client. This hack has to stay until we provide a fix in the Mbed OS repo.", - "value": 1 + "version-number": { + "value": "0" + }, + "version-number-str": { + "value": "\"0.1.0\"" + }, + "vendor-id": { + "value": "0xFFF1" + }, + "product-id": { + "value": "0x8001" } } } diff --git a/examples/lighting-app/mbed/.gitignore b/examples/lighting-app/mbed/.gitignore index 414487d53eb835..ef564644de9016 100644 --- a/examples/lighting-app/mbed/.gitignore +++ b/examples/lighting-app/mbed/.gitignore @@ -1 +1,2 @@ build-*/ +mcuboot diff --git a/examples/lighting-app/mbed/CMakeLists.txt b/examples/lighting-app/mbed/CMakeLists.txt index e4734238239a72..8035b7a88b312c 100644 --- a/examples/lighting-app/mbed/CMakeLists.txt +++ b/examples/lighting-app/mbed/CMakeLists.txt @@ -5,7 +5,6 @@ cmake_minimum_required(VERSION 3.19.0) get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../.. REALPATH) get_filename_component(MBED_COMMON ${CHIP_ROOT}/examples/platform/mbed REALPATH) -get_filename_component(LIGHTING_COMMON ${CHIP_ROOT}/examples/lighting-app/lighting-common REALPATH) get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) get_filename_component(NLIO_ROOT ${CHIP_ROOT}/third_party/nlio/repo/include REALPATH) @@ -17,9 +16,21 @@ configure_file( set(MBED_PATH ${MBED_OS_PATH} CACHE INTERNAL "") set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") +set(MCUBOOT_PATH ${MBED_MCU_BOOT_PATH} CACHE INTERNAL "") +set(APP_PATH ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "") +set(APP_TYPE ${MBED_APP_TYPE} CACHE INTERNAL "") +set(BOOT_ENABLED FALSE) set(APP_TARGET chip-mbed-lighting-app-example) +if(APP_TYPE STREQUAL "boot" OR APP_TYPE STREQUAL "upgrade") + set(BOOT_ENABLED TRUE) +endif() + include(${MBED_PATH}/tools/cmake/app.cmake) +if(MBED_TARGET STREQUAL "CY8CPROTO_062_4343W" AND BOOT_ENABLED) + list(REMOVE_ITEM MBED_TARGET_LABELS CM0P_SLEEP) + list(REMOVE_ITEM MBED_TARGET_DEFINITIONS COMPONENT_CM0P_SLEEP=1) +endif() include(${CHIP_ROOT}/src/app/chip_data_model.cmake) project(${APP_TARGET}) @@ -35,14 +46,12 @@ mbed_configure_app_target(${APP_TARGET}) target_include_directories(${APP_TARGET} PRIVATE main/include/ - ${LIGHTING_COMMON} ${MBED_COMMON}/util/include ${GEN_DIR}/app-common ${GEN_DIR}/lighting-app ${NLIO_ROOT} ) -# TODO - re-use chip_data_model.cmake to add cluster implementations. target_sources(${APP_TARGET} PRIVATE main/AppTask.cpp main/LightingManager.cpp @@ -51,12 +60,12 @@ target_sources(${APP_TARGET} PRIVATE ${GEN_DIR}/lighting-app/zap-generated/callback-stub.cpp ${GEN_DIR}/lighting-app/zap-generated/IMClusterCommandHandler.cpp ${MBED_COMMON}/util/LEDWidget.cpp + ${MBED_COMMON}/util/DFUManager.cpp ) chip_configure_data_model(${APP_TARGET} INCLUDE_SERVER ZAP_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../lighting-common/lighting-app.zap - GEN_DIR ${GEN_DIR}/lighting-app/zap-generated ) target_link_libraries(${APP_TARGET} mbed-os-posix-socket mbed-os mbed-ble mbed-events mbed-netsocket mbed-storage mbed-storage-kv-global-api mbed-mbedtls mbed-emac chip) diff --git a/examples/lighting-app/mbed/config.in b/examples/lighting-app/mbed/config.in index a13a8e62e17b43..2d07ccc63b03c3 100644 --- a/examples/lighting-app/mbed/config.in +++ b/examples/lighting-app/mbed/config.in @@ -3,4 +3,5 @@ CONFIG_CHIP_WITH_EXTERNAL_MBEDTLS=y CONFIG_CHIP_PROJECT_CONFIG=main/include/CHIPProjectConfig.h CONFIG_CHIP_BYPASS_RENDEZVOUS=n CONFIG_MBED_BSD_SOCKET_TRACE=n -CONFIG_CHIP_PW_RPC=y \ No newline at end of file +CONFIG_CHIP_PW_RPC=y +CONFIG_CHIP_OTA_REQUESTOR=y \ No newline at end of file diff --git a/examples/lighting-app/mbed/main/AppTask.cpp b/examples/lighting-app/mbed/main/AppTask.cpp index 6e8f8180f2e90f..f36adc2aa52d85 100644 --- a/examples/lighting-app/mbed/main/AppTask.cpp +++ b/examples/lighting-app/mbed/main/AppTask.cpp @@ -19,22 +19,18 @@ #include "AppTask.h" #include "LEDWidget.h" #include "LightingManager.h" -#include - -#ifdef CAPSENSE_ENABLED -#include "capsense.h" -#endif -// FIXME: Undefine the `sleep()` function included by the CHIPDeviceLayer.h -// from unistd.h to avoid a conflicting declaration with the `sleep()` provided -// by Mbed-OS in mbed_power_mgmt.h. -#define sleep unistd_sleep #include +#include #include +#include +#include +#include #include -#undef sleep -#include +// mbed-os headers +#include "drivers/Timeout.h" +#include "events/EventQueue.h" // ZAP -- ZCL Advanced Platform #include @@ -42,14 +38,12 @@ #include #include -#include -#include - -// mbed-os headers +#ifdef CAPSENSE_ENABLED +#include "capsense.h" +#else #include "drivers/InterruptIn.h" -#include "drivers/Timeout.h" -#include "events/EventQueue.h" #include "platform/Callback.h" +#endif #define FACTORY_RESET_TRIGGER_TIMEOUT (MBED_CONF_APP_FACTORY_RESET_TRIGGER_TIMEOUT) #define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT (MBED_CONF_APP_FACTORY_RESET_CANCEL_WINDOW_TIMEOUT) @@ -60,13 +54,15 @@ static LEDWidget sStatusLED(MBED_CONF_APP_SYSTEM_STATE_LED); -static mbed::InterruptIn sLightingButton(LIGHTING_BUTTON); -static mbed::InterruptIn sFunctionButton(FUNCTION_BUTTON); #ifdef CAPSENSE_ENABLED static mbed::CapsenseButton CapFunctionButton(Capsense::getInstance(), 0); static mbed::CapsenseButton CapLockButton(Capsense::getInstance(), 1); static mbed::CapsenseSlider CapSlider(Capsense::getInstance()); +#else +static mbed::InterruptIn sLightingButton(LIGHTING_BUTTON); +static mbed::InterruptIn sFunctionButton(FUNCTION_BUTTON); #endif + static bool sIsWiFiStationProvisioned = false; static bool sIsWiFiStationEnabled = false; static bool sIsWiFiStationConnected = false; @@ -77,6 +73,7 @@ static mbed::Timeout sFunctionTimer; static events::EventQueue sAppEventQueue; +using namespace ::chip; using namespace ::chip::Credentials; using namespace ::chip::DeviceLayer; @@ -84,6 +81,7 @@ AppTask AppTask::sAppTask; int AppTask::Init() { + CHIP_ERROR error; // Register the callback to init the MDNS server when connectivity is available PlatformMgr().AddEventHandler( [](const ChipDeviceEvent * event, intptr_t arg) { @@ -116,10 +114,15 @@ int AppTask::Init() LightingMgr().Init(MBED_CONF_APP_LIGHTING_STATE_LED); LightingMgr().SetCallbacks(ActionInitiated, ActionCompleted); - chip::DeviceLayer::ConnectivityMgrImpl().StartWiFiManagement(); + ConnectivityMgrImpl().StartWiFiManagement(); // Init ZCL Data Model and start server - chip::Server::GetInstance().Init(); + error = Server::GetInstance().Init(); + if (error != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Server initialization failed: %s", error.AsString()); + return EXIT_FAILURE; + } // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); @@ -127,6 +130,13 @@ int AppTask::Init() // QR code will be used with CHIP Tool PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); + error = GetDFUManager().Init(); + if (error != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "DFU manager initialization failed: %s", error.AsString()); + return EXIT_FAILURE; + } + return 0; } diff --git a/examples/lighting-app/mbed/main/include/AppTask.h b/examples/lighting-app/mbed/main/include/AppTask.h index 1abd6380677e3f..af3c93d3824824 100644 --- a/examples/lighting-app/mbed/main/include/AppTask.h +++ b/examples/lighting-app/mbed/main/include/AppTask.h @@ -21,6 +21,7 @@ #include "AppEvent.h" #include "LightingManager.h" +#include class AppTask { diff --git a/examples/lighting-app/mbed/mbed_app.json b/examples/lighting-app/mbed/mbed_app.json index 992e89df51661e..ef6e52dc961ac1 100644 --- a/examples/lighting-app/mbed/mbed_app.json +++ b/examples/lighting-app/mbed/mbed_app.json @@ -11,7 +11,10 @@ "nsapi.default-wifi-password": "\"YOUR_PASSWORD\"", "mbed-trace.max-level": "TRACE_LEVEL_DEBUG", "mbed-trace.enable": true, - "target.printf_lib": "std" + "target.printf_lib": "std", + "mcuboot.bootloader-build": false, + "mcuboot.log-enable": true, + "mcuboot.log-level": "MCUBOOT_LOG_LEVEL_ERROR" }, "CY8CPROTO_062_4343W": { "target.network-default-interface-type": "WIFI", @@ -23,7 +26,13 @@ ], "target.components_add": ["capsense"], "lighting-state-led": "P9_6", - "lighting-button": "USER_BUTTON" + "lighting-button": "USER_BUTTON", + "mcuboot.primary-slot-address": "0x10022000", + "mcuboot.slot-size": "0x180000", + "mcuboot.scratch-address": "0x101A2000", + "mcuboot.scratch-size": "0x40000", + "mcuboot.max-img-sectors": "0xC00", + "mcuboot.header-size": "0x400" } }, "config": { @@ -63,9 +72,17 @@ "help": "Name used for BLE advertising.", "value": "\"MBED-lighting\"" }, - "use-gatt-indication-ack-hack": { - "help": "Fake a TX transfer confirmation. Send a 'kCHIPoBLEIndicateConfirm' event as soon as data is sent, without waiting for the actual ACK from the GATT client. This hack has to stay until we provide a fix in the Mbed OS repo.", - "value": 1 + "version-number": { + "value": "0" + }, + "version-number-str": { + "value": "\"0.1.0\"" + }, + "vendor-id": { + "value": "0xFFF1" + }, + "product-id": { + "value": "0x8005" } } } diff --git a/examples/lock-app/mbed/.gitignore b/examples/lock-app/mbed/.gitignore index 414487d53eb835..ef564644de9016 100644 --- a/examples/lock-app/mbed/.gitignore +++ b/examples/lock-app/mbed/.gitignore @@ -1 +1,2 @@ build-*/ +mcuboot diff --git a/examples/lock-app/mbed/CMakeLists.txt b/examples/lock-app/mbed/CMakeLists.txt index 08e5d110935031..9c6f57a6edc725 100644 --- a/examples/lock-app/mbed/CMakeLists.txt +++ b/examples/lock-app/mbed/CMakeLists.txt @@ -16,9 +16,21 @@ configure_file( set(MBED_PATH ${MBED_OS_PATH} CACHE INTERNAL "") set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") +set(MCUBOOT_PATH ${MBED_MCU_BOOT_PATH} CACHE INTERNAL "") +set(APP_PATH ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "") +set(APP_TYPE ${MBED_APP_TYPE} CACHE INTERNAL "") +set(BOOT_ENABLED FALSE) set(APP_TARGET chip-mbed-lock-app-example) +if(APP_TYPE STREQUAL "boot" OR APP_TYPE STREQUAL "upgrade") + set(BOOT_ENABLED TRUE) +endif() + include(${MBED_PATH}/tools/cmake/app.cmake) +if(MBED_TARGET STREQUAL "CY8CPROTO_062_4343W" AND BOOT_ENABLED) + list(REMOVE_ITEM MBED_TARGET_LABELS CM0P_SLEEP) + list(REMOVE_ITEM MBED_TARGET_DEFINITIONS COMPONENT_CM0P_SLEEP=1) +endif() include(${CHIP_ROOT}/src/app/chip_data_model.cmake) project(${APP_TARGET}) @@ -34,10 +46,10 @@ mbed_configure_app_target(${APP_TARGET}) target_include_directories(${APP_TARGET} PRIVATE main/include/ + ${MBED_COMMON}/util/include ${GEN_DIR}/app-common ${GEN_DIR}/lock-app ${NLIO_ROOT} - ${MBED_COMMON}/util/include ) target_sources(${APP_TARGET} PRIVATE @@ -48,6 +60,7 @@ target_sources(${APP_TARGET} PRIVATE ${GEN_DIR}/lock-app/zap-generated/callback-stub.cpp ${GEN_DIR}/lock-app/zap-generated/IMClusterCommandHandler.cpp ${MBED_COMMON}/util/LEDWidget.cpp + ${MBED_COMMON}/util/DFUManager.cpp ) chip_configure_data_model(${APP_TARGET} diff --git a/examples/lock-app/mbed/config.in b/examples/lock-app/mbed/config.in index a13a8e62e17b43..6c687926f2f5c7 100644 --- a/examples/lock-app/mbed/config.in +++ b/examples/lock-app/mbed/config.in @@ -3,4 +3,5 @@ CONFIG_CHIP_WITH_EXTERNAL_MBEDTLS=y CONFIG_CHIP_PROJECT_CONFIG=main/include/CHIPProjectConfig.h CONFIG_CHIP_BYPASS_RENDEZVOUS=n CONFIG_MBED_BSD_SOCKET_TRACE=n -CONFIG_CHIP_PW_RPC=y \ No newline at end of file +CONFIG_CHIP_PW_RPC=y +CONFIG_CHIP_OTA_REQUESTOR=n \ No newline at end of file diff --git a/examples/lock-app/mbed/main/AppTask.cpp b/examples/lock-app/mbed/main/AppTask.cpp index e4ec43f298e681..7bee0b52c5949a 100644 --- a/examples/lock-app/mbed/main/AppTask.cpp +++ b/examples/lock-app/mbed/main/AppTask.cpp @@ -18,25 +18,19 @@ #include "AppTask.h" #include "BoltLockManager.h" -#include "LEDWidget.h" -#include - -#ifdef CAPSENSE_ENABLED -#include "capsense.h" -#endif +#include -// FIXME: Undefine the `sleep()` function included by the CHIPDeviceLayer.h -// from unistd.h to avoid a conflicting declaration with the `sleep()` provided -// by Mbed-OS in mbed_power_mgmt.h. -#define sleep unistd_sleep #include +#include #include #include #include +#include #include -#undef sleep -#include +// mbed-os headers +#include "drivers/Timeout.h" +#include "events/EventQueue.h" // ZAP -- ZCL Advanced Platform #include @@ -44,11 +38,12 @@ #include #include -// mbed-os headers +#ifdef CAPSENSE_ENABLED +#include "capsense.h" +#else #include "drivers/InterruptIn.h" -#include "drivers/Timeout.h" -#include "events/EventQueue.h" #include "platform/Callback.h" +#endif #define FACTORY_RESET_TRIGGER_TIMEOUT (MBED_CONF_APP_FACTORY_RESET_TRIGGER_TIMEOUT) #define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT (MBED_CONF_APP_FACTORY_RESET_CANCEL_WINDOW_TIMEOUT) @@ -80,6 +75,7 @@ static mbed::Timeout sFunctionTimer; static events::EventQueue sAppEventQueue; +using namespace ::chip; using namespace ::chip::Credentials; using namespace ::chip::DeviceLayer; @@ -87,6 +83,7 @@ AppTask AppTask::sAppTask; int AppTask::Init() { + CHIP_ERROR error; // Register the callback to init the MDNS server when connectivity is available PlatformMgr().AddEventHandler( [](const ChipDeviceEvent * event, intptr_t arg) { @@ -120,10 +117,15 @@ int AppTask::Init() BoltLockMgr().Init(); BoltLockMgr().SetCallbacks(ActionInitiated, ActionCompleted); - chip::DeviceLayer::ConnectivityMgrImpl().StartWiFiManagement(); + ConnectivityMgrImpl().StartWiFiManagement(); // Init ZCL Data Model and start server - chip::Server::GetInstance().Init(); + error = Server::GetInstance().Init(); + if (error != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Server initialization failed: %s", error.AsString()); + return EXIT_FAILURE; + } // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); @@ -131,6 +133,13 @@ int AppTask::Init() // QR code will be used with CHIP Tool PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); + error = GetDFUManager().Init(); + if (error != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "DFU manager initialization failed: %s", error.AsString()); + return EXIT_FAILURE; + } + return 0; } diff --git a/examples/lock-app/mbed/main/include/AppTask.h b/examples/lock-app/mbed/main/include/AppTask.h index 98a43023035f9e..acc6703fd4004f 100644 --- a/examples/lock-app/mbed/main/include/AppTask.h +++ b/examples/lock-app/mbed/main/include/AppTask.h @@ -21,6 +21,7 @@ #include "AppEvent.h" #include "BoltLockManager.h" +#include class AppTask { diff --git a/examples/lock-app/mbed/mbed_app.json b/examples/lock-app/mbed/mbed_app.json index 16043348d8a7e9..5be513f8616d23 100644 --- a/examples/lock-app/mbed/mbed_app.json +++ b/examples/lock-app/mbed/mbed_app.json @@ -11,7 +11,10 @@ "nsapi.default-wifi-password": "\"YOUR_PASSWORD\"", "mbed-trace.max-level": "TRACE_LEVEL_DEBUG", "mbed-trace.enable": true, - "target.printf_lib": "std" + "target.printf_lib": "std", + "mcuboot.bootloader-build": false, + "mcuboot.log-enable": true, + "mcuboot.log-level": "MCUBOOT_LOG_LEVEL_ERROR" }, "CY8CPROTO_062_4343W": { "target.network-default-interface-type": "WIFI", @@ -23,7 +26,13 @@ ], "target.components_add": ["capsense"], "lock-state-led": "P9_6", - "lock-button": "USER_BUTTON" + "lock-button": "USER_BUTTON", + "mcuboot.primary-slot-address": "0x10022000", + "mcuboot.slot-size": "0x180000", + "mcuboot.scratch-address": "0x101A2000", + "mcuboot.scratch-size": "0x40000", + "mcuboot.max-img-sectors": "0xC00", + "mcuboot.header-size": "0x400" } }, "config": { @@ -36,7 +45,7 @@ "value": "LED1" }, "lock-state-led": { - "help": "lighting status LED.", + "help": "Lock status LED.", "value": "LED2" }, "function-button": { @@ -44,7 +53,7 @@ "value": "BUTTON1" }, "lock-button": { - "help": "lighting botton pin.", + "help": "Lock botton pin.", "value": "BUTTON2" }, "actuator-movement-period-ms": { @@ -63,9 +72,17 @@ "help": "Name used for BLE advertising.", "value": "\"MBED-lock\"" }, - "use-gatt-indication-ack-hack": { - "help": "Fake a TX transfer confirmation. Send a 'kCHIPoBLEIndicateConfirm' event as soon as data is sent, without waiting for the actual ACK from the GATT client. This hack has to stay until we provide a fix in the Mbed OS repo.", - "value": 1 + "version-number": { + "value": "0" + }, + "version-number-str": { + "value": "\"0.1.0\"" + }, + "vendor-id": { + "value": "0xFFF1" + }, + "product-id": { + "value": "0x8006" } } } diff --git a/examples/ota-requestor-app/mbed/CMakeLists.txt b/examples/ota-requestor-app/mbed/CMakeLists.txt index 943802cf07245b..fde496b3ff7a31 100644 --- a/examples/ota-requestor-app/mbed/CMakeLists.txt +++ b/examples/ota-requestor-app/mbed/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.19.0) get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../.. REALPATH) get_filename_component(MBED_COMMON ${CHIP_ROOT}/examples/platform/mbed REALPATH) get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) -get_filename_component(NLIO_DIR ${CHIP_ROOT}/third_party/nlio/repo/include REALPATH) +get_filename_component(NLIO_ROOT ${CHIP_ROOT}/third_party/nlio/repo/include REALPATH) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/config.in @@ -27,7 +27,7 @@ if(APP_TYPE STREQUAL "boot" OR APP_TYPE STREQUAL "upgrade") endif() include(${MBED_PATH}/tools/cmake/app.cmake) -if(MBED_TARGET STREQUAL "CY8CPROTO_062_4343W" AND BOOT_ENABLED) +if(MBED_TARGET STREQUAL "CY8CPROTO_062_4343W" AND BOOT_ENABLED) list(REMOVE_ITEM MBED_TARGET_LABELS CM0P_SLEEP) list(REMOVE_ITEM MBED_TARGET_DEFINITIONS COMPONENT_CM0P_SLEEP=1) endif() @@ -48,13 +48,17 @@ target_include_directories(${APP_TARGET} PRIVATE main/include/ ${GEN_DIR}/app-common ${MBED_COMMON}/util/include - ${NLIO_DIR} + ${NLIO_ROOT} + ${GEN_DIR}/ota-requestor-app ) target_sources(${APP_TARGET} PRIVATE - main/main.cpp - main/AppTask.cpp - ${MBED_COMMON}/util/LEDWidget.cpp + main/main.cpp + main/AppTask.cpp + ${GEN_DIR}//ota-requestor-app/zap-generated/callback-stub.cpp + ${GEN_DIR}/ota-requestor-app/zap-generated/IMClusterCommandHandler.cpp + ${MBED_COMMON}/util/LEDWidget.cpp + ${MBED_COMMON}/util/DFUManager.cpp ) chip_configure_data_model(${APP_TARGET} diff --git a/examples/ota-requestor-app/mbed/README.md b/examples/ota-requestor-app/mbed/README.md index 8cbc56b310eee4..7c26810e345230 100644 --- a/examples/ota-requestor-app/mbed/README.md +++ b/examples/ota-requestor-app/mbed/README.md @@ -226,8 +226,7 @@ After device reset these lines should be visible: [INFO][CHIP]: [-]Mbed ota-requestor-app example application start ... - -[INFO][chip]: [-]Mbed ota-requestor-app example application run + [INFO][chip]: [-]Mbed ota-requestor-app example application run The ota-requestor-app application launched correctly and you can follow traces in the terminal. @@ -306,8 +305,16 @@ following states are possible: procedure. **LEDs 1-4** blink in unison when the factory reset procedure is initiated. -- _Pressed for less than 3 s_ — Initiates the OTA software update - process. This feature is not currently supported. +- _Pressed for less than 3 s_ — Trigger confirm user response. + +**Button 1** can be used for the following purposes: + +- _Pressed for 6 s_ — Initiates the commissioning reset of the device. + The fabric IDs are deleted and BLE advertising start. Releasing the button + within the 6-second window cancels the commissioning reset procedure. **LEDs + 1-4** blink in unison when the commissioning reset procedure is initiated. + +- _Pressed for less than 3 s_ — Trigger reject user response. **Button 1** — Pressing the button once delete all fabric IDs and start BLE advertising. diff --git a/examples/ota-requestor-app/mbed/main/AppTask.cpp b/examples/ota-requestor-app/mbed/main/AppTask.cpp index 21708959a44cb5..e05d128ad1a7b0 100644 --- a/examples/ota-requestor-app/mbed/main/AppTask.cpp +++ b/examples/ota-requestor-app/mbed/main/AppTask.cpp @@ -33,18 +33,9 @@ #ifdef CAPSENSE_ENABLED #include "capsense.h" -#endif - -#ifdef CHIP_OTA_REQUESTOR -#include "GenericOTARequestorDriver.h" -#include -#include -#include -#endif // CHIP_OTA_REQUESTOR - -#ifdef BOOT_ENABLED -#include "blockdevice/SlicingBlockDevice.h" -#include +#else +#include "drivers/InterruptIn.h" +#include "platform/Callback.h" #endif static bool sIsWiFiStationProvisioned = false; @@ -62,22 +53,22 @@ using namespace ::chip::DeviceLayer; static LEDWidget sStatusLED(MBED_CONF_APP_SYSTEM_STATE_LED); #define FACTORY_RESET_TRIGGER_TIMEOUT (MBED_CONF_APP_FACTORY_RESET_TRIGGER_TIMEOUT) -#define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT (MBED_CONF_APP_FACTORY_RESET_CANCEL_WINDOW_TIMEOUT) +#define COMMISSIONING_RESET_TRIGGER_TIMEOUT (MBED_CONF_APP_FACTORY_RESET_TRIGGER_TIMEOUT) +#define RESET_CANCEL_WINDOW_TIMEOUT (MBED_CONF_APP_RESET_CANCEL_WINDOW_TIMEOUT) +#define USER_RESPONSE_TIMEOUT (MBED_CONF_APP_USER_RESPONSE_TIMEOUT) -#define FUNCTION_BUTTON (MBED_CONF_APP_FUNCTION_BUTTON) -#define BLE_BUTTON (MBED_CONF_APP_BLE_BUTTON) -#define BUTTON_PUSH_EVENT 1 -#define BUTTON_RELEASE_EVENT 0 +#define FUNCTION_BUTTON1 (MBED_CONF_APP_FUNCTION_BUTTON1) +#define FUNCTION_BUTTON2 (MBED_CONF_APP_FUNCTION_BUTTON2) #ifdef CAPSENSE_ENABLED -static mbed::CapsenseButton CapFunctionButton(Capsense::getInstance(), 0); -static mbed::CapsenseButton CapBleButton(Capsense::getInstance(), 1); +static mbed::CapsenseButton CapFunctionButton1(Capsense::getInstance(), 0); +static mbed::CapsenseButton CapFunctionButton2(Capsense::getInstance(), 1); #else -static mbed::InterruptIn sFunctionButton(FUNCTION_BUTTON); -static mbed::InterruptIn sBleButton(BLE_BUTTON); +static mbed::InterruptIn sFunctionButton1(FUNCTION_BUTTON1); +static mbed::InterruptIn sFunctionButton2(FUNCTION_BUTTON2); #endif -static mbed::Timeout sFunctionTimer; +static mbed::Timeout sFunctionTimer[AppTask::kFunction_Button_last]; AppTask AppTask::sAppTask; @@ -101,13 +92,15 @@ int AppTask::Init() // Initialize buttons #ifdef CAPSENSE_ENABLED - CapFunctionButton.fall(mbed::callback(this, &AppTask::FunctionButtonPressEventHandler)); - CapFunctionButton.rise(mbed::callback(this, &AppTask::FunctionButtonReleaseEventHandler)); - CapBleButton.fall(mbed::callback(this, &AppTask::BleButtonPressEventHandler)); + CapFunctionButton1.fall(mbed::callback(this, &AppTask::FunctionButton1PressEventHandler)); + CapFunctionButton1.rise(mbed::callback(this, &AppTask::FunctionButton1ReleaseEventHandler)); + CapFunctionButton2.fall(mbed::callback(this, &AppTask::FunctionButton2PressEventHandler)); + CapFunctionButton2.rise(mbed::callback(this, &AppTask::FunctionButton2ReleaseEventHandler)); #else - sFunctionButton.fall(mbed::callback(this, &AppTask::FunctionButtonPressEventHandler)); - sFunctionButton.rise(mbed::callback(this, &AppTask::FunctionButtonReleaseEventHandler)); - sBleButton.fall(mbed::callback(this, &AppTask::BleButtonPressEventHandler)); + sFunctionButton1.fall(mbed::callback(this, &AppTask::FunctionButton1PressEventHandler)); + sFunctionButton1.rise(mbed::callback(this, &AppTask::FunctionButton1ReleaseEventHandler)); + sFunctionButton2.fall(mbed::callback(this, &AppTask::FunctionButton2PressEventHandler)); + sFunctionButton2.rise(mbed::callback(this, &AppTask::FunctionButton2ReleaseEventHandler)); #endif ConnectivityMgrImpl().StartWiFiManagement(); @@ -126,46 +119,13 @@ int AppTask::Init() // QR code will be used with CHIP Tool PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); -#ifdef CHIP_OTA_REQUESTOR - // Initialize the instance of the main Requestor Class - OTARequestor * requestor = new OTARequestor(); - if (requestor == nullptr) - { - ChipLogError(NotSpecified, "Create OTA Requestor core failed"); - return EXIT_FAILURE; - } - SetRequestorInstance(requestor); - - // Initialize an instance of the Requestor Driver - GenericOTARequestorDriver * requestorDriver = new GenericOTARequestorDriver; - if (requestorDriver == nullptr) - { - ChipLogError(NotSpecified, "Create OTA Requestor driver failed"); - return EXIT_FAILURE; - } - - // Initialize the Downloader object - BDXDownloader * downloader = new BDXDownloader(); - if (downloader == nullptr) - { - ChipLogError(NotSpecified, "Create OTA Downloader failed"); - return EXIT_FAILURE; - } - - // Initialize the Image Processor object - OTAImageProcessorImpl * imageProcessor = new OTAImageProcessorImpl; - if (imageProcessor == nullptr) + error = GetDFUManager().Init(&mOnUpdateAvailableCallback, &mOnUpdateApplyCallback); + if (error != CHIP_NO_ERROR) { - ChipLogError(NotSpecified, "Create OTA Image Processor failed"); + ChipLogError(NotSpecified, "DFU manager initialization failed: %s", error.AsString()); return EXIT_FAILURE; } - requestor->Init(&(chip::Server::GetInstance()), requestorDriver, downloader); - imageProcessor->SetOTADownloader(downloader); - downloader->SetImageProcessorDelegate(imageProcessor); - requestorDriver->Init(requestor, imageProcessor); -#endif // CHIP_OTA_REQUESTOR - return 0; } @@ -250,33 +210,74 @@ void AppTask::DispatchEvent(const AppEvent * aEvent) } } -void AppTask::BleButtonPressEventHandler() +void AppTask::StartTimer(uint8_t index, uint32_t aTimeoutInMs) +{ + auto chronoTimeoutMs = std::chrono::duration(aTimeoutInMs); + sFunctionTimer[index].attach(mTimerCallbacks[index], chronoTimeoutMs); + mFunctionTimerActive[index] = true; +} + +void AppTask::CancelTimer(uint8_t index) +{ + sFunctionTimer[index].detach(); + mFunctionTimerActive[index] = false; +} + +void AppTask::TimerButton1EventHandler() +{ + AppEvent event; + event.Type = AppEvent::kEventType_Timer; + event.TimerEvent.index = kFunction_Button_1; + event.Handler = FunctionTimerEventHandler; + sAppTask.PostEvent(&event); +} + +void AppTask::TimerButton2EventHandler() +{ + AppEvent event; + event.Type = AppEvent::kEventType_Timer; + event.TimerEvent.index = kFunction_Button_2; + event.Handler = FunctionTimerEventHandler; + sAppTask.PostEvent(&event); +} + +void AppTask::FunctionButton1PressEventHandler() { AppEvent button_event; button_event.Type = AppEvent::kEventType_Button; - button_event.ButtonEvent.Pin = BLE_BUTTON; - button_event.ButtonEvent.Action = BUTTON_PUSH_EVENT; - button_event.Handler = BleHandler; + button_event.ButtonEvent.button = kFunction_Button_1; + button_event.ButtonEvent.action = kFunction_Button_push; + button_event.Handler = ButtonHandler; sAppTask.PostEvent(&button_event); } -void AppTask::FunctionButtonPressEventHandler() +void AppTask::FunctionButton1ReleaseEventHandler() { AppEvent button_event; button_event.Type = AppEvent::kEventType_Button; - button_event.ButtonEvent.Pin = FUNCTION_BUTTON; - button_event.ButtonEvent.Action = BUTTON_PUSH_EVENT; - button_event.Handler = FunctionHandler; + button_event.ButtonEvent.button = kFunction_Button_1; + button_event.ButtonEvent.action = kFunction_Button_release; + button_event.Handler = ButtonHandler; sAppTask.PostEvent(&button_event); } -void AppTask::FunctionButtonReleaseEventHandler() +void AppTask::FunctionButton2PressEventHandler() { AppEvent button_event; button_event.Type = AppEvent::kEventType_Button; - button_event.ButtonEvent.Pin = FUNCTION_BUTTON; - button_event.ButtonEvent.Action = BUTTON_RELEASE_EVENT; - button_event.Handler = FunctionHandler; + button_event.ButtonEvent.button = kFunction_Button_2; + button_event.ButtonEvent.action = kFunction_Button_push; + button_event.Handler = ButtonHandler; + sAppTask.PostEvent(&button_event); +} + +void AppTask::FunctionButton2ReleaseEventHandler() +{ + AppEvent button_event; + button_event.Type = AppEvent::kEventType_Button; + button_event.ButtonEvent.button = kFunction_Button_2; + button_event.ButtonEvent.action = kFunction_Button_release; + button_event.Handler = ButtonHandler; sAppTask.PostEvent(&button_event); } @@ -290,127 +291,226 @@ void AppTask::ButtonEventHandler(uint32_t id, bool pushed) AppEvent button_event; button_event.Type = AppEvent::kEventType_Button; - button_event.ButtonEvent.Pin = id == 0 ? BLE_BUTTON : FUNCTION_BUTTON; - button_event.ButtonEvent.Action = pushed ? BUTTON_PUSH_EVENT : BUTTON_RELEASE_EVENT; - - if (id == 0) - { - button_event.Handler = BleHandler; - } - else - { - button_event.Handler = FunctionHandler; - } + button_event.ButtonEvent.button = id == 0 ? kFunction_Button_1 : kFunction_Button_2; + button_event.ButtonEvent.action = pushed ? kFunction_Button_push : kFunction_Button_release; + button_event.Handler = ButtonHandler; sAppTask.PostEvent(&button_event); } -void AppTask::StartTimer(uint32_t aTimeoutInMs) +void AppTask::ButtonHandler(AppEvent * aEvent) { - auto chronoTimeoutMs = std::chrono::duration(aTimeoutInMs); - sFunctionTimer.attach(mbed::callback(this, &AppTask::TimerEventHandler), chronoTimeoutMs); - mFunctionTimerActive = true; -} + if (aEvent->Type != AppEvent::kEventType_Button) + return; -void AppTask::CancelTimer() -{ - sFunctionTimer.detach(); - mFunctionTimerActive = false; -} + switch (aEvent->ButtonEvent.button) + { + case kFunction_Button_1: + // To trigger a confirm response: press the FUNCTION_BUTTON1 button briefly (< FACTORY_RESET_TRIGGER_TIMEOUT) + // To initiate factory reset: press the FUNCTION_BUTTON1 for FACTORY_RESET_TRIGGER_TIMEOUT + + // RESET_CANCEL_WINDOW_TIMEOUT All LEDs start blinking after FACTORY_RESET_TRIGGER_TIMEOUT to signal factory reset + // has been initiated. To cancel factory reset: release the FUNCTION_BUTTON1 once all LEDs start blinking within the + // RESET_CANCEL_WINDOW_TIMEOUT + if (aEvent->ButtonEvent.action == kFunction_Button_push) + { + if (!sAppTask.mFunctionTimerActive[kFunction_Button_1] && + sAppTask.mFunction[kFunction_Button_1] == kFunction_NoneSelected) + { + sAppTask.StartTimer(kFunction_Button_1, FACTORY_RESET_TRIGGER_TIMEOUT); -void AppTask::TimerEventHandler() -{ - AppEvent event; - event.Type = AppEvent::kEventType_Timer; - event.Handler = FunctionTimerEventHandler; - sAppTask.PostEvent(&event); -} + sAppTask.mFunction[kFunction_Button_1] = kFunction_ConfirmResponse; + } + } + else + { + // If the button was released before factory reset got initiated, trigger a confirm response. + if (sAppTask.mFunctionTimerActive[kFunction_Button_1] && + sAppTask.mFunction[kFunction_Button_1] == kFunction_ConfirmResponse) + { + sAppTask.CancelTimer(kFunction_Button_1); + sAppTask.mFunction[kFunction_Button_1] = kFunction_NoneSelected; + sAppTask.mUserResponseFlag.set(kUser_Response_confirm); + } + else if (sAppTask.mFunctionTimerActive[kFunction_Button_1] && + sAppTask.mFunction[kFunction_Button_1] == kFunction_FactoryReset) + { + sAppTask.CancelTimer(kFunction_Button_1); -void AppTask::FunctionTimerEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type != AppEvent::kEventType_Timer) - return; + // Change the function to none selected since factory reset has been canceled. + sAppTask.mFunction[kFunction_Button_1] = kFunction_NoneSelected; - // If we reached here, the button was held past FACTORY_RESET_TRIGGER_TIMEOUT, initiate factory reset - if (sAppTask.mFunctionTimerActive && sAppTask.mFunction == kFunction_SoftwareUpdate) - { - ChipLogProgress(NotSpecified, "Factory Reset Triggered. Release button within %ums to cancel.", - FACTORY_RESET_CANCEL_WINDOW_TIMEOUT); + ChipLogProgress(NotSpecified, "Factory Reset has been Canceled"); + } + } + break; + case kFunction_Button_2: + // To trigger a reject response: press the FUNCTION_BUTTON2 button briefly (< COMMISSIONING_RESET_TRIGGER_TIMEOUT) + // To initiate commissioning reset: press the FUNCTION_BUTTON2 for COMMISSIONING_RESET_TRIGGER_TIMEOUT + + // RESET_CANCEL_WINDOW_TIMEOUT All LEDs start blinking after COMMISSIONING_RESET_TRIGGER_TIMEOUT to signal commissioning + // reset has been initiated. To cancel commissioning reset: release the FUNCTION_BUTTON2 once all LEDs start blinking within + // the RESET_CANCEL_WINDOW_TIMEOUT + if (aEvent->ButtonEvent.action == kFunction_Button_push) + { + if (!sAppTask.mFunctionTimerActive[kFunction_Button_2] && + sAppTask.mFunction[kFunction_Button_2] == kFunction_NoneSelected) + { + sAppTask.StartTimer(kFunction_Button_2, COMMISSIONING_RESET_TRIGGER_TIMEOUT); - // Start timer for FACTORY_RESET_CANCEL_WINDOW_TIMEOUT to allow user to - // cancel, if required. - sAppTask.StartTimer(FACTORY_RESET_CANCEL_WINDOW_TIMEOUT); - sAppTask.mFunction = kFunction_FactoryReset; + sAppTask.mFunction[kFunction_Button_2] = kFunction_RejectResponse; + } + } + else + { + // If the button was released before factory reset got initiated, trigger a confirm response. + if (sAppTask.mFunctionTimerActive[kFunction_Button_2] && + sAppTask.mFunction[kFunction_Button_2] == kFunction_RejectResponse) + { + sAppTask.CancelTimer(kFunction_Button_2); + sAppTask.mFunction[kFunction_Button_2] = kFunction_NoneSelected; + sAppTask.mUserResponseFlag.set(kUser_Response_reject); + } + else if (sAppTask.mFunctionTimerActive[kFunction_Button_2] && + sAppTask.mFunction[kFunction_Button_2] == kFunction_CommissioningReset) + { + sAppTask.CancelTimer(kFunction_Button_2); - // Turn off all LEDs before starting blink to make sure blink is co-ordinated. - sStatusLED.Set(false); + // Change the function to none selected since factory reset has been canceled. + sAppTask.mFunction[kFunction_Button_2] = kFunction_NoneSelected; - sStatusLED.Blink(500); - } - else if (sAppTask.mFunctionTimerActive && sAppTask.mFunction == kFunction_FactoryReset) - { - // Actually trigger Factory Reset - ChipLogProgress(NotSpecified, "Factory Reset initiated"); - sAppTask.mFunction = kFunction_NoneSelected; - ConfigurationMgr().InitiateFactoryReset(); + ChipLogProgress(NotSpecified, "Commissioning Reset has been Canceled"); + } + } + break; + default: + ChipLogError(NotSpecified, "Button type not supported"); } } -void AppTask::FunctionHandler(AppEvent * aEvent) +void AppTask::FunctionTimerEventHandler(AppEvent * aEvent) { - if (aEvent->ButtonEvent.Pin != FUNCTION_BUTTON) + if (aEvent->Type != AppEvent::kEventType_Timer) return; - // To trigger software update: press the FUNCTION_BUTTON button briefly (< FACTORY_RESET_TRIGGER_TIMEOUT) - // To initiate factory reset: press the FUNCTION_BUTTON for FACTORY_RESET_TRIGGER_TIMEOUT + FACTORY_RESET_CANCEL_WINDOW_TIMEOUT - // All LEDs start blinking after FACTORY_RESET_TRIGGER_TIMEOUT to signal factory reset has been initiated. - // To cancel factory reset: release the FUNCTION_BUTTON once all LEDs start blinking within the - // FACTORY_RESET_CANCEL_WINDOW_TIMEOUT - if (aEvent->ButtonEvent.Action == BUTTON_PUSH_EVENT) + switch (aEvent->TimerEvent.index) { - if (!sAppTask.mFunctionTimerActive && sAppTask.mFunction == kFunction_NoneSelected) + case kFunction_Button_1: + // If we reached here, the button was held past FACTORY_RESET_TRIGGER_TIMEOUT, initiate factory reset + if (sAppTask.mFunctionTimerActive[kFunction_Button_1] && + sAppTask.mFunction[kFunction_Button_1] == kFunction_ConfirmResponse) { - sAppTask.StartTimer(FACTORY_RESET_TRIGGER_TIMEOUT); + ChipLogProgress(NotSpecified, "Factory Reset Triggered. Release button within %ums to cancel.", + RESET_CANCEL_WINDOW_TIMEOUT); + + // Start timer for RESET_CANCEL_WINDOW_TIMEOUT to allow user to + // cancel, if required. + sAppTask.StartTimer(kFunction_Button_1, RESET_CANCEL_WINDOW_TIMEOUT); + sAppTask.mFunction[kFunction_Button_1] = kFunction_FactoryReset; - sAppTask.mFunction = kFunction_SoftwareUpdate; + // Turn off all LEDs before starting blink to make sure blink is co-ordinated. + sStatusLED.Set(false); + sStatusLED.Blink(500); } - } - else - { - // If the button was released before factory reset got initiated, trigger a software update. - if (sAppTask.mFunctionTimerActive && sAppTask.mFunction == kFunction_SoftwareUpdate) + else if (sAppTask.mFunctionTimerActive[kFunction_Button_1] && + sAppTask.mFunction[kFunction_Button_1] == kFunction_FactoryReset) + { + // Actually trigger Factory Reset + ChipLogProgress(NotSpecified, "Factory Reset initiated"); + sAppTask.CancelTimer(kFunction_Button_1); + sAppTask.mFunction[kFunction_Button_1] = kFunction_NoneSelected; + + ConfigurationMgr().InitiateFactoryReset(); + } + break; + case kFunction_Button_2: + // If we reached here, the button was held past COMMISSIONING_RESET_TRIGGER_TIMEOUT, initiate factory reset + if (sAppTask.mFunctionTimerActive[kFunction_Button_2] && sAppTask.mFunction[kFunction_Button_2] == kFunction_RejectResponse) { - sAppTask.CancelTimer(); - sAppTask.mFunction = kFunction_NoneSelected; - ChipLogError(NotSpecified, "Software Update not supported."); + ChipLogProgress(NotSpecified, "Commissioning Reset Triggered. Release button within %ums to cancel.", + RESET_CANCEL_WINDOW_TIMEOUT); + + // Start timer for RESET_CANCEL_WINDOW_TIMEOUT to allow user to + // cancel, if required. + sAppTask.StartTimer(kFunction_Button_2, RESET_CANCEL_WINDOW_TIMEOUT); + sAppTask.mFunction[kFunction_Button_2] = kFunction_CommissioningReset; + + // Turn off all LEDs before starting blink to make sure blink is co-ordinated. + sStatusLED.Set(false); + sStatusLED.Blink(500); } - else if (sAppTask.mFunctionTimerActive && sAppTask.mFunction == kFunction_FactoryReset) + else if (sAppTask.mFunctionTimerActive[kFunction_Button_2] && + sAppTask.mFunction[kFunction_Button_2] == kFunction_CommissioningReset) { - sAppTask.CancelTimer(); + // Actually trigger Commissioning Reset + ChipLogProgress(NotSpecified, "Commissioning Reset initiated"); + sAppTask.CancelTimer(kFunction_Button_2); + sAppTask.mFunction[kFunction_Button_2] = kFunction_NoneSelected; - // Change the function to none selected since factory reset has been canceled. - sAppTask.mFunction = kFunction_NoneSelected; + chip::Server::GetInstance().GetFabricTable().DeleteAllFabrics(); - ChipLogProgress(NotSpecified, "Factory Reset has been Canceled"); + if (ConnectivityMgr().IsBLEAdvertisingEnabled()) + { + ChipLogProgress(NotSpecified, "BLE advertising is already enabled"); + return; + } + + if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) + { + ChipLogProgress(NotSpecified, "OpenBasicCommissioningWindow() failed"); + } } + break; + default: + ChipLogError(NotSpecified, "Timer event index not supported [%d]", index); } } -void AppTask::BleHandler(AppEvent * aEvent) +bool AppTask::OnUpdateAvailableHandler(void * context, uint32_t softwareVersion, chip::CharSpan softwareVersionString) { - if (aEvent->Type == AppEvent::kEventType_Button) + AppTask * appTask = reinterpret_cast(context); + ChipLogProgress(NotSpecified, "\tNew update available: \t %.*s [%d]", static_cast(softwareVersionString.size()), + softwareVersionString.data(), softwareVersion); + + ChipLogProgress(NotSpecified, "\tDo you want to download new update?"); + ChipLogProgress(NotSpecified, "\tRespond by pressing the button"); + ChipLogProgress(NotSpecified, "\t%10s%10s", "BUTTON0", "BUTTON1"); + ChipLogProgress(NotSpecified, "\t%10s%10s", "YES", "NO"); + if (USER_RESPONSE_TIMEOUT > 0) { - chip::Server::GetInstance().GetFabricTable().DeleteAllFabrics(); + ChipLogProgress(NotSpecified, "\tWaiting response timeout %d", std::chrono::seconds(USER_RESPONSE_TIMEOUT).count()); + } - if (ConnectivityMgr().IsBLEAdvertisingEnabled()) - { - ChipLogProgress(NotSpecified, "BLE advertising is already enabled"); - return; - } + appTask->mUserResponseFlag.clear(); + uint32_t timeout = USER_RESPONSE_TIMEOUT > 0 ? USER_RESPONSE_TIMEOUT : osWaitForever; + uint32_t response = appTask->mUserResponseFlag.wait_any(kUser_Response_confirm | kUser_Response_reject, timeout); + if (response == osFlagsErrorTimeout) + { + ChipLogProgress(NotSpecified, "\tWaiting for user response timeout..."); + } + ChipLogProgress(NotSpecified, "\tDownload new update %s", response == kUser_Response_confirm ? "CONFIRM" : "REJECT"); + return response == kUser_Response_confirm; +} - if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) - { - ChipLogProgress(NotSpecified, "OpenBasicCommissioningWindow() failed"); - } +bool AppTask::OnUpdateApplyHandler(void * context) +{ + AppTask * appTask = reinterpret_cast(context); + + ChipLogProgress(NotSpecified, "\tNew update downloaded"); + ChipLogProgress(NotSpecified, "\tDo you want to apply new update?"); + ChipLogProgress(NotSpecified, "\tRespond by pressing the button"); + ChipLogProgress(NotSpecified, "\t%10s%10s", "YES", "NO"); + ChipLogProgress(NotSpecified, "\t%10s%10s", "BUTTON0", "BUTTON1"); + if (USER_RESPONSE_TIMEOUT > 0) + { + ChipLogProgress(NotSpecified, "\tWaiting response timeout %d", std::chrono::seconds(USER_RESPONSE_TIMEOUT).count()); + } + + appTask->mUserResponseFlag.clear(); + uint32_t timeout = USER_RESPONSE_TIMEOUT > 0 ? USER_RESPONSE_TIMEOUT : osWaitForever; + uint32_t response = appTask->mUserResponseFlag.wait_any(kUser_Response_confirm | kUser_Response_reject, timeout); + if (response == osFlagsErrorTimeout) + { + ChipLogProgress(NotSpecified, "\tWaiting for user response timeout..."); } + ChipLogProgress(NotSpecified, "\tApply new update %s", response == kUser_Response_confirm ? "CONFIRM" : "REJECT"); + return response == kUser_Response_confirm; } diff --git a/examples/ota-requestor-app/mbed/main/include/AppEvent.h b/examples/ota-requestor-app/mbed/main/include/AppEvent.h index 48e2344c71eb32..29e97550ac60bb 100644 --- a/examples/ota-requestor-app/mbed/main/include/AppEvent.h +++ b/examples/ota-requestor-app/mbed/main/include/AppEvent.h @@ -38,9 +38,14 @@ struct AppEvent { struct { - int Pin; - uint8_t Action; + uint8_t button; + uint8_t action; } ButtonEvent; + + struct + { + uint8_t index; + } TimerEvent; }; EventHandler Handler; diff --git a/examples/ota-requestor-app/mbed/main/include/AppTask.h b/examples/ota-requestor-app/mbed/main/include/AppTask.h index 4aa3dbde0ca943..103802325866a8 100644 --- a/examples/ota-requestor-app/mbed/main/include/AppTask.h +++ b/examples/ota-requestor-app/mbed/main/include/AppTask.h @@ -20,8 +20,10 @@ #pragma once #include "AppEvent.h" +#include +#include +#include #include - class AppTask { public: @@ -31,7 +33,32 @@ class AppTask void ButtonEventHandler(uint32_t id, bool pushed); + enum FunctionButton + { + kFunction_Button_1 = 0, + kFunction_Button_2, + kFunction_Button_last + }; + + enum FunctionButtonAction + { + kFunction_Button_release = 0, + kFunction_Button_push + }; + + enum UserResponseType + { + kUser_Response_confirm = 0x1, + kUser_Response_reject = 0x2 + }; + private: + AppTask() : mOnUpdateAvailableCallback(OnUpdateAvailableHandler, this), mOnUpdateApplyCallback(OnUpdateApplyHandler, this) + { + mTimerCallbacks[kFunction_Button_1] = mbed::callback(this, &AppTask::TimerButton1EventHandler); + mTimerCallbacks[kFunction_Button_2] = mbed::callback(this, &AppTask::TimerButton2EventHandler); + } + friend AppTask & GetAppTask(void); int Init(); @@ -39,28 +66,38 @@ class AppTask void DispatchEvent(const AppEvent * event); static void FunctionTimerEventHandler(AppEvent * aEvent); - static void FunctionHandler(AppEvent * aEvent); - static void BleHandler(AppEvent * aEvent); + static void ButtonHandler(AppEvent * aEvent); - void BleButtonPressEventHandler(void); - void FunctionButtonPressEventHandler(void); - void FunctionButtonReleaseEventHandler(void); + void FunctionButton1PressEventHandler(void); + void FunctionButton1ReleaseEventHandler(void); + void FunctionButton2PressEventHandler(void); + void FunctionButton2ReleaseEventHandler(void); - void StartTimer(uint32_t aTimeoutInMs); - void CancelTimer(void); - void TimerEventHandler(void); + void StartTimer(uint8_t index, uint32_t aTimeoutInMs); + void CancelTimer(uint8_t index); + void TimerButton1EventHandler(); + void TimerButton2EventHandler(); + + static bool OnUpdateAvailableHandler(void * context, uint32_t softwareVersion, chip::CharSpan softwareVersionString); + static bool OnUpdateApplyHandler(void * context); + + chip::Callback::Callback mOnUpdateAvailableCallback; + chip::Callback::Callback mOnUpdateApplyCallback; enum Function_t { - kFunction_NoneSelected = 0, - kFunction_SoftwareUpdate = 0, + kFunction_NoneSelected = 0, + kFunction_ConfirmResponse, + kFunction_RejectResponse, kFunction_FactoryReset, - + kFunction_CommissioningReset, kFunction_Invalid }; - Function_t mFunction; - bool mFunctionTimerActive; + Function_t mFunction[kFunction_Button_last]; + bool mFunctionTimerActive[kFunction_Button_last]; + mbed::Callback mTimerCallbacks[kFunction_Button_last]; + rtos::EventFlags mUserResponseFlag; static AppTask sAppTask; }; diff --git a/examples/ota-requestor-app/mbed/main/include/CHIPProjectConfig.h b/examples/ota-requestor-app/mbed/main/include/CHIPProjectConfig.h index 9282dfbceace05..222b6ed33c0b37 100644 --- a/examples/ota-requestor-app/mbed/main/include/CHIPProjectConfig.h +++ b/examples/ota-requestor-app/mbed/main/include/CHIPProjectConfig.h @@ -31,11 +31,3 @@ // Use a default pairing code if one hasn't been provisioned in flash. #define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 #define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 - -#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING MBED_CONF_APP_VERSION_NUMBER_STR -#endif - -#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION MBED_CONF_APP_VERSION_NUMBER -#endif diff --git a/examples/ota-requestor-app/mbed/main/main.cpp b/examples/ota-requestor-app/mbed/main/main.cpp index a91d0946ca06a1..ddf7ecac40d560 100644 --- a/examples/ota-requestor-app/mbed/main/main.cpp +++ b/examples/ota-requestor-app/mbed/main/main.cpp @@ -27,10 +27,6 @@ #include "capsense.h" #endif -#ifdef BOOT_ENABLED -#include -#endif - using namespace ::chip; using namespace ::chip::DeviceLayer; using namespace ::chip::Platform; @@ -49,20 +45,6 @@ int main() ChipLogProgress(SoftwareUpdate, "Mbed OTA Requestor example application start"); -#ifdef BOOT_ENABLED - ret = boot_set_confirmed(); - if (ret == 0) - { - ChipLogProgress(NotSpecified, "Boot confirmed"); - } - else - { - ChipLogError(NotSpecified, "Failed to confirm boot: %d", ret); - } - ChipLogProgress(NotSpecified, "Current software version: [%ld] %s", uint32_t(CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION), - CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); -#endif - ret = mbedtls_platform_setup(NULL); if (ret) { diff --git a/examples/ota-requestor-app/mbed/mbed_app.json b/examples/ota-requestor-app/mbed/mbed_app.json index 8f0644e1d0a3e2..7a6b470c752f9f 100644 --- a/examples/ota-requestor-app/mbed/mbed_app.json +++ b/examples/ota-requestor-app/mbed/mbed_app.json @@ -25,12 +25,12 @@ "WHD_PRINT_DISABLE" ], "target.components_add": ["capsense"], - "ble-button": "USER_BUTTON", + "function-button2": "USER_BUTTON", "mcuboot.primary-slot-address": "0x10022000", - "mcuboot.slot-size": "0x140000", - "mcuboot.scratch-address": "0x10162000", + "mcuboot.slot-size": "0x180000", + "mcuboot.scratch-address": "0x101A2000", "mcuboot.scratch-size": "0x40000", - "mcuboot.max-img-sectors": "0xA00", + "mcuboot.max-img-sectors": "0xC00", "mcuboot.header-size": "0x400" } }, @@ -43,35 +43,45 @@ "help": "System status LED.", "value": "LED1" }, - "function-button": { - "help": "Function button pin.", + "function-button1": { + "help": "Function button 1 pin.", "value": "BUTTON1" }, - "ble-button": { - "help": "BLE button pin.", + "function-button2": { + "help": "Function button 2 pin.", "value": "BUTTON2" }, "factory-reset-trigger-timeout": { - "help": "'function-button' press timeout to trigger a factory reset (in milliseconds).", + "help": "'function-button1' press timeout to trigger a factory reset (in milliseconds).", "value": 3000 }, - "factory-reset-cancel-window-timeout": { - "help": "'function-button' press timeout to cancel a factory reset (in milliseconds). The total 'function-button' press time to have the factory reset actually initiated is equal to 'factory-reset-trigger-timeout' + 'factory-reset-cancel-window-timeout'.", + "commissioning-reset-trigger-timeout": { + "help": "'function-button2' press timeout to trigger a commissioning reset (in milliseconds).", "value": 3000 }, + "reset-cancel-window-timeout": { + "help": "'function-buttonX' press timeout to cancel a reset task (in milliseconds). The total 'function-buttonX' press time to have the specific reset actually initiated is equal to '-reset-trigger-timeout' + 'reset-cancel-window-timeout'.", + "value": 3000 + }, + "user-response-timeout": { + "help": "Amount of time (in milliseconds) to wait for a response from the user. Value equal 0 means waiting forever", + "value": 0 + }, "ble-device-name": { "help": "Name used for BLE advertising.", "value": "\"MBED-ota-req\"" }, - "use-gatt-indication-ack-hack": { - "help": "Fake a TX transfer confirmation. Send a 'kCHIPoBLEIndicateConfirm' event as soon as data is sent, without waiting for the actual ACK from the GATT client. This hack has to stay until we provide a fix in the Mbed OS repo.", - "value": 1 - }, "version-number": { "value": "0" }, "version-number-str": { "value": "\"0.1.0\"" + }, + "vendor-id": { + "value": "0xFFF1" + }, + "product-id": { + "value": "0x8008" } } } diff --git a/examples/pigweed-app/mbed/.gitignore b/examples/pigweed-app/mbed/.gitignore index 414487d53eb835..ef564644de9016 100644 --- a/examples/pigweed-app/mbed/.gitignore +++ b/examples/pigweed-app/mbed/.gitignore @@ -1 +1,2 @@ build-*/ +mcuboot diff --git a/examples/pigweed-app/mbed/CMakeLists.txt b/examples/pigweed-app/mbed/CMakeLists.txt index 140c8a64b61aa8..7e2e7e2b85e9eb 100644 --- a/examples/pigweed-app/mbed/CMakeLists.txt +++ b/examples/pigweed-app/mbed/CMakeLists.txt @@ -5,7 +5,6 @@ cmake_minimum_required(VERSION 3.19.0) get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../.. REALPATH) get_filename_component(MBED_COMMON ${CHIP_ROOT}/examples/platform/mbed REALPATH) -get_filename_component(APP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/.. REALPATH) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/config.in @@ -15,9 +14,21 @@ configure_file( set(MBED_PATH ${MBED_OS_PATH} CACHE INTERNAL "") set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") +set(MCUBOOT_PATH ${MBED_MCU_BOOT_PATH} CACHE INTERNAL "") +set(APP_PATH ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "") +set(APP_TYPE ${MBED_APP_TYPE} CACHE INTERNAL "") +set(BOOT_ENABLED FALSE) set(APP_TARGET chip-mbed-pigweed-app-example) +if(APP_TYPE STREQUAL "boot" OR APP_TYPE STREQUAL "upgrade") + set(BOOT_ENABLED TRUE) +endif() + include(${MBED_PATH}/tools/cmake/app.cmake) +if(MBED_TARGET STREQUAL "CY8CPROTO_062_4343W" AND BOOT_ENABLED) + list(REMOVE_ITEM MBED_TARGET_LABELS CM0P_SLEEP) + list(REMOVE_ITEM MBED_TARGET_DEFINITIONS COMPONENT_CM0P_SLEEP=1) +endif() project(${APP_TARGET}) @@ -31,15 +42,15 @@ add_subdirectory(${CHIP_ROOT}/config/mbed ./chip_build) mbed_configure_app_target(${APP_TARGET}) target_include_directories(${APP_TARGET} PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} + main/include/ ${MBED_COMMON}/util/include ${CHIP_ROOT}/src/lib/support - ${CMAKE_CURRENT_SOURCE_DIR}/main/include/ ) target_sources(${APP_TARGET} PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/main/main.cpp - ${MBED_COMMON}/util/LEDWidget.cpp + main/main.cpp + ${MBED_COMMON}/util/LEDWidget.cpp + ${MBED_COMMON}/util/DFUManager.cpp ) target_link_libraries(${APP_TARGET} mbed-os-posix-socket mbed-os mbed-ble mbed-events mbed-netsocket mbed-storage mbed-storage-kv-global-api mbed-mbedtls mbed-emac chip) diff --git a/examples/pigweed-app/mbed/config.in b/examples/pigweed-app/mbed/config.in index a13a8e62e17b43..6c687926f2f5c7 100644 --- a/examples/pigweed-app/mbed/config.in +++ b/examples/pigweed-app/mbed/config.in @@ -3,4 +3,5 @@ CONFIG_CHIP_WITH_EXTERNAL_MBEDTLS=y CONFIG_CHIP_PROJECT_CONFIG=main/include/CHIPProjectConfig.h CONFIG_CHIP_BYPASS_RENDEZVOUS=n CONFIG_MBED_BSD_SOCKET_TRACE=n -CONFIG_CHIP_PW_RPC=y \ No newline at end of file +CONFIG_CHIP_PW_RPC=y +CONFIG_CHIP_OTA_REQUESTOR=n \ No newline at end of file diff --git a/examples/pigweed-app/mbed/main/include/CHIPProjectConfig.h b/examples/pigweed-app/mbed/main/include/CHIPProjectConfig.h index 4326ea54b7d3ee..f4873be770c6c7 100644 --- a/examples/pigweed-app/mbed/main/include/CHIPProjectConfig.h +++ b/examples/pigweed-app/mbed/main/include/CHIPProjectConfig.h @@ -26,3 +26,11 @@ */ #pragma once + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING MBED_CONF_APP_VERSION_NUMBER_STR +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION MBED_CONF_APP_VERSION_NUMBER +#endif diff --git a/examples/pigweed-app/mbed/main/main.cpp b/examples/pigweed-app/mbed/main/main.cpp index c4a415cd63804f..563b3312c03fa8 100644 --- a/examples/pigweed-app/mbed/main/main.cpp +++ b/examples/pigweed-app/mbed/main/main.cpp @@ -15,8 +15,11 @@ * limitations under the License. */ -#include "LEDWidget.h" #include "Rpc.h" +#include +#include + +#include "rtos/Thread.h" #include #include @@ -29,7 +32,9 @@ static LEDWidget sStatusLED(MBED_CONF_APP_SYSTEM_STATE_LED); int main() { - int ret = 0; + int ret = 0; + CHIP_ERROR err = CHIP_NO_ERROR; + rtos::Thread * rpcThread = nullptr; mbed_logging_init(); @@ -37,7 +42,15 @@ int main() sStatusLED.Set(true); - auto rpcThread = chip::rpc::Init(); + err = GetDFUManager().Init(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "DFU manager initialization failed: %s", err.AsString()); + ret = EXIT_FAILURE; + goto exit; + } + + rpcThread = chip::rpc::Init(); if (rpcThread == NULL) { ChipLogError(NotSpecified, "RPC service initialization and run failed"); diff --git a/examples/pigweed-app/mbed/mbed_app.json b/examples/pigweed-app/mbed/mbed_app.json index 8f146bb0e3a750..1b73ad5393e555 100644 --- a/examples/pigweed-app/mbed/mbed_app.json +++ b/examples/pigweed-app/mbed/mbed_app.json @@ -11,7 +11,10 @@ "nsapi.default-wifi-password": "\"YOUR_PASSWORD\"", "mbed-trace.max-level": "TRACE_LEVEL_DEBUG", "mbed-trace.enable": true, - "target.printf_lib": "std" + "target.printf_lib": "std", + "mcuboot.bootloader-build": false, + "mcuboot.log-enable": true, + "mcuboot.log-level": "MCUBOOT_LOG_LEVEL_ERROR" }, "CY8CPROTO_062_4343W": { "target.network-default-interface-type": "WIFI", @@ -20,7 +23,13 @@ "NL_ASSERT_LOG=NL_ASSERT_LOG_DEFAULT", "NL_ASSERT_EXPECT_FLAGS=NL_ASSERT_FLAG_LOG", "WHD_PRINT_DISABLE" - ] + ], + "mcuboot.primary-slot-address": "0x10022000", + "mcuboot.slot-size": "0x180000", + "mcuboot.scratch-address": "0x101A2000", + "mcuboot.scratch-size": "0x40000", + "mcuboot.max-img-sectors": "0xC00", + "mcuboot.header-size": "0x400" } }, "config": { @@ -31,6 +40,18 @@ "system-state-led": { "help": "System status LED.", "value": "LED1" + }, + "version-number": { + "value": "0" + }, + "version-number-str": { + "value": "\"0.1.0\"" + }, + "vendor-id": { + "value": "0xFFF1" + }, + "product-id": { + "value": "0x800B" } } } diff --git a/examples/platform/mbed/bootloader/mbed_app.json b/examples/platform/mbed/bootloader/mbed_app.json index a3a147fbc6334d..1c14b532cc7a70 100644 --- a/examples/platform/mbed/bootloader/mbed_app.json +++ b/examples/platform/mbed/bootloader/mbed_app.json @@ -28,10 +28,10 @@ "CY8CPROTO_062_4343W": { "target.components_remove": ["WHD"], "mcuboot.primary-slot-address": "0x10022000", - "mcuboot.slot-size": "0x140000", - "mcuboot.scratch-address": "0x10162000", + "mcuboot.slot-size": "0x180000", + "mcuboot.scratch-address": "0x101A2000", "mcuboot.scratch-size": "0x40000", - "mcuboot.max-img-sectors": "0xA00", + "mcuboot.max-img-sectors": "0xC00", "mcuboot.overwrite-only": true } } diff --git a/examples/platform/mbed/ota/generate_ota_list_image.py b/examples/platform/mbed/ota/generate_ota_list_image.py new file mode 100644 index 00000000000000..72c6dd74c102e9 --- /dev/null +++ b/examples/platform/mbed/ota/generate_ota_list_image.py @@ -0,0 +1,85 @@ +#!/usr/bin/env -S python3 + +# +# Copyright (c) 2022 Project CHIP Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +## +# @file +# Generates OTA image list file based on Mbed project configuration file (mbed_app.json) +# OTA image list JSON file (see /examples/ota-provider-app/linux/README.md) +# +# Usage: generate_ota_list_image.py + +import json +import os +import string +import sys + +FILE_NAME = "ota-image-list.json" + +FILE_DATA_TEMPLATE = """{ + "deviceSoftwareVersionModel": [ + { + "vendorId": 0, + "productId": 0, + "softwareVersion": 0, + "softwareVersionString": "", + "cDVersionNumber": 0, + "softwareVersionValid": true, + "minApplicableSoftwareVersion": 0, + "maxApplicableSoftwareVersion": 1000, + "otaURL": "" + } + ] +} +""" + + +def CreateOtaListFile(config, imagePath): + data = json.loads(FILE_DATA_TEMPLATE) + + data["deviceSoftwareVersionModel"][0]["vendorId"] = int( + config["config"]["vendor-id"]["value"], base=16) + data["deviceSoftwareVersionModel"][0]["productId"] = int( + config["config"]["product-id"]["value"], base=16) + data["deviceSoftwareVersionModel"][0]["softwareVersion"] = int( + config["config"]["version-number"]["value"]) + data["deviceSoftwareVersionModel"][0]["softwareVersionString"] = config[ + "config"]["version-number-str"]["value"].strip('"\\') + data["deviceSoftwareVersionModel"][0]["otaURL"] = str(imagePath) + + output_path = os.path.join(os.path.dirname(imagePath), FILE_NAME) + + with open(output_path, 'w') as jsonFile: + json.dump(data, jsonFile) + + +def main(): + if len(sys.argv) != 3: + print('Usage: ' + sys.argv[0] + + ' ') + exit(1) + + config_json_path = sys.argv[1] + image_path = sys.argv[2] + with open(config_json_path, 'r') as json_file: + config = json.loads(json_file.read()) + + CreateOtaListFile(config, image_path) + + +if __name__ == "__main__": + main() diff --git a/examples/platform/mbed/util/DFUManager.cpp b/examples/platform/mbed/util/DFUManager.cpp new file mode 100644 index 00000000000000..a26b7f1f47d320 --- /dev/null +++ b/examples/platform/mbed/util/DFUManager.cpp @@ -0,0 +1,91 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "DFUManager.h" + +#ifdef CHIP_OTA_REQUESTOR +#include +#endif // CHIP_OTA_REQUESTOR + +#ifdef BOOT_ENABLED +#include +#endif // BOOT_ENABLED + +DFUManager DFUManager::sDFUMgr; + +CHIP_ERROR DFUManager::Init(chip::Callback::Callback * onUpdateAvailable, + chip::Callback::Callback * onUpdateApply) +{ + int ret; + CHIP_ERROR err = CHIP_NO_ERROR; + + mOnUpdateAvailableCallback = onUpdateAvailable; + mOnUpdateApplyCallback = onUpdateApply; + +#ifdef BOOT_ENABLED + ret = boot_set_confirmed(); + if (ret == 0) + { + ChipLogProgress(SoftwareUpdate, "Boot confirmed"); + } + else + { + ChipLogError(SoftwareUpdate, "Failed to confirm boot: %d", ret); + err = CHIP_ERROR_INTERNAL; + } + +#if defined(CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION) && defined(CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING) + ChipLogProgress(SoftwareUpdate, "Current software version: [%ld] %s", uint32_t(CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION), + CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); +#endif // CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION && CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#endif // BOOT_ENABLED + +#ifdef CHIP_OTA_REQUESTOR + SetRequestorInstance(&mRequestorCore); + mRequestorCore.Init(&(chip::Server::GetInstance()), &mRequestorDriver, &mDownloader); + mImageProcessor.SetOTADownloader(&mDownloader); + mDownloader.SetImageProcessorDelegate(&mImageProcessor); + mRequestorDriver.Init(&mRequestorCore, &mImageProcessor, &mOnOtaUpdateAvailableCallback, &mOnOtaUpdateApplyCallback); +#endif // CHIP_OTA_REQUESTOR + + return err; +} + +#ifdef CHIP_OTA_REQUESTOR +bool DFUManager::OnOtaUpdateAvailableHandler(void * context, const chip::UpdateDescription & desc) +{ + DFUManager * dfuMgr = reinterpret_cast(context); + if (dfuMgr->mOnUpdateAvailableCallback) + { + return dfuMgr->mOnUpdateAvailableCallback->mCall(dfuMgr->mOnUpdateAvailableCallback->mContext, desc.softwareVersion, + desc.softwareVersionStr); + } + + return true; +} + +bool DFUManager::OnOtaUpdateApplyHandler(void * context) +{ + DFUManager * dfuMgr = reinterpret_cast(context); + if (dfuMgr->mOnUpdateApplyCallback) + { + return dfuMgr->mOnUpdateApplyCallback->mCall(dfuMgr->mOnUpdateAvailableCallback->mContext); + } + + return true; +} +#endif diff --git a/examples/platform/mbed/util/include/DFUManager.h b/examples/platform/mbed/util/include/DFUManager.h new file mode 100644 index 00000000000000..aed8b29bb9e7da --- /dev/null +++ b/examples/platform/mbed/util/include/DFUManager.h @@ -0,0 +1,75 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of Device Firmware Upgrade using Matter OTA. + */ + +#pragma once + +#include +#include +#include + +#ifdef CHIP_OTA_REQUESTOR +#include +#include +#include +#include +#endif // CHIP_OTA_REQUESTOR + +typedef bool (*OnUpdateAvailable)(void * context, uint32_t softwareVersion, chip::CharSpan softwareVersionString); +typedef bool (*OnUpdateApply)(void * context); + +class DFUManager +{ +public: + CHIP_ERROR Init(chip::Callback::Callback * onUpdateAvailable = nullptr, + chip::Callback::Callback * onUpdateApply = nullptr); + +private: +#ifdef CHIP_OTA_REQUESTOR + DFUManager() : + mOnOtaUpdateAvailableCallback(OnOtaUpdateAvailableHandler, this), mOnOtaUpdateApplyCallback(OnOtaUpdateApplyHandler, this) + {} +#endif + friend DFUManager & GetDFUManager(void); + + static DFUManager sDFUMgr; + +#ifdef CHIP_OTA_REQUESTOR + chip::OTARequestor mRequestorCore; + chip::DeviceLayer::OTARequestorDriverImpl mRequestorDriver; + chip::BDXDownloader mDownloader; + chip::OTAImageProcessorImpl mImageProcessor; + + static bool OnOtaUpdateAvailableHandler(void * context, const chip::UpdateDescription & desc); + static bool OnOtaUpdateApplyHandler(void * context); + + chip::Callback::Callback mOnOtaUpdateAvailableCallback; + chip::Callback::Callback mOnOtaUpdateApplyCallback; +#endif // CHIP_OTA_REQUESTOR + + chip::Callback::Callback * mOnUpdateAvailableCallback; + chip::Callback::Callback * mOnUpdateApplyCallback; +}; + +inline DFUManager & GetDFUManager(void) +{ + return DFUManager::sDFUMgr; +} diff --git a/examples/shell/mbed/.gitignore b/examples/shell/mbed/.gitignore index 414487d53eb835..ef564644de9016 100644 --- a/examples/shell/mbed/.gitignore +++ b/examples/shell/mbed/.gitignore @@ -1 +1,2 @@ build-*/ +mcuboot diff --git a/examples/shell/mbed/CMakeLists.txt b/examples/shell/mbed/CMakeLists.txt index fbd5b2576ecf9b..da45aeb1a7b94f 100644 --- a/examples/shell/mbed/CMakeLists.txt +++ b/examples/shell/mbed/CMakeLists.txt @@ -4,8 +4,10 @@ cmake_minimum_required(VERSION 3.19.0) get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../.. REALPATH) -get_filename_component(APP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/.. REALPATH) +get_filename_component(MBED_COMMON ${CHIP_ROOT}/examples/platform/mbed REALPATH) +get_filename_component(SHELL_COMMON ${CHIP_ROOT}/examples/shell/shell_common REALPATH) get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) +get_filename_component(NLIO_ROOT ${CHIP_ROOT}/third_party/nlio/repo/include REALPATH) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/config.in @@ -15,9 +17,21 @@ configure_file( set(MBED_PATH ${MBED_OS_PATH} CACHE INTERNAL "") set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") +set(MCUBOOT_PATH ${MBED_MCU_BOOT_PATH} CACHE INTERNAL "") +set(APP_PATH ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "") +set(APP_TYPE ${MBED_APP_TYPE} CACHE INTERNAL "") +set(BOOT_ENABLED FALSE) set(APP_TARGET chip-mbed-shell-example) +if(APP_TYPE STREQUAL "boot" OR APP_TYPE STREQUAL "upgrade") + set(BOOT_ENABLED TRUE) +endif() + include(${MBED_PATH}/tools/cmake/app.cmake) +if(MBED_TARGET STREQUAL "CY8CPROTO_062_4343W" AND BOOT_ENABLED) + list(REMOVE_ITEM MBED_TARGET_LABELS CM0P_SLEEP) + list(REMOVE_ITEM MBED_TARGET_DEFINITIONS COMPONENT_CM0P_SLEEP=1) +endif() project(${APP_TARGET}) @@ -32,17 +46,22 @@ add_subdirectory(${CHIP_ROOT}/config/mbed ./chip_build) mbed_configure_app_target(${APP_TARGET}) target_include_directories(${APP_TARGET} PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/main/include - ${APP_ROOT}/shell_common/include - ${GEN_DIR}/app-common) + main/include + ${MBED_COMMON}/util/include + ${SHELL_COMMON}/include + ${GEN_DIR}/app-common + ${NLIO_ROOT} +) target_sources(${APP_TARGET} PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/main/main.cpp - ${APP_ROOT}/shell_common/cmd_misc.cpp - ${APP_ROOT}/shell_common/cmd_otcli.cpp - ${APP_ROOT}/shell_common/cmd_ping.cpp - ${APP_ROOT}/shell_common/cmd_send.cpp - ${APP_ROOT}/shell_common/globals.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/main/main.cpp + ${SHELL_COMMON}/cmd_misc.cpp + ${SHELL_COMMON}/cmd_otcli.cpp + ${SHELL_COMMON}/cmd_ping.cpp + ${SHELL_COMMON}/cmd_send.cpp + ${SHELL_COMMON}/cmd_server.cpp + ${SHELL_COMMON}/globals.cpp + ${MBED_COMMON}/util/DFUManager.cpp ) target_link_libraries(${APP_TARGET} mbed-os-posix-socket mbed-os mbed-ble mbed-events mbed-netsocket mbed-storage mbed-storage-kv-global-api mbed-mbedtls mbed-emac chip) diff --git a/examples/shell/mbed/config.in b/examples/shell/mbed/config.in index 33fc7acf3c4a8f..ace6c25e719399 100644 --- a/examples/shell/mbed/config.in +++ b/examples/shell/mbed/config.in @@ -4,3 +4,4 @@ CONFIG_CHIP_PROJECT_CONFIG=main/include/CHIPProjectConfig.h CONFIG_CHIP_BYPASS_RENDEZVOUS=n CONFIG_CHIP_LIB_SHELL=y CONFIG_MBED_BSD_SOCKET_TRACE=n +CONFIG_CHIP_OTA_REQUESTOR=y diff --git a/examples/shell/mbed/main/main.cpp b/examples/shell/mbed/main/main.cpp index 9d7d16c57184fb..36404a443d19d1 100644 --- a/examples/shell/mbed/main/main.cpp +++ b/examples/shell/mbed/main/main.cpp @@ -17,6 +17,7 @@ #include "mbedtls/platform.h" #include +#include #include #include #include @@ -83,6 +84,14 @@ int main() goto exit; } + err = GetDFUManager().Init(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "DFU manager initialization failed: %s", err.AsString()); + ret = EXIT_FAILURE; + goto exit; + } + // Initialize the default streamer that was linked. ret = Engine::Root().Init(); if (ret) @@ -95,6 +104,7 @@ int main() cmd_otcli_init(); cmd_ping_init(); cmd_send_init(); + cmd_app_server_init(); ChipLogProgress(NotSpecified, "Mbed shell example application run"); diff --git a/examples/shell/mbed/mbed_app.json b/examples/shell/mbed/mbed_app.json index b33037b883bbb1..b41f5ba20ca48c 100644 --- a/examples/shell/mbed/mbed_app.json +++ b/examples/shell/mbed/mbed_app.json @@ -11,7 +11,10 @@ "nsapi.default-wifi-password": "\"YOUR_PASSWORD\"", "mbed-trace.max-level": "TRACE_LEVEL_DEBUG", "mbed-trace.enable": true, - "target.printf_lib": "std" + "target.printf_lib": "std", + "mcuboot.bootloader-build": false, + "mcuboot.log-enable": true, + "mcuboot.log-level": "MCUBOOT_LOG_LEVEL_ERROR" }, "CY8CPROTO_062_4343W": { "target.network-default-interface-type": "WIFI", @@ -20,13 +23,31 @@ "NL_ASSERT_LOG=NL_ASSERT_LOG_DEFAULT", "NL_ASSERT_EXPECT_FLAGS=NL_ASSERT_FLAG_LOG", "WHD_PRINT_DISABLE" - ] + ], + "mcuboot.primary-slot-address": "0x10022000", + "mcuboot.slot-size": "0x180000", + "mcuboot.scratch-address": "0x101A2000", + "mcuboot.scratch-size": "0x40000", + "mcuboot.max-img-sectors": "0xC00", + "mcuboot.header-size": "0x400" } }, "config": { "ble-device-name": { "help": "Name used for BLE advertising.", "value": "\"MBED-shell\"" + }, + "version-number": { + "value": "0" + }, + "version-number-str": { + "value": "\"0.1.0\"" + }, + "vendor-id": { + "value": "0xFFF1" + }, + "product-id": { + "value": "0x8012" } } } diff --git a/scripts/examples/mbed_example.sh b/scripts/examples/mbed_example.sh index cef30fde0164ea..c7d6f0adfd19bc 100755 --- a/scripts/examples/mbed_example.sh +++ b/scripts/examples/mbed_example.sh @@ -18,7 +18,6 @@ cd "$(dirname "$0")"/../.. CHIP_ROOT=$PWD -cd "$CHIP_ROOT"/examples SUPPORTED_TOOLCHAIN=(GCC_ARM ARM) SUPPORTED_TARGET_BOARD=(CY8CPROTO_062_4343W) @@ -110,8 +109,11 @@ set -e # Exit immediately if a command exits with a non-zero status. # Activate Matter environment source "$CHIP_ROOT"/scripts/activate.sh +# Application directory setup +APP_DIRECTORY="$CHIP_ROOT"/examples/"$APP"/mbed + # Build directory setup -BUILD_DIRECTORY="$APP"/mbed/build-"$TARGET_BOARD"/"$PROFILE"/ +BUILD_DIRECTORY="$APP_DIRECTORY"/build-"$TARGET_BOARD"/"$PROFILE" # Set bootloader root directory BOOTLOADER_ROOT_DIRECTORY="$CHIP_ROOT"/examples/platform/mbed/bootloader @@ -179,23 +181,23 @@ if [[ "$COMMAND" == *"build"* ]]; then MBED_OS_POSIX_SOCKET_PATH="$CHIP_ROOT"/third_party/mbed-os-posix-socket/repo if [[ "$TYPE" == "boot" || "$TYPE" == "upgrade" ]]; then - ln -sfTr "$MBED_MCU_BOOT_PATH"/boot/mbed "$APP"/mbed/mcuboot + ln -sfTr "$MBED_MCU_BOOT_PATH"/boot/mbed "$APP_DIRECTORY"/mcuboot fi # Generate config file for selected target, toolchain and hardware - mbed-tools configure -t "$TOOLCHAIN" -m "$TARGET_BOARD" -p "$APP"/mbed/ -o "$BUILD_DIRECTORY" --mbed-os-path "$MBED_OS_PATH" + mbed-tools configure -t "$TOOLCHAIN" -m "$TARGET_BOARD" -p "$APP_DIRECTORY" -o "$BUILD_DIRECTORY" --mbed-os-path "$MBED_OS_PATH" # Remove old artifacts to force linking rm -rf "$BUILD_DIRECTORY/chip-"* # Build application - cmake -S "$APP/mbed" -B "$BUILD_DIRECTORY" -GNinja -DCMAKE_BUILD_TYPE="$PROFILE" -DMBED_OS_PATH="$MBED_OS_PATH" -DMBED_OS_POSIX_SOCKET_PATH="$MBED_OS_POSIX_SOCKET_PATH" -DMBED_MCU_BOOT_PATH="$MBED_MCU_BOOT_PATH" -DMBED_APP_TYPE="$TYPE" + cmake -S "$APP_DIRECTORY" -B "$BUILD_DIRECTORY" -GNinja -DCMAKE_BUILD_TYPE="$PROFILE" -DMBED_OS_PATH="$MBED_OS_PATH" -DMBED_OS_POSIX_SOCKET_PATH="$MBED_OS_POSIX_SOCKET_PATH" -DMBED_MCU_BOOT_PATH="$MBED_MCU_BOOT_PATH" -DMBED_APP_TYPE="$TYPE" cmake --build "$BUILD_DIRECTORY" if [[ "$TYPE" == "boot" || "$TYPE" == "upgrade" ]]; then - APP_VERSION=$(jq '.config."version-number-str".value' "$APP"/mbed/mbed_app.json | tr -d '\\"') - HEADER_SIZE=$(jq '.target_overrides.'\""$TARGET_BOARD"\"'."mcuboot.header-size"' "$APP"/mbed/mbed_app.json | tr -d \") - SLOT_SIZE=$(jq '.target_overrides.'\""$TARGET_BOARD"\"'."mcuboot.slot-size"' "$APP"/mbed/mbed_app.json | tr -d \") + APP_VERSION=$(jq '.config."version-number-str".value' "$APP_DIRECTORY"/mbed_app.json | tr -d '\\"') + HEADER_SIZE=$(jq '.target_overrides.'\""$TARGET_BOARD"\"'."mcuboot.header-size"' "$APP_DIRECTORY"/mbed_app.json | tr -d \") + SLOT_SIZE=$(jq '.target_overrides.'\""$TARGET_BOARD"\"'."mcuboot.slot-size"' "$APP_DIRECTORY"/mbed_app.json | tr -d \") if [[ "$TYPE" == "boot" ]]; then # Signed the primary application @@ -211,6 +213,7 @@ if [[ "$COMMAND" == *"build"* ]]; then "$BUILD_DIRECTORY"/chip-mbed-"$APP"-example.hex "$BUILD_DIRECTORY"/chip-mbed-"$APP"-example-signed.hex # Convert hex image to raw binary file arm-none-eabi-objcopy -I ihex -O binary "$BUILD_DIRECTORY"/chip-mbed-"$APP"-example-signed.hex "$BUILD_DIRECTORY"/chip-mbed-"$APP"-example.bin + python "$CHIP_ROOT"/examples/platform/mbed/ota/generate_ota_list_image.py "$APP_DIRECTORY"/mbed_app.json "$BUILD_DIRECTORY"/chip-mbed-"$APP"-example.bin fi fi fi diff --git a/src/app/clusters/ota-requestor/OTARequestor.cpp b/src/app/clusters/ota-requestor/OTARequestor.cpp index 6e524919a5b5e6..50df46e0ddb057 100644 --- a/src/app/clusters/ota-requestor/OTARequestor.cpp +++ b/src/app/clusters/ota-requestor/OTARequestor.cpp @@ -664,7 +664,8 @@ CHIP_ERROR OTARequestor::ExtractUpdateDescription(const QueryImageResponseDecoda VerifyOrReturnError(response.softwareVersion.HasValue(), CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(response.softwareVersionString.HasValue(), CHIP_ERROR_INVALID_ARGUMENT); - update.softwareVersion = response.softwareVersion.Value(); + update.softwareVersion = response.softwareVersion.Value(); + update.softwareVersionStr = response.softwareVersionString.Value(); VerifyOrReturnError(response.updateToken.HasValue(), CHIP_ERROR_INVALID_ARGUMENT); update.updateToken = response.updateToken.Value(); diff --git a/src/include/platform/OTARequestorDriver.h b/src/include/platform/OTARequestorDriver.h index bd99df6abc3eea..23df6d99c41716 100644 --- a/src/include/platform/OTARequestorDriver.h +++ b/src/include/platform/OTARequestorDriver.h @@ -35,6 +35,7 @@ struct UpdateDescription { CharSpan imageURI; uint32_t softwareVersion; + CharSpan softwareVersionStr; ByteSpan updateToken; bool userConsentNeeded; ByteSpan metadataForRequestor; diff --git a/src/platform/GenericOTARequestorDriver.h b/src/platform/GenericOTARequestorDriver.h index 053698aa916e41..a029325ebd00cb 100644 --- a/src/platform/GenericOTARequestorDriver.h +++ b/src/platform/GenericOTARequestorDriver.h @@ -54,7 +54,7 @@ class GenericOTARequestorDriver : public OTARequestorDriver void UpdateDiscontinued() override; void UpdateCancelled() override; -private: +protected: void ScheduleDelayedAction(UpdateFailureState state, System::Clock::Seconds32 delay, System::TimerCompleteCallback action); OTARequestorInterface * mRequestor = nullptr; diff --git a/src/platform/mbed/BLEManagerImpl.cpp b/src/platform/mbed/BLEManagerImpl.cpp index ab8a34477746ce..0dfa816c246264 100644 --- a/src/platform/mbed/BLEManagerImpl.cpp +++ b/src/platform/mbed/BLEManagerImpl.cpp @@ -420,10 +420,11 @@ struct CHIPService : public ble::GattServer::EventHandler { ChipLogDetail(DeviceLayer, "GATT %s, connHandle=%d, attHandle=%d", __FUNCTION__, params.connHandle, params.attHandle); - // FIXME: ACK hack -#if (defined(MBED_CONF_APP_USE_GATT_INDICATION_ACK_HACK) && (MBED_CONF_APP_USE_GATT_INDICATION_ACK_HACK != 0)) + // Note: This is applicable to both notification and indication: If a + // notification is sent then onDataSent is called as soon as the data + // has been pushed into the Bluetooth controller. For indication, onDataSent + // is called when the confirmation has been received. onConfirmationReceived(params); -#endif } void onDataWritten(const GattWriteCallbackParams & params) override diff --git a/src/platform/mbed/CHIPDevicePlatformConfig.h b/src/platform/mbed/CHIPDevicePlatformConfig.h index 7edd1c91a6755b..8f47d0c2c6bf6b 100644 --- a/src/platform/mbed/CHIPDevicePlatformConfig.h +++ b/src/platform/mbed/CHIPDevicePlatformConfig.h @@ -27,18 +27,34 @@ #define CHIP_DEVICE_CONFIG_ENABLE_THREAD 0 +#define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 0 + #ifndef CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE #define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1 -#endif +#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE -#define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 0 +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING MBED_CONF_APP_VERSION_NUMBER_STR +#endif // CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING -#define CHIP_DEVICE_CONFIG_ENABLE_DNSSD 1 +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION MBED_CONF_APP_VERSION_NUMBER +#endif // CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION -#ifndef CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE -#define CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE 8192 -#endif // CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE +#ifndef CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID MBED_CONF_APP_VENDOR_ID +#endif // CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID MBED_CONF_APP_PRODUCT_ID +#endif // CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID // ========== Platform-specific Configuration Overrides ========= #define CHIP_DEVICE_CONFIG_LOG_PROVISIONING_HASH 0 + +#define CHIP_DEVICE_CONFIG_ENABLE_DNSSD 1 + +#ifndef CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE +#define CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE 8192 +#endif // CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE diff --git a/src/platform/mbed/MbedConfig.cpp b/src/platform/mbed/MbedConfig.cpp index 95ef2d81340113..bf64b3e3074076 100644 --- a/src/platform/mbed/MbedConfig.cpp +++ b/src/platform/mbed/MbedConfig.cpp @@ -42,9 +42,11 @@ namespace Internal { // *** CAUTION ***: Changing the names or namespaces of these values will *break* existing devices. +#define STR_EXPAND(tok) #tok + // Note: An external mbed parameter could be useful so an application can put // chip NVS values in a single place -#define CHIP_CONFIG_KV_STORE_PARTITION "/kv/" +#define CHIP_CONFIG_KV_STORE_PARTITION STR_EXPAND(MBED_CONF_STORAGE_DEFAULT_KV) // NVS namespaces used to store device configuration information. #define CHIP_CONFIG_FACTORY_PREFIX "chip-factory-" diff --git a/src/platform/mbed/OTAImageProcessorImpl.cpp b/src/platform/mbed/OTAImageProcessorImpl.cpp index 6e122e118508a7..714601f6c0336d 100644 --- a/src/platform/mbed/OTAImageProcessorImpl.cpp +++ b/src/platform/mbed/OTAImageProcessorImpl.cpp @@ -23,6 +23,8 @@ #ifdef BOOT_ENABLED #include "bootutil/bootutil.h" #include "flash_map_backend/secondary_bd.h" +#include "platform/mbed_power_mgmt.h" +#include "rtos/ThisThread.h" #endif using namespace ::chip::DeviceLayer::Internal; @@ -49,7 +51,7 @@ int OTAImageProcessorImpl::MemoryTest() if (!mBlockDevice) { - ChipLogError(NotSpecified, "Block device not set"); + ChipLogError(SoftwareUpdate, "Block device not set"); return 1; } @@ -57,12 +59,12 @@ int OTAImageProcessorImpl::MemoryTest() ret = mBlockDevice->init(); if (ret) { - ChipLogError(NotSpecified, "Block device initialization failed [%d]", ret); + ChipLogError(SoftwareUpdate, "Block device initialization failed [%d]", ret); goto exit; } // Get the block device type - ChipLogProgress(NotSpecified, "Block device type: %s", mBlockDevice->get_type()); + ChipLogProgress(SoftwareUpdate, "Block device type: %s", mBlockDevice->get_type()); // Get device geometry read_size = mBlockDevice->get_read_size(); @@ -70,12 +72,12 @@ int OTAImageProcessorImpl::MemoryTest() erase_size = mBlockDevice->get_erase_size(); full_size = mBlockDevice->size(); - ChipLogProgress(NotSpecified, "--- Block device geometry ---"); - ChipLogProgress(NotSpecified, "read_size: %lld B", read_size); - ChipLogProgress(NotSpecified, "program_size: %lld B", program_size); - ChipLogProgress(NotSpecified, "erase_size: %lld B", erase_size); - ChipLogProgress(NotSpecified, "size: %lld B", full_size); - ChipLogProgress(NotSpecified, "---\n"); + ChipLogProgress(SoftwareUpdate, "--- Block device geometry ---"); + ChipLogProgress(SoftwareUpdate, "read_size: %lld B", read_size); + ChipLogProgress(SoftwareUpdate, "program_size: %lld B", program_size); + ChipLogProgress(SoftwareUpdate, "erase_size: %lld B", erase_size); + ChipLogProgress(SoftwareUpdate, "size: %lld B", full_size); + ChipLogProgress(SoftwareUpdate, "---\n"); // Allocate a block with enough space for our data, aligned to the // nearest program_size. This is the minimum size necessary to write @@ -89,34 +91,34 @@ int OTAImageProcessorImpl::MemoryTest() ret = mBlockDevice->read(buffer, 0, buffer_size); if (ret) { - ChipLogError(NotSpecified, "Block device read failed [%d]", ret); + ChipLogError(SoftwareUpdate, "Block device read failed [%d]", ret); goto exit; } - ChipLogProgress(NotSpecified, "--- Currently stored data ---"); + ChipLogProgress(SoftwareUpdate, "--- Currently stored data ---"); for (size_t i = 0; i < buffer_size; i += 16) { for (size_t j = 0; j < 16; j++) { if (i + j < buffer_size) { - ChipLogProgress(NotSpecified, "%02x ", buffer[i + j]); + ChipLogProgress(SoftwareUpdate, "%02x ", buffer[i + j]); } else { - ChipLogProgress(NotSpecified, " "); + ChipLogProgress(SoftwareUpdate, " "); } } - ChipLogProgress(NotSpecified, " "); + ChipLogProgress(SoftwareUpdate, " "); } - ChipLogProgress(NotSpecified, "---\n"); + ChipLogProgress(SoftwareUpdate, "---\n"); // Write data to first block, write occurs in two parts, // an erase followed by a program ret = mBlockDevice->erase(0, erase_size); if (ret) { - ChipLogError(NotSpecified, "Block device erase failed [%d]", ret); + ChipLogError(SoftwareUpdate, "Block device erase failed [%d]", ret); goto exit; } @@ -127,27 +129,27 @@ int OTAImageProcessorImpl::MemoryTest() ret = mBlockDevice->read(buffer, 0, buffer_size); if (ret) { - ChipLogError(NotSpecified, "Block device read failed [%d]", ret); + ChipLogError(SoftwareUpdate, "Block device read failed [%d]", ret); goto exit; } - ChipLogProgress(NotSpecified, "--- Stored data after erase ---"); + ChipLogProgress(SoftwareUpdate, "--- Stored data after erase ---"); for (size_t i = 0; i < buffer_size; i += 16) { for (size_t j = 0; j < 16; j++) { if (i + j < buffer_size) { - ChipLogProgress(NotSpecified, "%02x ", buffer[i + j]); + ChipLogProgress(SoftwareUpdate, "%02x ", buffer[i + j]); } else { - ChipLogProgress(NotSpecified, " "); + ChipLogProgress(SoftwareUpdate, " "); } - ChipLogProgress(NotSpecified, " "); + ChipLogProgress(SoftwareUpdate, " "); } } - ChipLogProgress(NotSpecified, "---\n"); + ChipLogProgress(SoftwareUpdate, "---\n"); // Clear the buffer so we don't get old data memset(buffer, 0x0, buffer_size); @@ -157,7 +159,7 @@ int OTAImageProcessorImpl::MemoryTest() ret = mBlockDevice->program(buffer, 0, buffer_size); if (ret) { - ChipLogError(NotSpecified, "Block device program failed [%d]", ret); + ChipLogError(SoftwareUpdate, "Block device program failed [%d]", ret); goto exit; } @@ -169,43 +171,43 @@ int OTAImageProcessorImpl::MemoryTest() ret = mBlockDevice->read(buffer, 0, buffer_size); if (ret) { - ChipLogError(NotSpecified, "Block device read failed [%d]", ret); + ChipLogError(SoftwareUpdate, "Block device read failed [%d]", ret); goto exit; } - ChipLogProgress(NotSpecified, "--- Stored data after write ---"); + ChipLogProgress(SoftwareUpdate, "--- Stored data after write ---"); for (size_t i = 0; i < buffer_size; i += 16) { for (size_t j = 0; j < 16; j++) { if (i + j < buffer_size) { - ChipLogProgress(NotSpecified, "%02x ", buffer[i + j]); + ChipLogProgress(SoftwareUpdate, "%02x ", buffer[i + j]); } else { - ChipLogProgress(NotSpecified, " "); + ChipLogProgress(SoftwareUpdate, " "); } } - ChipLogProgress(NotSpecified, " %.*s", buffer_size - i, &buffer[i]); + ChipLogProgress(SoftwareUpdate, " %.*s", buffer_size - i, &buffer[i]); } - ChipLogProgress(NotSpecified, "---\n"); + ChipLogProgress(SoftwareUpdate, "---\n"); ret = strcmp(buffer, "Hello Storage!"); if (ret) { - ChipLogError(NotSpecified, "Data compare failed"); + ChipLogError(SoftwareUpdate, "Data compare failed"); } else { - ChipLogProgress(NotSpecified, "--- MEMORY TEST PASS ---"); + ChipLogProgress(SoftwareUpdate, "--- MEMORY TEST PASS ---"); } exit: if (ret) { - ChipLogError(NotSpecified, "--- MEMORY TEST FAILED ---"); + ChipLogError(SoftwareUpdate, "--- MEMORY TEST FAILED ---"); } if (buffer) @@ -216,7 +218,7 @@ int OTAImageProcessorImpl::MemoryTest() ret = mBlockDevice->deinit(); if (ret) { - ChipLogError(NotSpecified, "Block deinitialization read failed [%d]", ret); + ChipLogError(SoftwareUpdate, "Block deinitialization read failed [%d]", ret); goto exit; } @@ -379,6 +381,11 @@ void OTAImageProcessorImpl::HandleApply(intptr_t context) { ChipLogError(SoftwareUpdate, "Setting the update candidate as pending failed: %d", ret); } + + // Restart the device + ChipLogProgress(SoftwareUpdate, "Device restarting...."); + rtos::ThisThread::sleep_for(3000); + system_reset(); #endif } @@ -447,7 +454,7 @@ int OTAImageProcessorImpl::PrepareMemory() if (!mBlockDevice) { - ChipLogError(NotSpecified, "Block device not set"); + ChipLogError(SoftwareUpdate, "Block device not set"); return 1; } @@ -466,7 +473,7 @@ int OTAImageProcessorImpl::PrepareMemory() ret = mBlockDevice->read(&buff, 0, read_size); if (ret) { - ChipLogError(NotSpecified, "Block device read failed [%d]", ret); + ChipLogError(SoftwareUpdate, "Block device read failed [%d]", ret); return ret; } @@ -479,7 +486,7 @@ int OTAImageProcessorImpl::CloseMemory() if (!mBlockDevice) { - ChipLogError(NotSpecified, "Block device not set"); + ChipLogError(SoftwareUpdate, "Block device not set"); return 1; } @@ -501,7 +508,7 @@ int OTAImageProcessorImpl::ClearMemory() if (!mBlockDevice) { - ChipLogError(NotSpecified, "Block device not set"); + ChipLogError(SoftwareUpdate, "Block device not set"); return 1; } @@ -522,7 +529,7 @@ int OTAImageProcessorImpl::ProgramMemory() if (!mBlockDevice) { - ChipLogError(NotSpecified, "Block device not set"); + ChipLogError(SoftwareUpdate, "Block device not set"); return 1; } diff --git a/src/platform/mbed/OTARequestorDriverImpl.cpp b/src/platform/mbed/OTARequestorDriverImpl.cpp new file mode 100644 index 00000000000000..4fb6be1577a31f --- /dev/null +++ b/src/platform/mbed/OTARequestorDriverImpl.cpp @@ -0,0 +1,62 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "OTARequestorDriverImpl.h" +#include + +namespace chip { +namespace DeviceLayer { + +namespace { + +OTARequestorDriverImpl * ToDriver(void * context) +{ + return static_cast(context); +} + +} // namespace + +void OTARequestorDriverImpl::UpdateAvailable(const UpdateDescription & update, System::Clock::Seconds32 delay) +{ + VerifyOrDie(mRequestor != nullptr); + if (onOtaUpdateAvailableCallback) + { + if (!onOtaUpdateAvailableCallback->mCall(onOtaUpdateAvailableCallback->mContext, update)) + { + return; + } + } + ScheduleDelayedAction(UpdateFailureState::kDownloading, delay, + [](System::Layer *, void * context) { ToDriver(context)->mRequestor->DownloadUpdate(); }); +} + +void OTARequestorDriverImpl::UpdateDownloaded() +{ + VerifyOrDie(mRequestor != nullptr); + if (onOtaUpdateApplyCallback) + { + if (!onOtaUpdateApplyCallback->mCall(onOtaUpdateApplyCallback->mContext)) + { + return; + } + } + mRequestor->ApplyUpdate(); +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/mbed/OTARequestorDriverImpl.h b/src/platform/mbed/OTARequestorDriverImpl.h new file mode 100644 index 00000000000000..8de15e5b272b8c --- /dev/null +++ b/src/platform/mbed/OTARequestorDriverImpl.h @@ -0,0 +1,66 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* This file contains the declarations for OTARequestorDriver, a platform-agnostic + * interface for processing firmware update. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "blockdevice/BlockDevice.h" + +namespace chip { + +namespace DeviceLayer { + +typedef bool (*OnOtaUpdateAvailable)(void * context, const UpdateDescription &); +typedef bool (*OnOtaUpdateApply)(void * context); + +class OTARequestorDriverImpl : public GenericOTARequestorDriver +{ + + friend class GenericOTARequestorDriver; + +public: + void Init(OTARequestorInterface * requestor, OTAImageProcessorInterface * processor, + Callback::Callback * onUpdateAvailable = nullptr, + Callback::Callback * onUpdateApply = nullptr) + { + mRequestor = requestor; + mImageProcessor = processor; + onOtaUpdateAvailableCallback = onUpdateAvailable; + onOtaUpdateApplyCallback = onUpdateApply; + } + + void UpdateAvailable(const UpdateDescription & update, System::Clock::Seconds32 delay); + void UpdateDownloaded(void); + +private: + Callback::Callback * onOtaUpdateAvailableCallback; + Callback::Callback * onOtaUpdateApplyCallback; +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/test_driver/mbed/unit_tests/mbed_app.json b/src/test_driver/mbed/unit_tests/mbed_app.json index de63cab8902205..be0c616c3b1bab 100644 --- a/src/test_driver/mbed/unit_tests/mbed_app.json +++ b/src/test_driver/mbed/unit_tests/mbed_app.json @@ -28,9 +28,17 @@ } }, "config": { - "use-gatt-indication-ack-hack": { - "help": "Fake a TX transfer confirmation. Send a 'kCHIPoBLEIndicateConfirm' event as soon as data is sent, without waiting for the actual ACK from the GATT client. This hack has to stay until we provide a fix in the Mbed OS repo.", - "value": 1 + "version-number": { + "value": "0" + }, + "version-number-str": { + "value": "\"0.1.0\"" + }, + "vendor-id": { + "value": "0xFFF1" + }, + "product-id": { + "value": "0x8001" } } }