diff --git a/.restyled.yaml b/.restyled.yaml index f55a0e367d91bd..c201729d30e41a 100644 --- a/.restyled.yaml +++ b/.restyled.yaml @@ -72,7 +72,6 @@ exclude: - "scripts/tools/zap/tests/outputs/**/*" # Matches generated output 1:1 - "examples/chef/sample_app_util/test_files/*.yaml" - "examples/chef/zzz_generated/**/*" - - "examples/platform/nxp/k32w/k32w0/scripts/demo_generated_certs/**/*" - "examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/*" # zap-generated files - "integrations/cloudbuild/*.yaml" # uglier long command line content - "scripts/run_codegen_targets.sh" # shellharden breaks for loops over command outputs diff --git a/BUILD.gn b/BUILD.gn index 82c8d855bfd291..8a78d8f55f3bd0 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -689,7 +689,7 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { if (enable_k32w_lighting_app_build) { group("k32w_lighting_app") { - deps = [ "${chip_root}/examples/lighting-app/nxp/k32w/k32w0/(${chip_root}/config/k32w/toolchain:k32w_lighting_app)" ] + deps = [ "${chip_root}/examples/lighting-app/nxp/k32w0/(${chip_root}/config/k32w/toolchain:k32w_lighting_app)" ] } extra_build_deps += [ ":k32w_lighting_app" ] @@ -697,7 +697,7 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { if (enable_k32w_lock_app_build) { group("k32w_lock_app") { - deps = [ "${chip_root}/examples/lock-app/nxp/k32w/k32w0/(${chip_root}/config/k32w/toolchain:k32w_lock_app)" ] + deps = [ "${chip_root}/examples/lock-app/nxp/k32w0/(${chip_root}/config/k32w/toolchain:k32w_lock_app)" ] } extra_build_deps += [ ":k32w_lock_app" ] @@ -705,7 +705,7 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { if (enable_k32w_shell_app_build) { group("k32w_shell_app") { - deps = [ "${chip_root}/examples/shell/nxp/k32w/k32w0/(${chip_root}/config/k32w/toolchain:k32w_shell_app)" ] + deps = [ "${chip_root}/examples/shell/nxp/k32w0/(${chip_root}/config/k32w/toolchain:k32w_shell_app)" ] } extra_build_deps += [ ":k32w_shell_app" ] diff --git a/config/k32w/toolchain/BUILD.gn b/config/k32w/toolchain/BUILD.gn index f386bcd0cd4c97..5189a17eff5a67 100644 --- a/config/k32w/toolchain/BUILD.gn +++ b/config/k32w/toolchain/BUILD.gn @@ -20,27 +20,27 @@ import("${build_root}/toolchain/arm_gcc/arm_toolchain.gni") arm_toolchain("k32w_lighting_app") { toolchain_args = { current_os = "freertos" - import("${chip_root}/examples/lighting-app/nxp/k32w/k32w0/args.gni") + import("${chip_root}/examples/lighting-app/nxp/k32w0/args.gni") } } arm_toolchain("k32w_lock_app") { toolchain_args = { current_os = "freertos" - import("${chip_root}/examples/lock-app/nxp/k32w/k32w0/args.gni") + import("${chip_root}/examples/lock-app/nxp/k32w0/args.gni") } } arm_toolchain("k32w_contact_sensor_app") { toolchain_args = { current_os = "freertos" - import("${chip_root}/examples/contact-sensor-app/nxp/k32w/k32w0/args.gni") + import("${chip_root}/examples/contact-sensor-app/nxp/k32w0/args.gni") } } arm_toolchain("k32w_shell_app") { toolchain_args = { current_os = "freertos" - import("${chip_root}/examples/shell/nxp/k32w/k32w0/args.gni") + import("${chip_root}/examples/shell/nxp/k32w0/args.gni") } } diff --git a/docs/QUICK_START.md b/docs/QUICK_START.md index 10833e0c0c1ed7..d5d80703c5e61f 100644 --- a/docs/QUICK_START.md +++ b/docs/QUICK_START.md @@ -17,10 +17,10 @@ and platforms. Use one of the controllers listed above and then a Border Router and Node combination listed below. -| <div style="width:200px">Border Router</div> | <div style="width:200px">Node</div> | Description | -| -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [**ot-br**](https://openthread.io/guides/border-router/build)<br>Thread Border Router <li>RasPi <li>BeagleBone | **lighting-app** <li>[Nordic nRF5x](https://github.com/project-chip/connectedhomeip/tree/master/examples/lighting-app/nrfconnect/README.md) <li> [NXP K32W](https://github.com/project-chip/connectedhomeip/tree/master/examples/lighting-app/nxp/k32w/k32w0/README.md) <li> [Qorvo QPG6100](https://github.com/project-chip/connectedhomeip/tree/master/examples/lighting-app/qpg) <li> [Silicon Labs EFR32](https://github.com/project-chip/connectedhomeip/tree/master/examples/lighting-app/silabs/README.md) | The Lighting example is supported by many of the available Thread platforms. See the chip-tool controller instructions for how to actuate the light on/off cluster. | -| [**ot-br**](https://openthread.io/guides/border-router/build)<br>Thread Border Router <li>RasPi <li>BeagleBone | **lock-app** <li>[Nordic nRF5x](https://github.com/project-chip/connectedhomeip/tree/master/examples/lock-app/nrfconnect/README.md) <li> [NXP K32W](https://github.com/project-chip/connectedhomeip/tree/master/examples/lock-app/nxp/k32w/k32w0/README.md) <li> [Qorvo QPG6100](https://github.com/project-chip/connectedhomeip/tree/master/examples/lock-app/qpg) <li> [Silicon Labs EFR32](https://github.com/project-chip/connectedhomeip/tree/master/examples/lock-app/efr32/README.md) <li> [TI CC13x2x7](https://github.com/project-chip/connectedhomeip/tree/master/examples/lock-app/cc13x2x7_26x2x7/README.md) | The Lock example is supported by many of the available Thread and Wi-Fi platforms. | +| <div style="width:200px">Border Router</div> | <div style="width:200px">Node</div> | Description | +| -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [**ot-br**](https://openthread.io/guides/border-router/build)<br>Thread Border Router <li>RasPi <li>BeagleBone | **lighting-app** <li>[Nordic nRF5x](https://github.com/project-chip/connectedhomeip/tree/master/examples/lighting-app/nrfconnect/README.md) <li> [NXP K32W](https://github.com/project-chip/connectedhomeip/tree/master/examples/lighting-app/nxp/k32w0/README.md) <li> [Qorvo QPG6100](https://github.com/project-chip/connectedhomeip/tree/master/examples/lighting-app/qpg) <li> [Silicon Labs EFR32](https://github.com/project-chip/connectedhomeip/tree/master/examples/lighting-app/silabs/README.md) | The Lighting example is supported by many of the available Thread platforms. See the chip-tool controller instructions for how to actuate the light on/off cluster. | +| [**ot-br**](https://openthread.io/guides/border-router/build)<br>Thread Border Router <li>RasPi <li>BeagleBone | **lock-app** <li>[Nordic nRF5x](https://github.com/project-chip/connectedhomeip/tree/master/examples/lock-app/nrfconnect/README.md) <li> [Qorvo QPG6100](https://github.com/project-chip/connectedhomeip/tree/master/examples/lock-app/qpg) <li> [Silicon Labs EFR32](https://github.com/project-chip/connectedhomeip/tree/master/examples/lock-app/efr32/README.md) <li> [TI CC13x2x7](https://github.com/project-chip/connectedhomeip/tree/master/examples/lock-app/cc13x2x7_26x2x7/README.md) | The Lock example is supported by many of the available Thread and Wi-Fi platforms. | ## Controllers diff --git a/docs/guides/nxp/nxp_k32w0_ota_guide.md b/docs/guides/nxp/nxp_k32w0_ota_guide.md new file mode 100644 index 00000000000000..147bfdf2ee97e4 --- /dev/null +++ b/docs/guides/nxp/nxp_k32w0_ota_guide.md @@ -0,0 +1,232 @@ +# NXP K32W0x1 OTA guide + +## The Secondary Stage Bootloader (SSBL) + +There are multiple SSBL binaries provided by the SDK: + +| description | github SDK path | package SDK path | +| ------------------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | +| Default SSBL | NA | `boards/k32w061dk6/wireless_examples/framework/ssbl/binary/ssbl.bin` | +| SSBL with PDM in external flash | `examples/k32w061dk6/wireless_examples/framework/ssbl/binary/ssbl_ext_flash_pdm_support.bin` | `boards/k32w061dk6/wireless_examples/framework/ssbl/binary/ssbl_ext_flash_pdm_support.bin` | + +The SSBL is also built alongside the reference application and it can be +configured according to the following table: + +| gn arg | default | description | +| --------------------------------- | --------------------------- | ---------------------------------------------------------------------------------------- | +| `ssbl_pdm_external_flash` | true | Enable/disable PDM in external flash | +| `ssbl_multi_image_support` | true | Enable/disable multi-image OTA feature | +| `ssbl_ota_entry_storage` | "OTACustomStorage_ExtFlash" | Configure custom OTA entry storage type | +| `ssbl_simple_hash_verification` | false | Enable/disable simple hash verification alternative to secure boot | +| `ssbl_optimize_spifi_flash` | false | Optimize `SPIFI` flash driver size | +| `ssbl_spifi_dual_mode` | false | Enable/disable `SPIFI` dual mode support (e.g. used by K32W041AM variant) | +| `ssbl_version` | 0 | Set SSBL version | +| `ssbl_use_redlib` | false | Enable/disable usage of `redlib` NXP library. If false, the build will use `newlib` nano | +| `ssbl_ota_data_in_external_flash` | false | Enable/disable OTA support for application with sections stored in external flash | + +## Simple hash verification + +When secure boot is not used, a simple hash can be appended at the end of the +image for integrity check. Applications should be built with +`chip_simple_hash_verification=1`. + +## Writing the SSBL + +Before writing the SSBL, it it recommanded to fully erase the internal flash. + +Using DK6Programmer utility from Windows: + +``` +DK6Programmer.exe -V 5 -P 1000000 -s <COM_PORT> -e Flash +``` + +Using `dk6prog` from `SPSDK`: + +``` +$ dk6prog listdev +This is an experimental utility. Use with caution! + +List of available devices: +DEVICE ID: DN038ZH3, VID: 0x403, PID: 0x6015, Serial number: DN038ZH3, Description: DK6 Carrier Board, Address: 9, Backend: Backend.PYFTDI +$ dk6prog -d DN038ZH3 erase 0 0x9de00 + +This is an experimental utility. Use with caution! + +Erasing memory [####################################] 100% +``` + +`chip-k32w0x-ssbl.bin` must be written at address 0 in the internal flash: + +Using DK6Programmer utility from Windows: + +``` +DK6Programmer.exe -V2 -s <COM_PORT> -P 1000000 -Y -p FLASH@0x00="chip-k32w0x-ssbl.bin" +``` + +Using `dk6prog` from `SPSDK`: + +``` +$ dk6prog -d DN038ZH3 write 0 ~/path/to/bin/chip-k32w0x-ssbl.bin + +This is an experimental utility. Use with caution! + +Writing memory [####################################] 100% +Written 7890 bytes to memory ID 0 at address 0x0 +``` + +### Writing the PSECT + +This is the list of all supported partitions: + +``` +0000000010000000 : SSBL partition + + 00000000 -----------> Start Address + 1000 ---------------> 0x0010 Number of 512-bytes pages + 00 -----------------> 0x00 Bootable flag + 00 -----------------> 0x00 Image type (0x00 = SSBL) + +00400000c9040101: Application partition + + 00400000 -----------> 0x00004000 Start Address + c904 ---------------> 0x04c9 Number of 512-bytes pages + 01 -----------------> 0x01 Bootable flag + 01 -----------------> 0x01 Image type (0x01 = Application) + +00000010800000fe: Ext Flash text partition + + 00000010 -----------> 0x10000000 Start Address (external flash) + 8000 ---------------> 0x0080 Number of 512-bytes pages + 00 -----------------> 0x00 Bootable flag + fe -----------------> 0xFE Image type (0xFE = Ext Flash text) + +00000110300200fc : OTA Image partition + + 00000110 -----------> 0x10010000 Start Address + 3002----------------> 0x0230 Number of 512-bytes pages + 00 -----------------> 0x00 Bootable flag + fc -----------------> 0xFC Image type (0xFC = OTA partition) + +00000510100000fd: NVM partition + + 00000510 -----------> 0x10050000 Start Address + 1000 ---------------> 0x0010 Number of 512-bytes pages + 00 -----------------> 0x00 Bootable flag + fd -----------------> 0xFD Image type (0xFD = NVM partition) +``` + +First, image directory 0 (SSBL partition) must be written: + +Using DK6Programmer utility from Windows: + +``` +DK6Programmer.exe -V5 -s <COM port> -P 1000000 -w image_dir_0=0000000010000000 +``` + +Using `dk6prog` from `SPSDK`: + +``` +$ dk6prog -d DN038ZH3 write 0x160 [[0000000010000000]] 8 PSECT + +This is an experimental utility. Use with caution! + +Writing memory [####################################] 100% +Written 8 bytes to memory ID PSECT at address 0x160 +``` + +Here is the interpretation of the fields: + +``` +00000000 -> start address 0x00000000 +1000 -> size = 0x0010 pages of 512-bytes (= 8kB) +00 -> not bootable (only used by the SSBL to support SSBL update) +00 -> SSBL Image Type +``` + +Second, image directory 1 (application partition) must be written: + +Using DK6Programmer utility from Windows: + +``` +DK6Programmer.exe -V5 -s <COM port> -P 1000000 -w image_dir_1=00400000C9040101 +``` + +Using `dk6prog` from `SPSDK`: + +``` +$ dk6prog -d DN038ZH3 write 0x168 [[00400000C9040101]] 8 PSECT + +This is an experimental utility. Use with caution! + +Writing memory [####################################] 100% +Written 8 bytes to memory ID PSECT at address 0x168 +``` + +Here is the interpretation of the fields: + +``` +00400000 -> start address 0x00004000 +C904 -> 0x4C9 pages of 512-bytes (= 612.5kB) +01 -> bootable flag +01 -> image type for the application +``` + +Please note the user can write additional partitions by writing +`image_dir_2/3/4` with the wanted configuration. In case of using the `SPSDK` +tool, the appropriate offset must be calculated + +## Removing SSBL Upgrade Region + +The example also offers the possibility to remove SSBL upgrade region, for +reserving more space for application level. + +A new flag `chip_reduce_ssbl_size` is introduced. In order to remove the SSBL +upgrade region, `chip_reduce_ssbl_size=true` must be provided to the build +system + +The programming method will change: + +- Writing image directory 1 should change to Using DK6Programmer utility from + Windows: + + ``` + DK6Programmer.exe -V5 -s <COM port> -P 1000000 -w image_dir_1=00200000D9040101 + ``` + + Using `dk6prog` from `SPSDK`: + + ``` + $ dk6prog -d DN038ZH3 write 0x168 [[00200000D9040101]] 8 PSECT + + This is an experimental utility. Use with caution! + + Writing memory [####################################] 100% + Written 8 bytes to memory ID PSECT at address 0x168 + ``` + + Here is the interpretation of the fields: + + ``` + 00200000 -> start address 0x00002000 + D904 -> 0x4D9 pages of 512-bytes (= 620.5kB) + 01 -> bootable flag + 01 -> image type for the application + ``` + +- Matter application offset address should change to Using DK6Programmer + utility from Windows: + + ``` + DK6Programmer.exe -V2 -s <COM_PORT> -P 1000000 -Y -p FLASH@0x2000="chip-k32w0x-contact-example.bin" + ``` + + Using `dk6prog` from `SPSDK`: + + ``` + $ dk6prog -d DN038ZH3 write 0x2000 ~/path/to/bin/chip-k32w0x-contact-example.bin + + This is an experimental utility. Use with caution! + + Writing memory [####################################] 100% + Written 596450 bytes to memory ID 0 at address 0x2000 + ``` diff --git a/docs/guides/nxp/nxp_k32w_android_commissioning.md b/docs/guides/nxp/nxp_k32w_android_commissioning.md index 6d872f5f7ba268..a37d60f0f0ba4e 100644 --- a/docs/guides/nxp/nxp_k32w_android_commissioning.md +++ b/docs/guides/nxp/nxp_k32w_android_commissioning.md @@ -8,16 +8,17 @@ onto a CHIP-enabled Thread network. <hr> -- [Overview](#overview) -- [Requirements](#requirements) -- [Building and programming OpenThread RCP firmware](#building-and-programming-openthread-rcp-firmware) -- [Configuring PC as Thread Border Router](#configuring-pc-as-a-thread-border-router) -- [Building and programming NXP K32W Light Example Application](#building-and-programming-nxp-k32w-light-example-application) -- [Building and installing Android CHIPTool](#building-and-installing-android-chiptool) -- [Forming a Thread network on the Border Router](#forming-a-thread-network-on-the-border-router) -- [Preparing accessory device](#preparing-accessory-device) -- [Commissioning accessory device](#commissioning-accessory-device) -- [Sending CHIP commands](#sending-chip-commands) +- [Commissioning NXP K32W using Android CHIPTool](#commissioning-nxp-k32w-using-android-chiptool) + - [Overview](#overview) + - [Requirements](#requirements) + - [Building and programming OpenThread RCP firmware](#building-and-programming-openthread-rcp-firmware) + - [Configuring PC as a Thread Border Router](#configuring-pc-as-a-thread-border-router) + - [Building and programming NXP K32W Light Example Application](#building-and-programming-nxp-k32w-light-example-application) + - [Building and installing Android CHIPTool](#building-and-installing-android-chiptool) + - [Forming a Thread network on the Border Router](#forming-a-thread-network-on-the-border-router) + - [Preparing accessory device](#preparing-accessory-device) + - [Commissioning accessory device](#commissioning-accessory-device) + - [Sending CHIP commands](#sending-chip-commands) <hr> @@ -47,7 +48,7 @@ The following diagram shows the connectivity between network components required to allow communication between devices running the CHIPTool and Light applications: - + <hr> @@ -111,7 +112,7 @@ the RCP firmware onto an K32W061 DK6: This creates an RCP image in the `bin/ot-rcp` directory. 6. Program the RCP firmware using the official - [OpenThread Flash Instructions](https://github.com/openthread/openthread/blob/master/examples/platforms/k32w/k32w061/README.md#flash-binaries). + [OpenThread Flash Instructions](https://github.com/openthread/openthread/blob/master/examples/platforms/k32w061/README.md#flash-binaries). 7. Plug-in the K32W061 DK6 to the PC. @@ -348,7 +349,7 @@ To make your PC work as a Thread Border Router, complete the following tasks: ## Building and programming NXP K32W Light Example Application See -[NXP K32W Light Example Application README](../../../examples/lighting-app/nxp/k32w/k32w0/README.md) +[NXP K32W Light Example Application README](../../../examples/lighting-app/nxp/k32w0/README.md) to learn how to build and program the light example onto an K32W061 DK6. <hr> @@ -396,7 +397,7 @@ CHIPTool is now ready to be used for commissioning. 3. Navigate to the _Form_ tab then push the _Form_ button using the default parameters: -  +  4. The message _Form operation is successful_ should be display after a few seconds. @@ -430,7 +431,7 @@ To prepare the accessory device for commissioning, complete the following steps: 1. Make sure that JP4 and JP7 jumpers are in leftmost position and a mini-USB cable is connected between the LPC connector and PC -  +  2. Use a terminal emulator (e.g.: Putty) to connect to the UART console of the accessory device. Use a baudrate of 115200. @@ -466,14 +467,14 @@ section, complete the following steps: progress with scanning, connection, and pairing. At the end of this process, the Thread network settings screen appears. -  +  6. In the Thread network settings screen, use the default settings and tap the _SAVE NETWORK_ button to send a Thread provisioning message to the accessory device. You will see the "Network provisioning completed" message when the accessory device successfully joins the Thread network. -  +  <hr> @@ -483,7 +484,7 @@ section, complete the following steps: the provisioning is completed successfully and you are connected to the device. -  +  2. Verify that the text box on the screen is not empty and contains the IPv6 address of the accessory device. diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/build_overrides b/examples/contact-sensor-app/nxp/k32w/k32w0/build_overrides deleted file mode 120000 index ad07557834803a..00000000000000 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/build_overrides +++ /dev/null @@ -1 +0,0 @@ -../../../../build_overrides/ \ No newline at end of file diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/third_party/connectedhomeip b/examples/contact-sensor-app/nxp/k32w/k32w0/third_party/connectedhomeip deleted file mode 120000 index 305f2077ffe860..00000000000000 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/third_party/connectedhomeip +++ /dev/null @@ -1 +0,0 @@ -../../../../../.. \ No newline at end of file diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/.gn b/examples/contact-sensor-app/nxp/k32w0/.gn similarity index 93% rename from examples/contact-sensor-app/nxp/k32w/k32w0/.gn rename to examples/contact-sensor-app/nxp/k32w0/.gn index 363727423ce903..1f7e4941f8d9fc 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/.gn +++ b/examples/contact-sensor-app/nxp/k32w0/.gn @@ -27,5 +27,5 @@ default_args = { import("//args.gni") # Import default platform configs - import("${chip_root}/src/platform/nxp/k32w/k32w0/args.gni") + import("${chip_root}/src/platform/nxp/k32w0/args.gni") } diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/BUILD.gn b/examples/contact-sensor-app/nxp/k32w0/BUILD.gn similarity index 90% rename from examples/contact-sensor-app/nxp/k32w/k32w0/BUILD.gn rename to examples/contact-sensor-app/nxp/k32w0/BUILD.gn index b69897172a1e8d..c51b8787ea2922 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/BUILD.gn +++ b/examples/contact-sensor-app/nxp/k32w0/BUILD.gn @@ -41,7 +41,7 @@ if (chip_pw_tokenizer_logging) { assert(current_os == "freertos") -k32w0_platform_dir = "${chip_root}/examples/platform/nxp/k32w/k32w0" +k32w0_platform_dir = "${nxp_sdk_matter_support_root}/examples/platform/k32w0" k32w0_sdk("sdk") { sources = [ @@ -88,6 +88,7 @@ k32w0_executable("contact_sensor_app") { defines = [] sources = [ + "${k32w0_platform_dir}/util/DefaultTestEventTriggerDelegate.cpp", "${k32w0_platform_dir}/util/LEDWidget.cpp", "${k32w0_platform_dir}/util/include/LEDWidget.h", "main/AppTask.cpp", @@ -119,17 +120,12 @@ k32w0_executable("contact_sensor_app") { "${k32w0_platform_dir}/app/support:freertos_mbedtls_utils", ] - if (chip_openthread_ftd) { - deps += [ - "${chip_root}/third_party/openthread/repo:libopenthread-cli-ftd", - "${chip_root}/third_party/openthread/repo:libopenthread-ftd", - ] - } else { - deps += [ - "${chip_root}/third_party/openthread/repo:libopenthread-cli-mtd", - "${chip_root}/third_party/openthread/repo:libopenthread-mtd", - ] - } + defines += [ "CONNECTIVITY_MANAGER_THREAD_DEVICE_TYPE=ConnectivityManager::kThreadDeviceType_SleepyEndDevice" ] + + deps += [ + "${chip_root}/third_party/openthread/repo:libopenthread-cli-mtd", + "${chip_root}/third_party/openthread/repo:libopenthread-mtd", + ] #lit and sit are using different zap files if (chip_enable_icd_lit) { @@ -187,6 +183,11 @@ group("k32w0") { ":binsign", ":contact_sensor_app", ] + + if (chip_enable_ota_requestor) { + deps += [ "${k32w0_platform_dir}/ssbl:ssbl" ] + } + if (chip_pw_tokenizer_logging) { deps += [ ":contact_sensor_app.database" ] } @@ -201,6 +202,10 @@ action("binsign") { if (chip_simple_hash_verification == 1) { args = [ "--simple-hash" ] } + + if (chip_enable_ota_requestor) { + args = [ "--ota-enabled" ] + } } group("default") { diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/README.md b/examples/contact-sensor-app/nxp/k32w0/README.md similarity index 72% rename from examples/contact-sensor-app/nxp/k32w/k32w0/README.md rename to examples/contact-sensor-app/nxp/k32w0/README.md index ac418ecbd4aa77..305aa0b176af2a 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/README.md +++ b/examples/contact-sensor-app/nxp/k32w0/README.md @@ -30,6 +30,8 @@ network. - [Rotating device id](#rotating-device-id) - [Manufacturing data](#manufacturing-data) - [Flashing and debugging](#flashing-and-debugging) + - [Using DK6programmer](#using-dk6programmer) + - [Using MCUXpresso](#using-mcuxpresso) - [Pigweed tokenizer](#pigweed-tokenizer) - [Detokenizer script](#detokenizer-script) - [Notes](#notes) @@ -39,21 +41,14 @@ network. - [Tinycrypt ECC library](#tinycrypt-ecc-library) - [Building steps](#building-steps-1) - [OTA](#ota) - - [Writing the SSBL](#writing-the-ssbl) - - [Features](#features) - - [Multi image](#multi-image) - - [Simple hash verification](#simple-hash-verification) - - [Writing the PSECT](#writing-the-psect) - - [Writing the application](#writing-the-application) - [OTA Testing](#ota-testing) - - [Known issues ota](#known-issues-ota) + - [Known issues OTA](#known-issues-ota) - [Low power](#low-power) - [Known issues low power](#known-issues-low-power) - - [Removing SSBL Upgrade Region](#removing-ssbl-upgrade-region) ## Introduction - + The K32W061 contact sensor example application provides a working demonstration of a connected contact sensor device, built using the Project CHIP codebase and @@ -83,7 +78,7 @@ Deployment of this firmware configuration requires the K32W061 board setups using the K32W061 module board, SE051 Expansion board and Generic Expansion board as shown below: - + The SE051H Secure Element extension may be used for best in class security and offloading some of the Project CHIP cryptographic operations. Depending on your @@ -186,10 +181,10 @@ contact status. In order to build the Project CHIP example, we recommend using a Linux distribution (supported Operating Systems are listed in -[BUILDING.md](../../../../../docs/guides/BUILDING.md#tested-operating systems)). +[BUILDING.md](../../../../docs/guides/BUILDING.md#tested-operating-systems)). - Make sure that below prerequisites are correctly installed (as described in - [BUILDING.md](../../../../../docs/guides/BUILDING.md#prerequisites))) + [BUILDING.md](../../../../docs/guides/BUILDING.md#prerequisites)) ``` sudo apt-get install git gcc g++ pkg-config libssl-dev libdbus-1-dev \ @@ -219,18 +214,18 @@ user@ubuntu:~/Desktop/git/connectedhomeip$ source scripts/bootstrap.sh - Step 3: Init NXP SDK(s) ``` -user@ubuntu:~/Desktop/git/connectedhomeip$ scripts/setup/nxp/update_nxp_sdk.py --platform k32w0 +user@ubuntu:~/Desktop/git/connectedhomeip$ third_party/nxp/nxp_matter_support/scripts/update_nxp_sdk.py --platform k32w0 ``` -Note: By default setup/nxp/update_nxp_sdk.py will try to initialize all NXP -SDKs. Arg "-- help" could be used to view all available options. +Note: By default update_nxp_sdk.py will try to initialize all NXP SDKs. Arg "-- +help" could be used to view all available options. - Start building the application: ```bash -user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/contact-sensor-app/nxp/k32w/k32w0 -user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w/k32w0$ gn gen out/debug -user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w/k32w0$ ninja -C out/debug +user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/contact-sensor-app/nxp/k32w0 +user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w0$ gn gen out/debug +user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w0$ ninja -C out/debug ``` To build with Secure Element, follow the same steps as above but set @@ -267,7 +262,7 @@ used to control an antenna switch. In order to use this feature, user must set In case signing errors are encountered when running the "sign_images.sh" script (run automatically) install the recommanded packages (python version > 3, pip3, -pycrypto, pycryptodome): +pycryptodome): ``` user@ubuntu:~$ python3 --version @@ -275,7 +270,6 @@ Python 3.8.2 user@ubuntu:~$ pip3 --version pip 20.0.2 from /usr/lib/python3/dist-packages/pip (python 3.8) user@ubuntu:~$ pip3 list | grep -i pycrypto -pycrypto 2.6.1 pycryptodome 3.9.8 ``` @@ -357,20 +351,20 @@ Please use the following build args: ## Manufacturing data See -[Guide for writing manufacturing data on NXP devices](../../../../../docs/guides/nxp/nxp_manufacturing_flow.md). +[Guide for writing manufacturing data on NXP devices](../../../../docs/guides/nxp/nxp_manufacturing_flow.md). There are factory data generated binaries available in -examples/platform/nxp/k32w/k32w0/scripts/demo_generated_factory_data folder. -These are based on the DAC, PAI and PAA certificates found in +`third_party/nxp/nxp_matter_support/examples/platform/k32w0/scripts/demo_generated_factory_data` +folder. These are based on the DAC, PAI and PAA certificates found in scripts/tools/nxp/demo_generated_certs folder. The demo_factory_data_dut1.bin uses the DAC certificate and private key found in -examples/platform/nxp/k32w/k32w0/scripts/demo_generated_factory_data/dac/dut1 +`third_party/nxp/nxp_matter_support/examples/platform/k32w0/scripts/demo_generated_factory_data/dac/dut1` folder. The demo_factory_data_dut2.bin uses the DAC certificate and private key found in -examples/platform/nxp/k32w/k32w0/scripts/demo_generated_factory_data/dac/dut2 +`third_party/nxp/nxp_matter_support/examples/platform/k32w0/scripts/demo_generated_factory_data/dac/dut2` folder. These two factory data binaries can be used for testing topologies with 2 DUTS. They contain the corresponding DACs/PAIs generated using -generate_nxp_chip_factory_bin.py script. The discriminator is 14014 and the +`generate_nxp_chip_factory_bin.py` script. The discriminator is 14014 and the passcode is 1000. These demo certificates are working with the CDs installed in CHIPProjectConfig.h. @@ -379,18 +373,140 @@ Regarding factory data provider, there are two options: - use the default factory data provider: `FactoryDataProviderImpl` by setting `chip_with_factory_data=1` in the gn build command. - use a custom factory data provider: please see - [Guide for implementing a custom factory data provider](../../../../platform/nxp/k32w/k32w0/common/README.md). + [Guide for implementing a custom factory data provider](../../../platform/nxp/k32w0/doc/CustomFactoryDataProvider.md). This can be enabled when `chip_with_factory_data=1` by setting `use_custom_factory_provider=1` in the gn build command. ## Flashing and debugging -Program the firmware using the official +Instructions to program the firmware can be found also at [OpenThread Flash Instructions](https://github.com/openthread/ot-nxp/tree/main/src/k32w0/k32w061#flash-binaries). -All you have to do is to replace the Openthread binaries from the above -documentation with _out/debug/chip-k32w0x-contact-example.bin_ if DK6Programmer -is used or with _out/debug/chip-k32w0x-contact-example_ if MCUXpresso is used. +### Using DK6programmer + +The application binary's path is _out/debug/chip-k32w0x-contact-example.bin_. + +DK6Programmer can be used for flashing the application. There are two available +versions of the DK6Programmer tool. + +The legacy version consists of a Windows executable found inside the +[SDK](https://mcuxpresso.nxp.com/en/welcome) at path +`tools/JN-SW-4407-DK6-Flash-Programmer`. This is a Windows application that can +be installed using the .exe file. Once the application is installed, the COM +port for K32W061 must be identified: + +``` +C:\nxp\DK6ProductionFlashProgrammer>DK6Programmer.exe --list +Available connections: +<COM_PORT> +``` + +Once the COM port is identified, the required binary can be flashed: + +``` +DK6Programmer.exe -V2 -s <COM_PORT> -P 1000000 -Y -p FLASH@0x4000="chip-k32w0x-contact-example.bin" +``` + +> **_Note:_** The above example takes into account that the binary uses the +> `chip_enable_ota_requestor=true` option. The address offset corresponds to the +> space left for the SSBL binary and the OTA space for the SSBL. If +> `chip_enable_ota_requestor` is set to `false`, then `0x4000` needs to be +> replaced with `0x0`. + +DK6 Flash Programmer tool has also been integrated part of +[NXP Secure Provisioning SDK (SPSDK)](https://github.com/nxp-mcuxpresso/spsdk). +This tool is supported by environments like Windows, Linux or Mac. + +`SPSDK` can be installed and run from a Python environment using +[these instructions](https://spsdk.readthedocs.io/en/latest/usage/installation.html). +This enables the user to have transparent access to the dk6 programming tool +through `SPSDK`. + +``` +# after specific environment installation steps +$ spsdk --help +... + +-- dk6prog Tool for reading and programming flash memory of DK6 target devices. + � +-- erase Erase the memory. + � +-- info Prints the information about the connected device. + � +-- isp Issues ISP sequence as defined in Driver interface. + � +-- listdev Prints the information about the connected devices. + � +-- read Reads the memory and writes it to the file or stdout. + � +-- write Write the memory. +... +``` + +Dependencies for the `dk6prog` module can be installed using the following +command, more details +[here](https://spsdk.readthedocs.io/en/latest/usage/installation.html#dk6-tools): + +``` +$ pip install spsdk[dk6] +``` + +The `SPSDK` installation adds `dk6prog` as executable to system path, so user +can use directly `dk6prog` from terminal. The following commands are to be used +to write the chip-k32w0x-contact-example binary to the board. + +``` +$ dk6prog listdev +This is an experimental utility. Use with caution! + +List of available devices: +DEVICE ID: DN038ZH3, VID: 0x403, PID: 0x6015, Serial number: DN038ZH3, Description: DK6 Carrier Board, Address: 9, Backend: Backend.PYFTDI +$ dk6prog -d DN038ZH3 write 0x4000 ~/path/to/bin/chip-k32w0x-contact-example.bin + +This is an experimental utility. Use with caution! + +Writing memory [####################################] 100% +Written 596450 bytes to memory ID 0 at address 0x4000 +``` + +> **_Note:_** Running `dk6prog` from Windows OS command line requires an integer +> value for DEVICE ID. + +``` +C:\nxp\spsdk>dk6prog listdev + +This is an experimental utility. Use with caution! + +List of available devices: +DEVICE ID: 0, VID: 0x0, PID: 0x0, Serial number: b'DN038ZH3', Description: b'DK6 Carrier Board', Address: 67330069, Backend: Backend.FTD2xx + +C:\nxp\spsdk>dk6prog -d 0 info + +This is an experimental utility. Use with caution! + +Chip ID: 0x88888888 +ROM Version: 0x140000cc +MAC Address: A8:2B:1F:03:00:8D:15:00 + +Detected DEVICE: UNKNOWN + + Memory Memory ID Base Address Length Sector Size Memory Type Access +---------------------------------------------------------------------------------------------- + FLASH 0 0x0 0x9de00 0x200 FLASH All is available + PSECT 1 0x0 0x1e0 0x10 FLASH All is available + pFLASH 2 0x0 0x1e0 0x10 FLASH All is available + Config 3 0x9fc00 0x200 0x200 FLASH All is available + EFUSE 4 0x0 0x80 0x2 EFUSE (OTP) Write Enabled + ROM 5 0x3000000 0x20000 0x1 ROM Write Enabled + RAM0 6 0x4000000 0x16000 0x1 RAM Write Enabled + RAM1 7 0x4020000 0x10000 0x1 RAM Write Enabled +``` + +> **_Note:_** The above example takes into account that the binary uses the +> `chip_enable_ota_requestor=true` option. The address offset corresponds to the +> space left for the SSBL binary and the OTA space for the SSBL. If +> `chip_enable_ota_requestor` is set to `false`, then `0x4000` needs to be +> replaced with `0x0`. + +### Using MCUXpresso + +If flashing and debugging is required, MCUXpresso can be used as instructed in +[MCUXpresso flashing and debugging instructions](https://github.com/openthread/ot-nxp/tree/main/src/k32w0/k32w061#using-mcuxpresso-ide). +The file needed to be used in MCUXpresso is +_out/debug/chip-k32w0x-contact-example_. ## Pigweed tokenizer @@ -403,7 +519,7 @@ needed for parsing the hashed scripts. The python3 script detokenizer.py is a script that decodes the tokenized logs either from a file or from a serial port. It is located in the following path -`examples/platform/nxp/k32w/k32w0/scripts/detokenizer.py`. +`third_party/nxp/nxp_matter_support/examples/platform/k32w0/scripts/detokenizer.py`. The script can be used in the following ways: @@ -438,7 +554,7 @@ by the script is loaded by the environment. An example of running the detokenizer script to see logs of a contact-sensor app: ``` -python3 ../../../../../examples/platform/nxp/k32w/k32w0/scripts/detokenizer.py serial -i /dev/ttyACM0 -d out/debug/chip-k32w0x-contact-example-database.bin -o device.txt +python3 ../../../../third_party/nxp/nxp_matter_support/examples/platform/k32w0/scripts/detokenizer.py serial -i /dev/ttyACM0 -d out/debug/chip-k32w0x-contact-example-database.bin -o device.txt ``` ### Known issues tokenizer @@ -483,179 +599,49 @@ In order to use the Tinycrypt ECC library, use the following build arguments: ## OTA -The internal flash needs to be prepared for the OTA process. First 16K of the -internal flash needs to be populated with a Secondary Stage Bootloader (SSBL) -related data while the last 8.5K of flash space is holding image directory -related data (PSECT). The space between these two zones will be filled by the +Over the air updates (OTA) require several software components running on the +K32W0x1. Firstly, a Secondary Stage Bootloader (SSBL) is required written in the +first part of the internal flash memory, usually starting at address 0x0. This +enables the board to boot and check if a new OTA binary has been received. If +this is true, the bootloader writes the OTA binary to the appropriate storage, +internal and/or external flash, after which it reboots the board. If no new OTA +binaries have been found, then the bootloader gives execution control to the application. -### Writing the SSBL - -The SDK already provides an SSBL binary compiled with external flash support: -`boards/k32w061dk6/wireless_examples/framework/ssbl/binary/ssbl_ext_flash_pdm_support.bin`, -but it does not offer multi-image OTA support. - -Alternatively, the SSBL can ge generated from one of the SDK demo examples. The -SSBL demo application can be imported from the `Quickstart panel`: -`Import SDK example(s) -> select wireless -> framework -> ssbl` application. - - - -### Features - -#### Multi image - -To support multi-image OTA feature, the SSBL project must be compiled using the -following defines: - -- `PDM_EXT_FLASH=1` - support PDM in external flash. -- `gOTAUseCustomOtaEntry=1` - support custom OTA entry for multi-image. -- `gOTACustomOtaEntryMemory=OTACustomStorage_ExtFlash` - K32W0 uses - `OTACustomStorage_ExtFlash` (1) by default. -- `SPIFI_DUAL_MODE_SUPPORT=1` - only for configurations that use dual `SPIFI` - flash (e.g. K32W041AM variant). - -Optionally, add the following defines: - -- `SPIFI_OPTIM_SIZE=1` - to optimize SSBL size. -- `EXTERNAL_FLASH_DATA_OTA=1` - to support external read only data. - - - -#### Simple hash verification - -When secure boot is not used, a simple hash can be appended at the end of the -image for integrity check. Applications should be built with -`chip_simple_hash_verification=1`. - -To support simple hash verification feature, the SSBL project must be compiled -with: - -- `gSimpleHashVerification=1` - -and update the post-build command to use simple hash verification instead of the -default options. Go to -`Project -> Properties -> C/C++ Build -> Settings -> Build steps` and press -`Edit` under `Post-build steps` subsection. The command should look similar to: - - - -Once compiled, the required SSBL file is called `k32w061dk6_ssbl.bin`. - - - -Before writing the SSBL, it it recommanded to fully erase the internal flash: - -``` -DK6Programmer.exe -V 5 -P 1000000 -s <COM_PORT> -e Flash -``` - -`k32w061dk6_ssbl.bin` must be written at address 0 in the internal flash: - -``` -DK6Programmer.exe -V2 -s <COM_PORT> -P 1000000 -Y -p FLASH@0x00="k32w061dk6_ssbl.bin" -``` - -### Writing the PSECT - -This is the list of all supported partitions: - -``` -0000000010000000 : SSBL partition - - 00000000 -----------> Start Address - 1000 ---------------> 0x0010 Number of 512-bytes pages - 00 -----------------> 0x00 Bootable flag - 00 -----------------> 0x00 Image type (0x00 = SSBL) - -00400000c9040101: Application partition - - 00400000 -----------> 0x00004000 Start Address - c904 ---------------> 0x04c9 Number of 512-bytes pages - 01 -----------------> 0x01 Bootable flag - 01 -----------------> 0x01 Image type (0x01 = Application) - -00000010800000fe: Ext Flash text partition - - 00000010 -----------> 0x10000000 Start Address (external flash) - 8000 ---------------> 0x0080 Number of 512-bytes pages - 00 -----------------> 0x00 Bootable flag - fe -----------------> 0xFE Image type (0xFE = Ext Flash text) - -00000110300200fc : OTA Image partition - - 00000110 -----------> 0x10010000 Start Address - 3002----------------> 0x0230 Number of 512-bytes pages - 00 -----------------> 0x00 Bootable flag - fc -----------------> 0xFC Image type (0xFC = OTA partition) - -00000510100000fd: NVM partition - - 00000510 -----------> 0x10050000 Start Address - 1000 ---------------> 0x0010 Number of 512-bytes pages - 00 -----------------> 0x00 Bootable flag - fd -----------------> 0xFD Image type (0xFD = NVM partition) -``` - -First, image directory 0 (SSBL partition) must be written: - -``` -DK6Programmer.exe -V5 -s <COM port> -P 1000000 -w image_dir_0=0000000010000000 -``` - -Here is the interpretation of the fields: - -``` -00000000 -> start address 0x00000000 -1000 -> size = 0x0010 pages of 512-bytes (= 8kB) -00 -> not bootable (only used by the SSBL to support SSBL update) -00 -> SSBL Image Type -``` - -Second, image directory 1 (application partition) must be written: - -``` -DK6Programmer.exe -V5 -s <COM port> -P 1000000 -w image_dir_1=00400000C9040101 -``` - -Here is the interpretation of the fields: - -``` -00400000 -> start address 0x00004000 -C904 -> 0x4C9 pages of 512-bytes (= 612.5kB) -01 -> bootable flag -01 -> image type for the application -``` - -Please note the user can write additional partitions by writing -`image_dir_2/3/4` with the wanted configuration. - -### Writing the application +The internal flash needs to be prepared for the OTA process. First 16K of the +internal flash needs to be populated with SSBL related data while the last 8.5K +of flash space is holding flash configuration related data. The space between +these two zones will be filled by the application. More details regarding the +internal flash space can be found in the +[linker file](../../../../third_party/nxp/nxp_matter_support/examples/platform/k32w0/app/ldscripts/chip-k32w0x-linker.ld). -DK6Programmer can be used for flashing the application: +The steps for building the SSBL binary with appropriate configuration and +writing to the board the binary and other OTA related configurations are +described in the +[K32W0x1 OTA guide](../../../../docs/guides/nxp/nxp_k32w0_ota_guide.md). -``` -DK6Programmer.exe -V2 -s <COM_PORT> -P 1000000 -Y -p FLASH@0x4000="chip-k32w0x-contact-example.bin" -``` +Note that the application needs to be built using the +`chip_enable_ota_requestor=true` option. This is enabled in the configuration by +default if no `chip_enable_ota_requestor` explicit setting is done. -If debugging is needed, MCUXpresso can be used then for flashing the -application. Please make sure that the application is written at address 0x4000: - - +Please also note that, by default, the device expects the OTA image to be +encrypted with the same key specified by `chip_with_ota_key`. See `args.gni` for +the default gn configuration. ### OTA Testing The OTA topology used for OTA testing is illustrated in the figure below. Topology is similar with the one used for Matter Test Events. - + The concept for OTA is the next one: - there is an OTA Provider Application that holds the OTA image. In our case, this is a Linux application running on an Ubuntu based-system; -- the OTA Requestor functionality is embedded inside the Lighting Application. - It will be used for requesting OTA blocks from the OTA Provider; +- the OTA Requestor functionality is embedded inside the Contact Sensor + Application. It will be used for requesting OTA blocks from the OTA + Provider; - the controller (a linux application called chip-tool) will be used for commissioning both the device and the OTA Provider App. The device will be commissioned using the standard Matter flow (BLE + IEEE 802.15.4) while the @@ -663,19 +649,19 @@ The concept for OTA is the next one: of chip-tool; - during commissioning, each device is assigned a node id by the chip-tool (can be specified manually by the user). Using the node id of the device and - of the lighting application, chip-tool triggers the OTA transfer by invoking - the _announce-ota-provider_ command - basically, the OTA Requestor is - informed of the node id of the OTA Provider Application. + of the contact sensor application, chip-tool triggers the OTA transfer by + invoking the _announce-ota-provider_ command - basically, the OTA Requestor + is informed of the node id of the OTA Provider Application. _Computer #1_ can be any system running an Ubuntu distribution. We recommand -using TE 7.5 instructions from -[here](https://groups.csa-iot.org/wg/matter-csg/document/24839), where RPi 4 are -proposed. Also, TE 7.5 instructions document point to the OS/Docker images that -should be used on the RPis. For compatibility reasons, we recommand compiling -chip-tool and OTA Provider applications with the same commit id that was used -for compiling the Lighting Application. Also, please note that there is a single -controller (chip-tool) running on Computer #1 which is used for commissioning -both the device and the OTA Provider Application. If needed, +using CSA official instructions from +[here](https://groups.csa-iot.org/wg/matter-csg/document/28566), where RPi 4 are +proposed. Also, CSA official instructions document point to the OS/Docker images +that should be used on the RPis. For compatibility reasons, we recommand +compiling chip-tool and OTA Provider applications with the same commit id that +was used for compiling the Contact Sensor Application. Also, please note that +there is a single controller (chip-tool) running on Computer #1 which is used +for commissioning both the device and the OTA Provider Application. If needed, [these instructions](https://itsfoss.com/connect-wifi-terminal-ubuntu/) could be used for connecting the RPis to WiFi. @@ -696,7 +682,7 @@ Build OTA image: In order to build an OTA image, use NXP wrapper over the standard tool `src/app/ota_image_tool.py`: -- `scripts/tools/nxp/ota/ota_image_tool.py`. +- `scripts/tools/nxp/ota/ota_image_tool.py` The tool can be used to generate an OTA image with the following format: @@ -725,7 +711,7 @@ The address for storing the custom OTA entry can also be specified: address that does not overlap with anything else. Please see more in the -[OTA image tool guide](../../../../../scripts/tools/nxp/ota/README.md). +[OTA image tool guide](../../../../scripts/tools/nxp/ota/README.md). Here is an example that generates an OTA image with application update TLV: @@ -735,16 +721,16 @@ Here is an example that generates an OTA image with application update TLV: Please note the two options `--enc_enable` and `--input_ota_key`, which are mandatory when `chip_with_ota_encryption=1`. The value of `--input_ota_key` must -match the value of `chip_with_ota_key`. See `args.gni` for the default gn -configuration. +match the value of `chip_with_ota_key`. A note regarding OTA image header version (`-vn` option). An application binary has its own software version, given by -`CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION` (`42020` by default), which can be +`CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION` (`1` by default), which can be overwritten. For having a correct OTA process, the OTA header version should be -the same as the binary embedded software version. A user can set a custom -software version in the gn build args by setting `chip_software_version` to the -wanted version. +the same as the binary embedded software version. When building the update +image, the build arguments `nxp_software_version=2` and +`nxp_sofware_version_string=\"2.0\"` can be added to the gn gen command in order +to specify the upgraded version. Start the OTA Provider Application: @@ -774,7 +760,7 @@ Start the OTA process: user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool otasoftwareupdaterequestor announce-otaprovider 1 0 0 0 2 0 ``` -### Known issues ota +### Known issues OTA - SRP cache on the openthread border router needs to flushed each time a new commissioning process is attempted. For this, factory reset the device, then @@ -827,13 +813,13 @@ Power Measurement Tool can be used inside MCUXpresso for checking the power consumption pattern: Window -> Show View -> Other -> Power Measurement Tool. The configuration for this tool is the next one: - + Also, please make sure that the J14 jumper is set to the _ENABLED_ position and no expansion board is attached to the DK6. A view from this tool is illustrated below: - + Please note that that the Power Measurement Tool is not very accurate and professional tools must be used if exact power consumption needs to be known. @@ -842,34 +828,3 @@ professional tools must be used if exact power consumption needs to be known. - Power Measurement Tool may not work correctly in MCUXpresso versions greater that 11.0.1. - -## Removing SSBL Upgrade Region - -The example also offers the possibility to remove SSBL upgrade region, for -reserving more space for application level. - -A new flag `chip_reduce_ssbl_size` is introduced. In order to remove the SSBL -upgrade region, `chip_reduce_ssbl_size=true` must be provided to the build -system - -The programming method will change: - -- writing image directory 1 should change to - - ``` - DK6Programmer.exe -V5 -s <COM port> -P 1000000 -w image_dir_1=00200000D9040101 - ``` - - Here is the interpretation of the fields: - - ``` - 00200000 -> start address 0x00002000 - D904 -> 0x4D9 pages of 512-bytes (= 620.5kB) - 01 -> bootable flag - 01 -> image type for the application - ``` - -- Matter application offset address should change to - ``` - DK6Programmer.exe -V2 -s <COM_PORT> -P 1000000 -Y -p FLASH@0x2000="chip-k32w0x-contact-example.bin" - ``` diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/args.gni b/examples/contact-sensor-app/nxp/k32w0/args.gni similarity index 97% rename from examples/contact-sensor-app/nxp/k32w/k32w0/args.gni rename to examples/contact-sensor-app/nxp/k32w0/args.gni index e328a6ede9011f..1709f1da735d5d 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/args.gni +++ b/examples/contact-sensor-app/nxp/k32w0/args.gni @@ -24,6 +24,7 @@ chip_with_ota_key = "1234567890ABCDEFA1B2C3D4E5F6F1B4" chip_stack_lock_tracking = "fatal" chip_enable_ble = true +chip_generate_link_map_file = true chip_enable_icd_server = true chip_enable_icd_lit = false diff --git a/examples/contact-sensor-app/nxp/k32w0/build_overrides b/examples/contact-sensor-app/nxp/k32w0/build_overrides new file mode 120000 index 00000000000000..ee19c065d619a2 --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w0/build_overrides @@ -0,0 +1 @@ +../../../build_overrides/ \ No newline at end of file diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h b/examples/contact-sensor-app/nxp/k32w0/include/CHIPProjectConfig.h similarity index 98% rename from examples/contact-sensor-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h rename to examples/contact-sensor-app/nxp/k32w0/include/CHIPProjectConfig.h index 301d53824a7e55..2b0afde85d56fe 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h +++ b/examples/contact-sensor-app/nxp/k32w0/include/CHIPProjectConfig.h @@ -145,11 +145,11 @@ * {MAJOR_VERSION}.0d{MINOR_VERSION} */ #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "03-2022-te8" +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING NXP_CONFIG_DEVICE_SOFTWARE_VERSION_STRING #endif #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 42020 +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION NXP_CONFIG_DEVICE_SOFTWARE_VERSION #endif #ifndef CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/include/FreeRTOSConfig.h b/examples/contact-sensor-app/nxp/k32w0/include/FreeRTOSConfig.h similarity index 100% rename from examples/contact-sensor-app/nxp/k32w/k32w0/include/FreeRTOSConfig.h rename to examples/contact-sensor-app/nxp/k32w0/include/FreeRTOSConfig.h diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/AppTask.cpp b/examples/contact-sensor-app/nxp/k32w0/main/AppTask.cpp similarity index 96% rename from examples/contact-sensor-app/nxp/k32w/k32w0/main/AppTask.cpp rename to examples/contact-sensor-app/nxp/k32w0/main/AppTask.cpp index d7d9763e491a62..d350a4527d281c 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/main/AppTask.cpp +++ b/examples/contact-sensor-app/nxp/k32w0/main/AppTask.cpp @@ -42,11 +42,12 @@ #include <app/clusters/ota-requestor/DefaultOTARequestor.h> #include <app/clusters/ota-requestor/DefaultOTARequestorDriver.h> #include <app/clusters/ota-requestor/DefaultOTARequestorStorage.h> -#include <src/platform/nxp/k32w/common/OTAImageProcessorImpl.h> +#include <src/platform/nxp/common/legacy/OTAImageProcessorImpl.h> #endif -#include <src/platform/nxp/k32w/k32w0/BLEManagerImpl.h> +#include <src/platform/nxp/k32w0/BLEManagerImpl.h> +#include "DefaultTestEventTriggerDelegate.h" #include "Keyboard.h" #include "LED.h" #include "LEDWidget.h" @@ -94,6 +95,11 @@ static chip::DeviceLayer::CustomFactoryDataProvider sCustomFactoryDataProvider; #endif #endif +// This key is for testing/certification only and should not be used in production devices. +// For production devices this key must be provided from factory data. +uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; + static Identify gIdentify = { chip::EndpointId{ 1 }, AppTask::OnIdentifyStart, AppTask::OnIdentifyStop, Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator }; @@ -107,7 +113,7 @@ static BDXDownloader gDownloader; constexpr uint16_t requestedOtaBlockSize = 1024; #endif -#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA && CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR +#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA && CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR CHIP_ERROR CustomFactoryDataRestoreMechanism(void) { K32W_LOG("This is a custom factory data restore mechanism."); @@ -154,7 +160,7 @@ static void CheckOtaEntry() if (ota_entries.ota_state == otaApplied) { K32W_LOG("OTA successfully applied"); -#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA && CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR +#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA && CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR // If this point is reached, it means OTA_CommitCustomEntries was successfully called. // Delete the factory data backup to stop doing a restore when the factory data provider // is initialized. This ensures that both the factory data and app were updated, otherwise @@ -184,7 +190,7 @@ CHIP_ERROR AppTask::Init() if (ContactSensorMgr().Init() != 0) { K32W_LOG("ContactSensorMgr().Init() failed"); - assert(status == 0); + assert(0); } PlatformMgr().AddEventHandler(MatterEventHandler, 0); @@ -196,9 +202,8 @@ CHIP_ERROR AppTask::Init() CheckOtaEntry(); #endif - // Initialize device attestation config #if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA -#if CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR sFactoryDataProvider.RegisterRestoreMechanism(CustomFactoryDataRestoreMechanism); #endif ReturnErrorOnFailure(sFactoryDataProvider.Init()); @@ -299,6 +304,8 @@ void AppTask::InitServer(intptr_t arg) chip::DeviceLayer::SetDeviceInfoProvider(&infoProvider); // Init ZCL Data Model and start server + static DefaultTestEventTriggerDelegate sTestEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; + initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate; chip::Inet::EndPointStateOpenThread::OpenThreadEndpointInitParam nativeParams; nativeParams.lockCb = LockOpenThreadTask; nativeParams.unlockCb = UnlockOpenThreadTask; diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/ContactSensorManager.cpp b/examples/contact-sensor-app/nxp/k32w0/main/ContactSensorManager.cpp similarity index 100% rename from examples/contact-sensor-app/nxp/k32w/k32w0/main/ContactSensorManager.cpp rename to examples/contact-sensor-app/nxp/k32w0/main/ContactSensorManager.cpp diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/ZclCallbacks.cpp b/examples/contact-sensor-app/nxp/k32w0/main/ZclCallbacks.cpp similarity index 100% rename from examples/contact-sensor-app/nxp/k32w/k32w0/main/ZclCallbacks.cpp rename to examples/contact-sensor-app/nxp/k32w0/main/ZclCallbacks.cpp diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/AppEvent.h b/examples/contact-sensor-app/nxp/k32w0/main/include/AppEvent.h similarity index 100% rename from examples/contact-sensor-app/nxp/k32w/k32w0/main/include/AppEvent.h rename to examples/contact-sensor-app/nxp/k32w0/main/include/AppEvent.h diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/AppTask.h b/examples/contact-sensor-app/nxp/k32w0/main/include/AppTask.h similarity index 95% rename from examples/contact-sensor-app/nxp/k32w/k32w0/main/include/AppTask.h rename to examples/contact-sensor-app/nxp/k32w0/main/include/AppTask.h index c3203d78eb543e..3f81915dca23f9 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/AppTask.h +++ b/examples/contact-sensor-app/nxp/k32w0/main/include/AppTask.h @@ -27,7 +27,7 @@ #include "CHIPProjectConfig.h" #if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA -#include <platform/nxp/k32w/k32w0/FactoryDataProviderImpl.h> +#include <platform/nxp/k32w0/FactoryDataProviderImpl.h> #if CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER #include "CustomFactoryDataProvider.h" #endif @@ -50,6 +50,9 @@ class AppTask { public: +#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA + using FactoryDataProvider = chip::DeviceLayer::FactoryDataProviderImpl; +#endif CHIP_ERROR StartAppTask(); static void AppTaskMain(void * pvParameter); diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/ContactSensorManager.h b/examples/contact-sensor-app/nxp/k32w0/main/include/ContactSensorManager.h similarity index 100% rename from examples/contact-sensor-app/nxp/k32w/k32w0/main/include/ContactSensorManager.h rename to examples/contact-sensor-app/nxp/k32w0/main/include/ContactSensorManager.h diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/app_config.h b/examples/contact-sensor-app/nxp/k32w0/main/include/app_config.h similarity index 100% rename from examples/contact-sensor-app/nxp/k32w/k32w0/main/include/app_config.h rename to examples/contact-sensor-app/nxp/k32w0/main/include/app_config.h diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/main.cpp b/examples/contact-sensor-app/nxp/k32w0/main/main.cpp similarity index 98% rename from examples/contact-sensor-app/nxp/k32w/k32w0/main/main.cpp rename to examples/contact-sensor-app/nxp/k32w0/main/main.cpp index 56288842a3f5de..9517d7e2cf4309 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/main/main.cpp +++ b/examples/contact-sensor-app/nxp/k32w0/main/main.cpp @@ -154,7 +154,7 @@ extern "C" void main_task(void const * argument) */ sched_enable(); - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); + err = ConnectivityMgr().SetThreadDeviceType(CONNECTIVITY_MANAGER_THREAD_DEVICE_TYPE); if (err != CHIP_NO_ERROR) { goto exit; diff --git a/examples/contact-sensor-app/nxp/k32w0/third_party/connectedhomeip b/examples/contact-sensor-app/nxp/k32w0/third_party/connectedhomeip new file mode 120000 index 00000000000000..3efed95be5dbe9 --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w0/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../../ \ No newline at end of file diff --git a/examples/lighting-app/nxp/k32w/k32w0/build_overrides b/examples/lighting-app/nxp/k32w/k32w0/build_overrides deleted file mode 120000 index ad07557834803a..00000000000000 --- a/examples/lighting-app/nxp/k32w/k32w0/build_overrides +++ /dev/null @@ -1 +0,0 @@ -../../../../build_overrides/ \ No newline at end of file diff --git a/examples/lighting-app/nxp/k32w/k32w0/third_party/connectedhomeip b/examples/lighting-app/nxp/k32w/k32w0/third_party/connectedhomeip deleted file mode 120000 index 305f2077ffe860..00000000000000 --- a/examples/lighting-app/nxp/k32w/k32w0/third_party/connectedhomeip +++ /dev/null @@ -1 +0,0 @@ -../../../../../.. \ No newline at end of file diff --git a/examples/lighting-app/nxp/k32w/k32w0/.gn b/examples/lighting-app/nxp/k32w0/.gn similarity index 94% rename from examples/lighting-app/nxp/k32w/k32w0/.gn rename to examples/lighting-app/nxp/k32w0/.gn index cfa8fcb8c07dc4..e0a89b885879e6 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/.gn +++ b/examples/lighting-app/nxp/k32w0/.gn @@ -31,5 +31,5 @@ default_args = { [ "${chip_root}/scripts/setup/requirements.build.txt" ] # Import default platform configs - import("${chip_root}/src/platform/nxp/k32w/k32w0/args.gni") + import("${chip_root}/src/platform/nxp/k32w0/args.gni") } diff --git a/examples/lighting-app/nxp/k32w/k32w0/BUILD.gn b/examples/lighting-app/nxp/k32w0/BUILD.gn similarity index 87% rename from examples/lighting-app/nxp/k32w/k32w0/BUILD.gn rename to examples/lighting-app/nxp/k32w0/BUILD.gn index 82afd7ad22864d..a63a5967c3948b 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/BUILD.gn +++ b/examples/lighting-app/nxp/k32w0/BUILD.gn @@ -40,7 +40,7 @@ if (chip_pw_tokenizer_logging) { assert(current_os == "freertos") -k32w0_platform_dir = "${chip_root}/examples/platform/nxp/k32w/k32w0" +k32w0_platform_dir = "${nxp_sdk_matter_support_root}/examples/platform/k32w0" k32w0_sdk("sdk") { sources = [ @@ -84,7 +84,10 @@ k32w0_sdk("sdk") { k32w0_executable("light_app") { output_name = "chip-k32w0x-light-example" + defines = [] + sources = [ + "${k32w0_platform_dir}/util/DefaultTestEventTriggerDelegate.cpp", "${k32w0_platform_dir}/util/LEDWidget.cpp", "${k32w0_platform_dir}/util/include/LEDWidget.h", "main/AppTask.cpp", @@ -96,15 +99,13 @@ k32w0_executable("light_app") { "main/main.cpp", ] - public = [ "${chip_root}/src/platform/nxp/k32w/k32w0/DefaultTestEventTriggerDelegate.h" ] - if (chip_with_factory_data == 1 && use_custom_factory_provider == 1) { sources += [ "${k32w0_platform_dir}/common/CustomFactoryDataProvider.cpp", "${k32w0_platform_dir}/common/CustomFactoryDataProvider.h", ] - defines = [ "CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER=1" ] + defines += [ "CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER=1" ] } deps = [ @@ -112,7 +113,6 @@ k32w0_executable("light_app") { "${chip_root}/examples/common/QRCode", "${chip_root}/examples/lighting-app/nxp/zap/", "${chip_root}/examples/providers:device_info_provider", - "${chip_root}/src/app:test-event-trigger", "${chip_root}/src/lib", "${chip_root}/src/platform:syscalls_stub", "${chip_root}/src/platform/logging:default", @@ -120,17 +120,12 @@ k32w0_executable("light_app") { "${k32w0_platform_dir}/app/support:freertos_mbedtls_utils", ] - if (chip_openthread_ftd) { - deps += [ - "${chip_root}/third_party/openthread/repo:libopenthread-cli-ftd", - "${chip_root}/third_party/openthread/repo:libopenthread-ftd", - ] - } else { - deps += [ - "${chip_root}/third_party/openthread/repo:libopenthread-cli-mtd", - "${chip_root}/third_party/openthread/repo:libopenthread-mtd", - ] - } + defines += [ "CONNECTIVITY_MANAGER_THREAD_DEVICE_TYPE=ConnectivityManager::kThreadDeviceType_MinimalEndDevice" ] + + deps += [ + "${chip_root}/third_party/openthread/repo:libopenthread-cli-mtd", + "${chip_root}/third_party/openthread/repo:libopenthread-mtd", + ] cflags = [ "-Wconversion" ] @@ -169,6 +164,11 @@ group("k32w0") { ":binsign", ":light_app", ] + + if (chip_enable_ota_requestor) { + deps += [ "${k32w0_platform_dir}/ssbl:ssbl" ] + } + if (chip_pw_tokenizer_logging) { deps += [ ":light_app.database" ] } @@ -183,6 +183,10 @@ action("binsign") { if (chip_simple_hash_verification == 1) { args = [ "--simple-hash" ] } + + if (chip_enable_ota_requestor) { + args = [ "--ota-enabled" ] + } } group("default") { diff --git a/examples/lighting-app/nxp/k32w/k32w0/README.md b/examples/lighting-app/nxp/k32w0/README.md similarity index 73% rename from examples/lighting-app/nxp/k32w/k32w0/README.md rename to examples/lighting-app/nxp/k32w0/README.md index a0f560e2e884c4..518e0232a4f6cb 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/README.md +++ b/examples/lighting-app/nxp/k32w0/README.md @@ -27,10 +27,12 @@ network. - [Identify cluster LED state](#identify-cluster-led-state) - [Building](#building) - [Overwrite board config files](#overwrite-board-config-files) - - [Known issues building](#known-issues-building) + - [Known issues building](#known-issues-building) - [Rotating device id](#rotating-device-id) - [Manufacturing data](#manufacturing-data) - [Flashing and debugging](#flashing-and-debugging) + - [Using DK6programmer](#using-dk6programmer) + - [Using MCUXpresso](#using-mcuxpresso) - [Pigweed tokenizer](#pigweed-tokenizer) - [Detokenizer script](#detokenizer-script) - [Notes](#notes) @@ -40,18 +42,12 @@ network. - [Tinycrypt ECC library](#tinycrypt-ecc-library) - [Building steps](#building-steps-1) - [OTA](#ota) - - [Writing the SSBL](#writing-the-ssbl) - - [Features](#features) - - [Multi image](#multi-image) - - [Simple hash verification](#simple-hash-verification) - - [Writing the PSECT](#writing-the-psect) - - [Writing the application](#writing-the-application) - [OTA Testing](#ota-testing) - - [Known issues ota](#known-issues-ota) + - [Known issues OTA](#known-issues-ota) ## Introduction - + The K32W061 lighting example application provides a working demonstration of a light bulb device, built using the Project CHIP codebase and the NXP K32W061 @@ -81,7 +77,7 @@ Deployment of this firmware configuration requires the K32W061 board setups using the K32W061 module board, SE051 Expansion board and Generic Expansion board as shown below: - + The SE051H Secure Element extension may be used for best in class security and offloading some of the Project CHIP cryptographic operations. Depending on your @@ -198,10 +194,10 @@ effects: In order to build the Project CHIP example, we recommend using a Linux distribution (supported Operating Systems are listed in -[BUILDING.md](../../../../../docs/guides/BUILDING.md#tested-operating systems)). +[BUILDING.md](../../../../docs/guides/BUILDING.md#tested-operating-systems)). - Make sure that below prerequisites are correctly installed (as described in - [BUILDING.md](../../../../../docs/guides/BUILDING.md#prerequisites))) + [BUILDING.md](../../../../docs/guides/BUILDING.md#prerequisites)) ``` sudo apt-get install git gcc g++ pkg-config libssl-dev libdbus-1-dev \ @@ -231,18 +227,18 @@ user@ubuntu:~/Desktop/git/connectedhomeip$ source scripts/bootstrap.sh - Step 3: Init NXP SDK(s) ``` -user@ubuntu:~/Desktop/git/connectedhomeip$ scripts/setup/nxp/update_nxp_sdk.py --platform k32w0 +user@ubuntu:~/Desktop/git/connectedhomeip$ third_party/nxp/nxp_matter_support/scripts/update_nxp_sdk.py --platform k32w0 ``` -Note: By default setup/nxp/update_nxp_sdk.py will try to initialize all NXP -SDKs. Arg "-- help" could be used to view all available options. +Note: By default update_nxp_sdk.py will try to initialize all NXP SDKs. Arg "-- +help" could be used to view all available options. - Start building the application: ```bash -user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/lighting-app/nxp/k32w/k32w0 -user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w/k32w0$ gn gen out/debug -user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w/k32w0$ ninja -C out/debug +user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/lighting-app/nxp/k32w0 +user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w0$ gn gen out/debug +user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w0$ ninja -C out/debug ``` To build with Secure Element, follow the same steps as above but set @@ -279,7 +275,7 @@ used to control an antenna switch. In order to use this feature, user must set In case signing errors are encountered when running the "sign_images.sh" script (run automatically) install the recommanded packages (python version > 3, pip3, -pycrypto, pycryptodome): +pycryptodome): ``` user@ubuntu:~$ python3 --version @@ -287,7 +283,6 @@ Python 3.8.2 user@ubuntu:~$ pip3 --version pip 20.0.2 from /usr/lib/python3/dist-packages/pip (python 3.8) user@ubuntu:~$ pip3 list | grep -i pycrypto -pycrypto 2.6.1 pycryptodome 3.9.8 ``` @@ -310,7 +305,7 @@ k32w0_sdk("sdk") { This variable will be used by `k32w0_sdk.gni` to overwrite `chip_with_DK6` option, thus the reference board configuration files will no longer be used. -## Known issues building +### Known issues building - When using Secure element and cross-compiling on Linux, log messages from the Plug&Trust middleware stack may not echo to the console. @@ -333,20 +328,20 @@ Please use the following build args: ## Manufacturing data See -[Guide for writing manufacturing data on NXP devices](../../../../../docs/guides/nxp/nxp_manufacturing_flow.md). +[Guide for writing manufacturing data on NXP devices](../../../../docs/guides/nxp/nxp_manufacturing_flow.md). There are factory data generated binaries available in -examples/platform/nxp/k32w/k32w0/scripts/demo_generated_factory_data folder. -These are based on the DAC, PAI and PAA certificates found in +`third_party/nxp/nxp_matter_support/examples/platform/k32w0/scripts/demo_generated_factory_data` +folder. These are based on the DAC, PAI and PAA certificates found in scripts/tools/nxp/demo_generated_certs folder. The demo_factory_data_dut1.bin uses the DAC certificate and private key found in -examples/platform/nxp/k32w/k32w0/scripts/demo_generated_factory_data/dac/dut1 +`third_party/nxp/nxp_matter_support/examples/platform/k32w0/scripts/demo_generated_factory_data/dac/dut1` folder. The demo_factory_data_dut2.bin uses the DAC certificate and private key found in -examples/platform/nxp/k32w/k32w0/scripts/demo_generated_factory_data/dac/dut2 +`third_party/nxp/nxp_matter_support/examples/platform/k32w0/scripts/demo_generated_factory_data/dac/dut2` folder. These two factory data binaries can be used for testing topologies with 2 DUTS. They contain the corresponding DACs/PAIs generated using -generate_nxp_chip_factory_bin.py script. The discriminator is 14014 and the +`generate_nxp_chip_factory_bin.py` script. The discriminator is 14014 and the passcode is 1000. These demo certificates are working with the CDs installed in CHIPProjectConfig.h. @@ -355,18 +350,140 @@ Regarding factory data provider, there are two options: - use the default factory data provider: `FactoryDataProviderImpl` by setting `chip_with_factory_data=1` in the gn build command. - use a custom factory data provider: please see - [Guide for implementing a custom factory data provider](../../../../platform/nxp/k32w/k32w0/common/README.md). + [Guide for implementing a custom factory data provider](../../../platform/nxp/k32w0/doc/CustomFactoryDataProvider.md). This can be enabled when `chip_with_factory_data=1` by setting `use_custom_factory_provider=1` in the gn build command. ## Flashing and debugging -Program the firmware using the official +Instructions to program the firmware can be found also at [OpenThread Flash Instructions](https://github.com/openthread/ot-nxp/tree/main/src/k32w0/k32w061#flash-binaries). -All you have to do is to replace the Openthread binaries from the above -documentation with _out/debug/chip-k32w0x-light-example.bin_ if DK6Programmer is -used or with _out/debug/chip-k32w0x-light-example_ if MCUXpresso is used. +### Using DK6programmer + +The application binary's path is _out/debug/chip-k32w0x-light-example.bin_. + +DK6Programmer can be used for flashing the application. There are two available +versions of the DK6Programmer tool. + +The legacy version consists of a Windows executable found inside the +[SDK](https://mcuxpresso.nxp.com/en/welcome) at path +`tools/JN-SW-4407-DK6-Flash-Programmer`. This is a Windows application that can +be installed using the .exe file. Once the application is installed, the COM +port for K32W061 must be identified: + +``` +C:\nxp\DK6ProductionFlashProgrammer>DK6Programmer.exe --list +Available connections: +<COM_PORT> +``` + +Once the COM port is identified, the required binary can be flashed: + +``` +DK6Programmer.exe -V2 -s <COM_PORT> -P 1000000 -Y -p FLASH@0x4000="chip-k32w0x-light-example.bin" +``` + +> **_Note:_** The above example takes into account that the binary uses the +> `chip_enable_ota_requestor=true` option. The address offset corresponds to the +> space left for the SSBL binary and the OTA space for the SSBL. If +> `chip_enable_ota_requestor` is set to `false`, then `0x4000` needs to be +> replaced with `0x0`. + +DK6 Flash Programmer tool has also been integrated part of +[NXP Secure Provisioning SDK (SPSDK)](https://github.com/nxp-mcuxpresso/spsdk). +This tool is supported by environments like Windows, Linux or Mac. + +`SPSDK` can be installed and run from a Python environment using +[these instructions](https://spsdk.readthedocs.io/en/latest/usage/installation.html). +This enables the user to have transparent access to the dk6 programming tool +through `SPSDK`. + +``` +# after specific environment installation steps +$ spsdk --help +... + +-- dk6prog Tool for reading and programming flash memory of DK6 target devices. + � +-- erase Erase the memory. + � +-- info Prints the information about the connected device. + � +-- isp Issues ISP sequence as defined in Driver interface. + � +-- listdev Prints the information about the connected devices. + � +-- read Reads the memory and writes it to the file or stdout. + � +-- write Write the memory. +... +``` + +Dependencies for the `dk6prog` module can be installed using the following +command, more details +[here](https://spsdk.readthedocs.io/en/latest/usage/installation.html#dk6-tools): + +``` +$ pip install spsdk[dk6] +``` + +The `SPSDK` installation adds `dk6prog` as executable to system path, so user +can use directly `dk6prog` from terminal. The following commands are to be used +to write the chip-k32w0x-light-example binary to the board. + +``` +$ dk6prog listdev +This is an experimental utility. Use with caution! + +List of available devices: +DEVICE ID: DN038ZH3, VID: 0x403, PID: 0x6015, Serial number: DN038ZH3, Description: DK6 Carrier Board, Address: 9, Backend: Backend.PYFTDI +$ dk6prog -d DN038ZH3 write 0x4000 ~/path/to/bin/chip-k32w0x-light-example.bin + +This is an experimental utility. Use with caution! + +Writing memory [####################################] 100% +Written 596450 bytes to memory ID 0 at address 0x4000 +``` + +> **_Note:_** Running `dk6prog` from Windows OS command line requires an integer +> value for DEVICE ID. + +``` +C:\nxp\spsdk>dk6prog listdev + +This is an experimental utility. Use with caution! + +List of available devices: +DEVICE ID: 0, VID: 0x0, PID: 0x0, Serial number: b'DN038ZH3', Description: b'DK6 Carrier Board', Address: 67330069, Backend: Backend.FTD2xx + +C:\nxp\spsdk>dk6prog -d 0 info + +This is an experimental utility. Use with caution! + +Chip ID: 0x88888888 +ROM Version: 0x140000cc +MAC Address: A8:2B:1F:03:00:8D:15:00 + +Detected DEVICE: UNKNOWN + + Memory Memory ID Base Address Length Sector Size Memory Type Access +---------------------------------------------------------------------------------------------- + FLASH 0 0x0 0x9de00 0x200 FLASH All is available + PSECT 1 0x0 0x1e0 0x10 FLASH All is available + pFLASH 2 0x0 0x1e0 0x10 FLASH All is available + Config 3 0x9fc00 0x200 0x200 FLASH All is available + EFUSE 4 0x0 0x80 0x2 EFUSE (OTP) Write Enabled + ROM 5 0x3000000 0x20000 0x1 ROM Write Enabled + RAM0 6 0x4000000 0x16000 0x1 RAM Write Enabled + RAM1 7 0x4020000 0x10000 0x1 RAM Write Enabled +``` + +> **_Note:_** The above example takes into account that the binary uses the +> `chip_enable_ota_requestor=true` option. The address offset corresponds to the +> space left for the SSBL binary and the OTA space for the SSBL. If +> `chip_enable_ota_requestor` is set to `false`, then `0x4000` needs to be +> replaced with `0x0`. + +### Using MCUXpresso + +If flashing and debugging is required, MCUXpresso can be used as instructed in +[MCUXpresso flashing and debugging instructions](https://github.com/openthread/ot-nxp/tree/main/src/k32w0/k32w061#using-mcuxpresso-ide). +The file needed to be used in MCUXpresso is +_out/debug/chip-k32w0x-light-example_. ## Pigweed tokenizer @@ -379,7 +496,7 @@ needed for parsing the hashed scripts. The python3 script detokenizer.py is a script that decodes the tokenized logs either from a file or from a serial port. It is located in the following path -`examples/platform/nxp/k32w/k32w0/scripts/detokenizer.py`. +`third_party/nxp/nxp_matter_support/examples/platform/k32w0/scripts/detokenizer.py`. The script can be used in the following ways: @@ -414,7 +531,7 @@ by the script is loaded by the environment. An example of running the detokenizer script to see logs of a lighting app: ``` -python3 ../../../../../examples/platform/nxp/k32w/k32w0/scripts/detokenizer.py serial -i /dev/ttyACM0 -d out/debug/chip-k32w0x-light-example-database.bin -o device.txt +python3 ../../../../third_party/nxp/nxp_matter_support/examples/platform/k32w0/scripts/detokenizer.py serial -i /dev/ttyACM0 -d out/debug/chip-k32w0x-light-example-database.bin -o device.txt ``` ### Known issues tokenizer @@ -459,172 +576,37 @@ In order to use the Tinycrypt ECC library, use the following build arguments: ## OTA -The internal flash needs to be prepared for the OTA process. First 16K of the -internal flash needs to be populated with a Secondary Stage Bootloader (SSBL) -related data while the last 8.5K of flash space is holding image directory -related data (PSECT). The space between these two zones will be filled by the +Over the air updates (OTA) require several software components running on the +K32W0x1. Firstly, a Secondary Stage Bootloader (SSBL) is required written in the +first part of the internal flash memory, usually starting at address 0x0. This +enables the board to boot and check if a new OTA binary has been received. If +this is true, the bootloader writes the OTA binary to the appropriate storage, +internal and/or external flash, after which it reboots the board. If no new OTA +binaries have been found, then the bootloader gives execution control to the application. -### Writing the SSBL - -The SDK already provides an SSBL binary compiled with external flash support: -`boards/k32w061dk6/wireless_examples/framework/ssbl/binary/ssbl_ext_flash_pdm_support.bin`, -but it does not offer multi-image OTA support. - -Alternatively, the SSBL can ge generated from one of the SDK demo examples. The -SSBL demo application can be imported from the `Quickstart panel`: -`Import SDK example(s) -> select wireless -> framework -> ssbl` application. - - - -### Features - -#### Multi image - -To support multi-image OTA feature, the SSBL project must be compiled using the -following defines: - -- `PDM_EXT_FLASH=1` - support PDM in external flash. -- `gOTAUseCustomOtaEntry=1` - support custom OTA entry for multi-image. -- `gOTACustomOtaEntryMemory=OTACustomStorage_ExtFlash` - K32W0 uses - `OTACustomStorage_ExtFlash` (1) by default. -- `SPIFI_DUAL_MODE_SUPPORT=1` - only for configurations that use dual `SPIFI` - flash (e.g. K32W041AM variant). - -Optionally, add the following defines: - -- `SPIFI_OPTIM_SIZE=1` - to optimize SSBL size. -- `EXTERNAL_FLASH_DATA_OTA=1` - to support external read only data. - - - -#### Simple hash verification - -When secure boot is not used, a simple hash can be appended at the end of the -image for integrity check. Applications should be built with -`chip_simple_hash_verification=1`. - -To support simple hash verification feature, the SSBL project must be compiled -with: - -- `gSimpleHashVerification=1` - -and update the post-build command to use simple hash verification instead of the -default options. Go to -`Project -> Properties -> C/C++ Build -> Settings -> Build steps` and press -`Edit` under `Post-build steps` subsection. The command should look similar to: - - - -Once compiled, the required SSBL file is called `k32w061dk6_ssbl.bin`. - - - -Before writing the SSBL, it it recommanded to fully erase the internal flash: - -``` -DK6Programmer.exe -V 5 -P 1000000 -s <COM_PORT> -e Flash -``` - -`k32w061dk6_ssbl.bin` must be written at address 0 in the internal flash: - -``` -DK6Programmer.exe -V2 -s <COM_PORT> -P 1000000 -Y -p FLASH@0x00="k32w061dk6_ssbl.bin" -``` - -### Writing the PSECT - -This is the list of all supported partitions: - -``` -0000000010000000 : SSBL partition - - 00000000 -----------> Start Address - 1000 ---------------> 0x0010 Number of 512-bytes pages - 00 -----------------> 0x00 Bootable flag - 00 -----------------> 0x00 Image type (0x00 = SSBL) - -00400000c9040101: Application partition - - 00400000 -----------> 0x00004000 Start Address - c904 ---------------> 0x04c9 Number of 512-bytes pages - 01 -----------------> 0x01 Bootable flag - 01 -----------------> 0x01 Image type (0x01 = Application) - -00000010800000fe: Ext Flash text partition - - 00000010 -----------> 0x10000000 Start Address (external flash) - 8000 ---------------> 0x0080 Number of 512-bytes pages - 00 -----------------> 0x00 Bootable flag - fe -----------------> 0xFE Image type (0xFE = Ext Flash text) - -00000110300200fc : OTA Image partition - - 00000110 -----------> 0x10010000 Start Address - 3002----------------> 0x0230 Number of 512-bytes pages - 00 -----------------> 0x00 Bootable flag - fc -----------------> 0xFC Image type (0xFC = OTA partition) - -00000510100000fd: NVM partition - - 00000510 -----------> 0x10050000 Start Address - 1000 ---------------> 0x0010 Number of 512-bytes pages - 00 -----------------> 0x00 Bootable flag - fd -----------------> 0xFD Image type (0xFD = NVM partition) -``` - -First, image directory 0 (SSBL partition) must be written: - -``` -DK6Programmer.exe -V5 -s <COM port> -P 1000000 -w image_dir_0=0000000010000000 -``` - -Here is the interpretation of the fields: - -``` -00000000 -> start address 0x00000000 -1000 -> size = 0x0010 pages of 512-bytes (= 8kB) -00 -> not bootable (only used by the SSBL to support SSBL update) -00 -> SSBL Image Type -``` - -Second, image directory 1 (application partition) must be written: - -``` -DK6Programmer.exe -V5 -s <COM port> -P 1000000 -w image_dir_1=00400000C9040101 -``` - -Here is the interpretation of the fields: - -``` -00400000 -> start address 0x00004000 -C904 -> 0x4C9 pages of 512-bytes (= 612.5kB) -01 -> bootable flag -01 -> image type for the application -``` - -Please note the user can write additional partitions by writing -`image_dir_2/3/4` with the wanted configuration. - -### Writing the application - -DK6Programmer can be used for flashing the application: - -``` -DK6Programmer.exe -V2 -s <COM_PORT> -P 1000000 -Y -p FLASH@0x4000="chip-k32w0x-light-example.bin" -``` +The internal flash needs to be prepared for the OTA process. First 16K of the +internal flash needs to be populated with SSBL related data while the last 8.5K +of flash space is holding flash configuration related data. The space between +these two zones will be filled by the application. More details regarding the +internal flash space can be found in the +[linker file](../../../../third_party/nxp/nxp_matter_support/examples/platform/k32w0/app/ldscripts/chip-k32w0x-linker.ld). -If debugging is needed, MCUXpresso can be used then for flashing the -application. Please make sure that the application is written at address 0x4000: +The steps for building the SSBL binary with appropriate configuration and +writing to the board the binary and other OTA related configurations are +described in the +[K32W0x1 OTA guide](../../../../docs/guides/nxp/nxp_k32w0_ota_guide.md). - +Note that the application needs to be built using the +`chip_enable_ota_requestor=true` option. This is enabled in the configuration by +default if no `chip_enable_ota_requestor` explicit setting is done. ### OTA Testing The OTA topology used for OTA testing is illustrated in the figure below. Topology is similar with the one used for Matter Test Events. - + The concept for OTA is the next one: @@ -701,21 +683,22 @@ The address for storing the custom OTA entry can also be specified: address that does not overlap with anything else. Please see more in the -[OTA image tool guide](../../../../../scripts/tools/nxp/ota/README.md). +[OTA image tool guide](../../../../scripts/tools/nxp/ota/README.md). Here is an example that generates an OTA image with application update TLV: ``` -./scripts/tools/nxp/ota/ota_image_tool.py create -v 0xDEAD -p 0xBEEF -vn 42021 -vs "1.0" -da sha256 --app-input-file chip-k32w0x-light-example.bin chip-k32w0x-light-example.ota +./scripts/tools/nxp/ota/ota_image_tool.py create -v 0xDEAD -p 0xBEEF -vn 2 -vs "2.0" -da sha256 --app-input-file chip-k32w0x-light-example.bin chip-k32w0x-light-example.ota ``` A note regarding OTA image header version (`-vn` option). An application binary has its own software version, given by -`CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION` (`42020` by default), which can be +`CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION` (`1` by default), which can be overwritten. For having a correct OTA process, the OTA header version should be -the same as the binary embedded software version. A user can set a custom -software version in the gn build args by setting `chip_software_version` to the -wanted version. +the same as the binary embedded software version. When building the update +image, the build arguments `nxp_software_version=2` and +`nxp_sofware_version_string=\"2.0\"` can be added to the gn gen command in order +to specify the upgraded version. Start the OTA Provider Application: @@ -745,7 +728,7 @@ Start the OTA process: user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool otasoftwareupdaterequestor announce-otaprovider 1 0 0 0 2 0 ``` -## Known issues ota +### Known issues OTA - SRP cache on the openthread border router needs to flushed each time a new commissioning process is attempted. For this, factory reset the device, then diff --git a/examples/lighting-app/nxp/k32w/k32w0/args.gni b/examples/lighting-app/nxp/k32w0/args.gni similarity index 96% rename from examples/lighting-app/nxp/k32w/k32w0/args.gni rename to examples/lighting-app/nxp/k32w0/args.gni index f5fd7a83cd9005..7126cf38ad5f3b 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/args.gni +++ b/examples/lighting-app/nxp/k32w0/args.gni @@ -20,6 +20,7 @@ k32w0_sdk_target = get_label_info(":sdk", "label_no_toolchain") chip_enable_ota_requestor = true chip_stack_lock_tracking = "fatal" chip_enable_ble = true +chip_generate_link_map_file = true is_debug = false diff --git a/examples/lighting-app/nxp/k32w0/build_overrides b/examples/lighting-app/nxp/k32w0/build_overrides new file mode 120000 index 00000000000000..ee19c065d619a2 --- /dev/null +++ b/examples/lighting-app/nxp/k32w0/build_overrides @@ -0,0 +1 @@ +../../../build_overrides/ \ No newline at end of file diff --git a/examples/lighting-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h b/examples/lighting-app/nxp/k32w0/include/CHIPProjectConfig.h similarity index 97% rename from examples/lighting-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h rename to examples/lighting-app/nxp/k32w0/include/CHIPProjectConfig.h index e32575e55ff5c4..62b2b0273f1da4 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h +++ b/examples/lighting-app/nxp/k32w0/include/CHIPProjectConfig.h @@ -86,7 +86,7 @@ 0xe4, 0x76, 0x1b, 0xfd, 0x05, \ } -// All remaining data will be pulled from provisioning region of flash. +// All remaining data will be pulled from the provisioning region of flash. #endif #else @@ -146,11 +146,11 @@ * {MAJOR_VERSION}.0d{MINOR_VERSION} */ #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "03-2022-te8" +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING NXP_CONFIG_DEVICE_SOFTWARE_VERSION_STRING #endif #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 42020 +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION NXP_CONFIG_DEVICE_SOFTWARE_VERSION #endif #ifndef CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME diff --git a/examples/lighting-app/nxp/k32w/k32w0/include/FreeRTOSConfig.h b/examples/lighting-app/nxp/k32w0/include/FreeRTOSConfig.h similarity index 100% rename from examples/lighting-app/nxp/k32w/k32w0/include/FreeRTOSConfig.h rename to examples/lighting-app/nxp/k32w0/include/FreeRTOSConfig.h diff --git a/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp b/examples/lighting-app/nxp/k32w0/main/AppTask.cpp similarity index 98% rename from examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp rename to examples/lighting-app/nxp/k32w0/main/AppTask.cpp index 22535a1c974c92..7db25b0a7c0451 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp +++ b/examples/lighting-app/nxp/k32w0/main/AppTask.cpp @@ -29,7 +29,6 @@ #include <lib/support/ThreadOperationalDataset.h> #include <platform/CHIPDeviceLayer.h> #include <platform/internal/DeviceNetworkInfo.h> -#include <src/platform/nxp/k32w/k32w0/DefaultTestEventTriggerDelegate.h> #include <app-common/zap-generated/attributes/Accessors.h> #include <app-common/zap-generated/ids/Clusters.h> @@ -44,9 +43,10 @@ #include <app/clusters/ota-requestor/DefaultOTARequestor.h> #include <app/clusters/ota-requestor/DefaultOTARequestorDriver.h> #include <app/clusters/ota-requestor/DefaultOTARequestorStorage.h> -#include <src/platform/nxp/k32w/common/OTAImageProcessorImpl.h> +#include <src/platform/nxp/common/legacy/OTAImageProcessorImpl.h> #endif +#include "DefaultTestEventTriggerDelegate.h" #include "Keyboard.h" #include "LED.h" #include "LEDWidget.h" @@ -116,7 +116,7 @@ static BDXDownloader gDownloader; constexpr uint16_t requestedOtaBlockSize = 1024; #endif -#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA && CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR +#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA && CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR CHIP_ERROR CustomFactoryDataRestoreMechanism(void) { K32W_LOG("This is a custom factory data restore mechanism."); @@ -151,7 +151,7 @@ static void CheckOtaEntry() if (ota_entries.ota_state == otaApplied) { K32W_LOG("OTA successfully applied"); -#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA && CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR +#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA && CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR // If this point is reached, it means OTA_CommitCustomEntries was successfully called. // Delete the factory data backup to stop doing a restore when the factory data provider // is initialized. This ensures that both the factory data and app were updated, otherwise @@ -187,9 +187,8 @@ CHIP_ERROR AppTask::Init() CheckOtaEntry(); #endif - // Initialize device attestation config #if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA -#if CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR sFactoryDataProvider.RegisterRestoreMechanism(CustomFactoryDataRestoreMechanism); #endif ReturnErrorOnFailure(sFactoryDataProvider.Init()); diff --git a/examples/lighting-app/nxp/k32w/k32w0/main/LightingManager.cpp b/examples/lighting-app/nxp/k32w0/main/LightingManager.cpp similarity index 100% rename from examples/lighting-app/nxp/k32w/k32w0/main/LightingManager.cpp rename to examples/lighting-app/nxp/k32w0/main/LightingManager.cpp diff --git a/examples/lighting-app/nxp/k32w/k32w0/main/ZclCallbacks.cpp b/examples/lighting-app/nxp/k32w0/main/ZclCallbacks.cpp similarity index 100% rename from examples/lighting-app/nxp/k32w/k32w0/main/ZclCallbacks.cpp rename to examples/lighting-app/nxp/k32w0/main/ZclCallbacks.cpp diff --git a/examples/lighting-app/nxp/k32w/k32w0/main/include/AppEvent.h b/examples/lighting-app/nxp/k32w0/main/include/AppEvent.h similarity index 100% rename from examples/lighting-app/nxp/k32w/k32w0/main/include/AppEvent.h rename to examples/lighting-app/nxp/k32w0/main/include/AppEvent.h diff --git a/examples/lighting-app/nxp/k32w/k32w0/main/include/AppTask.h b/examples/lighting-app/nxp/k32w0/main/include/AppTask.h similarity index 95% rename from examples/lighting-app/nxp/k32w/k32w0/main/include/AppTask.h rename to examples/lighting-app/nxp/k32w0/main/include/AppTask.h index 0c455f431a8cf4..7dca1f700f6b89 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/main/include/AppTask.h +++ b/examples/lighting-app/nxp/k32w0/main/include/AppTask.h @@ -27,7 +27,7 @@ #include "CHIPProjectConfig.h" #if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA -#include <platform/nxp/k32w/k32w0/FactoryDataProviderImpl.h> +#include <platform/nxp/k32w0/FactoryDataProviderImpl.h> #if CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER #include "CustomFactoryDataProvider.h" #endif @@ -50,6 +50,9 @@ class AppTask { public: +#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA + using FactoryDataProvider = chip::DeviceLayer::FactoryDataProviderImpl; +#endif CHIP_ERROR StartAppTask(); static void AppTaskMain(void * pvParameter); diff --git a/examples/lighting-app/nxp/k32w/k32w0/main/include/LightingManager.h b/examples/lighting-app/nxp/k32w0/main/include/LightingManager.h similarity index 100% rename from examples/lighting-app/nxp/k32w/k32w0/main/include/LightingManager.h rename to examples/lighting-app/nxp/k32w0/main/include/LightingManager.h diff --git a/examples/lighting-app/nxp/k32w/k32w0/main/include/app_config.h b/examples/lighting-app/nxp/k32w0/main/include/app_config.h similarity index 100% rename from examples/lighting-app/nxp/k32w/k32w0/main/include/app_config.h rename to examples/lighting-app/nxp/k32w0/main/include/app_config.h diff --git a/examples/lighting-app/nxp/k32w/k32w0/main/main.cpp b/examples/lighting-app/nxp/k32w0/main/main.cpp similarity index 97% rename from examples/lighting-app/nxp/k32w/k32w0/main/main.cpp rename to examples/lighting-app/nxp/k32w0/main/main.cpp index a8963a17c09096..6d95f10fe1168b 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/main/main.cpp +++ b/examples/lighting-app/nxp/k32w0/main/main.cpp @@ -139,7 +139,7 @@ extern "C" void main_task(void const * argument) */ sched_enable(); - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); + err = ConnectivityMgr().SetThreadDeviceType(CONNECTIVITY_MANAGER_THREAD_DEVICE_TYPE); if (err != CHIP_NO_ERROR) { goto exit; diff --git a/examples/lighting-app/nxp/k32w0/third_party/connectedhomeip b/examples/lighting-app/nxp/k32w0/third_party/connectedhomeip new file mode 120000 index 00000000000000..3efed95be5dbe9 --- /dev/null +++ b/examples/lighting-app/nxp/k32w0/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../../ \ No newline at end of file diff --git a/examples/platform/nxp/k32w/k32w0/BUILD.gn b/examples/platform/nxp/k32w/k32w0/BUILD.gn deleted file mode 100644 index eb0c79742f3b99..00000000000000 --- a/examples/platform/nxp/k32w/k32w0/BUILD.gn +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright (c) 2020 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. - -import("//build_overrides/chip.gni") -import("//build_overrides/nxp_sdk.gni") - -import("${nxp_sdk_build_root}/nxp_sdk.gni") - -import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") - -config("chip_examples_project_config") { - include_dirs = [ - "app/project_include", - "${chip_root}", - ] -} - -source_set("openthread_core_config_k32w0_chip_examples") { - sources = [ "app/project_include/OpenThreadConfig.h" ] - - public_deps = [ "${chip_root}/third_party/openthread/platforms/nxp/k32w/k32w0:openthread_core_config_k32w0" ] - - public_configs = [ ":chip_examples_project_config" ] -} diff --git a/examples/platform/nxp/k32w/k32w0/app/BUILD.gn b/examples/platform/nxp/k32w/k32w0/app/BUILD.gn deleted file mode 100644 index 8651bd56be4ecd..00000000000000 --- a/examples/platform/nxp/k32w/k32w0/app/BUILD.gn +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (c) 2020 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. - -import("//build_overrides/chip.gni") - -config("chip_examples_project_config") { - include_dirs = [ "app/project_include" ] -} - -source_set("openthread_core_config_k32w0_chip_examples") { - sources = [ "app/project_include/OpenThreadConfig.h" ] - - public_deps = [ "${chip_root}/third_party/openthread/platforms/nxp/k32w/k32w0:openthread_core_config_k32w0" ] - - public_configs = [ ":chip_examples_project_config" ] -} diff --git a/examples/platform/nxp/k32w/k32w0/app/args.gni b/examples/platform/nxp/k32w/k32w0/app/args.gni deleted file mode 100644 index 44a96b88a65b1b..00000000000000 --- a/examples/platform/nxp/k32w/k32w0/app/args.gni +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (c) 2020 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. - -import("//build_overrides/chip.gni") - -import("${chip_root}/src/platform/nxp/k32w/k32w0/args.gni") - -openthread_project_core_config_file = "OpenThreadConfig.h" - -chip_ble_project_config_include = "<CHIPProjectConfig.h>" -chip_device_project_config_include = "<CHIPProjectConfig.h>" -chip_project_config_include = "<CHIPProjectConfig.h>" -chip_inet_project_config_include = "<CHIPProjectConfig.h>" -chip_system_project_config_include = "<CHIPProjectConfig.h>" - -chip_system_config_provide_statistics = false -chip_with_nlfaultinjection = true diff --git a/examples/platform/nxp/k32w/k32w0/app/ldscripts/chip-k32w0x-linker.ld b/examples/platform/nxp/k32w/k32w0/app/ldscripts/chip-k32w0x-linker.ld deleted file mode 100644 index c51182b104ec53..00000000000000 --- a/examples/platform/nxp/k32w/k32w0/app/ldscripts/chip-k32w0x-linker.ld +++ /dev/null @@ -1,448 +0,0 @@ -/* - * Copyright (c) 2019, The OpenThread Authors. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @file - * GCC linker script for K32W061/K32W041. - */ - -/******************* Map of K32W0 internal flash *********************************** - - 0x000A_0000 - - - - +---------------+ - - - - - - - - - | | - 8.5K | Flash config | - | RESERVED | 0x0009_DE00 - - - - +---------------+ - - - - - - - - - | | - 2K | Factory data | - | | 0x0009_D600 - - - - +---------------+ - - - - - - - - - | | - 1K | App metadata | - | | 0x0009_D200 - - - - +---------------+ - - - - - - - - - | | - 612.5K | Application | - | | 0x0000_4000 - - - - +---------------+ - - - - - - - - - | | - 8K | SSBL update | - | | 0x0000_2000 - - - - +---------------+ - - - - - - - - - | | - 8K | SSBL | - | | 0x0000_0000 - - - - +---------------+ - - - - - - - - - 0x0000_0000 - -* - If OTA is disabled, SSBL and SSBL updated region are not present. - - The only address range that changes is the application, which will span from - 0x0000_0000 to 0x0009_D200, having 628.5K max size. - *****************************************************************************/ - -/******************* Map of DK6 external flash *********************************** - - 0x0010_0000 - - - - +---------------+ - - - - - - - - - | | - 252K | PDM area | - | | 0x000C_1000 - - - - +---------------+ - - - - - - - - - | | - 4K | OTA entry | - | | 0x000C_0000 - - - - +---------------+ - - - - - - - - - | | - 768K | OTA area | - | | - - - - +---------------+ - - - - - - - - - 0x0000_0000 - - *****************************************************************************/ - -OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") - -/* - * stack size for the boot rom during warm boot and application - * 256 is sufficient (pwrm_test) but keep it large to 1024 - */ -BOOT_RESUME_STACK_SIZE = 1024; - -STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x01000; - -MEM_RAM0_BASE = 0x4000400; -MEM_RAM0_SIZE = 0x0015c00; - -MEM_RAM1_BASE = 0x4020000; -MEM_RAM1_SIZE = 0x10000; - -/* internal flash size: 640K */ -m_int_flash_size = 0xA0000; -m_int_sector_size = 512; - -/* first 8K: SSBL, next 8K: SSBL update region */ -m_app_start = DEFINED(__app_load_address__) ? __app_load_address__ : 0x0; - -/* flash_config: 8.5K */ -m_flash_config_size = 0x2200; - -/* sizeof(BOOT_BLOCK_T) + sizeof(IMAGE_CERT_T) + SIGNATURE_LEN + alignment = 1024 bytes */ -m_app_meta_data = 0x400; - -/* manufacturing data: 2K */ -m_factory_data_size = 0x800; - -/* 16K: SSBL + SSBL update region */ -m_ssbl_size = 0x4000; - -/* default app size, without OTA */ -m_app_default_size = m_int_flash_size - m_flash_config_size - m_app_meta_data - m_factory_data_size; - -m_app_size = DEFINED(__app_stated_size__) ? __app_stated_size__ : m_app_default_size; - -MEMORY -{ - Flash640 (rx) : ORIGIN = m_app_start, LENGTH = m_app_size - - SCRATCH_RAM(rwx) : ORIGIN = 0x4000000, LENGTH = 0x400 /* 1K bytes (alias SCRATCH_RAM) */ - RAM0 (rwx) : ORIGIN = 0x4000400, LENGTH = 0x0015BE0 /* [87K - 32] bytes (alias RAM) */ - reserved (rwx) : ORIGIN = 0x4015FE0, LENGTH = 0x20 /* 32 bytes (reserved for ROM code) */ - RAM1 (rwx) : ORIGIN = 0x4020000, LENGTH = 0x10000 /* 64K bytes (alias RAM2) */ -} - -/* Define a symbol for the top of each memory region */ -__top_RAM1 = MEM_RAM1_BASE + MEM_RAM1_SIZE; /* 64K bytes */ - -/* The second RAM bank is dedicated entirely to heap + stack. */ -HEAP_SIZE = MEM_RAM1_SIZE - STACK_SIZE; -ASSERT(((HEAP_SIZE + STACK_SIZE) == MEM_RAM1_SIZE), "Heap size + stack size should total RAM1 size."); - -/* set external flash properties - external flash is present on the DK6 board */ -m_ext_flash_size = 0x00100000; -m_ext_flash_base = 0x00000000; -m_ext_flash_sector_size = 4096; - -NVMSectorCountLink = 63; - -NV_STORAGE_SIZE = NVMSectorCountLink * m_ext_flash_sector_size; -NV_STORAGE_MAX_SECTORS = NVMSectorCountLink; -NV_STORAGE_SECTOR_SIZE = m_ext_flash_sector_size; -NV_STORAGE_START_ADDRESS = m_ext_flash_size - 1; -NV_STORAGE_END_ADDRESS = NV_STORAGE_START_ADDRESS - NV_STORAGE_SIZE + 1; - -INT_STORAGE_START = m_int_flash_size - 1; -INT_STORAGE_SIZE = m_int_flash_size; -INT_STORAGE_END = 0x00000000; -INT_STORAGE_SECTOR_SIZE = m_int_sector_size; - -FACTORY_DATA_START_ADDRESS = m_int_flash_size - m_flash_config_size - m_factory_data_size; -FACTORY_DATA_END_ADDRESS = FACTORY_DATA_START_ADDRESS + m_factory_data_size - 1; - -__ram_vector_table__ = 1; -vector_table_size = 0x120; -M_VECTOR_RAM_SIZE = DEFINED(__ram_vector_table__) ? vector_table_size : 0x0; - -__base_RAM0 = 0x4000400; - -ENTRY(ResetISR) - -SECTIONS -{ - /* MAIN TEXT SECTION */ - .header : ALIGN(4) - { - _flash_start = ABSOLUTE(.); - _flash_beg = ABSOLUTE(.); - - FILL(0xff) - __vectors_start__ = ABSOLUTE(.) ; - __VECTOR_TABLE = .; - __Vectors = .; - KEEP(*(.isr_vector)) - /* Global Section Table */ - . = ALIGN(4) ; - __section_table_start = .; - __data_section_table = .; - LONG(LOADADDR(.data)); - LONG( ADDR(.data)); - LONG( SIZEOF(.data)); - __data_section_table_end = .; - __bss_section_table = .; - LONG( ADDR(.bss)); - LONG( SIZEOF(.bss)); - __bss_section_table_end = .; - __section_table_end = . ; - /* End of Global Section Table */ - - FILL(0xff) - . = ALIGN (0x10); - } >Flash640 - - .ro_nonce : ALIGN(0x10) - { - _FlsNonceStart = ABSOLUTE(.); - *(.ro_nonce) /* nonce value is 16 bytes.*/ - FILL(0xff) - . = ALIGN (0x10); - } > Flash640 - - .ro_ota_header : ALIGN(0x10) - { - _enc_start = ABSOLUTE(.); - _enc_offset = (_enc_start & 0x0000000F); - _FlsOtaHeader = ABSOLUTE(.); - *(.ro_ota_header) /* Ota Header 69 bytes*/ - FILL(0xff) - . = ALIGN (0x10); - } > Flash640 - - .ro_se_lnkKey (ALIGN((. - _enc_offset), 16) + _enc_offset): - { - _FlsLinkKey = ABSOLUTE(.); - *(.ro_se_lnkKey) /* Link Key 16 bytes*/ - FILL(0xff) - . = ALIGN (0x10); - } > Flash640 - - .filler : - { - BYTE(0xff); - FILL(0xff); - . = ALIGN(0x40); - } > Flash640 - - .text : ALIGN(0x40) - { - FILL(0xff) - - *(.after_vectors*) - *(.text*) - - KEEP(*(.init)) - KEEP(*(.fini)) - - /* .ctors */ - *crtbegin.o(.ctors) - *crtbegin?.o(.ctors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) - *(SORT(.ctors.*)) - *(.ctors) - - /* .dtors */ - *crtbegin.o(.dtors) - *crtbegin?.o(.dtors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) - *(SORT(.dtors.*)) - *(.dtors) - - *(.rodata .rodata.* .constdata .constdata.*) - - . = ALIGN(4); - } > Flash640 - /* - * for exception handling/unwind - some Newlib functions (in common - * with C++ and STDC++) use this. - */ - .ARM.extab : ALIGN(4) - { - FILL(0xff) - *(.ARM.extab* .gnu.linkonce.armextab.*) - } > Flash640 - __exidx_start = .; - - .ARM.exidx : ALIGN(4) - { - FILL(0xff) - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > Flash640 - __exidx_end = .; - - _etext = .; - - .heap (COPY): - { - __HeapBase = .; - _heap = .; - KEEP(*(.heap*)) - PROVIDE(end = .); - . = ALIGN(4); - __end__ = .; - _end_heap = .; - __HeapLimit = .; - } > RAM1 - - .interrupts_ram : ALIGN(0x200) - { - . = ALIGN(4); - __VECTOR_RAM__ = .; - __interrupts_ram_start__ = .; /* Create a global symbol at data start */ - *(.m_interrupts_ram) /* This is a user defined section */ - . += M_VECTOR_RAM_SIZE; - . = ALIGN(4); - __interrupts_ram_end__ = .; /* Define a global symbol at data end */ - } > RAM0 - .scratch_area (NOLOAD): ALIGN(4) - { - __scratch_area_start__ = .; - . = ALIGN(4) ; - . += 0x400; - __scratch_area_top__ = .; - } > SCRATCH_RAM - - /* MAIN DATA SECTION */ - .uninit_RESERVED : ALIGN(4) - { - KEEP(*(.bss.$RESERVED*)) - . = ALIGN(4) ; - _end_uninit_RESERVED = .; - } > RAM0 - - /* Main DATA section (RAM0) */ - .data : ALIGN(4) - { - FILL(0xff) - _data = . ; - *(vtable) - *(.ramfunc*) - *(.data*) - - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP(*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - - . = ALIGN(4); - /* init data */ - __init_array_start = . ; - KEEP(*(SORT(.init_array.*))) - KEEP(*(.init_array)) - __init_array_end = . ; - - . = ALIGN(4); - /* finit data */ - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP(*(SORT(.fini_array.*))) - KEEP(*(.fini_array)) - PROVIDE_HIDDEN (__fini_array_end = .); - - KEEP(*(.jcr*)) - - . = ALIGN(4) ; - _edata = . ; - } > RAM0 AT>Flash640 - - __VECTOR_RAM = __VECTOR_RAM__; - __RAM_VECTOR_TABLE_SIZE_BYTES = DEFINED(__ram_vector_table__) ? (__interrupts_ram_end__ - __interrupts_ram_start__) : 0x0; - - /* MAIN BSS SECTION */ - .bss (NOLOAD) : ALIGN(4) - { - _bss = .; - *(.bss*) - *(COMMON) - *(g_u32NwkFrameCounter) - . = ALIGN(4) ; - _ebss = .; - - PROVIDE(end = .); - } > RAM0 - - /* BSS section for MAC buffers */ - .bss_MAC (NOLOAD) : ALIGN(4) - { - /* MAC buffer section: must be within 128kB block. __mac_buffer_base is - defined further down to be on 128kB alignment */ - __mac_buffer_start = .; - *(.mac_buffer) - - . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ - } > RAM0 - - /* BSS section for unretained contents */ - .bss_discard (NOLOAD) : ALIGN(4) - { - *(.discard.bss.pdm) - - . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ - } > RAM0 - - /* DEFAULT NOINIT SECTION */ - .noinit (NOLOAD): ALIGN(4) - { - _noinit = .; - *(.noinit*) - . = ALIGN(4) ; - _end_noinit = .; - } > RAM0 - - /* end of firmware RAM to be retained in power down mode */ - _end_fw_retention = .; - - /* non retained RAM section */ - /* stack for rom boot during warm resume */ - .boot_resume_stack (NOLOAD): ALIGN(4) - { - _boot_resume_stack = .; - *(.boot_resume_stack*) - . += BOOT_RESUME_STACK_SIZE; - . = ALIGN(4) ; - _end_boot_resume_stack = .; - } > RAM0 - - __nv_storage_end_address = NV_STORAGE_END_ADDRESS; - __nv_storage_start_address = NV_STORAGE_START_ADDRESS; - - PROVIDE(_vStackTop = __top_RAM1); - PROVIDE(__mac_buffer_base = (__mac_buffer_start & 0xfffe0000)); - PROVIDE(BOOT_GetStartPowerMode = 0x03000e9d); - PROVIDE(ROM_GetFlash = 0x03000e0d); - PROVIDE(pmc_reset_get_cause = 0x030046e9); - PROVIDE(psector_ReadIeee802_15_4_MacId1 = 0x030053b1); - PROVIDE(Chip_LOWPOWER_ChipSoftwareReset = 0x03003fa1); - PROVIDE(_pvHeapStart = _heap); - PROVIDE(_pvHeapLimit = _pvHeapStart + (HEAP_SIZE)); - PROVIDE(_scratch_buf_start = __scratch_area_start__); - PROVIDE(_scratch_buf_end = __scratch_area_top__); - - __StackLimit = _vStackTop - STACK_SIZE; - ASSERT(__StackLimit >= _end_heap, "Stack and heap spaces are overlapping!") - - __MATTER_FACTORY_DATA_START = FACTORY_DATA_START_ADDRESS; - __MATTER_FACTORY_DATA_SIZE = m_factory_data_size; - - /* The .ro_version section inside SSBL is set after the .m_interrupts sections, - * which is assumed to never change, so the offset remains the same across different - * SSBL versions. This symbol is used in Matter Application to retrieve the SSBL version. */ - __MATTER_SSBL_VERSION_START = 0x00000120; - - ASSERT(((m_app_start + m_app_size + m_app_meta_data + m_factory_data_size + m_flash_config_size) <= m_int_flash_size), - "Internal flash capacity exceeded") - -} diff --git a/examples/platform/nxp/k32w/k32w0/app/project_include/OpenThreadConfig.h b/examples/platform/nxp/k32w/k32w0/app/project_include/OpenThreadConfig.h deleted file mode 100644 index d76a51a6fbb55b..00000000000000 --- a/examples/platform/nxp/k32w/k32w0/app/project_include/OpenThreadConfig.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * - * Copyright (c) 2020 Google LLC. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * Overrides to default OpenThread configuration. - * - */ - -#include "openthread-core-k32w061-config.h" - -#pragma once - -// Disable the Nxp-supplied OpenThread logging facilities -// and use the facilities provided by the Device Layer -// (see src/platform/K32W/Logging.cpp). -#undef OPENTHREAD_CONFIG_LOG_OUTPUT -#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_APP - -// When operating in a less than ideal RF environment, having a more forgiving configuration -// of OpenThread makes thread a great deal more reliable. -#undef OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_MAX_RETRY_DELAY -#define OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_MAX_RETRY_DELAY 120 // default is 28800 - -#undef OPENTHREAD_CONFIG_MAC_DEFAULT_MAX_FRAME_RETRIES_DIRECT -#define OPENTHREAD_CONFIG_MAC_DEFAULT_MAX_FRAME_RETRIES_DIRECT 15 // default is 3 - -#undef OPENTHREAD_CONFIG_MAC_DEFAULT_MAX_FRAME_RETRIES_INDIRECT -#define OPENTHREAD_CONFIG_MAC_DEFAULT_MAX_FRAME_RETRIES_INDIRECT 1 // default is 0 - -#undef OPENTHREAD_CONFIG_MAC_MAX_TX_ATTEMPTS_INDIRECT_POLLS -#define OPENTHREAD_CONFIG_MAC_MAX_TX_ATTEMPTS_INDIRECT_POLLS 16 // default is 4 - -// Enable periodic parent search to speed up finding a better parent. -#undef OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE -#define OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE 1 // default is 0 - -#undef OPENTHREAD_CONFIG_PARENT_SEARCH_RSS_THRESHOLD -#define OPENTHREAD_CONFIG_PARENT_SEARCH_RSS_THRESHOLD -45 // default is -65 - -#undef OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH -#define OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH 1 // default is 0 - -// Use smaller maximum interval to speed up reattaching. -#undef OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_MAXIMUM_INTERVAL -#define OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_MAXIMUM_INTERVAL (60 * 10 * 1000) // default 1200000 ms - -// disable unused features -#undef OPENTHREAD_CONFIG_COAP_API_ENABLE -#define OPENTHREAD_CONFIG_COAP_API_ENABLE 0 - -#undef OPENTHREAD_CONFIG_JOINER_ENABLE -#define OPENTHREAD_CONFIG_JOINER_ENABLE 0 - -#undef OPENTHREAD_CONFIG_COMMISSIONER_ENABLE -#define OPENTHREAD_CONFIG_COMMISSIONER_ENABLE 0 - -#undef OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE -#define OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE 0 - -#undef OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE -#define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE 0 - -#undef OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE -#define OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE 0 - -#undef OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE -#define OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE 0 - -#undef OPENTHREAD_CONFIG_TCP_ENABLE -#define OPENTHREAD_CONFIG_TCP_ENABLE 0 - -#undef OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE -#define OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 0 - -#undef OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE -#define OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE 0 - -#undef OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS -#define OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS 44 - -#undef OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE -#define OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE 0 - -#undef OPENTHREAD_CONFIG_SRP_SERVER_ENABLE -#define OPENTHREAD_CONFIG_SRP_SERVER_ENABLE 0 - -#undef OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE -#define OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE 0 - -#define UART_USE_SERIAL_MGR 1 -#define UART_USE_SERIAL_MGR_LOG 1 - -// #define OPENTHREAD_CONFIG_LOG_LEVEL OT_LOG_LEVEL_DEBG - -// Use the NXP-supplied default platform configuration for remainder -// of OpenThread config options. -// -// NB: This file gets included during the build of OpenThread. Hence -// it cannot use "openthread" in the path to the included file. -// diff --git a/examples/platform/nxp/k32w/k32w0/app/support/BUILD.gn b/examples/platform/nxp/k32w/k32w0/app/support/BUILD.gn deleted file mode 100644 index 7b10c468a02fe6..00000000000000 --- a/examples/platform/nxp/k32w/k32w0/app/support/BUILD.gn +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright (c) 2020 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. - -import("//build_overrides/chip.gni") -import("//build_overrides/nxp_sdk.gni") - -config("support_config") { - include_dirs = [ "../../../../.." ] - - # Link options that provides replace dynamic memory operations in standard - # library with the FreeRTOS malloc in platform code. - ldflags = [ - # memory allocation -- these must be re-entrant and do locking - "-Wl,--wrap=malloc", - "-Wl,--wrap=free", - "-Wl,--wrap=realloc", - "-Wl,--wrap=calloc", - "-Wl,--wrap=MemoryAlloc", - - # Wrap these in case internal newlib call them (e.g. strdup will) - # directly call _malloc_r) - "-Wl,--wrap=_malloc_r", - "-Wl,--wrap=_realloc_r", - "-Wl,--wrap=_free_r", - "-Wl,--wrap=_calloc_r", - ] -} - -source_set("freertos_mbedtls_utils") { - sources = [ - "FreeRtosHooks.c", - "FreeRtosHooks.h", - "Memconfig.cpp", - ] - - deps = [ "${chip_root}/src/lib/support" ] - - cflags = [ "-Wconversion" ] - - public_configs = [ ":support_config" ] -} diff --git a/examples/platform/nxp/k32w/k32w0/app/support/FreeRtosHooks.c b/examples/platform/nxp/k32w/k32w0/app/support/FreeRtosHooks.c deleted file mode 100644 index 59cae3f6d14cf9..00000000000000 --- a/examples/platform/nxp/k32w/k32w0/app/support/FreeRtosHooks.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * - * Copyright (c) 2020 Google LLC. - * 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 "FreeRtosHooks.h" - -#include "FreeRTOS.h" -#include "semphr.h" - -#include <assert.h> - -#include <stdio.h> -#include <string.h> - -#include "PDM.h" -#include "PWR_Interface.h" -#include "TimersManager.h" -#include "board.h" -#include "pdm_ram_storage_glue.h" - -/* Bluetooth Low Energy */ -#include "ble_config.h" -#include "l2ca_cb_interface.h" - -#include "controller_interface.h" - -#if defined gLoggingActive_d && (gLoggingActive_d > 0) -#include "dbg_logging.h" -#ifndef DBG_APP -#define DBG_APP 0 -#endif -#define APP_DBG_LOG(fmt, ...) \ - if (DBG_APP) \ - do \ - { \ - DbgLogAdd(__FUNCTION__, fmt, VA_NUM_ARGS(__VA_ARGS__), ##__VA_ARGS__); \ - } while (0); -#else -#define APP_DBG_LOG(...) -#endif - -#if (configUSE_TICKLESS_IDLE != 0) -#define DBG_PostStepTickAssess 0 -#if DBG_PostStepTickAssess && !gTimestampUseWtimer_c -#error "gTimestampUseWtimer_c required for DBG_PostStepTickAssess" -#endif -#if defined(gPWR_FreqScalingWFI) && (gPWR_FreqScalingWFI != 0) -/* this MACRO is required when gPWR_FreqScalingWFI is not equal to zero (system clock frequency - reduced in WFI) */ -#define App_SuppressTickInStopMode 1 -#else -#define App_SuppressTickInStopMode 0 -#endif -#if gPWR_CpuClk_48MHz -/* for systick accuracy, this is recommended to enable FRO calibration */ -#define gApp_SystemClockCalibration 1 -#endif -#endif - -#define PDM_MAX_WRITES_INFINITE 0xFF - -static inline void mutex_init(mbedtls_threading_mutex_t * p_mutex) -{ - assert(p_mutex != NULL); - *p_mutex = xSemaphoreCreateMutex(); - assert(*p_mutex != NULL); -} - -static inline void mutex_free(mbedtls_threading_mutex_t * p_mutex) -{ - assert(p_mutex != NULL); - assert(*p_mutex != NULL); - vSemaphoreDelete(*p_mutex); -} - -static inline int mutex_lock(mbedtls_threading_mutex_t * p_mutex) -{ - assert(p_mutex != NULL); - assert(*p_mutex != NULL); - return xSemaphoreTake(*p_mutex, portMAX_DELAY) != pdTRUE; -} - -static inline int mutex_unlock(mbedtls_threading_mutex_t * p_mutex) -{ - assert(p_mutex != NULL); - assert(*p_mutex != NULL); - return xSemaphoreGive(*p_mutex) != pdTRUE; -} - -void freertos_mbedtls_mutex_init(void) -{ - mbedtls_threading_set_alt(mutex_init, mutex_free, mutex_lock, mutex_unlock); -} - -void freertos_mbedtls_mutex_free(void) -{ - mbedtls_threading_free_alt(); -} - -#if (configUSE_TICKLESS_IDLE != 0) - -/* - * Setup the systick timer to generate the tick interrupts at the required - * frequency. - */ -void vPortSetupTimerInterrupt(void) -{ - /* Stop and clear the SysTick. */ - SysTick->CTRL = 0UL; - SysTick->VAL = 0UL; - -#if DBG_PostStepTickAssess - tickless_SystickCheckDriftInit(); -#endif - - /* configure module for tickless mode */ - tickless_init(); - -#if gApp_SystemClockCalibration - /* calibration on the internal FRO48MHz clock - this clock is inaccurate (2%), - * so it needs calibration if we want the systick to be accurate to less - * than 500pp. */ - tickless_StartFroCalibration(); -#endif - - /* Configure SysTick to interrupt at the requested rate. */ - SysTick_Config(CLOCK_GetFreq(kCLOCK_CoreSysClk) / configTICK_RATE_HZ); -} - -void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime) -{ - tmrlp_tickless_systick_t lp_ctx; - APP_DBG_LOG("xExpectedIdleTime = %d ticks %d ms", xExpectedIdleTime, xExpectedIdleTime * portTICK_PERIOD_MS); - OSA_InterruptDisable(); - - /* Do not go to sleep, lowpower or WFI if there is a pending task to schedule - * Scheduler is suspended when calling vPortSuppressTicksAndSleep, - * as interrupt are disabled if one is pending, eTaskConfirmSleepModeStatus - * will prevent sleep. - */ - if (eTaskConfirmSleepModeStatus() == eAbortSleep) - { - APP_DBG_LOG("task to schedule"); - /* Do nothing */ - } -#if gApp_SystemClockCalibration - /* Prevent lowpower / tickless mode if cal ongoing - get estimated core freq */ - else if (tickless_EstimateCoreClockFreq()) - { - /* can eventually enter sleep or re evaluate on next idle loop, the calibration shall take 4 ms average */ - // PWR_EnterSleep(); - } -#endif - - /* Do not go to power down if: - * - the RTOS is expecting a wake-up too close to the current date - * To worth a power down the xExpectedIdleTime should be - * > to 2 rtos tick (which includes residual_count worst margin + carry after wake-up worst margin) - * + enter/exist power down duration converted in RTOS tick - * - power down is not allowed - */ - else if ((xExpectedIdleTime > - (2 + ((PWR_SYSTEM_EXIT_LOW_POWER_DURATION_MS + PWR_SYSTEM_ENTER_LOW_POWER_DURATION_MS) / portTICK_PERIOD_MS) + 1))) - { - int result = PWR_CheckIfDeviceCanGoToSleepExt(); - if (result >= kPmPowerDown0) - { - PWR_WakeupReason_t wakeupReason; - lp_ctx.exitTicklessDuration32kTick = MILLISECONDS_TO_TICKS32K(PWR_SYSTEM_EXIT_LOW_POWER_DURATION_MS); - /* Tickless pre processing */ - tickless_PreProcessing(&lp_ctx, xExpectedIdleTime); - - /* Enter power down */ - wakeupReason = PWR_EnterPowerDown(); - - APP_DBG_LOG("wakeReason=%x", (uint16_t) wakeupReason.AllBits); - (void) wakeupReason; - - /* Tickless post processing */ - tickless_PostProcessing(&lp_ctx); - -#if DBG_PostStepTickAssess - if (wakeupReason.Bits.FromTMR == 1) - configASSERT(lp_ctx.idle_tick_jump == xExpectedIdleTime); - if (wakeupReason.Bits.DidPowerDown == 1) - configASSERT((wakeupReason.AllBits & ~0x8000U) != 0); -#endif - } - else if ((result == kPmSleep) || (result < 0)) - { -#if App_SuppressTickInStopMode - lp_ctx.exitTicklessDuration32kTick = 0; - /* Tickless pre processing */ - tickless_PreProcessing(&lp_ctx, xExpectedIdleTime); -#endif - - PWR_EnterSleep(); - -#if App_SuppressTickInStopMode - /* Tickless post processing */ - tickless_PostProcessing(&lp_ctx); -#endif - } - } - else - { -#if App_SuppressTickInStopMode - lp_ctx.exitTicklessDuration32kTick = 0; - /* Tickless pre processing */ - tickless_PreProcessing(&lp_ctx, xExpectedIdleTime); -#endif - - PWR_EnterSleep(); - -#if App_SuppressTickInStopMode - /* Tickless post processing */ - tickless_PostProcessing(&lp_ctx); -#endif - } - -#if DBG_PostStepTickAssess - tickless_SystickCheckDrift(); -#endif - - OSA_InterruptEnable(); -} -#endif /* (configUSE_TICKLESS_IDLE != 0) */ - -static void BOARD_ActionOnIdle(void) -{ -#if ((defined gTcxo32k_ModeEn_c) && (gTcxo32k_ModeEn_c != 0)) - BOARD_tcxo32k_compensation_run(2, 0); -#endif -#if ((defined gTcxo32M_ModeEn_c) && (gTcxo32M_ModeEn_c != 0)) - BOARD_tcxo32M_compensation_run(2, 10); /* 2 degrees - wait for 10us */ -#endif -} - -extern void OTAIdleActivities(void); -extern bool AppHaveBLEConnections(void); - -void vApplicationIdleHook(void) -{ -#if PDM_SAVE_IDLE - /* While in BLE connection during commissioning, PDM saves should be paused */ - if (!AppHaveBLEConnections()) - { - FS_vIdleTask(PDM_MAX_WRITES_INFINITE); - } -#endif - - OTAIdleActivities(); - -#if gAdcUsed_d - BOARD_ADCMeasure(); -#endif - - BOARD_ActionOnIdle(); -} diff --git a/examples/platform/nxp/k32w/k32w0/app/support/FreeRtosHooks.h b/examples/platform/nxp/k32w/k32w0/app/support/FreeRtosHooks.h deleted file mode 100644 index a27f72d498f81d..00000000000000 --- a/examples/platform/nxp/k32w/k32w0/app/support/FreeRtosHooks.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * Copyright (c) 2020 Nest Labs, Inc. - * 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 - -typedef void * mbedtls_threading_mutex_t; - -extern void mbedtls_threading_set_alt(void (*mutex_init)(mbedtls_threading_mutex_t *), - void (*mutex_free)(mbedtls_threading_mutex_t *), - int (*mutex_lock)(mbedtls_threading_mutex_t *), - int (*mutex_unlock)(mbedtls_threading_mutex_t *)); - -extern void mbedtls_threading_free_alt(void); - -#ifdef __cplusplus -extern "C" { -#endif - -/**@brief Function for initializing alternative MbedTLS mutexes to enable the usage of the FreeRTOS implementation. */ -void freertos_mbedtls_mutex_init(void); - -/**@brief Function for releasing MbedTLS alternative mutexes. */ -void freertos_mbedtls_mutex_free(void); - -#ifdef __cplusplus -} -#endif diff --git a/examples/platform/nxp/k32w/k32w0/app/support/Memconfig.cpp b/examples/platform/nxp/k32w/k32w0/app/support/Memconfig.cpp deleted file mode 100644 index e5acf5ea3ceecb..00000000000000 --- a/examples/platform/nxp/k32w/k32w0/app/support/Memconfig.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* - * - * Copyright (c) 2020-2021 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * This file contains platform specific implementations for stdlib malloc/calloc/realloc/free - * functions, so that CHIPPlatformMemory* works as intended with the platform's heap. - */ - -#include "FreeRTOS.h" -#include "task.h" -#include <cstring> -#include <stdint.h> -#include <stdlib.h> - -#ifndef NDEBUG -#include <atomic> -#include <cstdio> -#endif - -#include <src/lib/support/logging/CHIPLogging.h> - -#if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC -#include <dmalloc.h> -#include <lib/support/SafeInt.h> -#endif // CHIP_CONFIG_MEMORY_DEBUG_DMALLOC - -/* Assumes 8bit bytes! */ -#define heapBITS_PER_BYTE ((size_t) 8) - -/* Define the linked list structure. This is used to link free blocks in order -of their memory address. */ -typedef struct A_BLOCK_LINK -{ - struct A_BLOCK_LINK * pxNextFreeBlock; /*<< The next free block in the list. */ - size_t xBlockSize; /*<< The size of the free block. */ -} BlockLink_t; - -/* The size of the structure placed at the beginning of each allocated memory -block must by correctly byte aligned. */ -static const size_t xHeapStructSize = - (sizeof(BlockLink_t) + ((size_t) (portBYTE_ALIGNMENT - 1))) & ~((size_t) portBYTE_ALIGNMENT_MASK); - -/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize -member of an BlockLink_t structure is set then the block belongs to the -application. When the bit is free the block is still part of the free heap -space. */ -static size_t xBlockAllocatedBit = ((size_t) 1) << ((sizeof(size_t) * heapBITS_PER_BYTE) - 1); - -extern "C" { - -/* xPortMallocUsableSize relies on heap4 implementation. -It returns the size of an allocated block and it is -called by __wrap_realloc. -Thus it is validated in __wrap_realloc function that the allocated size -of the old_ptr is smaller than the allocated size of new_ptr */ -size_t xPortMallocUsableSize(void * pv) -{ - uint8_t * puc = (uint8_t *) pv; - BlockLink_t * pxLink; - void * voidp; - size_t sz = 0; - - if (pv != NULL) - { - vTaskSuspendAll(); - { - /* The memory being checked will have an BlockLink_t structure immediately - before it. */ - puc -= xHeapStructSize; - - /* This casting is to keep the compiler from issuing warnings. */ - voidp = (void *) puc; - pxLink = (BlockLink_t *) voidp; - - /* Check if the block is actually allocated. */ - configASSERT((pxLink->xBlockSize & xBlockAllocatedBit) != 0); - configASSERT(pxLink->pxNextFreeBlock == NULL); - - sz = (pxLink->xBlockSize & ~xBlockAllocatedBit) - xHeapStructSize; - } - (void) xTaskResumeAll(); - } - - return sz; -} - -void * __wrap_malloc(size_t size) -{ - return pvPortMalloc(size); -} - -void __wrap_free(void * ptr) -{ - vPortFree(ptr); -} - -void * __wrap_calloc(size_t num, size_t size) -{ - size_t total_size = num * size; - - // Handle overflow from (num * size) - if ((size != 0) && ((total_size / size) != num)) - { - return nullptr; - } - - void * ptr = pvPortMalloc(total_size); - if (ptr) - { - memset(ptr, 0, total_size); - } - else - { - ChipLogError(DeviceLayer, "__wrap_calloc: Could not allocate memory!"); - } - - return ptr; -} - -void * __wrap_realloc(void * ptr, size_t new_size) -{ - - void * new_ptr = NULL; - - if (new_size) - { - size_t old_ptr_size = xPortMallocUsableSize(ptr); - if (new_size <= old_ptr_size) - { - /* Return old pointer if the newly allocated size is smaller - or equal to the allocated size for old_ptr */ - return ptr; - } - - /* if old_ptr is NULL, then old_ptr_size is zero and new_ptr will be returned */ - new_ptr = pvPortMalloc(new_size); - - if (!new_ptr) - { - ChipLogError(DeviceLayer, "__wrap_realloc: Could not allocate memory!"); - return NULL; - } - - memset(reinterpret_cast<uint8_t *>(new_ptr) + old_ptr_size, 0, (new_size - old_ptr_size)); - memcpy(new_ptr, ptr, old_ptr_size); - } - - vPortFree(ptr); - - return new_ptr; -} - -void * __wrap__malloc_r(void * REENT, size_t size) -{ - return __wrap_malloc(size); -} - -void __wrap__free_r(void * REENT, void * ptr) -{ - __wrap_free(ptr); -} - -void * __wrap__realloc_r(void * REENT, void * ptr, size_t new_size) -{ - return __wrap_realloc(ptr, new_size); -} - -} // extern "C" diff --git a/examples/platform/nxp/k32w/k32w0/args.gni b/examples/platform/nxp/k32w/k32w0/args.gni deleted file mode 100644 index 5af5e1d18b3123..00000000000000 --- a/examples/platform/nxp/k32w/k32w0/args.gni +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (c) 2020 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. - -import("//build_overrides/chip.gni") - -import("${chip_root}/src/platform/nxp/k32w/k32w0/args.gni") - -openthread_core_config_deps = [] -openthread_core_config_deps = [ "${chip_root}/examples/platform/nxp/k32w/k32w0:openthread_core_config_k32w0_chip_examples" ] - -chip_ble_project_config_include = "<CHIPProjectConfig.h>" -chip_device_project_config_include = "<CHIPProjectConfig.h>" -chip_project_config_include = "<CHIPProjectConfig.h>" -chip_inet_project_config_include = "<CHIPProjectConfig.h>" -chip_system_project_config_include = "<CHIPProjectConfig.h>" - -chip_system_config_provide_statistics = false -chip_with_nlfaultinjection = true - -chip_system_config_use_open_thread_inet_endpoints = true -chip_with_lwip = false diff --git a/examples/platform/nxp/k32w/k32w0/common/CustomFactoryDataProvider.cpp b/examples/platform/nxp/k32w/k32w0/common/CustomFactoryDataProvider.cpp deleted file mode 100644 index 7f2f6d9bc0cad0..00000000000000 --- a/examples/platform/nxp/k32w/k32w0/common/CustomFactoryDataProvider.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * 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 "CustomFactoryDataProvider.h" - -namespace chip { -namespace DeviceLayer { - -static constexpr size_t kMaxLengthCustomId1 = 10; -static constexpr size_t kMaxLengthCustomId2 = 50; -static constexpr size_t kMaxLengthCustomId3 = 100; - -CustomFactoryDataProvider::CustomFactoryDataProvider() -{ - // Custom ids should be from a range that does not overlap with the standard factory data range. - static_assert((uint16_t) CustomFactoryIds::kCustomId1 >= (uint16_t) FactoryDataProvider::FactoryDataId::kMaxId); -} - -CHIP_ERROR CustomFactoryDataProvider::ParseFunctionExample() -{ - uint8_t data_buf[kMaxLengthCustomId1]; - MutableByteSpan buffer(data_buf); - memset(buffer.data(), 0, buffer.size()); - uint16_t userDataSize = 0; - // A user can use FactoryDataProvider::SearchForId to read an id from internal - // flash factory data section. - auto * provider = static_cast<FactoryDataProvider *>(DeviceLayer::GetDeviceInstanceInfoProvider()); - ReturnErrorOnFailure((provider != nullptr) ? CHIP_NO_ERROR : CHIP_ERROR_INVALID_ADDRESS); - ReturnErrorOnFailure(provider->SearchForId(CustomFactoryIds::kCustomId1, buffer.data(), buffer.size(), userDataSize)); - - // Data should now be ready for custom parsing. - - return CHIP_NO_ERROR; -} - -} // namespace DeviceLayer -} // namespace chip diff --git a/examples/platform/nxp/k32w/k32w0/common/CustomFactoryDataProvider.h b/examples/platform/nxp/k32w/k32w0/common/CustomFactoryDataProvider.h deleted file mode 100644 index dfb722d67fdc11..00000000000000 --- a/examples/platform/nxp/k32w/k32w0/common/CustomFactoryDataProvider.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * 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. - */ -#pragma once - -#include <platform/nxp/k32w/k32w0/FactoryDataProviderImpl.h> - -namespace chip { -namespace DeviceLayer { - -/** - * @brief This is an example class that extends the platform factory data provider - * to support custom functionality. Users should implement their own custom - * provider based on this example. - */ - -class CustomFactoryDataProvider -{ -public: - /* Custom IDs should start from at least FactoryDataId::kMaxId, which is - * the next available valid ID. Last default ID is kMaxId - 1. - */ - enum CustomFactoryIds - { - kCustomId1 = 200, // Random id that is greater than FactoryDataId::kMaxId. - kCustomId2, - kCustomId3, - kCustomMaxId - }; - - CustomFactoryDataProvider(); - - /* Declare here custom functions to be implemented. */ - CHIP_ERROR ParseFunctionExample(); -}; - -} // namespace DeviceLayer -} // namespace chip diff --git a/examples/platform/nxp/k32w/k32w0/doc/images/ssbl_bin.JPG b/examples/platform/nxp/k32w/k32w0/doc/images/ssbl_bin.JPG deleted file mode 100644 index fb871d45aeb5f9..00000000000000 Binary files a/examples/platform/nxp/k32w/k32w0/doc/images/ssbl_bin.JPG and /dev/null differ diff --git a/examples/platform/nxp/k32w/k32w0/doc/images/ssbl_multi_image.JPG b/examples/platform/nxp/k32w/k32w0/doc/images/ssbl_multi_image.JPG deleted file mode 100644 index 31449b25cf269e..00000000000000 Binary files a/examples/platform/nxp/k32w/k32w0/doc/images/ssbl_multi_image.JPG and /dev/null differ diff --git a/examples/platform/nxp/k32w/k32w0/doc/images/ssbl_select.JPG b/examples/platform/nxp/k32w/k32w0/doc/images/ssbl_select.JPG deleted file mode 100644 index 79ea51b62698e8..00000000000000 Binary files a/examples/platform/nxp/k32w/k32w0/doc/images/ssbl_select.JPG and /dev/null differ diff --git a/examples/platform/nxp/k32w/k32w0/doc/images/ssbl_simple_hash.JPG b/examples/platform/nxp/k32w/k32w0/doc/images/ssbl_simple_hash.JPG deleted file mode 100755 index 9ec701b0bb1d86..00000000000000 Binary files a/examples/platform/nxp/k32w/k32w0/doc/images/ssbl_simple_hash.JPG and /dev/null differ diff --git a/examples/platform/nxp/k32w/k32w0/scripts/demo_generated_factory_data/demo_factory_data_dut1.bin b/examples/platform/nxp/k32w/k32w0/scripts/demo_generated_factory_data/demo_factory_data_dut1.bin deleted file mode 100644 index 44370e1deb3a2f..00000000000000 Binary files a/examples/platform/nxp/k32w/k32w0/scripts/demo_generated_factory_data/demo_factory_data_dut1.bin and /dev/null differ diff --git a/examples/platform/nxp/k32w/k32w0/scripts/demo_generated_factory_data/demo_factory_data_dut2.bin b/examples/platform/nxp/k32w/k32w0/scripts/demo_generated_factory_data/demo_factory_data_dut2.bin deleted file mode 100644 index f47a8b4c53a908..00000000000000 Binary files a/examples/platform/nxp/k32w/k32w0/scripts/demo_generated_factory_data/demo_factory_data_dut2.bin and /dev/null differ diff --git a/examples/platform/nxp/k32w/k32w0/scripts/detokenizer.py b/examples/platform/nxp/k32w/k32w0/scripts/detokenizer.py deleted file mode 100644 index 6f76903e97f8a5..00000000000000 --- a/examples/platform/nxp/k32w/k32w0/scripts/detokenizer.py +++ /dev/null @@ -1,148 +0,0 @@ -import argparse -import os -import sys - -import pw_tokenizer -import serial - - -def parse_args(): - """Parse input arguments - - Return: - parsed arguments struncture - """ - - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='type') - subparsers.required = True - - parser_file = subparsers.add_parser('file') - parser_file.add_argument( - "-i", "--input", help="Input file name.", required=True) - parser_file.add_argument( - "-d", "--database", help="Token database.", required=True) - parser_file.add_argument( - "-o", "--output", help="Output file name.", required=True) - - parser_file = subparsers.add_parser('serial') - parser_file.add_argument( - "-i", "--input", help="Input serial port name.", required=True) - parser_file.add_argument( - "-d", "--database", help="Token database.", required=True) - parser_file.add_argument( - "-o", "--output", help="Output file name. Write to stdout and to file.") - - return parser.parse_args() - - -def decode_string(tstr, detok): - """Decodes a single token. - - Args: - tstr - encoded input string - detok - detokenizer - - Return: - decoded string or None - """ - try: - t = bytes.fromhex(tstr) - s = str(detok.detokenize(t)) - - if s.find('$') == 0: - return None - return s - except ValueError: - return None - - -def decode_serial(serialport, outfile, database): - """Decodes logs from serial port. - - Args: - infile - path to input file - outfile - path to output file - database - path to token database - """ - - detokenizer = pw_tokenizer.Detokenizer(database) - input = serial.Serial(serialport, 115200, timeout=None) - - output = None - if outfile: - output = open(outfile, 'w') - - if input: - - try: - while (True): - # read line from serial port and ascii decode - line = input.readline().decode('ascii').strip() - # find token start and detokenize - idx = line.rfind(']') - dstr = decode_string(line[idx + 1:], detokenizer) - if dstr: - line = line[:idx+1] + dstr - print(line, file=sys.stdout) - if output: - print(line, file=output) - except Exception: - print("Serial error or program closed", file=sys.stderr) - - if output: - input.close() - output.close() - - else: - print("Invalid or closed serial port.", file=sys.stderr) - - -def decode_file(infile, outfile, database): - """Decodes logs from input file. - - Args: - infile - path to input file - outfile - path to output file - database - path to token database - """ - - if os.path.isfile(infile): - - detokenizer = pw_tokenizer.Detokenizer(database) - - output = open(outfile, 'w') - - with open(infile, 'rb') as file: - for line in file: - try: - # ascii decode line - # serial terminals may include non ascii characters - line = line.decode('ascii').strip() - except Exception: - continue - # find token start and detokenize - idx = line.rfind(']') - dstr = decode_string(line[idx + 1:], detokenizer) - if dstr: - line = line[:idx+1] + dstr - print(line, file=output) - output.close() - - else: - print("File does not exist or is not a file.", file=sys.stderr) - - -def detokenize_input(): - - args = parse_args() - - if args.type == 'file': - decode_file(args.input, args.output, args.database) - if args.type == 'serial': - decode_serial(args.input, args.output, args.database) - - -if __name__ == '__main__': - detokenize_input() - sys.exit(0) diff --git a/examples/platform/nxp/k32w/k32w0/scripts/sign-outdir.py b/examples/platform/nxp/k32w/k32w0/scripts/sign-outdir.py deleted file mode 100644 index 8660b4bc5f4b06..00000000000000 --- a/examples/platform/nxp/k32w/k32w0/scripts/sign-outdir.py +++ /dev/null @@ -1,37 +0,0 @@ -import argparse -import os -import subprocess - - -def main(args): - if "NXP_K32W0_SDK_ROOT" in os.environ and os.environ["NXP_K32W0_SDK_ROOT"] != "": - sign_images_path = os.environ["NXP_K32W0_SDK_ROOT"] + "/tools/imagetool/sign_images.sh" - else: - sign_images_path = os.path.abspath( - __file__ + "/../../../../../../../third_party/nxp/k32w0_sdk/repo/core/tools/imagetool/sign_images.sh") - - # Give execute permission if needed - if os.access(sign_images_path, os.X_OK) is False: - os.chmod(sign_images_path, 0o766) - - # Convert script to unix format if needed - subprocess.call("(file " + sign_images_path + " | grep CRLF > /dev/null) && (dos2unix " + sign_images_path + ")", shell=True) - - # Call sign_images.sh script with the output directory - cmd = sign_images_path + " " + os.getcwd() - if args.simple_hash: - cmd = cmd + " -SimpleHashVerification" - - subprocess.call(cmd, shell=True) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument( - "--simple-hash", - help="When enabled, adds a hash of the whole image at the end of the binary.", - action="store_true" - ) - args = parser.parse_args() - - main(args) diff --git a/examples/platform/nxp/k32w/k32w0/util/LEDWidget.cpp b/examples/platform/nxp/k32w/k32w0/util/LEDWidget.cpp deleted file mode 100644 index fec3a5b0afca70..00000000000000 --- a/examples/platform/nxp/k32w/k32w0/util/LEDWidget.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * Copyright (c) 2019 Google LLC. - * 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 "LEDWidget.h" - -#include <system/SystemClock.h> - -void LEDWidget::Init(LED_t led) -{ - mLastChangeTimeMS = 0; - mBlinkOnTimeMS = 0; - mBlinkOffTimeMS = 0; - mGPIONum = led; - mState = false; - - Set(false); -} - -void LEDWidget::Invert(void) -{ - Set(!mState); -} - -void LEDWidget::Set(bool state) -{ - mLastChangeTimeMS = mBlinkOnTimeMS = mBlinkOffTimeMS = 0; - DoSet(state); -} - -void LEDWidget::Blink(uint32_t changeRateMS) -{ - Blink(changeRateMS, changeRateMS); -} - -void LEDWidget::Blink(uint32_t onTimeMS, uint32_t offTimeMS) -{ - mBlinkOnTimeMS = onTimeMS; - mBlinkOffTimeMS = offTimeMS; - Animate(); -} - -void LEDWidget::Animate() -{ - if (mBlinkOnTimeMS != 0 && mBlinkOffTimeMS != 0) - { - uint64_t nowMS = chip::System::SystemClock().GetMonotonicMilliseconds64().count(); - uint64_t stateDurMS = mState ? mBlinkOnTimeMS : mBlinkOffTimeMS; - uint64_t nextChangeTimeMS = mLastChangeTimeMS + stateDurMS; - - if (nextChangeTimeMS < nowMS) - { - DoSet(!mState); - mLastChangeTimeMS = nowMS; - } - } -} - -void LEDWidget::DoSet(bool state) -{ - mState = state; - - if (state) - { - LED_TurnOnLed(mGPIONum); - } - else - { - LED_TurnOffLed(mGPIONum); - } -} diff --git a/examples/platform/nxp/k32w/k32w0/util/include/LEDWidget.h b/examples/platform/nxp/k32w/k32w0/util/include/LEDWidget.h deleted file mode 100644 index f725eeaa9d74f5..00000000000000 --- a/examples/platform/nxp/k32w/k32w0/util/include/LEDWidget.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * - * Copyright (c) 2020 Google LLC. - * 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 "LED.h" - -#pragma once - -class LEDWidget -{ -public: - void Init(LED_t gpioNum); - void Set(bool state); - void Invert(void); - void Blink(uint32_t changeRateMS); - void Blink(uint32_t onTimeMS, uint32_t offTimeMS); - void Animate(); - -private: - uint64_t mLastChangeTimeMS; - uint32_t mBlinkOnTimeMS; - uint32_t mBlinkOffTimeMS; - LED_t mGPIONum; - bool mState; - - void DoSet(bool state); -}; diff --git a/examples/platform/nxp/k32w/k32w0/common/README.md b/examples/platform/nxp/k32w0/doc/CustomFactoryDataProvider.md similarity index 100% rename from examples/platform/nxp/k32w/k32w0/common/README.md rename to examples/platform/nxp/k32w0/doc/CustomFactoryDataProvider.md diff --git a/examples/platform/nxp/k32w/k32w0/doc/images/chiptool_main_screen.png b/examples/platform/nxp/k32w0/doc/images/chiptool_main_screen.png similarity index 100% rename from examples/platform/nxp/k32w/k32w0/doc/images/chiptool_main_screen.png rename to examples/platform/nxp/k32w0/doc/images/chiptool_main_screen.png diff --git a/examples/platform/nxp/k32w/k32w0/doc/images/flash_location.JPG b/examples/platform/nxp/k32w0/doc/images/flash_location.JPG similarity index 100% rename from examples/platform/nxp/k32w/k32w0/doc/images/flash_location.JPG rename to examples/platform/nxp/k32w0/doc/images/flash_location.JPG diff --git a/examples/platform/nxp/k32w/k32w0/doc/images/form_web.JPG b/examples/platform/nxp/k32w0/doc/images/form_web.JPG similarity index 100% rename from examples/platform/nxp/k32w/k32w0/doc/images/form_web.JPG rename to examples/platform/nxp/k32w0/doc/images/form_web.JPG diff --git a/examples/platform/nxp/k32w/k32w0/doc/images/k32w-dk6-connectors.jpg b/examples/platform/nxp/k32w0/doc/images/k32w-dk6-connectors.jpg similarity index 100% rename from examples/platform/nxp/k32w/k32w0/doc/images/k32w-dk6-connectors.jpg rename to examples/platform/nxp/k32w0/doc/images/k32w-dk6-connectors.jpg diff --git a/examples/platform/nxp/k32w/k32w0/doc/images/k32w-dk6.jpg b/examples/platform/nxp/k32w0/doc/images/k32w-dk6.jpg similarity index 100% rename from examples/platform/nxp/k32w/k32w0/doc/images/k32w-dk6.jpg rename to examples/platform/nxp/k32w0/doc/images/k32w-dk6.jpg diff --git a/examples/platform/nxp/k32w/k32w0/doc/images/k32w-se.jpg b/examples/platform/nxp/k32w0/doc/images/k32w-se.jpg similarity index 100% rename from examples/platform/nxp/k32w/k32w0/doc/images/k32w-se.jpg rename to examples/platform/nxp/k32w0/doc/images/k32w-se.jpg diff --git a/examples/platform/nxp/k32w/k32w0/doc/images/mcux-sdk-download.JPG b/examples/platform/nxp/k32w0/doc/images/mcux-sdk-download.JPG similarity index 100% rename from examples/platform/nxp/k32w/k32w0/doc/images/mcux-sdk-download.JPG rename to examples/platform/nxp/k32w0/doc/images/mcux-sdk-download.JPG diff --git a/examples/platform/nxp/k32w/k32w0/doc/images/nxp_hw_connectivity.JPG b/examples/platform/nxp/k32w0/doc/images/nxp_hw_connectivity.JPG similarity index 100% rename from examples/platform/nxp/k32w/k32w0/doc/images/nxp_hw_connectivity.JPG rename to examples/platform/nxp/k32w0/doc/images/nxp_hw_connectivity.JPG diff --git a/examples/platform/nxp/k32w/k32w0/doc/images/on_off_cluster.png b/examples/platform/nxp/k32w0/doc/images/on_off_cluster.png similarity index 100% rename from examples/platform/nxp/k32w/k32w0/doc/images/on_off_cluster.png rename to examples/platform/nxp/k32w0/doc/images/on_off_cluster.png diff --git a/examples/platform/nxp/k32w/k32w0/doc/images/ota_topology.JPG b/examples/platform/nxp/k32w0/doc/images/ota_topology.JPG similarity index 100% rename from examples/platform/nxp/k32w/k32w0/doc/images/ota_topology.JPG rename to examples/platform/nxp/k32w0/doc/images/ota_topology.JPG diff --git a/examples/platform/nxp/k32w/k32w0/doc/images/pdm_ext_flash.JPG b/examples/platform/nxp/k32w0/doc/images/pdm_ext_flash.JPG similarity index 100% rename from examples/platform/nxp/k32w/k32w0/doc/images/pdm_ext_flash.JPG rename to examples/platform/nxp/k32w0/doc/images/pdm_ext_flash.JPG diff --git a/examples/platform/nxp/k32w/k32w0/doc/images/power_conf.JPG b/examples/platform/nxp/k32w0/doc/images/power_conf.JPG similarity index 100% rename from examples/platform/nxp/k32w/k32w0/doc/images/power_conf.JPG rename to examples/platform/nxp/k32w0/doc/images/power_conf.JPG diff --git a/examples/platform/nxp/k32w/k32w0/doc/images/power_view.JPG b/examples/platform/nxp/k32w0/doc/images/power_view.JPG similarity index 100% rename from examples/platform/nxp/k32w/k32w0/doc/images/power_view.JPG rename to examples/platform/nxp/k32w0/doc/images/power_view.JPG diff --git a/examples/platform/nxp/k32w/k32w0/doc/images/select-sdk.JPG b/examples/platform/nxp/k32w0/doc/images/select-sdk.JPG similarity index 100% rename from examples/platform/nxp/k32w/k32w0/doc/images/select-sdk.JPG rename to examples/platform/nxp/k32w0/doc/images/select-sdk.JPG diff --git a/examples/platform/nxp/k32w/k32w0/doc/images/thread_credentials.png b/examples/platform/nxp/k32w0/doc/images/thread_credentials.png similarity index 100% rename from examples/platform/nxp/k32w/k32w0/doc/images/thread_credentials.png rename to examples/platform/nxp/k32w0/doc/images/thread_credentials.png diff --git a/gn_build.sh b/gn_build.sh index 9f6c76571da593..e9110442a52293 100755 --- a/gn_build.sh +++ b/gn_build.sh @@ -164,7 +164,7 @@ if [[ ! -d "$NXP_K32W0_SDK_ROOT" ]]; then echo "Hint: Set \$NXP_K32W0_SDK_ROOT to enable building for K32W061" else echo 'To build the K32W lock sample as a standalone project': - echo "(cd $CHIP_ROOT/examples/lock-app/nxp/k32w/k32w0; gn gen out/debug --args='$k32w_sdk_args'; ninja -C out/debug)" + echo "(cd $CHIP_ROOT/examples/lock-app/nxp/k32w0; gn gen out/debug --args='$k32w_sdk_args'; ninja -C out/debug)" fi echo diff --git a/scripts/build/builders/nxp.py b/scripts/build/builders/nxp.py index b72015f0afc677..e119a78b5e2cc2 100644 --- a/scripts/build/builders/nxp.py +++ b/scripts/build/builders/nxp.py @@ -54,7 +54,7 @@ def Name(self, os_env): def FolderName(self, os_env): if self == NxpBoard.K32W0: - return 'k32w/k32w0' + return 'k32w0' elif self == NxpBoard.K32W1: return 'k32w/k32w1' elif self == NxpBoard.RW61X: diff --git a/scripts/setup/requirements.nxp.txt b/scripts/setup/requirements.nxp.txt index a78e1f0fc6230d..615e170ce83ce4 100644 --- a/scripts/setup/requirements.nxp.txt +++ b/scripts/setup/requirements.nxp.txt @@ -1,4 +1,3 @@ crc>=7.0.0 jsonschema>=4.17.0 -pycrypto>=2.6.1 pycryptodome>=3.20.0 diff --git a/src/platform/nxp/common/legacy/BLEManagerCommon.cpp b/src/platform/nxp/common/legacy/BLEManagerCommon.cpp new file mode 100644 index 00000000000000..d9dbde88f3a614 --- /dev/null +++ b/src/platform/nxp/common/legacy/BLEManagerCommon.cpp @@ -0,0 +1,1435 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * Copyright (c) 2020 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the BLEManager singleton object + * for the K32W platforms. + */ + +/* this file behaves like a config.h, comes first */ +#include <platform/internal/CHIPDeviceLayerInternal.h> + +#include <platform/CommissionableDataProvider.h> + +#include <crypto/CHIPCryptoPAL.h> + +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + +#include <ble/Ble.h> + +#include "board.h" +#include "gatt_db_app_interface.h" +#include "gatt_db_handles.h" +#include "stdio.h" +#include "timers.h" + +#if defined(CPU_JN518X) && defined(chip_with_low_power) && (chip_with_low_power == 1) +#include "PWR_Configuration.h" +#endif + +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING +#include <platform/DeviceInstanceInfoProvider.h> +#include <setup_payload/AdditionalDataPayloadGenerator.h> +#endif + +/******************************************************************************* + * Local data types + *******************************************************************************/ +extern "C" bool_t Ble_ConfigureHostStackConfig(void); + +#if defined(chip_with_low_power) && (chip_with_low_power == 1) +extern "C" void PWR_DisallowDeviceToSleep(void); +extern "C" void PWR_AllowDeviceToSleep(void); +#endif + +using namespace ::chip; +using namespace ::chip::Ble; + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +namespace { +/******************************************************************************* + * Macros & Constants definitions + *******************************************************************************/ +/* Timeout of BLE commands */ +#define CHIP_BLE_KW_EVNT_TIMEOUT 1000 / portTICK_PERIOD_MS + +/** BLE advertisement state changed */ +#define CHIP_BLE_KW_EVNT_ADV_CHANGED 0x0001 +/** BLE advertisement command failed */ +#define CHIP_BLE_KW_EVNT_ADV_FAILED 0x0002 +/** BLE advertisement setup failed */ +#define CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED 0x0004 +/** BLE advertisement parameters setup complete */ +#define CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE 0x0008 +/** BLE advertisement data setup complete */ +#define CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE 0x0010 +/** BLE random address set */ +#define CHIP_BLE_KW_EVNT_RND_ADDR_SET 0x0020 +/** BLE Initialization complete */ +#define CHIP_BLE_KW_EVNT_INIT_COMPLETE 0x0040 +/** BLE Received a handle value confirmation from the client */ +#define CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED 0x0080 +/** BLE send indication failed */ +#define CHIP_BLE_KW_EVNT_INDICATION_FAILED 0x0100 +/** TX Power Level Set */ +#define CHIP_BLE_KW_EVNT_POWER_LEVEL_SET 0x0200 +/** Maximal time of connection without activity */ +#define CHIP_BLE_KW_CONN_TIMEOUT 60000 +/** Maximum number of pending BLE events */ +#define CHIP_BLE_EVENT_QUEUE_MAX_ENTRIES 10 + +#define LOOP_EV_BLE (0x08) + +/* controller task configuration */ +#define CONTROLLER_TASK_PRIORITY (6U) +#define CONTROLLER_TASK_STACK_SIZE (gControllerTaskStackSize_c / sizeof(StackType_t)) + +/* host task configuration */ +#define HOST_TASK_PRIORITY (4U) +#define HOST_TASK_STACK_SIZE (gHost_TaskStackSize_c / sizeof(StackType_t)) + +/* advertising configuration */ +#define BLEKW_ADV_MAX_NO (2) +#define BLEKW_SCAN_RSP_MAX_NO (2) +#define BLEKW_MAX_ADV_DATA_LEN (31) +#define CHIP_ADV_SHORT_UUID_LEN (2) + +/* FreeRTOS sw timer */ +TimerHandle_t sbleAdvTimeoutTimer; + +/* Queue used to synchronize asynchronous messages from the KW BLE tasks */ +QueueHandle_t sBleEventQueue; + +/* Used to manage asynchronous events from BLE Stack: e.g.: GAP setup finished */ +EventGroupHandle_t sEventGroup; + +TimerHandle_t connectionTimeout; + +const uint8_t ShortUUID_CHIPoBLEService[] = { 0xF6, 0xFF }; + +#if defined(chip_with_low_power) && (chip_with_low_power == 1) +static bool bleAppStopInProgress; +#endif + +BLEManagerCommon * sImplInstance = nullptr; + +} // namespace + +CHIP_ERROR BLEManagerCommon::_Init() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EventBits_t eventBits; + uint16_t attChipRxHandle[1] = { (uint16_t) value_chipoble_rx }; + +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + uint16_t attChipC3Handle[1] = { (uint16_t) value_chipoble_c3 }; +#endif + + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled; + + // Check if BLE stack is initialized + VerifyOrExit(!mFlags.Has(Flags::kK32WBLEStackInitialized), err = CHIP_ERROR_INCORRECT_STATE); + + // Initialize the Chip BleLayer. + err = BleLayer::Init(this, this, &DeviceLayer::SystemLayer()); + SuccessOrExit(err); + + /* Initialization of message wait events - + * used for receiving BLE Stack events */ + sEventGroup = xEventGroupCreate(); + VerifyOrExit(sEventGroup != NULL, err = CHIP_ERROR_INCORRECT_STATE); + + /* Prepare callback input queue.*/ + sBleEventQueue = xQueueCreate(CHIP_BLE_EVENT_QUEUE_MAX_ENTRIES, sizeof(blekw_msg_t *)); + VerifyOrExit(sBleEventQueue != NULL, err = CHIP_ERROR_INCORRECT_STATE); + + /* Create the connection timeout timer. */ + connectionTimeout = + xTimerCreate("bleTimeoutTmr", pdMS_TO_TICKS(CHIP_BLE_KW_CONN_TIMEOUT), pdFALSE, (void *) 0, blekw_connection_timeout_cb); + VerifyOrExit(connectionTimeout != NULL, err = CHIP_ERROR_INCORRECT_STATE); + + sImplInstance = GetImplInstance(); + + /* BLE platform code initialization */ + SuccessOrExit(err = InitHostController(&blekw_generic_cb)); + + /* Register the GATT server callback */ + VerifyOrExit(GattServer_RegisterCallback(blekw_gatt_server_cb) == gBleSuccess_c, err = CHIP_ERROR_INCORRECT_STATE); + + /* Wait until BLE Stack is ready */ + eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_INIT_COMPLETE, pdTRUE, pdTRUE, CHIP_BLE_KW_EVNT_TIMEOUT); + VerifyOrExit(eventBits & CHIP_BLE_KW_EVNT_INIT_COMPLETE, err = CHIP_ERROR_INCORRECT_STATE); + +#if BLE_HIGH_TX_POWER + /* Set Adv Power */ + Gap_SetTxPowerLevel(gAdvertisingPowerLeveldBm_c, gTxPowerAdvChannel_c); + eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_POWER_LEVEL_SET, pdTRUE, pdTRUE, CHIP_BLE_KW_EVNT_TIMEOUT); + VerifyOrExit(eventBits & CHIP_BLE_KW_EVNT_POWER_LEVEL_SET, err = CHIP_ERROR_INCORRECT_STATE); + + /* Set Connect Power */ + Gap_SetTxPowerLevel(gConnectPowerLeveldBm_c, gTxPowerConnChannel_c); + eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_POWER_LEVEL_SET, pdTRUE, pdTRUE, CHIP_BLE_KW_EVNT_TIMEOUT); + VerifyOrExit(eventBits & CHIP_BLE_KW_EVNT_POWER_LEVEL_SET, err = CHIP_ERROR_INCORRECT_STATE); +#endif + +#if defined(CPU_JN518X) && defined(chip_with_low_power) && (chip_with_low_power == 1) + PWR_ChangeDeepSleepMode(cPWR_PowerDown_RamRet); +#endif + + GattServer_RegisterHandlesForWriteNotifications(1, attChipRxHandle); +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + VerifyOrExit(GattServer_RegisterHandlesForReadNotifications(1, attChipC3Handle) == gBleSuccess_c, + err = CHIP_ERROR_INCORRECT_STATE); +#endif + + mFlags.Set(Flags::kK32WBLEStackInitialized); + mFlags.Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART ? true : false); + mFlags.Set(Flags::kFastAdvertisingEnabled); + + // Create FreeRTOS sw timer for BLE timeouts and interval change. + sbleAdvTimeoutTimer = xTimerCreate("BleAdvTimer", // Just a text name, not used by the RTOS kernel + pdMS_TO_TICKS(100), // == default timer period (mS) + false, // no timer reload (==one-shot) + (void *) this, // init timer id = ble obj context + BleAdvTimeoutHandler // timer callback handler + ); + VerifyOrExit(sbleAdvTimeoutTimer != NULL, err = CHIP_ERROR_INCORRECT_STATE); + +exit: + return err; +} + +uint16_t BLEManagerCommon::_NumConnections(void) +{ + return static_cast<uint16_t>(mDeviceConnected == true); +} + +bool BLEManagerCommon::_IsAdvertisingEnabled(void) +{ + return mFlags.Has(Flags::kAdvertisingEnabled); +} + +bool BLEManagerCommon::_IsAdvertising(void) +{ + return mFlags.Has(Flags::kAdvertising); +} + +CHIP_ERROR BLEManagerCommon::_SetAdvertisingEnabled(bool val) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE); + + if (mFlags.Has(Flags::kAdvertisingEnabled) != val) + { + mFlags.Set(Flags::kAdvertisingEnabled, val); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + } + +exit: + return err; +} + +CHIP_ERROR BLEManagerCommon::_SetAdvertisingMode(BLEAdvertisingMode mode) +{ + switch (mode) + { + case BLEAdvertisingMode::kFastAdvertising: + mFlags.Set(Flags::kFastAdvertisingEnabled); + break; + case BLEAdvertisingMode::kSlowAdvertising: { + // We are in FreeRTOS timer service context, which is a default daemon task and has + // the highest priority. Stop advertising should be scheduled to run from Matter task. + mFlags.Clear(Flags::kFastAdvertisingEnabled); + PlatformMgr().ScheduleWork(StopAdvertisingPriorToSwitchingMode, 0); + break; + } + default: + return CHIP_ERROR_INVALID_ARGUMENT; + } + mFlags.Set(Flags::kRestartAdvertising); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerCommon::_GetDeviceName(char * buf, size_t bufSize) +{ + if (strlen(mDeviceName) >= bufSize) + { + return CHIP_ERROR_BUFFER_TOO_SMALL; + } + strcpy(buf, mDeviceName); + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerCommon::_SetDeviceName(const char * deviceName) +{ + if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_NotSupported) + { + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + } + if (deviceName != NULL && deviceName[0] != 0) + { + if (strlen(deviceName) >= kMaxDeviceNameLength) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + memset(mDeviceName, 0, kMaxDeviceNameLength); + strcpy(mDeviceName, deviceName); + mFlags.Set(Flags::kDeviceNameSet); + ChipLogProgress(DeviceLayer, "Setting device name to : \"%s\"", deviceName); + } + else + { + mDeviceName[0] = 0; + mFlags.Clear(Flags::kDeviceNameSet); + } + + return CHIP_NO_ERROR; +} + +void BLEManagerCommon::_OnPlatformEvent(const ChipDeviceEvent * event) +{ + switch (event->Type) + { + case DeviceEventType::kCHIPoBLESubscribe: + ChipDeviceEvent connEstEvent; + + HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &CHIP_BLE_SVC_ID, &Ble::CHIP_BLE_CHAR_2_UUID); + connEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; + PlatformMgr().PostEventOrDie(&connEstEvent); + break; + + case DeviceEventType::kCHIPoBLEUnsubscribe: + HandleUnsubscribeReceived(event->CHIPoBLEUnsubscribe.ConId, &CHIP_BLE_SVC_ID, &Ble::CHIP_BLE_CHAR_2_UUID); + break; + + case DeviceEventType::kCHIPoBLEWriteReceived: + HandleWriteReceived(event->CHIPoBLEWriteReceived.ConId, &CHIP_BLE_SVC_ID, &Ble::CHIP_BLE_CHAR_1_UUID, + PacketBufferHandle::Adopt(event->CHIPoBLEWriteReceived.Data)); + break; + + case DeviceEventType::kCHIPoBLEConnectionError: + HandleConnectionError(event->CHIPoBLEConnectionError.ConId, event->CHIPoBLEConnectionError.Reason); + break; + + case DeviceEventType::kCHIPoBLEIndicateConfirm: + HandleIndicationConfirmation(event->CHIPoBLEIndicateConfirm.ConId, &CHIP_BLE_SVC_ID, &Ble::CHIP_BLE_CHAR_2_UUID); + break; + + default: + break; + } +} + +CHIP_ERROR BLEManagerCommon::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, + const ChipBleUUID * charId) +{ + ChipLogProgress(DeviceLayer, "BLEManagerCommon::SubscribeCharacteristic() not supported"); + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR BLEManagerCommon::UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, + const ChipBleUUID * charId) +{ + ChipLogProgress(DeviceLayer, "BLEManagerCommon::UnsubscribeCharacteristic() not supported"); + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR BLEManagerCommon::CloseConnection(BLE_CONNECTION_OBJECT conId) +{ + return blekw_stop_connection_internal(conId); +} + +uint16_t BLEManagerCommon::GetMTU(BLE_CONNECTION_OBJECT conId) const +{ + uint16_t tempMtu = 0; + (void) Gatt_GetMtu(conId, &tempMtu); + + return tempMtu; +} + +CHIP_ERROR BLEManagerCommon::SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) +{ + ChipLogProgress(DeviceLayer, "BLEManagerCommon::SendWriteRequest() not supported"); + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +void BLEManagerCommon::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) +{ + BLEMgrImpl().CloseConnection(conId); +} + +CHIP_ERROR BLEManagerCommon::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle data) +{ + VerifyOrReturnError(UUIDsMatch(&Ble::CHIP_BLE_CHAR_2_UUID, charId), BLE_ERROR_GATT_WRITE_FAILED); + + CHIP_ERROR err = CHIP_NO_ERROR; + + if (blekw_send_event(conId, value_chipoble_tx, data->Start(), data->DataLength()) != BLE_OK) + { + err = CHIP_ERROR_SENDING_BLOCKED; + } + else + { + ChipDeviceEvent event; + event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm; + event.CHIPoBLEIndicateConfirm.ConId = conId; + err = PlatformMgr().PostEvent(&event); + } + + return err; +} + +BLEManagerCommon::ble_err_t BLEManagerCommon::blekw_send_event(int8_t connection_handle, uint16_t handle, uint8_t * data, + uint32_t len) +{ + EventBits_t eventBits; + +#if CHIP_DEVICE_CHIP0BLE_DEBUG + ChipLogProgress(DeviceLayer, "Trying to send event."); +#endif + + if (connection_handle < 0 || handle <= 0) + { + ChipLogProgress(DeviceLayer, "BLE Event - Bad Handle"); + return BLE_E_FAIL; + } + + if (len > 0 && data == NULL) + { + ChipLogProgress(DeviceLayer, "BLE Event - Invalid Data"); + return BLE_E_FAIL; + } + + /************* Send the indication *************/ + xEventGroupClearBits(sEventGroup, CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED | CHIP_BLE_KW_EVNT_INDICATION_FAILED); + + if (GattServer_SendInstantValueIndication(connection_handle, handle, len, data) != gBleSuccess_c) + { + ChipLogProgress(DeviceLayer, "BLE Event - Can't sent indication"); + return BLE_E_FAIL; + } + + /* Wait until BLE Stack is ready */ + eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED | CHIP_BLE_KW_EVNT_INDICATION_FAILED, pdTRUE, + pdFALSE, CHIP_BLE_KW_EVNT_TIMEOUT); + + if (eventBits & CHIP_BLE_KW_EVNT_INDICATION_FAILED) + { + ChipLogProgress(DeviceLayer, "BLE Event - Sent Failed"); + return BLE_E_FAIL; + } + +#if CHIP_DEVICE_CHIP0BLE_DEBUG + ChipLogProgress(DeviceLayer, "BLE Event - Sent :-) "); +#endif + + return BLE_OK; +} +/******************************************************************************* + * Private functions + *******************************************************************************/ + +BLEManagerCommon::ble_err_t BLEManagerCommon::blekw_start_advertising(gapAdvertisingParameters_t * adv_params, + gapAdvertisingData_t * adv, gapScanResponseData_t * scnrsp) +{ + EventBits_t eventBits; + + /************* Set the advertising parameters *************/ + xEventGroupClearBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED | CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE); + + /* Set the advertising parameters */ + if (Gap_SetAdvertisingParameters(adv_params) != gBleSuccess_c) + { + vTaskDelay(1); + + /* Retry, just to make sure before giving up and sending an error. */ + if (Gap_SetAdvertisingParameters(adv_params) != gBleSuccess_c) + { + return BLE_E_SET_ADV_PARAMS; + } + } + + eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED | CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE, + pdTRUE, pdFALSE, CHIP_BLE_KW_EVNT_TIMEOUT); + + if (!(eventBits & CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE)) + { + return BLE_E_ADV_PARAMS_FAILED; + } + + /************* Set the advertising data *************/ + xEventGroupClearBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED | CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE); + + /* Set the advertising data */ + if (Gap_SetAdvertisingData(adv, scnrsp) != gBleSuccess_c) + { + return BLE_E_SET_ADV_DATA; + } + + eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED | CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE, + pdTRUE, pdFALSE, CHIP_BLE_KW_EVNT_TIMEOUT); + + if (!(eventBits & CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE)) + { + return BLE_E_ADV_SETUP_FAILED; + } + + /************* Start the advertising *************/ + xEventGroupClearBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED); + + if (gBleSuccess_c != Gap_CreateRandomDeviceAddress(NULL, NULL)) + { + return BLE_E_SET_ADV_PARAMS; + } + + eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_RND_ADDR_SET, pdTRUE, pdTRUE, CHIP_BLE_KW_EVNT_TIMEOUT); + + if (!(eventBits & CHIP_BLE_KW_EVNT_RND_ADDR_SET)) + { + return BLE_E_ADV_PARAMS_FAILED; + } + + /* Start the advertising */ + if (Gap_StartAdvertising(blekw_gap_advertising_cb, blekw_gap_connection_cb) != gBleSuccess_c) + { + return BLE_E_START_ADV; + } + +#if defined(chip_with_low_power) && (chip_with_low_power == 1) + PWR_DisallowDeviceToSleep(); +#endif + + eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED, pdTRUE, pdFALSE, + CHIP_BLE_KW_EVNT_TIMEOUT); + if (!(eventBits & CHIP_BLE_KW_EVNT_ADV_CHANGED)) + { +#if defined(chip_with_low_power) && (chip_with_low_power == 1) + PWR_AllowDeviceToSleep(); +#endif + return BLE_E_START_ADV_FAILED; + } + +#if defined(chip_with_low_power) && (chip_with_low_power == 1) + PWR_AllowDeviceToSleep(); +#endif + + return BLE_OK; +} + +BLEManagerCommon::ble_err_t BLEManagerCommon::blekw_stop_advertising(void) +{ + EventBits_t eventBits; + bleResult_t res; + + xEventGroupClearBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED); + + /* Stop the advertising data */ + res = Gap_StopAdvertising(); + if (res != gBleSuccess_c) + { + ChipLogProgress(DeviceLayer, "Failed to stop advertising %d", res); + return BLE_E_STOP; + } + + eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED, pdTRUE, pdFALSE, + CHIP_BLE_KW_EVNT_TIMEOUT); + + if (eventBits & CHIP_BLE_KW_EVNT_ADV_FAILED) + { + ChipLogProgress(DeviceLayer, "Stop advertising flat out failed."); + return BLE_E_ADV_FAILED; + } + else if (!(eventBits & CHIP_BLE_KW_EVNT_ADV_CHANGED)) + { + ChipLogProgress(DeviceLayer, "Stop advertising event timeout."); + return BLE_E_ADV_CHANGED; + } + + return BLE_OK; +} + +CHIP_ERROR BLEManagerCommon::ConfigureAdvertisingData(void) +{ + ble_err_t err; + CHIP_ERROR chipErr; + uint16_t discriminator; + uint16_t advInterval = 0; + gapAdvertisingData_t adv = { 0 }; + gapAdStructure_t adv_data[BLEKW_ADV_MAX_NO] = { { 0 } }; + gapAdStructure_t scan_rsp_data[BLEKW_SCAN_RSP_MAX_NO] = { { 0 } }; + uint8_t advPayload[BLEKW_MAX_ADV_DATA_LEN] = { 0 }; + gapScanResponseData_t scanRsp = { 0 }; + gapAdvertisingParameters_t adv_params = { 0 }; + uint8_t chipAdvDataFlags = (gLeGeneralDiscoverableMode_c | gBrEdrNotSupported_c); + uint8_t chipOverBleService[2]; + ChipBLEDeviceIdentificationInfo mDeviceIdInfo = { 0 }; + uint8_t mDeviceIdInfoLength = 0; + + chipErr = GetCommissionableDataProvider()->GetSetupDiscriminator(discriminator); + if (chipErr != CHIP_NO_ERROR) + { + return chipErr; + } + + if (!mFlags.Has(Flags::kDeviceNameSet)) + { + memset(mDeviceName, 0, kMaxDeviceNameLength); + snprintf(mDeviceName, kMaxDeviceNameLength, "%s%04u", CHIP_DEVICE_CONFIG_BLE_DEVICE_NAME_PREFIX, discriminator); + } + + /**************** Prepare advertising data *******************************************/ + adv.cNumAdStructures = BLEKW_ADV_MAX_NO; + + chipErr = ConfigurationMgr().GetBLEDeviceIdentificationInfo(mDeviceIdInfo); + SuccessOrExit(chipErr); + mDeviceIdInfoLength = sizeof(mDeviceIdInfo); + + if ((mDeviceIdInfoLength + CHIP_ADV_SHORT_UUID_LEN + 1) > BLEKW_MAX_ADV_DATA_LEN) + { + return CHIP_ERROR_INCORRECT_STATE; + } + + adv_data[0].length = 0x02; + adv_data[0].adType = gAdFlags_c; + adv_data[0].aData = (uint8_t *) (&chipAdvDataFlags); + + adv_data[1].length = static_cast<uint8_t>(mDeviceIdInfoLength + CHIP_ADV_SHORT_UUID_LEN + 1); + adv_data[1].adType = gAdServiceData16bit_c; + memcpy(advPayload, ShortUUID_CHIPoBLEService, CHIP_ADV_SHORT_UUID_LEN); + memcpy(&advPayload[CHIP_ADV_SHORT_UUID_LEN], (void *) &mDeviceIdInfo, mDeviceIdInfoLength); + adv_data[1].aData = advPayload; + + adv.aAdStructures = adv_data; + +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + ReturnErrorOnFailure(EncodeAdditionalDataTlv()); +#endif + + /**************** Prepare scan response data *******************************************/ + scanRsp.cNumAdStructures = BLEKW_SCAN_RSP_MAX_NO; + + scan_rsp_data[0].length = static_cast<uint8_t>(strlen(mDeviceName) + 1); + scan_rsp_data[0].adType = gAdCompleteLocalName_c; + scan_rsp_data[0].aData = (uint8_t *) mDeviceName; + + scan_rsp_data[1].length = sizeof(chipOverBleService) + 1; + scan_rsp_data[1].adType = gAdComplete16bitServiceList_c; + chipOverBleService[0] = ShortUUID_CHIPoBLEService[0]; + chipOverBleService[1] = ShortUUID_CHIPoBLEService[1]; + scan_rsp_data[1].aData = (uint8_t *) chipOverBleService; + + scanRsp.aAdStructures = scan_rsp_data; + + /**************** Prepare advertising parameters *************************************/ + if (mFlags.Has(Flags::kFastAdvertisingEnabled)) + { + advInterval = CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MAX; + } + else + { + advInterval = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX; + } + advInterval = (uint16_t) (advInterval * 0.625F); + + adv_params.minInterval = adv_params.maxInterval = advInterval; + adv_params.advertisingType = gAdvConnectableUndirected_c; + adv_params.ownAddressType = gBleAddrTypeRandom_c; + adv_params.peerAddressType = gBleAddrTypePublic_c; + memset(adv_params.peerAddress, 0, gcBleDeviceAddressSize_c); + adv_params.channelMap = (gapAdvertisingChannelMapFlags_t) (gAdvChanMapFlag37_c | gAdvChanMapFlag38_c | gAdvChanMapFlag39_c); + adv_params.filterPolicy = gProcessAll_c; + + err = blekw_start_advertising(&adv_params, &adv, &scanRsp); + if (err == BLE_OK) + { + ChipLogProgress(DeviceLayer, "Started Advertising at %d ms", advInterval); + } + else + { + ChipLogProgress(DeviceLayer, "Advertising error 0x%x!", err); + mFlags.Clear(Flags::kAdvertising); + return CHIP_ERROR_INCORRECT_STATE; + } + +exit: + return chipErr; +} + +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING +CHIP_ERROR BLEManagerCommon::EncodeAdditionalDataTlv() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + BitFlags<AdditionalDataFields> dataFields; + AdditionalDataPayloadGeneratorParams params; + +#if CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID) + uint8_t rotatingDeviceIdUniqueId[ConfigurationManager::kRotatingDeviceIDUniqueIDLength] = {}; + MutableByteSpan rotatingDeviceIdUniqueIdSpan(rotatingDeviceIdUniqueId); + + err = DeviceLayer::GetDeviceInstanceInfoProvider()->GetRotatingDeviceIdUniqueId(rotatingDeviceIdUniqueIdSpan); + SuccessOrExit(err); + err = ConfigurationMgr().GetLifetimeCounter(params.rotatingDeviceIdLifetimeCounter); + SuccessOrExit(err); + params.rotatingDeviceIdUniqueId = rotatingDeviceIdUniqueIdSpan; + dataFields.Set(AdditionalDataFields::RotatingDeviceId); +#endif /* CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID) */ + err = AdditionalDataPayloadGenerator().generateAdditionalDataPayload(params, sImplInstance->c3AdditionalDataBufferHandle, + dataFields); + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to generate TLV encoded Additional Data (%s)", __func__); + } + + return err; +} + +void BLEManagerCommon::HandleC3ReadRequest(blekw_msg_t * msg) +{ + bleResult_t result; + blekw_att_read_data_t * att_rd_data = (blekw_att_read_data_t *) msg->data.data; + deviceId_t deviceId = att_rd_data->device_id; + uint16_t handle = att_rd_data->handle; + uint16_t length = sImplInstance->c3AdditionalDataBufferHandle->DataLength(); + const uint8_t * data = (const uint8_t *) sImplInstance->c3AdditionalDataBufferHandle->Start(); + + result = GattDb_WriteAttribute(handle, length, data); + if (result != gBleSuccess_c) + { + ChipLogError(DeviceLayer, "Failed to write C3 characteristic: %d", result); + } + + result = GattServer_SendAttributeReadStatus(deviceId, handle, gAttErrCodeNoError_c); + if (result != gBleSuccess_c) + { + ChipLogError(DeviceLayer, "Failed to send response to C3 read request: %d", result); + } +} +#endif /* CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING */ + +CHIP_ERROR BLEManagerCommon::StartAdvertising(void) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + mFlags.Set(Flags::kAdvertising); + mFlags.Clear(Flags::kRestartAdvertising); + + if (mFlags.Has(Flags::kFastAdvertisingEnabled)) + { + StartBleAdvTimeoutTimer(CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_TIMEOUT); + } + + err = ConfigureAdvertisingData(); + + if (err == CHIP_NO_ERROR) + /* schedule NFC emulation stop */ + { + ChipDeviceEvent advChange; + advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; + advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Started; + err = PlatformMgr().PostEvent(&advChange); + } + + return err; +} + +CHIP_ERROR BLEManagerCommon::StopAdvertising(void) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + + if (mFlags.Has(Flags::kAdvertising)) + { + mFlags.Clear(Flags::kAdvertising); + mFlags.Clear(Flags::kRestartAdvertising); + + if (!mDeviceConnected) + { + ble_err_t err = blekw_stop_advertising(); + VerifyOrReturnError(err == BLE_OK, CHIP_ERROR_INCORRECT_STATE); + CancelBleAdvTimeoutTimer(); + } + +#if CONFIG_CHIP_NFC_COMMISSIONING + /* schedule NFC emulation stop */ + ChipDeviceEvent advChange; + advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; + advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Stopped; + error = PlatformMgr().PostEvent(&advChange); +#endif + } + + return error; +} + +void BLEManagerCommon::DriveBLEState(void) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + // Check if BLE stack is initialized + VerifyOrExit(mFlags.Has(Flags::kK32WBLEStackInitialized), err = CHIP_ERROR_INCORRECT_STATE); + + // Start advertising if needed... + if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled && mFlags.Has(Flags::kAdvertisingEnabled)) + { + // Start/re-start advertising if not already started, or if there is a pending change + // to the advertising configuration. + if (!mFlags.Has(Flags::kAdvertising) || mFlags.Has(Flags::kRestartAdvertising)) + { + err = StartAdvertising(); + SuccessOrExit(err); + } + } + // Otherwise, stop advertising if it is enabled. + else if (mFlags.Has(Flags::kAdvertising)) + { + err = StopAdvertising(); + SuccessOrExit(err); + // Reset to fast advertising mode only if SetBLEAdvertisingEnabled(false) was called (usually from app). + mFlags.Set(Flags::kFastAdvertisingEnabled); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %s", ErrorStr(err)); + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled; + } +} + +void BLEManagerCommon::DriveBLEState(intptr_t arg) +{ + sImplInstance->DriveBLEState(); +} + +void BLEManagerCommon::StopAdvertisingPriorToSwitchingMode(intptr_t arg) +{ + if (CHIP_NO_ERROR != sImplInstance->StopAdvertising()) + { + ChipLogProgress(DeviceLayer, "Failed to stop advertising"); + } +} + +void BLEManagerCommon::DoBleProcessing(void) +{ + blekw_msg_t * msg = NULL; + + while ((xQueueReceive(sBleEventQueue, &msg, 0) == pdTRUE) && msg) + { + if (msg->type == BLE_KW_MSG_ERROR) + { + if (msg->data.u8 == BLE_KW_MSG_2M_UPGRADE_ERROR) + { + ChipLogProgress(DeviceLayer, + "Warning. BLE is using 1Mbps. Couldn't upgrade to 2Mbps, " + "maybe the peer is missing 2Mbps support."); + } + else + { + ChipLogProgress(DeviceLayer, "BLE Error: %d.\n", msg->data.u8); + } + } + else if (msg->type == BLE_KW_MSG_CONNECTED) + { + sImplInstance->HandleConnectEvent(msg); + } + else if (msg->type == BLE_KW_MSG_DISCONNECTED) + { + sImplInstance->HandleConnectionCloseEvent(msg); + } + else if (msg->type == BLE_KW_MSG_MTU_CHANGED) + { + blekw_start_connection_timeout(); + ChipLogProgress(DeviceLayer, "BLE MTU size has been changed to %d.", msg->data.u16); + } + else if (msg->type == BLE_KW_MSG_ATT_WRITTEN || msg->type == BLE_KW_MSG_ATT_LONG_WRITTEN || + msg->type == BLE_KW_MSG_ATT_CCCD_WRITTEN) + { + sImplInstance->HandleWriteEvent(msg); + } + else if (msg->type == BLE_KW_MSG_ATT_READ) + { +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + blekw_att_read_data_t * att_rd_data = (blekw_att_read_data_t *) msg->data.data; + if (value_chipoble_c3 == att_rd_data->handle) + sImplInstance->HandleC3ReadRequest(msg); +#endif + } + else if (msg->type == BLE_KW_MSG_FORCE_DISCONNECT) + { + sImplInstance->HandleForceDisconnect(); + } + + /* Free the message from the queue */ + free(msg); + msg = NULL; + } +} + +void BLEManagerCommon::RegisterAppCallbacks(BLECallbackDelegate::GapGenericCallback gapCallback, + BLECallbackDelegate::GattServerCallback gattCallback) +{ + callbackDelegate.gapCallback = gapCallback; + callbackDelegate.gattCallback = gattCallback; +} + +void BLEManagerCommon::HandleConnectEvent(blekw_msg_t * msg) +{ + uint8_t deviceId = msg->data.u8; + ChipLogProgress(DeviceLayer, "BLE is connected with device: %d.\n", deviceId); + +#if gClkUseFro32K && defined(chip_with_low_power) && (chip_with_low_power == 1) + PWR_DisallowDeviceToSleep(); +#endif + + mDeviceId = deviceId; + mDeviceConnected = true; + + blekw_start_connection_timeout(); + PlatformMgr().ScheduleWork(DriveBLEState, 0); +} + +void BLEManagerCommon::HandleConnectionCloseEvent(blekw_msg_t * msg) +{ + uint8_t deviceId = msg->data.u8; + ChipLogProgress(DeviceLayer, "BLE is disconnected with device: %d.\n", deviceId); + +#if gClkUseFro32K && defined(chip_with_low_power) && (chip_with_low_power == 1) + PWR_AllowDeviceToSleep(); +#endif + + mDeviceConnected = false; + + ChipDeviceEvent event; + event.Type = DeviceEventType::kCHIPoBLEConnectionClosed; + event.CHIPoBLEConnectionError.ConId = deviceId; + event.CHIPoBLEConnectionError.Reason = BLE_ERROR_REMOTE_DEVICE_DISCONNECTED; + + CancelBleAdvTimeoutTimer(); + + PlatformMgr().PostEventOrDie(&event); + mFlags.Set(Flags::kRestartAdvertising); + mFlags.Set(Flags::kFastAdvertisingEnabled); + PlatformMgr().ScheduleWork(DriveBLEState, 0); +} + +void BLEManagerCommon::HandleWriteEvent(blekw_msg_t * msg) +{ + blekw_att_written_data_t * att_wr_data = (blekw_att_written_data_t *) msg->data.data; + attErrorCode_t status = gAttErrCodeNoError_c; + +#if CHIP_DEVICE_CHIP0BLE_DEBUG + ChipLogProgress(DeviceLayer, "Attribute write request(device: %d,handle: %d).", att_wr_data->device_id, att_wr_data->handle); +#endif + + blekw_start_connection_timeout(); + + if (value_chipoble_rx == att_wr_data->handle) + { + sImplInstance->HandleRXCharWrite(msg); + } + else if (cccd_chipoble_tx == att_wr_data->handle) + { + sImplInstance->HandleTXCharCCCDWrite(msg); + } + + /* TODO: do we need to send the status also for CCCD_WRITTEN? */ + if (msg->type != BLE_KW_MSG_ATT_CCCD_WRITTEN) + { + bleResult_t res = GattServer_SendAttributeWrittenStatus(att_wr_data->device_id, att_wr_data->handle, status); + + if (res != gBleSuccess_c) + { + ChipLogProgress(DeviceLayer, "GattServer_SendAttributeWrittenStatus returned %d", res); + } + } +} + +void BLEManagerCommon::HandleTXCharCCCDWrite(blekw_msg_t * msg) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + blekw_att_written_data_t * att_wr_data = (blekw_att_written_data_t *) msg->data.data; + ChipDeviceEvent event; + + VerifyOrExit(att_wr_data->length != 0, err = CHIP_ERROR_INCORRECT_STATE); + VerifyOrExit(att_wr_data->data != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + +#if CHIP_DEVICE_CHIP0BLE_DEBUG + ChipLogProgress(DeviceLayer, "CHIPoBLE %s received", *att_wr_data->data ? "subscribe" : "unsubscribe"); +#endif + + if (*att_wr_data->data) + { + if (!mDeviceSubscribed) + { + mDeviceSubscribed = true; + event.Type = DeviceEventType::kCHIPoBLESubscribe; + event.CHIPoBLESubscribe.ConId = att_wr_data->device_id; + err = PlatformMgr().PostEvent(&event); + } + } + else + { + mDeviceSubscribed = false; + event.Type = DeviceEventType::kCHIPoBLEUnsubscribe; + event.CHIPoBLESubscribe.ConId = att_wr_data->device_id; + err = PlatformMgr().PostEvent(&event); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "HandleTXCharCCCDWrite() failed: %s", ErrorStr(err)); + } +} + +void BLEManagerCommon::HandleRXCharWrite(blekw_msg_t * msg) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + System::PacketBufferHandle buf; + blekw_att_written_data_t * att_wr_data = (blekw_att_written_data_t *) msg->data.data; + + VerifyOrExit(att_wr_data->length != 0, err = CHIP_ERROR_INCORRECT_STATE); + VerifyOrExit(att_wr_data->data != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + + // Copy the data to a PacketBuffer. + buf = System::PacketBufferHandle::NewWithData(att_wr_data->data, att_wr_data->length); + VerifyOrExit(!buf.IsNull(), err = CHIP_ERROR_NO_MEMORY); + +#if CHIP_DEVICE_CHIP0BLE_DEBUG + ChipLogDetail(DeviceLayer, + "Write request/command received for" + "CHIPoBLE RX characteristic (con %u, len %u)", + att_wr_data->device_id, buf->DataLength()); +#endif + + // Post an event to the CHIP queue to deliver the data into the CHIP stack. + { + ChipDeviceEvent event; + event.Type = DeviceEventType::kCHIPoBLEWriteReceived; + event.CHIPoBLEWriteReceived.ConId = att_wr_data->device_id; + event.CHIPoBLEWriteReceived.Data = std::move(buf).UnsafeRelease(); + err = PlatformMgr().PostEvent(&event); + } +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "HandleRXCharWrite() failed: %s", ErrorStr(err)); + } +} + +void BLEManagerCommon::HandleForceDisconnect() +{ + ChipLogProgress(DeviceLayer, "BLE connection timeout: Forcing disconnection."); + + /* Set the advertising parameters */ + if (Gap_Disconnect(mDeviceId) != gBleSuccess_c) + { + ChipLogProgress(DeviceLayer, "Gap_Disconnect() failed."); + } + +#if defined(chip_with_low_power) && (chip_with_low_power == 1) + PWR_AllowDeviceToSleep(); +#endif +} + +/******************************************************************************* + * BLE stack callbacks + *******************************************************************************/ +void BLEManagerCommon::blekw_generic_cb(gapGenericEvent_t * pGenericEvent) +{ + /* Call BLE Conn Manager */ + BleConnManager_GenericEvent(pGenericEvent); + + if (sImplInstance && sImplInstance->callbackDelegate.gapCallback) + { + sImplInstance->callbackDelegate.gapCallback(pGenericEvent); + } + + switch (pGenericEvent->eventType) + { + case gInternalError_c: + /* Notify the CHIP that the BLE hardware report fail */ + ChipLogProgress(DeviceLayer, "BLE Internal Error: Code 0x%04X, Source 0x%08X, HCI OpCode %d.\n", + pGenericEvent->eventData.internalError.errorCode, pGenericEvent->eventData.internalError.errorSource, + pGenericEvent->eventData.internalError.hciCommandOpcode); + if ((gHciUnsupportedRemoteFeature_c == pGenericEvent->eventData.internalError.errorCode) && + (gLeSetPhy_c == pGenericEvent->eventData.internalError.errorSource)) + { + (void) blekw_msg_add_u8(BLE_KW_MSG_ERROR, BLE_KW_MSG_2M_UPGRADE_ERROR); + } + else + { + (void) blekw_msg_add_u8(BLE_KW_MSG_ERROR, BLE_INTERNAL_ERROR); + } + break; + + case gAdvertisingSetupFailed_c: + xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED); + break; + + case gAdvertisingParametersSetupComplete_c: + xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE); + break; + + case gAdvertisingDataSetupComplete_c: + xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE); + break; + + case gRandomAddressReady_c: + Gap_SetRandomAddress(pGenericEvent->eventData.addrReady.aAddress); + break; + + case gRandomAddressSet_c: + xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_RND_ADDR_SET); + break; + +#if BLE_HIGH_TX_POWER + case gTxPowerLevelSetComplete_c: + if (gBleSuccess_c == pGenericEvent->eventData.txPowerLevelSetStatus) + { + xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_POWER_LEVEL_SET); + } + break; +#endif + + case gInitializationComplete_c: + /* Common GAP configuration */ + BleConnManager_GapCommonConfig(); + + /* Set the local synchronization event */ + xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_INIT_COMPLETE); + break; + default: + break; + } +} + +void BLEManagerCommon::blekw_gap_advertising_cb(gapAdvertisingEvent_t * pAdvertisingEvent) +{ + if (pAdvertisingEvent->eventType == gAdvertisingStateChanged_c) + { + /* Set the local synchronization event */ + xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_CHANGED); + } + else + { + /* The advertisement start failed */ + ChipLogProgress(DeviceLayer, "Advertising failed: event=%d reason=0x%04X\n", pAdvertisingEvent->eventType, + pAdvertisingEvent->eventData.failReason); + + /* Set the local synchronization event */ + xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_FAILED); + } +} + +void BLEManagerCommon::blekw_gap_connection_cb(deviceId_t deviceId, gapConnectionEvent_t * pConnectionEvent) +{ + /* Call BLE Conn Manager */ + BleConnManager_GapPeripheralEvent(deviceId, pConnectionEvent); + + if (pConnectionEvent->eventType == gConnEvtConnected_c) + { +#if CHIP_DEVICE_K32W1 +#if defined(chip_with_low_power) && (chip_with_low_power == 1) + /* Disallow must be called here for K32W1, otherwise an assert will be reached. + * Disclaimer: this is a workaround until a better cross platform solution is found. */ + PWR_DisallowDeviceToSleep(); +#endif +#endif + +#if CHIP_DEVICE_CONFIG_BLE_SET_PHY_2M_REQ + ChipLogProgress(DeviceLayer, "BLE K32W: Trying to set the PHY to 2M"); + + (void) Gap_LeSetPhy(FALSE, deviceId, 0, gConnPhyUpdateReqTxPhySettings_c, gConnPhyUpdateReqRxPhySettings_c, + (uint16_t) gConnPhyUpdateReqPhyOptions_c); +#endif + + /* Notify App Task that the BLE is connected now */ + (void) blekw_msg_add_u8(BLE_KW_MSG_CONNECTED, (uint8_t) deviceId); +#if defined(chip_with_low_power) && (chip_with_low_power == 1) + PWR_AllowDeviceToSleep(); +#endif + } + else if (pConnectionEvent->eventType == gConnEvtDisconnected_c) + { + blekw_stop_connection_timeout(); + + /* Notify App Task that the BLE is disconnected now */ + (void) blekw_msg_add_u8(BLE_KW_MSG_DISCONNECTED, (uint8_t) deviceId); + +#if defined(chip_with_low_power) && (chip_with_low_power == 1) + if (bleAppStopInProgress == TRUE) + { + bleAppStopInProgress = FALSE; + PWR_AllowDeviceToSleep(); + } +#endif + } + else if (pConnectionEvent->eventType == gConnEvtPairingRequest_c) + { + /* Reject request for pairing */ + Gap_RejectPairing(deviceId, gPairingNotSupported_c); + } + else if (pConnectionEvent->eventType == gConnEvtAuthenticationRejected_c) + { + ChipLogProgress(DeviceLayer, "BLE Authentication rejected (reason:%d).\n", + pConnectionEvent->eventData.authenticationRejectedEvent.rejectReason); + } +} + +void BLEManagerCommon::blekw_connection_timeout_cb(TimerHandle_t timer) +{ + (void) blekw_msg_add_u8(BLE_KW_MSG_FORCE_DISCONNECT, 0); +} + +void BLEManagerCommon::blekw_start_connection_timeout(void) +{ + xTimerReset(connectionTimeout, 0); +} + +void BLEManagerCommon::blekw_stop_connection_timeout(void) +{ + ChipLogProgress(DeviceLayer, "Stopped connectionTimeout timer."); + xTimerStop(connectionTimeout, 0); +} + +void BLEManagerCommon::blekw_gatt_server_cb(deviceId_t deviceId, gattServerEvent_t * pServerEvent) +{ + if (sImplInstance && sImplInstance->callbackDelegate.gattCallback) + { + sImplInstance->callbackDelegate.gattCallback(deviceId, pServerEvent); + } + + switch (pServerEvent->eventType) + { + case gEvtMtuChanged_c: { + uint16_t tempMtu = 0; + + (void) Gatt_GetMtu(deviceId, &tempMtu); + blekw_msg_add_u16(BLE_KW_MSG_MTU_CHANGED, tempMtu); + break; + } + + case gEvtAttributeWritten_c: + blekw_msg_add_att_written(BLE_KW_MSG_ATT_WRITTEN, deviceId, pServerEvent->eventData.attributeWrittenEvent.handle, + pServerEvent->eventData.attributeWrittenEvent.aValue, + pServerEvent->eventData.attributeWrittenEvent.cValueLength); + break; + + case gEvtLongCharacteristicWritten_c: + blekw_msg_add_att_written(BLE_KW_MSG_ATT_LONG_WRITTEN, deviceId, pServerEvent->eventData.longCharWrittenEvent.handle, + pServerEvent->eventData.longCharWrittenEvent.aValue, + pServerEvent->eventData.longCharWrittenEvent.cValueLength); + break; + + case gEvtAttributeRead_c: + blekw_msg_add_att_read(BLE_KW_MSG_ATT_READ, deviceId, pServerEvent->eventData.attributeReadEvent.handle); + break; + + case gEvtCharacteristicCccdWritten_c: { + uint16_t cccd_val = pServerEvent->eventData.charCccdWrittenEvent.newCccd; + + blekw_msg_add_att_written(BLE_KW_MSG_ATT_CCCD_WRITTEN, deviceId, pServerEvent->eventData.charCccdWrittenEvent.handle, + (uint8_t *) &cccd_val, 2); + break; + } + + case gEvtHandleValueConfirmation_c: + /* Set the local synchronization event */ + xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED); + break; + + case gEvtError_c: + if (pServerEvent->eventData.procedureError.procedureType == gSendIndication_c) + { + /* Set the local synchronization event */ + xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_INDICATION_FAILED); + } + else + { + ChipLogProgress(DeviceLayer, "BLE Gatt Server Error: Code 0x%04X, Source %d.\n", + pServerEvent->eventData.procedureError.error, pServerEvent->eventData.procedureError.procedureType); + + /* Notify CHIP BLE App Task that the BLE hardware report fail */ + (void) blekw_msg_add_u8(BLE_KW_MSG_ERROR, BLE_INTERNAL_GATT_ERROR); + } + break; + + default: + break; + } +} +/******************************************************************************* + * Add to message queue functions + *******************************************************************************/ +CHIP_ERROR BLEManagerCommon::blekw_msg_add_att_written(blekw_msg_type_t type, uint8_t device_id, uint16_t handle, uint8_t * data, + uint16_t length) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + blekw_msg_t * msg = NULL; + blekw_att_written_data_t * att_wr_data; + + /* Allocate a buffer with enough space to store the packet */ + msg = (blekw_msg_t *) malloc(sizeof(blekw_msg_t) + sizeof(blekw_att_written_data_t) + length); + VerifyOrExit(msg, err = CHIP_ERROR_NO_MEMORY); + + msg->type = type; + msg->length = sizeof(blekw_att_written_data_t) + length; + att_wr_data = (blekw_att_written_data_t *) msg->data.data; + att_wr_data->device_id = device_id; + att_wr_data->handle = handle; + att_wr_data->length = length; + FLib_MemCpy(att_wr_data->data, data, length); + + VerifyOrExit(xQueueSend(sBleEventQueue, &msg, 0) == pdTRUE, err = CHIP_ERROR_NO_MEMORY); + otTaskletsSignalPending(NULL); + +exit: + return err; +} + +CHIP_ERROR BLEManagerCommon::blekw_msg_add_att_read(blekw_msg_type_t type, uint8_t device_id, uint16_t handle) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + blekw_msg_t * msg = NULL; + blekw_att_read_data_t * att_rd_data; + + /* Allocate a buffer with enough space to store the packet */ + msg = (blekw_msg_t *) malloc(sizeof(blekw_msg_t) + sizeof(blekw_att_read_data_t)); + VerifyOrExit(msg, err = CHIP_ERROR_NO_MEMORY); + + msg->type = type; + msg->length = sizeof(blekw_att_read_data_t); + att_rd_data = (blekw_att_read_data_t *) msg->data.data; + att_rd_data->device_id = device_id; + att_rd_data->handle = handle; + + VerifyOrExit(xQueueSend(sBleEventQueue, &msg, 0) == pdTRUE, err = CHIP_ERROR_NO_MEMORY); + otTaskletsSignalPending(NULL); + +exit: + return err; +} + +CHIP_ERROR BLEManagerCommon::blekw_msg_add_u8(blekw_msg_type_t type, uint8_t data) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + blekw_msg_t * msg = NULL; + + /* Allocate a buffer with enough space to store the packet */ + msg = (blekw_msg_t *) malloc(sizeof(blekw_msg_t)); + VerifyOrExit(msg, err = CHIP_ERROR_NO_MEMORY); + + msg->type = type; + msg->length = 0; + msg->data.u8 = data; + + VerifyOrExit(xQueueSend(sBleEventQueue, &msg, 0) == pdTRUE, err = CHIP_ERROR_NO_MEMORY); + otTaskletsSignalPending(NULL); + +exit: + return err; +} + +CHIP_ERROR BLEManagerCommon::blekw_msg_add_u16(blekw_msg_type_t type, uint16_t data) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + blekw_msg_t * msg = NULL; + + /* Allocate a buffer with enough space to store the packet */ + msg = (blekw_msg_t *) malloc(sizeof(blekw_msg_t)); + VerifyOrExit(msg, err = CHIP_ERROR_NO_MEMORY); + + msg->type = type; + msg->length = 0; + msg->data.u16 = data; + + VerifyOrExit(xQueueSend(sBleEventQueue, &msg, 0) == pdTRUE, err = CHIP_ERROR_NO_MEMORY); + otTaskletsSignalPending(NULL); + +exit: + return err; +} + +void BLEManagerCommon::BleAdvTimeoutHandler(TimerHandle_t xTimer) +{ + if (BLEMgrImpl().mFlags.Has(Flags::kFastAdvertisingEnabled)) + { + ChipLogDetail(DeviceLayer, "Start slow advertisement"); + BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kSlowAdvertising); + } +} + +void BLEManagerCommon::CancelBleAdvTimeoutTimer(void) +{ + if (xTimerStop(sbleAdvTimeoutTimer, 0) == pdFAIL) + { + ChipLogError(DeviceLayer, "Failed to stop BledAdv timeout timer"); + } +} + +void BLEManagerCommon::StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs) +{ + if (xTimerIsTimerActive(sbleAdvTimeoutTimer)) + { + CancelBleAdvTimeoutTimer(); + } + + // timer is not active, change its period to required value (== restart). + // FreeRTOS- Block for a maximum of 100 ticks if the change period command + // cannot immediately be sent to the timer command queue. + if (xTimerChangePeriod(sbleAdvTimeoutTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) != pdPASS) + { + ChipLogError(DeviceLayer, "Failed to start BledAdv timeout timer"); + } +} + +CHIP_ERROR BLEManagerCommon::blekw_stop_connection_internal(BLE_CONNECTION_OBJECT conId) +{ + ChipLogProgress(DeviceLayer, "Closing BLE GATT connection (con %u)", conId); + + if (Gap_Disconnect(conId) != gBleSuccess_c) + { + ChipLogProgress(DeviceLayer, "Gap_Disconnect() failed."); + return CHIP_ERROR_INTERNAL; + } +#if defined(chip_with_low_power) && (chip_with_low_power == 1) + else + { + bleAppStopInProgress = TRUE; + PWR_DisallowDeviceToSleep(); + } +#endif + + return CHIP_NO_ERROR; +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip +#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE diff --git a/src/platform/nxp/common/legacy/BLEManagerCommon.h b/src/platform/nxp/common/legacy/BLEManagerCommon.h new file mode 100644 index 00000000000000..b7fc1275d2501f --- /dev/null +++ b/src/platform/nxp/common/legacy/BLEManagerCommon.h @@ -0,0 +1,249 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * Copyright (c) 2020 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the BLEManager singleton object + * for the K32W platforms. + */ + +#pragma once + +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + +#include "fsl_os_abstraction.h" + +#include "ble_conn_manager.h" +#include "ble_general.h" +#include "ble_host_task_config.h" +#include "ble_host_tasks.h" +#include "gap_interface.h" +#include "gatt_db_dynamic.h" +#include "gatt_server_interface.h" + +#include "FreeRTOS.h" +#include "event_groups.h" +#include "timers.h" + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +using namespace chip::Ble; + +/** + * A delegate class that can be used by the application to subscribe to BLE events. + */ +struct BLECallbackDelegate +{ + using GapGenericCallback = void (*)(gapGenericEvent_t * event); + using GattServerCallback = void (*)(deviceId_t id, gattServerEvent_t * event); + + GapGenericCallback gapCallback = nullptr; + GattServerCallback gattCallback = nullptr; +}; + +/** + * Base class for different platform implementations (K32W0 and K32W1 for now). + */ +class BLEManagerCommon : public BLEManager, protected BleLayer, private BlePlatformDelegate, private BleApplicationDelegate +{ +protected: + // ===== Members that implement the BLEManager internal interface. + + CHIP_ERROR _Init(void); + CHIP_ERROR _Shutdown() { return CHIP_NO_ERROR; } + CHIPoBLEServiceMode _GetCHIPoBLEServiceMode(void); + CHIP_ERROR _SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val); + bool _IsAdvertisingEnabled(void); + CHIP_ERROR _SetAdvertisingEnabled(bool val); + bool _IsAdvertising(void); + CHIP_ERROR _SetAdvertisingMode(BLEAdvertisingMode mode); + CHIP_ERROR _GetDeviceName(char * buf, size_t bufSize); + CHIP_ERROR _SetDeviceName(const char * deviceName); + uint16_t _NumConnections(void); + void _OnPlatformEvent(const ChipDeviceEvent * event); + + // ===== Members that implement virtual methods on BlePlatformDelegate. + + CHIP_ERROR SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, + const Ble::ChipBleUUID * charId) override; + CHIP_ERROR UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, + const Ble::ChipBleUUID * charId) override; + CHIP_ERROR CloseConnection(BLE_CONNECTION_OBJECT conId) override; + uint16_t GetMTU(BLE_CONNECTION_OBJECT conId) const override; + CHIP_ERROR SendIndication(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId, + System::PacketBufferHandle pBuf) override; + CHIP_ERROR SendWriteRequest(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId, + System::PacketBufferHandle pBuf) override; + + // ===== Members that implement virtual methods on BleApplicationDelegate. + + void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) override; + + // ===== Private members reserved for use by this class only. + + enum class Flags : uint8_t + { + kAdvertisingEnabled = 0x0001, + kFastAdvertisingEnabled = 0x0002, + kAdvertising = 0x0004, + kRestartAdvertising = 0x0008, + kK32WBLEStackInitialized = 0x0010, + kDeviceNameSet = 0x0020, + }; + BitFlags<BLEManagerCommon::Flags> mFlags; + + enum + { + kMaxDeviceNameLength = 16, + kUnusedIndex = 0xFF, + }; + + typedef enum + { + BLE_KW_MSG_ERROR = 0x01, + BLE_KW_MSG_CONNECTED, + BLE_KW_MSG_DISCONNECTED, + BLE_KW_MSG_MTU_CHANGED, + BLE_KW_MSG_ATT_WRITTEN, + BLE_KW_MSG_ATT_LONG_WRITTEN, + BLE_KW_MSG_ATT_READ, + BLE_KW_MSG_ATT_CCCD_WRITTEN, + BLE_KW_MSG_FORCE_DISCONNECT, + } blekw_msg_type_t; + + typedef struct hk_ble_kw_msg_s + { + blekw_msg_type_t type; + uint16_t length; + union + { + uint8_t u8; + uint16_t u16; + uint32_t u32; + uint8_t data[1]; + char * str; + } data; + } blekw_msg_t; + + typedef enum ble_err_t + { + BLE_OK = 0, + BLE_INTERNAL_GATT_ERROR, + BLE_E_SET_ADV_PARAMS, + BLE_E_ADV_PARAMS_FAILED, + BLE_E_SET_ADV_DATA, + BLE_E_ADV_CHANGED, + BLE_E_ADV_FAILED, + BLE_E_ADV_SETUP_FAILED, + BLE_E_START_ADV, + BLE_E_STOP, + BLE_E_FAIL, + BLE_E_START_ADV_FAILED, + BLE_KW_MSG_2M_UPGRADE_ERROR, + BLE_INTERNAL_ERROR, + } ble_err_t; + + typedef struct ble_att_written_data_s + { + uint8_t device_id; + uint16_t handle; + uint16_t length; + uint8_t data[1]; + } blekw_att_written_data_t; + + typedef struct hk_ble_att_read_data_s + { + uint8_t device_id; + uint16_t handle; + } blekw_att_read_data_t; + + CHIPoBLEServiceMode mServiceMode; + char mDeviceName[kMaxDeviceNameLength + 1]; +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + chip::System::PacketBufferHandle c3AdditionalDataBufferHandle; +#endif + uint8_t mDeviceId; + bool mDeviceSubscribed = false; + bool mDeviceConnected = false; + + void DriveBLEState(void); + CHIP_ERROR ConfigureAdvertising(void); + CHIP_ERROR ConfigureAdvertisingData(void); + CHIP_ERROR StartAdvertising(void); + CHIP_ERROR StopAdvertising(void); + + void HandleConnectEvent(blekw_msg_t * msg); + void HandleConnectionCloseEvent(blekw_msg_t * msg); + void HandleWriteEvent(blekw_msg_t * msg); + void HandleRXCharWrite(blekw_msg_t * msg); + void HandleTXCharCCCDWrite(blekw_msg_t * msg); + void HandleForceDisconnect(); + +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + CHIP_ERROR EncodeAdditionalDataTlv(); + void HandleC3ReadRequest(blekw_msg_t * msg); +#endif + BLEManagerCommon::ble_err_t blekw_send_event(int8_t connection_handle, uint16_t handle, uint8_t * data, uint32_t len); + + static void DriveBLEState(intptr_t arg); + static void StopAdvertisingPriorToSwitchingMode(intptr_t arg); + static void BleAdvTimeoutHandler(TimerHandle_t xTimer); + static void CancelBleAdvTimeoutTimer(void); + static void StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs); + + static void blekw_connection_timeout_cb(TimerHandle_t timer); + static void blekw_generic_cb(gapGenericEvent_t * pGenericEvent); + static void blekw_gatt_server_cb(deviceId_t deviceId, gattServerEvent_t * pServerEvent); + static CHIP_ERROR blekw_msg_add_u8(blekw_msg_type_t type, uint8_t data); + static CHIP_ERROR blekw_msg_add_u16(blekw_msg_type_t type, uint16_t data); + static CHIP_ERROR blekw_msg_add_att_written(blekw_msg_type_t type, uint8_t device_id, uint16_t handle, uint8_t * data, + uint16_t length); + static CHIP_ERROR blekw_msg_add_att_read(blekw_msg_type_t type, uint8_t device_id, uint16_t handle); + static BLEManagerCommon::ble_err_t blekw_start_advertising(gapAdvertisingParameters_t * adv_params, gapAdvertisingData_t * adv, + gapScanResponseData_t * scnrsp); + static BLEManagerCommon::ble_err_t blekw_stop_advertising(void); + static void blekw_gap_advertising_cb(gapAdvertisingEvent_t * pAdvertisingEvent); + static void blekw_gap_connection_cb(deviceId_t deviceId, gapConnectionEvent_t * pConnectionEvent); + static void blekw_start_connection_timeout(void); + static void blekw_stop_connection_timeout(void); + static CHIP_ERROR blekw_stop_connection_internal(BLE_CONNECTION_OBJECT conId); + +public: + virtual CHIP_ERROR InitHostController(BLECallbackDelegate::GapGenericCallback cb_fp) = 0; + virtual BLEManagerCommon * GetImplInstance() = 0; + virtual CHIP_ERROR ResetController() { return CHIP_NO_ERROR; } + void DoBleProcessing(void); + + BLECallbackDelegate callbackDelegate; + void RegisterAppCallbacks(BLECallbackDelegate::GapGenericCallback gapCallback, + BLECallbackDelegate::GattServerCallback gattCallback); +}; + +inline BLEManager::CHIPoBLEServiceMode BLEManagerCommon::_GetCHIPoBLEServiceMode(void) +{ + return mServiceMode; +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip + +#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE diff --git a/src/platform/nxp/common/legacy/FactoryDataDriver.cpp b/src/platform/nxp/common/legacy/FactoryDataDriver.cpp new file mode 100644 index 00000000000000..6ddbedc3ca35c8 --- /dev/null +++ b/src/platform/nxp/common/legacy/FactoryDataDriver.cpp @@ -0,0 +1,76 @@ +/* + * + * Copyright (c) 2024 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 <lib/support/CodeUtils.h> +#include <lib/support/Span.h> +#include <platform/nxp/common/legacy/FactoryDataDriver.h> +#include <platform/nxp/common/legacy/FactoryDataProvider.h> + +namespace chip { +namespace DeviceLayer { + +FactoryDataDriver::~FactoryDataDriver() {} + +CHIP_ERROR FactoryDataDriver::UpdateValueInRam(uint8_t tag, ByteSpan & newValue) +{ + uint16_t oldLength = 0; + uint16_t newLength = newValue.size(); + uint32_t offset = 0; + uint8_t * factoryData = mFactoryDataRamBuff; + FactoryDataProvider::Header * header = (FactoryDataProvider::Header *) factoryData; + uint8_t * data = factoryData + sizeof(FactoryDataProvider::Header); + + while (offset < header->size) + { + memcpy(&oldLength, &data[offset + FactoryDataProvider::kLengthOffset], sizeof(oldLength)); + + if (tag != data[offset]) + { + offset += FactoryDataProvider::kValueOffset + oldLength; + continue; + } + + if (oldLength == newLength) + { + memcpy(&data[offset + FactoryDataProvider::kValueOffset], newValue.data(), newLength); + } + else + { + uint32_t oldEndOffset = offset + FactoryDataProvider::kValueOffset + oldLength; + + memcpy(&data[offset + FactoryDataProvider::kLengthOffset], &newLength, sizeof(newLength)); + memmove(&data[offset + FactoryDataProvider::kValueOffset + newLength], &data[oldEndOffset], + header->size - oldEndOffset); + memcpy(&data[offset + FactoryDataProvider::kValueOffset], newValue.data(), newLength); + } + + header->size = header->size - oldLength + newLength; + + uint8_t sha256Output[SHA256_HASH_SIZE] = { 0 }; + SHA256_Hash(data, header->size, sha256Output); + memcpy(header->hash, sha256Output, sizeof(header->hash)); + + ChipLogProgress(DeviceLayer, "Value at tag %d updated successfully.", tag); + return CHIP_NO_ERROR; + } + + ChipLogError(DeviceLayer, "Failed to find tag %d.", tag); + return CHIP_ERROR_NOT_FOUND; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/common/legacy/FactoryDataDriver.h b/src/platform/nxp/common/legacy/FactoryDataDriver.h new file mode 100644 index 00000000000000..93eb43a183e23c --- /dev/null +++ b/src/platform/nxp/common/legacy/FactoryDataDriver.h @@ -0,0 +1,113 @@ +/* + * + * Copyright (c) 2024 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. + */ +#pragma once + +namespace chip { +namespace DeviceLayer { + +// Forward declaration to define the getter for factory data provider impl instance +class FactoryDataDriverImpl; + +/** + * @brief This interface provides the functions that should be implemented + * to handle factory data update and factory data ram backup operations. + * This interface must be implemented by each platform. + */ + +class FactoryDataDriver +{ +public: + virtual ~FactoryDataDriver(); + + /*! + * \brief Initializes the FactoryDataDriver instance. + * + * @retval CHIP_NO_ERROR if operation was successful. + */ + virtual CHIP_ERROR Init() = 0; + + /*! + * \brief Checks whether the backup of the factory data exists (e.g in persistent storage). + * + * @retval true if backup exists otherwise return false. + */ + virtual bool DoesBackupExist(uint16_t * size) = 0; + + /*! + * \brief Deletes the backup of the factory data (e.g. from persistent storage). + * + * @retval CHIP_NO_ERROR if operation was successful. + */ + virtual CHIP_ERROR DeleteBackup(void) = 0; + + /*! + * \brief Allocates and initializes the factory data ram backup and copies + * factory data into it. + * + * @retval CHIP_NO_ERROR if operation was successful. + */ + virtual CHIP_ERROR InitRamBackup(void) = 0; + + /*! + * \brief Clear and deallocate the factory data ram backup. + * + * @retval CHIP_NO_ERROR if operation was successful. + */ + virtual CHIP_ERROR ClearRamBackup(void) = 0; + + /*! + * \brief Read the factory data from persistent storage into the factory data + * ram backup. + * + * @retval CHIP_NO_ERROR if operation was successful. + */ + virtual CHIP_ERROR ReadBackupInRam(void) = 0; + + /*! + * \brief Save / Backup the factory data into the persistent storage + * + * @retval CHIP_NO_ERROR if operation was successful. + */ + virtual CHIP_ERROR BackupFactoryData(void) = 0; + + /*! + * \brief Update / Write the factory data from the ram buffer + * + * @retval CHIP_NO_ERROR if operation was successful. + */ + virtual CHIP_ERROR UpdateFactoryData(void) = 0; + + /*! + * \brief Update TLV value from factory data based on tag + * @param tag TLV tag of component to update + * @param newValue Reference to the new value of the TLV component + * @retval CHIP_NO_ERROR if operation was successful. + */ + CHIP_ERROR UpdateValueInRam(uint8_t tag, ByteSpan & newValue); + +protected: + uint8_t * mFactoryDataRamBuff = nullptr; + uint32_t mSize = 0; + uint32_t mMaxSize = 0; +}; + +extern FactoryDataDriver & FactoryDataDrv(); + +extern FactoryDataDriverImpl & FactoryDataDrvImpl(); + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/common/legacy/FactoryDataProvider.cpp b/src/platform/nxp/common/legacy/FactoryDataProvider.cpp new file mode 100644 index 00000000000000..7ecc29a54cf077 --- /dev/null +++ b/src/platform/nxp/common/legacy/FactoryDataProvider.cpp @@ -0,0 +1,442 @@ +/* + * + * 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. + */ + +#if (!CONFIG_CHIP_LOAD_REAL_FACTORY_DATA || !(defined CONFIG_CHIP_LOAD_REAL_FACTORY_DATA)) +#include <credentials/examples/DeviceAttestationCredsExample.h> +#include <credentials/examples/ExampleDACs.h> +#include <credentials/examples/ExamplePAI.h> +#endif + +#include <credentials/CHIPCert.h> +#include <credentials/CertificationDeclaration.h> +#include <crypto/CHIPCryptoPAL.h> +#include <lib/core/CHIPError.h> +#include <lib/core/TLV.h> +#include <lib/support/Base64.h> +#include <lib/support/Span.h> +#include <platform/ConfigurationManager.h> +#include <platform/nxp/common/legacy/FactoryDataProvider.h> + +#include <cctype> + +namespace chip { +namespace DeviceLayer { + +static constexpr size_t kSpake2pSerializedVerifier_MaxBase64Len = + BASE64_ENCODED_LEN(chip::Crypto::kSpake2p_VerifierSerialized_Length) + 1; +static constexpr size_t kSpake2pSalt_MaxBase64Len = BASE64_ENCODED_LEN(chip::Crypto::kSpake2p_Max_PBKDF_Salt_Length) + 1; +/* Secure subsystem private key blob size is 32 + 24 = 56. + * DAC private key may be used to store an SSS exported blob instead of the private key. + */ +static constexpr size_t kDacPrivateKey_MaxLen = Crypto::kP256_PrivateKey_Length + 24; + +FactoryDataProvider::~FactoryDataProvider() {} + +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR + +CHIP_ERROR FactoryDataProvider::ValidateWithRestore() +{ + CHIP_ERROR error = CHIP_NO_ERROR; + + VerifyOrReturnError(mRestoreMechanisms.size() > 0, CHIP_FACTORY_DATA_RESTORE_MECHANISM); + + for (auto & restore : mRestoreMechanisms) + { + error = restore(); + if (error != CHIP_NO_ERROR) + { + continue; + } + + error = Validate(); + if (error != CHIP_NO_ERROR) + { + continue; + } + + break; + } + + if (error == CHIP_NO_ERROR) + { + error = mFactoryDataDriver->DeleteBackup(); + } + + return error; +} + +void FactoryDataProvider::RegisterRestoreMechanism(RestoreMechanism restore) +{ + mRestoreMechanisms.insert(mRestoreMechanisms.end(), restore); +} + +#endif + +CHIP_ERROR FactoryDataProvider::SignWithDacKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + Crypto::P256ECDSASignature signature; + Crypto::P256Keypair keypair; + Crypto::P256SerializedKeypair serializedKeypair; + uint8_t keyBuf[Crypto::kP256_PrivateKey_Length]; + MutableByteSpan dacPrivateKeySpan(keyBuf); + uint16_t keySize = 0; + + VerifyOrExit(!outSignBuffer.empty(), error = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit(!messageToSign.empty(), error = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit(outSignBuffer.size() >= signature.Capacity(), error = CHIP_ERROR_BUFFER_TOO_SMALL); + + /* Get private key of DAC certificate from reserved section */ + error = SearchForId(FactoryDataId::kDacPrivateKeyId, dacPrivateKeySpan.data(), dacPrivateKeySpan.size(), keySize); + SuccessOrExit(error); + dacPrivateKeySpan.reduce_size(keySize); + + /* Only the private key is used when signing */ + error = serializedKeypair.SetLength(Crypto::kP256_PublicKey_Length + dacPrivateKeySpan.size()); + SuccessOrExit(error); + memcpy(serializedKeypair.Bytes() + Crypto::kP256_PublicKey_Length, dacPrivateKeySpan.data(), dacPrivateKeySpan.size()); + + error = keypair.Deserialize(serializedKeypair); + SuccessOrExit(error); + + error = keypair.ECDSA_sign_msg(messageToSign.data(), messageToSign.size(), signature); + SuccessOrExit(error); + + error = CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, outSignBuffer); + +exit: + /* Sanitize temporary buffer */ + memset(keyBuf, 0, Crypto::kP256_PrivateKey_Length); + return error; +} + +CHIP_ERROR FactoryDataProvider::Validate() +{ + uint8_t output[Crypto::kSHA256_Hash_Length] = { 0 }; + + memcpy(&mHeader, (void *) mConfig.start, sizeof(Header)); + ReturnErrorCodeIf(mHeader.hashId != kHashId, CHIP_FACTORY_DATA_HASH_ID); + + ReturnErrorOnFailure(Crypto::Hash_SHA256((uint8_t *) mConfig.payload, mHeader.size, output)); + ReturnErrorCodeIf(memcmp(output, mHeader.hash, kHashLen) != 0, CHIP_FACTORY_DATA_SHA_CHECK); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::SearchForId(uint8_t searchedType, uint8_t * pBuf, size_t bufLength, uint16_t & length, + uint32_t * offset) +{ + uint32_t addr = mConfig.payload; + uint8_t type = 0; + + while (addr < (mConfig.payload + mHeader.size)) + { + memcpy(&type, (void *) addr, sizeof(type)); + memcpy(&length, (void *) (addr + 1), sizeof(length)); + + if (searchedType == type) + { + ReturnErrorCodeIf(bufLength < length, CHIP_ERROR_BUFFER_TOO_SMALL); + memcpy(pBuf, (void *) (addr + kValueOffset), length); + + if (offset) + *offset = (addr - mConfig.payload); + + return CHIP_NO_ERROR; + } + else + { + /* Jump past 3 bytes of length and then use length to jump to next data */ + addr = addr + kValueOffset + length; + } + } + + return CHIP_ERROR_NOT_FOUND; +} + +CHIP_ERROR FactoryDataProvider::GetCertificationDeclaration(MutableByteSpan & outBuffer) +{ +#if CHIP_USE_DEVICE_CONFIG_CERTIFICATION_DECLARATION + constexpr uint8_t kCdForAllExamples[] = CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION; + + return CopySpanToMutableSpan(ByteSpan{ kCdForAllExamples }, outBuffer); +#else + uint16_t declarationSize = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kCertDeclarationId, outBuffer.data(), outBuffer.size(), declarationSize)); + outBuffer.reduce_size(declarationSize); + + return CHIP_NO_ERROR; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) +{ + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & outBuffer) +{ + uint16_t certificateSize = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kDacCertificateId, outBuffer.data(), outBuffer.size(), certificateSize)); + outBuffer.reduce_size(certificateSize); + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) +{ + uint16_t certificateSize = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kPaiCertificateId, outBuffer.data(), outBuffer.size(), certificateSize)); + outBuffer.reduce_size(certificateSize); + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) +{ + return SignWithDacKey(messageToSign, outSignBuffer); +} + +CHIP_ERROR FactoryDataProvider::GetSetupDiscriminator(uint16_t & setupDiscriminator) +{ + uint32_t discriminator = 0; + uint16_t temp = 0; + + ReturnErrorOnFailure(SearchForId(FactoryDataId::kDiscriminatorId, (uint8_t *) &discriminator, sizeof(discriminator), temp)); + setupDiscriminator = (uint16_t) (discriminator & 0x0000FFFF); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::SetSetupDiscriminator(uint16_t setupDiscriminator) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR FactoryDataProvider::GetSpake2pIterationCount(uint32_t & iterationCount) +{ + uint16_t temp = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kIcId, (uint8_t *) &iterationCount, sizeof(iterationCount), temp)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) +{ + char saltB64[kSpake2pSalt_MaxBase64Len] = { 0 }; + uint16_t saltB64Len = 0; + + ReturnErrorOnFailure(SearchForId(FactoryDataId::kSaltId, (uint8_t *) (&saltB64[0]), sizeof(saltB64), saltB64Len)); + size_t saltLen = chip::Base64Decode32(saltB64, saltB64Len, reinterpret_cast<uint8_t *>(saltB64)); + + ReturnErrorCodeIf(saltLen > saltBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + memcpy(saltBuf.data(), saltB64, saltLen); + saltBuf.reduce_size(saltLen); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) +{ + char verifierB64[kSpake2pSerializedVerifier_MaxBase64Len] = { 0 }; + uint16_t verifierB64Len = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kVerifierId, (uint8_t *) &verifierB64[0], sizeof(verifierB64), verifierB64Len)); + + verifierLen = chip::Base64Decode32(verifierB64, verifierB64Len, reinterpret_cast<uint8_t *>(verifierB64)); + ReturnErrorCodeIf(verifierLen > verifierBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + memcpy(verifierBuf.data(), verifierB64, verifierLen); + verifierBuf.reduce_size(verifierLen); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetSetupPasscode(uint32_t & setupPasscode) +{ + uint16_t length = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kSetupPasscodeId, (uint8_t *) &setupPasscode, sizeof(setupPasscode), length)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::SetSetupPasscode(uint32_t setupPasscode) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR FactoryDataProvider::GetVendorName(char * buf, size_t bufSize) +{ + uint16_t length = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kVendorNameId, (uint8_t *) buf, bufSize, length)); + buf[length] = '\0'; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetVendorId(uint16_t & vendorId) +{ + uint16_t length = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kVidId, (uint8_t *) &vendorId, sizeof(vendorId), length)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetProductName(char * buf, size_t bufSize) +{ + uint16_t length = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kProductNameId, (uint8_t *) buf, bufSize, length)); + buf[length] = '\0'; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetProductId(uint16_t & productId) +{ + uint16_t length = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kPidId, (uint8_t *) &productId, sizeof(productId), length)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetPartNumber(char * buf, size_t bufSize) +{ + uint16_t length = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kPartNumber, (uint8_t *) buf, bufSize, length)); + buf[length] = '\0'; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetProductURL(char * buf, size_t bufSize) +{ + uint16_t length = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kProductURL, (uint8_t *) buf, bufSize, length)); + buf[length] = '\0'; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetProductLabel(char * buf, size_t bufSize) +{ + uint16_t length = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kProductLabel, (uint8_t *) buf, bufSize, length)); + buf[length] = '\0'; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetSerialNumber(char * buf, size_t bufSize) +{ + uint16_t length = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kSerialNumberId, (uint8_t *) buf, bufSize, length)); + buf[length] = '\0'; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) +{ + uint16_t length = 0; + uint8_t date[ConfigurationManager::kMaxManufacturingDateLength]; + + ReturnErrorOnFailure( + SearchForId(FactoryDataId::kManufacturingDateId, date, ConfigurationManager::kMaxManufacturingDateLength, length)); + date[length] = '\0'; + + if (length == 10 && isdigit(date[0]) && isdigit(date[1]) && isdigit(date[2]) && isdigit(date[3]) && date[4] == '-' && + isdigit(date[5]) && isdigit(date[6]) && date[7] == '-' && isdigit(date[8]) && isdigit(date[9])) + { + year = 1000 * (date[0] - '0') + 100 * (date[1] - '0') + 10 * (date[2] - '0') + date[3] - '0'; + month = 10 * (date[5] - '0') + date[6] - '0'; + day = 10 * (date[8] - '0') + date[9] - '0'; + } + else + { + ChipLogError(DeviceLayer, "Manufacturing date is not formatted correctly: YYYY-MM-DD."); + return CHIP_ERROR_INVALID_ARGUMENT; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetHardwareVersion(uint16_t & hardwareVersion) +{ + uint16_t length = 0; + ReturnErrorOnFailure( + SearchForId(FactoryDataId::kHardwareVersionId, (uint8_t *) &hardwareVersion, sizeof(hardwareVersion), length)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetHardwareVersionString(char * buf, size_t bufSize) +{ + uint16_t length = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kHardwareVersionStrId, (uint8_t *) buf, bufSize, length)); + buf[length] = '\0'; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) +{ + CHIP_ERROR err = CHIP_ERROR_NOT_IMPLEMENTED; +#if CHIP_ENABLE_ROTATING_DEVICE_ID + static_assert(ConfigurationManager::kRotatingDeviceIDUniqueIDLength >= ConfigurationManager::kMinRotatingDeviceIDUniqueIDLength, + "Length of unique ID for rotating device ID is smaller than minimum."); + uint16_t uniqueIdLen = 0; + err = SearchForId(FactoryDataId::kUniqueId, (uint8_t *) uniqueIdSpan.data(), uniqueIdSpan.size(), uniqueIdLen); +#if defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID) + if (err != CHIP_NO_ERROR) + { + constexpr uint8_t uniqueId[] = CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID; + + ReturnErrorCodeIf(sizeof(uniqueId) > uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + memcpy(uniqueIdSpan.data(), uniqueId, sizeof(uniqueId)); + uniqueIdLen = sizeof(uniqueId); + err = CHIP_NO_ERROR; + } +#endif // CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID + ReturnErrorOnFailure(err); + uniqueIdSpan.reduce_size(uniqueIdLen); +#endif + + return err; +} + +CHIP_ERROR FactoryDataProvider::GetProductFinish(app::Clusters::BasicInformation::ProductFinishEnum * finish) +{ + uint8_t productFinish; + uint16_t length = 0; + auto err = SearchForId(FactoryDataId::kProductFinish, &productFinish, sizeof(productFinish), length); + ReturnErrorCodeIf(err != CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); + + *finish = static_cast<app::Clusters::BasicInformation::ProductFinishEnum>(productFinish); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetProductPrimaryColor(app::Clusters::BasicInformation::ColorEnum * primaryColor) +{ + uint8_t color; + uint16_t length = 0; + auto err = SearchForId(FactoryDataId::kProductPrimaryColor, &color, sizeof(color), length); + ReturnErrorCodeIf(err != CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); + + *primaryColor = static_cast<app::Clusters::BasicInformation::ColorEnum>(color); + + return CHIP_NO_ERROR; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/common/legacy/FactoryDataProvider.h b/src/platform/nxp/common/legacy/FactoryDataProvider.h new file mode 100644 index 00000000000000..f7d05c3f1da1f4 --- /dev/null +++ b/src/platform/nxp/common/legacy/FactoryDataProvider.h @@ -0,0 +1,177 @@ +/* + * + * 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. + */ +#pragma once + +#include <credentials/DeviceAttestationCredsProvider.h> +#include <platform/CommissionableDataProvider.h> +#include <platform/internal/GenericDeviceInstanceInfoProvider.h> +#include <src/lib/core/CHIPError.h> + +#include <platform/nxp/common/legacy/FactoryDataDriver.h> + +#include <vector> + +#include "CHIPPlatformConfig.h" + +#include <vector> + +namespace chip { +namespace DeviceLayer { + +#define CHIP_FACTORY_DATA_ERROR(e) \ + ChipError(ChipError::Range::kLastRange, ((uint8_t) ChipError::Range::kLastRange << 2) | e, __FILE__, __LINE__) + +#define CHIP_FACTORY_DATA_SHA_CHECK CHIP_FACTORY_DATA_ERROR(0x01) +#define CHIP_FACTORY_DATA_HEADER_READ CHIP_FACTORY_DATA_ERROR(0x02) +#define CHIP_FACTORY_DATA_HASH_ID CHIP_FACTORY_DATA_ERROR(0x03) +#define CHIP_FACTORY_DATA_PDM_RESTORE CHIP_FACTORY_DATA_ERROR(0x04) +#define CHIP_FACTORY_DATA_NULL CHIP_FACTORY_DATA_ERROR(0x05) +#define CHIP_FACTORY_DATA_FLASH_ERASE CHIP_FACTORY_DATA_ERROR(0x06) +#define CHIP_FACTORY_DATA_FLASH_PROGRAM CHIP_FACTORY_DATA_ERROR(0x07) +#define CHIP_FACTORY_DATA_INTERNAL_FLASH_READ CHIP_FACTORY_DATA_ERROR(0x08) +#define CHIP_FACTORY_DATA_PDM_SAVE_RECORD CHIP_FACTORY_DATA_ERROR(0x09) +#define CHIP_FACTORY_DATA_PDM_READ_RECORD CHIP_FACTORY_DATA_ERROR(0x0A) +#define CHIP_FACTORY_DATA_RESTORE_MECHANISM CHIP_FACTORY_DATA_ERROR(0x0B) + +// Forward declaration to define the getter for factory data provider impl instance +class FactoryDataProviderImpl; + +/** + * @brief This class provides Commissionable data, Device Attestation Credentials, + * and Device Instance Info. + */ + +class FactoryDataProvider : public DeviceInstanceInfoProvider, + public CommissionableDataProvider, + public Credentials::DeviceAttestationCredentialsProvider +{ +public: + struct Header + { + uint32_t hashId; + uint32_t size; + uint8_t hash[4]; + }; + + struct FactoryDataConfig + { + uint32_t start; + uint32_t size; + uint32_t payload; + }; + + // Default factory data IDs + enum FactoryDataId + { + kVerifierId = 1, + kSaltId, + kIcId, + kDacPrivateKeyId, + kDacCertificateId, + kPaiCertificateId, + kDiscriminatorId, + kSetupPasscodeId, + kVidId, + kPidId, + kCertDeclarationId, + kVendorNameId, + kProductNameId, + kSerialNumberId, + kManufacturingDateId, + kHardwareVersionId, + kHardwareVersionStrId, + kUniqueId, + kPartNumber, + kProductURL, + kProductLabel, + kProductFinish, + kProductPrimaryColor, + kMaxId + }; + + static uint32_t kFactoryDataMaxSize; + static constexpr uint32_t kLengthOffset = 1; + static constexpr uint32_t kValueOffset = 3; + static constexpr uint32_t kHashLen = 4; + static constexpr size_t kHashId = 0xCE47BA5E; + + virtual ~FactoryDataProvider(); + + virtual CHIP_ERROR Init() = 0; + virtual CHIP_ERROR SignWithDacKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer); + virtual CHIP_ERROR Validate(); + + virtual CHIP_ERROR SearchForId(uint8_t searchedType, uint8_t * pBuf, size_t bufLength, uint16_t & length, + uint32_t * offset = nullptr); + +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR + using RestoreMechanism = CHIP_ERROR (*)(void); + + CHIP_ERROR ValidateWithRestore(); + void RegisterRestoreMechanism(RestoreMechanism mechanism); + + virtual CHIP_ERROR PreResetCheck() = 0; + virtual CHIP_ERROR PostResetCheck() = 0; +#endif + + // ===== Members functions that implement the CommissionableDataProvider + CHIP_ERROR GetSetupDiscriminator(uint16_t & setupDiscriminator) override; + CHIP_ERROR SetSetupDiscriminator(uint16_t setupDiscriminator) override; + CHIP_ERROR GetSpake2pIterationCount(uint32_t & iterationCount) override; + CHIP_ERROR GetSpake2pSalt(MutableByteSpan & saltBuf) override; + CHIP_ERROR GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) override; + CHIP_ERROR GetSetupPasscode(uint32_t & setupPasscode) override; + CHIP_ERROR SetSetupPasscode(uint32_t setupPasscode) override; + + // ===== Members functions that implement the DeviceAttestationCredentialsProvider + CHIP_ERROR GetCertificationDeclaration(MutableByteSpan & outBuffer) override; + CHIP_ERROR GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) override; + CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & outBuffer) override; + CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) override; + CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) override; + + // ===== Members functions that implement the GenericDeviceInstanceInfoProvider + CHIP_ERROR GetVendorName(char * buf, size_t bufSize) override; + CHIP_ERROR GetVendorId(uint16_t & vendorId) override; + CHIP_ERROR GetProductName(char * buf, size_t bufSize) override; + CHIP_ERROR GetProductId(uint16_t & productId) override; + CHIP_ERROR GetPartNumber(char * buf, size_t bufSize) override; + CHIP_ERROR GetProductURL(char * buf, size_t bufSize) override; + CHIP_ERROR GetProductLabel(char * buf, size_t bufSize) override; + CHIP_ERROR GetHardwareVersionString(char * buf, size_t bufSize) override; + CHIP_ERROR GetSerialNumber(char * buf, size_t bufSize) override; + CHIP_ERROR GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) override; + CHIP_ERROR GetHardwareVersion(uint16_t & hardwareVersion) override; + CHIP_ERROR GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) override; + CHIP_ERROR GetProductFinish(app::Clusters::BasicInformation::ProductFinishEnum * finish) override; + CHIP_ERROR GetProductPrimaryColor(app::Clusters::BasicInformation::ColorEnum * primaryColor) override; + +protected: + Header mHeader; + FactoryDataConfig mConfig; +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR + std::vector<RestoreMechanism> mRestoreMechanisms; + FactoryDataDriver * mFactoryDataDriver = nullptr; +#endif +}; + +extern FactoryDataProvider & FactoryDataPrvd(); + +extern FactoryDataProviderImpl & FactoryDataPrvdImpl(); + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/common/legacy/OTAFactoryDataProcessor.cpp b/src/platform/nxp/common/legacy/OTAFactoryDataProcessor.cpp new file mode 100644 index 00000000000000..4960ca2c4e0669 --- /dev/null +++ b/src/platform/nxp/common/legacy/OTAFactoryDataProcessor.cpp @@ -0,0 +1,165 @@ +/* + * + * Copyright (c) 2023 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 <app/server/Server.h> +#include <lib/core/TLV.h> +#include <platform/internal/CHIPDeviceLayerInternal.h> +#include <platform/nxp/common/legacy/OTAFactoryDataProcessor.h> + +namespace chip { + +CHIP_ERROR OTAFactoryDataProcessor::Init() +{ + mAccumulator.Init(mLength); + mFactoryDataDriver = &chip::DeviceLayer::FactoryDataDrv(); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAFactoryDataProcessor::Clear() +{ + OTATlvProcessor::ClearInternal(); + mAccumulator.Clear(); + mPayload.Clear(); + mFactoryDataDriver->ClearRamBackup(); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAFactoryDataProcessor::ProcessInternal(ByteSpan & block) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + + ReturnErrorOnFailure(mAccumulator.Accumulate(block)); +#if OTA_ENCRYPTION_ENABLE + MutableByteSpan mBlock = MutableByteSpan(mAccumulator.data(), mAccumulator.GetThreshold()); + OTATlvProcessor::vOtaProcessInternalEncryption(mBlock); +#endif + error = DecodeTlv(); + + if (error != CHIP_NO_ERROR) + { + // The factory data payload can contain a variable number of fields + // to be updated. CHIP_END_OF_TLV is returned if no more fields are + // found. + if (error == CHIP_END_OF_TLV) + { + return CHIP_NO_ERROR; + } + + Clear(); + } + + return error; +} + +CHIP_ERROR OTAFactoryDataProcessor::ApplyAction() +{ + CHIP_ERROR error = CHIP_NO_ERROR; + FactoryProvider * provider; + + ReturnErrorOnFailure(mFactoryDataDriver->InitRamBackup()); + ReturnErrorOnFailure(mFactoryDataDriver->BackupFactoryData()); + + SuccessOrExit(error = Update((uint8_t) Tags::kDacPrivateKeyId, mPayload.mCertDacKey)); + SuccessOrExit(error = Update((uint8_t) Tags::kDacCertificateId, mPayload.mCertDac)); + SuccessOrExit(error = Update((uint8_t) Tags::kPaiCertificateId, mPayload.mCertPai)); + SuccessOrExit(error = Update((uint8_t) Tags::kCertDeclarationId, mPayload.mCertDeclaration)); + + SuccessOrExit(error = mFactoryDataDriver->UpdateFactoryData()); + + provider = &chip::DeviceLayer::FactoryDataPrvd(); + VerifyOrReturnError(provider != nullptr, CHIP_ERROR_INTERNAL); + + SuccessOrExit(error = provider->PreResetCheck()); + +exit: + if (error != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to update factory data. Error: %s", ErrorStr(error)); + } + else + { + ChipLogProgress(DeviceLayer, "Factory data update finished."); + } + + return error; +} + +CHIP_ERROR OTAFactoryDataProcessor::AbortAction() +{ + CHIP_ERROR error = CHIP_NO_ERROR; + ReturnErrorOnFailure(mFactoryDataDriver->ReadBackupInRam()); + ReturnErrorOnFailure(mFactoryDataDriver->UpdateFactoryData()); + + error = mFactoryDataDriver->DeleteBackup(); + ReturnErrorOnFailure(error); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAFactoryDataProcessor::DecodeTlv() +{ + TLV::TLVReader tlvReader; + tlvReader.Init(mAccumulator.data(), mLength); + ReturnErrorOnFailure(tlvReader.Next(TLV::TLVType::kTLVType_Structure, TLV::AnonymousTag())); + + TLV::TLVType outerType; + ReturnErrorOnFailure(tlvReader.EnterContainer(outerType)); + ReturnErrorOnFailure(tlvReader.Next()); + + if (tlvReader.GetTag() == TLV::ContextTag((uint8_t) Tags::kDacPrivateKeyId)) + { + ReturnErrorOnFailure(tlvReader.Get(mPayload.mCertDacKey.Emplace())); + ReturnErrorOnFailure(tlvReader.Next()); + } + + if (tlvReader.GetTag() == TLV::ContextTag((uint8_t) Tags::kDacCertificateId)) + { + ReturnErrorOnFailure(tlvReader.Get(mPayload.mCertDac.Emplace())); + ReturnErrorOnFailure(tlvReader.Next()); + } + + if (tlvReader.GetTag() == TLV::ContextTag((uint8_t) Tags::kPaiCertificateId)) + { + ReturnErrorOnFailure(tlvReader.Get(mPayload.mCertPai.Emplace())); + ReturnErrorOnFailure(tlvReader.Next()); + } + + if (tlvReader.GetTag() == TLV::ContextTag((uint8_t) Tags::kCertDeclarationId)) + { + ReturnErrorOnFailure(tlvReader.Get(mPayload.mCertDeclaration.Emplace())); + } + + ReturnErrorOnFailure(tlvReader.ExitContainer(outerType)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAFactoryDataProcessor::Update(uint8_t tag, Optional<ByteSpan> & optional) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + if (optional.HasValue()) + { + error = mFactoryDataDriver->UpdateValueInRam(tag, optional.Value()); + } + + return error; +} + +} // namespace chip diff --git a/src/platform/nxp/common/legacy/OTAFactoryDataProcessor.h b/src/platform/nxp/common/legacy/OTAFactoryDataProcessor.h new file mode 100644 index 00000000000000..862aad2d9a6341 --- /dev/null +++ b/src/platform/nxp/common/legacy/OTAFactoryDataProcessor.h @@ -0,0 +1,78 @@ +/* + * + * Copyright (c) 2023 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 <lib/core/Optional.h> +#include <lib/support/ScopedBuffer.h> +#include <lib/support/Span.h> +#include <platform/nxp/common/legacy/FactoryDataDriver.h> +#include <platform/nxp/common/legacy/FactoryDataProvider.h> +#include <platform/nxp/common/legacy/OTATlvProcessor.h> +#include PLATFORM_FACTORY_DATA_PROVIDER_IMPL_HEADER + +namespace chip { + +using FactoryProvider = DeviceLayer::FactoryDataProvider; +using FactoryProviderImpl = DeviceLayer::FactoryDataProviderImpl; +using FactoryDataDriver = DeviceLayer::FactoryDataDriver; +using Tags = FactoryProvider::FactoryDataId; + +/** + * OTA custom payload that uses Matter TLVs. + * The custom payload is used when factory data needs updating. + * Factory data will be encoded using Matter TLV format to make + * use of the ChipTlv reader. A payload contains metadata (size of + * TLVs) and the TLVs themselves contained in a structure. + * If no factory data need to be updated, the metadata will be 0 + */ +struct OTAFactoryPayload +{ + Optional<ByteSpan> mCertDacKey; + Optional<ByteSpan> mCertDac; + Optional<ByteSpan> mCertPai; + Optional<ByteSpan> mCertDeclaration; + + void Clear() + { + mCertDacKey.ClearValue(); + mCertDac.ClearValue(); + mCertPai.ClearValue(); + mCertDeclaration.ClearValue(); + } +}; + +class OTAFactoryDataProcessor : public OTATlvProcessor +{ +public: + CHIP_ERROR Init() override; + CHIP_ERROR Clear() override; + CHIP_ERROR ApplyAction() override; + CHIP_ERROR AbortAction() override; + +private: + CHIP_ERROR ProcessInternal(ByteSpan & block) override; + CHIP_ERROR DecodeTlv(); + CHIP_ERROR Update(uint8_t tag, Optional<ByteSpan> & optional); + + OTAFactoryPayload mPayload; + OTADataAccumulator mAccumulator; + FactoryDataDriver * mFactoryDataDriver = nullptr; +}; + +} // namespace chip diff --git a/src/platform/nxp/common/legacy/OTAImageProcessorImpl.cpp b/src/platform/nxp/common/legacy/OTAImageProcessorImpl.cpp new file mode 100644 index 00000000000000..249b51b7681c22 --- /dev/null +++ b/src/platform/nxp/common/legacy/OTAImageProcessorImpl.cpp @@ -0,0 +1,424 @@ +/* + * + * Copyright (c) 2021-2023 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 <lib/support/BufferReader.h> +#include <platform/DiagnosticDataProvider.h> +#include <platform/internal/CHIPDeviceLayerInternal.h> +#include <platform/internal/GenericConfigurationManagerImpl.h> +#include <src/app/clusters/ota-requestor/OTADownloader.h> +#include <src/app/clusters/ota-requestor/OTARequestorInterface.h> + +#include <platform/nxp/common/legacy/OTAImageProcessorImpl.h> + +using namespace chip::DeviceLayer; +using namespace ::chip::DeviceLayer::Internal; + +#if USE_SMU2_STATIC +// The attribute specifier should not be changed. +static chip::OTAImageProcessorImpl gImageProcessor __attribute__((section(".smu2"))); +#else +static chip::OTAImageProcessorImpl gImageProcessor; +#endif + +namespace chip { + +CHIP_ERROR OTAImageProcessorImpl::Init(OTADownloader * downloader) +{ + ReturnErrorCodeIf(downloader == nullptr, CHIP_ERROR_INVALID_ARGUMENT); + mDownloader = downloader; + + OtaHookInit(); + + return CHIP_NO_ERROR; +} + +void OTAImageProcessorImpl::Clear() +{ + mHeaderParser.Clear(); + mAccumulator.Clear(); + mParams.totalFileBytes = 0; + mParams.downloadedBytes = 0; + mCurrentProcessor = nullptr; + + ReleaseBlock(); +} + +CHIP_ERROR OTAImageProcessorImpl::PrepareDownload() +{ + DeviceLayer::PlatformMgr().ScheduleWork(HandlePrepareDownload, reinterpret_cast<intptr_t>(this)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::Finalize() +{ + DeviceLayer::PlatformMgr().ScheduleWork(HandleFinalize, reinterpret_cast<intptr_t>(this)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::Apply() +{ + DeviceLayer::PlatformMgr().ScheduleWork(HandleApply, reinterpret_cast<intptr_t>(this)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::Abort() +{ + DeviceLayer::PlatformMgr().ScheduleWork(HandleAbort, reinterpret_cast<intptr_t>(this)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::ProcessBlock(ByteSpan & block) +{ + if ((block.data() == nullptr) || block.empty()) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + + // Store block data for HandleProcessBlock to access + CHIP_ERROR err = SetBlock(block); + if (err != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "Cannot set block data: %" CHIP_ERROR_FORMAT, err.Format()); + } + + DeviceLayer::PlatformMgr().ScheduleWork(HandleProcessBlock, reinterpret_cast<intptr_t>(this)); + return CHIP_NO_ERROR; +} + +void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context) +{ + auto * imageProcessor = reinterpret_cast<OTAImageProcessorImpl *>(context); + + VerifyOrReturn(imageProcessor != nullptr, ChipLogError(SoftwareUpdate, "ImageProcessor context is null")); + + VerifyOrReturn(imageProcessor->mDownloader != nullptr, ChipLogError(SoftwareUpdate, "mDownloader is null")); + + GetRequestorInstance()->GetProviderLocation(imageProcessor->mBackupProviderLocation); + + imageProcessor->mHeaderParser.Init(); + imageProcessor->mAccumulator.Init(sizeof(OTATlvHeader)); + imageProcessor->mDownloader->OnPreparedForDownload(CHIP_NO_ERROR); +} + +CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block) +{ + OTAImageHeader header; + ReturnErrorOnFailure(mHeaderParser.AccumulateAndDecode(block, header)); + + mParams.totalFileBytes = header.mPayloadSize; + mHeaderParser.Clear(); + ChipLogError(SoftwareUpdate, "Processed header successfully"); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::ProcessPayload(ByteSpan & block) +{ + CHIP_ERROR status = CHIP_NO_ERROR; + + while (true) + { + if (!mCurrentProcessor) + { + ReturnErrorOnFailure(mAccumulator.Accumulate(block)); + ByteSpan tlvHeader{ mAccumulator.data(), sizeof(OTATlvHeader) }; + ReturnErrorOnFailure(SelectProcessor(tlvHeader)); + ReturnErrorOnFailure(mCurrentProcessor->Init()); + } + + status = mCurrentProcessor->Process(block); + if (status == CHIP_ERROR_OTA_CHANGE_PROCESSOR) + { + mAccumulator.Clear(); + mAccumulator.Init(sizeof(OTATlvHeader)); + + mCurrentProcessor = nullptr; + + // If the block size is 0, it means that the processed data was a multiple of + // received BDX block size (e.g. 8 blocks of 1024 bytes were transferred). + // After state for selecting next processor is reset, a request for fetching next + // data must be sent. + if (block.size() == 0) + { + status = CHIP_NO_ERROR; + break; + } + } + else + { + break; + } + } + + return status; +} + +CHIP_ERROR OTAImageProcessorImpl::SelectProcessor(ByteSpan & block) +{ + OTATlvHeader header; + Encoding::LittleEndian::Reader reader(block.data(), sizeof(header)); + + ReturnErrorOnFailure(reader.Read32(&header.tag).StatusCode()); + ReturnErrorOnFailure(reader.Read32(&header.length).StatusCode()); + + auto pair = mProcessorMap.find(header.tag); + if (pair == mProcessorMap.end()) + { + ChipLogError(SoftwareUpdate, "There is no registered processor for tag: %" PRIu32, header.tag); + return CHIP_ERROR_OTA_PROCESSOR_NOT_REGISTERED; + } + + ChipLogDetail(SoftwareUpdate, "Selected processor with tag: %ld", pair->first); + mCurrentProcessor = pair->second; + mCurrentProcessor->SetLength(header.length); + mCurrentProcessor->SetWasSelected(true); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::RegisterProcessor(uint32_t tag, OTATlvProcessor * processor) +{ + auto pair = mProcessorMap.find(tag); + if (pair != mProcessorMap.end()) + { + ChipLogError(SoftwareUpdate, "A processor for tag %" PRIu32 " is already registered.", tag); + return CHIP_ERROR_OTA_PROCESSOR_ALREADY_REGISTERED; + } + + mProcessorMap.insert({ tag, processor }); + + return CHIP_NO_ERROR; +} + +void OTAImageProcessorImpl::HandleAbort(intptr_t context) +{ + ChipLogError(SoftwareUpdate, "OTA was aborted"); + auto * imageProcessor = reinterpret_cast<OTAImageProcessorImpl *>(context); + if (imageProcessor != nullptr) + { + imageProcessor->AbortAllProcessors(); + } + imageProcessor->Clear(); + + OtaHookAbort(); +} + +void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context) +{ + auto * imageProcessor = reinterpret_cast<OTAImageProcessorImpl *>(context); + + VerifyOrReturn(imageProcessor != nullptr, ChipLogError(SoftwareUpdate, "ImageProcessor context is null")); + + VerifyOrReturn(imageProcessor->mDownloader != nullptr, ChipLogError(SoftwareUpdate, "mDownloader is null")); + + CHIP_ERROR status; + auto block = ByteSpan(imageProcessor->mBlock.data(), imageProcessor->mBlock.size()); + + if (imageProcessor->mHeaderParser.IsInitialized()) + { + status = imageProcessor->ProcessHeader(block); + if (status != CHIP_NO_ERROR) + { + imageProcessor->HandleStatus(status); + } + } + + status = imageProcessor->ProcessPayload(block); + imageProcessor->HandleStatus(status); +} + +void OTAImageProcessorImpl::HandleStatus(CHIP_ERROR status) +{ + if (status == CHIP_NO_ERROR || status == CHIP_ERROR_BUFFER_TOO_SMALL) + { + mParams.downloadedBytes += mBlock.size(); + FetchNextData(0); + } + else if (status == CHIP_ERROR_OTA_FETCH_ALREADY_SCHEDULED) + { + mParams.downloadedBytes += mBlock.size(); + } + else + { + ChipLogError(SoftwareUpdate, "Image update canceled. Failed to process OTA block: %s", ErrorStr(status)); + GetRequestorInstance()->CancelImageUpdate(); + } +} + +void OTAImageProcessorImpl::AbortAllProcessors() +{ + ChipLogError(SoftwareUpdate, "All selected processors will call abort action"); + + for (auto const & pair : mProcessorMap) + { + if (pair.second->WasSelected()) + { + pair.second->AbortAction(); + pair.second->Clear(); + pair.second->SetWasSelected(false); + } + } +} + +bool OTAImageProcessorImpl::IsFirstImageRun() +{ + OTARequestorInterface * requestor = chip::GetRequestorInstance(); + if (requestor == nullptr) + { + return false; + } + + return requestor->GetCurrentUpdateState() == OTARequestorInterface::OTAUpdateStateEnum::kApplying; +} + +CHIP_ERROR OTAImageProcessorImpl::ConfirmCurrentImage() +{ + uint32_t currentVersion; + uint32_t targetVersion; + + OTARequestorInterface * requestor = chip::GetRequestorInstance(); + ReturnErrorCodeIf(requestor == nullptr, CHIP_ERROR_INTERNAL); + + targetVersion = requestor->GetTargetVersion(); + ReturnErrorOnFailure(DeviceLayer::ConfigurationMgr().GetSoftwareVersion(currentVersion)); + if (currentVersion != targetVersion) + { + ChipLogError(SoftwareUpdate, "Current sw version %" PRIu32 " is different than the expected sw version = %" PRIu32, + currentVersion, targetVersion); + return CHIP_ERROR_INCORRECT_STATE; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::SetBlock(ByteSpan & block) +{ + if (!IsSpanUsable(block)) + { + return CHIP_NO_ERROR; + } + + if (mBlock.size() < block.size()) + { + if (!mBlock.empty()) + { + ReleaseBlock(); + } + uint8_t * mBlock_ptr = static_cast<uint8_t *>(chip::Platform::MemoryAlloc(block.size())); + if (mBlock_ptr == nullptr) + { + return CHIP_ERROR_NO_MEMORY; + } + mBlock = MutableByteSpan(mBlock_ptr, block.size()); + } + + CHIP_ERROR err = CopySpanToMutableSpan(block, mBlock); + if (err != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "Cannot copy block data: %" CHIP_ERROR_FORMAT, err.Format()); + return err; + } + return CHIP_NO_ERROR; +} + +void OTAImageProcessorImpl::HandleFinalize(intptr_t context) +{ + auto * imageProcessor = reinterpret_cast<OTAImageProcessorImpl *>(context); + if (imageProcessor == nullptr) + { + return; + } + + imageProcessor->ReleaseBlock(); +} + +void OTAImageProcessorImpl::HandleApply(intptr_t context) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + auto * imageProcessor = reinterpret_cast<OTAImageProcessorImpl *>(context); + if (imageProcessor == nullptr) + { + return; + } + + for (auto const & pair : imageProcessor->mProcessorMap) + { + if (pair.second->WasSelected()) + { + error = pair.second->ApplyAction(); + if (error != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "Apply action for tag %d processor failed.", (uint8_t) pair.first); + // Revert all previously applied actions if current apply action fails. + // Reset image processor and requestor states. + imageProcessor->AbortAllProcessors(); + imageProcessor->Clear(); + GetRequestorInstance()->Reset(); + + return; + } + } + } + + for (auto const & pair : imageProcessor->mProcessorMap) + { + pair.second->Clear(); + pair.second->SetWasSelected(false); + } + + imageProcessor->mAccumulator.Clear(); + + ConfigurationManagerImpl().StoreSoftwareUpdateCompleted(); + PlatformMgr().HandleServerShuttingDown(); + + // Set the necessary information to inform the SSBL that a new image is available + // and trigger the actual device reboot after some time, to take into account + // queued actions, e.g. sending events to a subscription + SystemLayer().StartTimer( + chip::System::Clock::Milliseconds32(CHIP_DEVICE_LAYER_OTA_REBOOT_DELAY), + [](chip::System::Layer *, void *) { OtaHookReset(); }, nullptr); +} + +CHIP_ERROR OTAImageProcessorImpl::ReleaseBlock() +{ + if (mBlock.data() != nullptr) + { + chip::Platform::MemoryFree(mBlock.data()); + } + + mBlock = MutableByteSpan(); + return CHIP_NO_ERROR; +} + +void OTAImageProcessorImpl::FetchNextData(uint32_t context) +{ + auto * imageProcessor = &OTAImageProcessorImpl::GetDefaultInstance(); + SystemLayer().ScheduleLambda([imageProcessor] { + if (imageProcessor->mDownloader) + { + imageProcessor->mDownloader->FetchNextData(); + } + }); +} + +OTAImageProcessorImpl & OTAImageProcessorImpl::GetDefaultInstance() +{ + return gImageProcessor; +} + +} // namespace chip diff --git a/src/platform/nxp/common/legacy/OTAImageProcessorImpl.h b/src/platform/nxp/common/legacy/OTAImageProcessorImpl.h new file mode 100644 index 00000000000000..a30677037ea7f4 --- /dev/null +++ b/src/platform/nxp/common/legacy/OTAImageProcessorImpl.h @@ -0,0 +1,114 @@ +/* + * + * Copyright (c) 2021-2023 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 <lib/core/OTAImageHeader.h> +#include <map> +#include <platform/nxp/common/legacy/OTATlvProcessor.h> +#include <src/app/clusters/ota-requestor/OTADownloader.h> +#include <src/app/clusters/ota-requestor/OTARequestorInterface.h> +#include <src/include/platform/CHIPDeviceLayer.h> +#include <src/include/platform/OTAImageProcessor.h> + +/* + * OTA hooks that can be overwritten by application. + * Default behavior is implemented as WEAK symbols in platform OtaHooks.cpp. + */ + +/* + * This hook is called at the end of OTAImageProcessorImpl::Init. + * It should generally register the OTATlvProcessor instances. + */ +extern "C" CHIP_ERROR OtaHookInit(); + +/* + * This hook is called at the end of OTAImageProcessorImpl::HandleApply. + * The default implementation saves the internal OTA entry structure and resets the device. + */ +extern "C" void OtaHookReset(); + +/* + * This hook is called at the end of OTAImageProcessorImpl::HandleAbort. + * For example, it can be used to schedule a retry. + */ +extern "C" void OtaHookAbort(); + +namespace chip { + +class OTAImageProcessorImpl : public OTAImageProcessorInterface +{ +public: + using ProviderLocation = chip::OTARequestorInterface::ProviderLocationType; + + CHIP_ERROR Init(OTADownloader * downloader); + void Clear(); + + //////////// OTAImageProcessorInterface Implementation /////////////// + CHIP_ERROR PrepareDownload() override; + CHIP_ERROR Finalize() override; + CHIP_ERROR Apply() override; + CHIP_ERROR Abort() override; + CHIP_ERROR ProcessBlock(ByteSpan & block) override; + bool IsFirstImageRun() override; + CHIP_ERROR ConfirmCurrentImage() override; + + CHIP_ERROR ProcessHeader(ByteSpan & block); + CHIP_ERROR ProcessPayload(ByteSpan & block); + CHIP_ERROR SelectProcessor(ByteSpan & block); + CHIP_ERROR RegisterProcessor(uint32_t tag, OTATlvProcessor * processor); + Optional<ProviderLocation> & GetBackupProvider() { return mBackupProviderLocation; } + + static void FetchNextData(uint32_t context); + static OTAImageProcessorImpl & GetDefaultInstance(); + +private: + //////////// Actual handlers for the OTAImageProcessorInterface /////////////// + static void HandlePrepareDownload(intptr_t context); + static void HandleFinalize(intptr_t context); + static void HandleApply(intptr_t context); + static void HandleAbort(intptr_t context); + static void HandleProcessBlock(intptr_t context); + + void HandleStatus(CHIP_ERROR status); + + /** + * Called to allocate memory for mBlock if necessary and set it to block + */ + CHIP_ERROR SetBlock(ByteSpan & block); + + /** + * Called to release allocated memory for mBlock + */ + CHIP_ERROR ReleaseBlock(); + + /** + * Call AbortAction for all processors that were used + */ + void AbortAllProcessors(); + + MutableByteSpan mBlock; + OTADownloader * mDownloader; + OTAImageHeaderParser mHeaderParser; + OTATlvProcessor * mCurrentProcessor = nullptr; + OTADataAccumulator mAccumulator; + std::map<uint32_t, OTATlvProcessor *> mProcessorMap; + Optional<ProviderLocation> mBackupProviderLocation; +}; + +} // namespace chip diff --git a/src/platform/nxp/common/legacy/OTATlvProcessor.cpp b/src/platform/nxp/common/legacy/OTATlvProcessor.cpp new file mode 100644 index 00000000000000..e50da13cecdd31 --- /dev/null +++ b/src/platform/nxp/common/legacy/OTATlvProcessor.cpp @@ -0,0 +1,178 @@ +/* + * + * Copyright (c) 2023 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 <lib/core/TLV.h> +#include <lib/support/BufferReader.h> +#include <platform/internal/CHIPDeviceLayerInternal.h> + +#include <platform/nxp/common/legacy/OTAImageProcessorImpl.h> +#include <platform/nxp/common/legacy/OTATlvProcessor.h> +#if OTA_ENCRYPTION_ENABLE +#include "OtaUtils.h" +#include "rom_aes.h" +#endif +namespace chip { + +#if OTA_ENCRYPTION_ENABLE +constexpr uint8_t au8Iv[] = { 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x00, 0x00, 0x00, 0x00 }; +#endif + +CHIP_ERROR OTATlvProcessor::ApplyAction() +{ + return mApplyState == ApplyState::kApply ? CHIP_NO_ERROR : CHIP_ERROR_OTA_PROCESSOR_DO_NOT_APPLY; +} + +CHIP_ERROR OTATlvProcessor::Process(ByteSpan & block) +{ + CHIP_ERROR status = CHIP_NO_ERROR; + uint32_t bytes = chip::min(mLength - mProcessedLength, static_cast<uint32_t>(block.size())); + ByteSpan relevantData = block.SubSpan(0, bytes); + + status = ProcessInternal(relevantData); + if (!IsError(status)) + { + mProcessedLength += bytes; + block = block.SubSpan(bytes); + if (mProcessedLength == mLength) + { + status = ExitAction(); + if (!IsError(status)) + { + // If current block was processed fully and the block still contains data, it + // means that the block contains another TLV's data and the current processor + // should be changed by OTAImageProcessorImpl. + return CHIP_ERROR_OTA_CHANGE_PROCESSOR; + } + } + } + + return status; +} + +void OTATlvProcessor::ClearInternal() +{ + mLength = 0; + mProcessedLength = 0; + mWasSelected = false; + mApplyState = ApplyState::kApply; +#if OTA_ENCRYPTION_ENABLE + mIVOffset = 0; +#endif +} + +bool OTATlvProcessor::IsError(CHIP_ERROR & status) +{ + return status != CHIP_NO_ERROR && status != CHIP_ERROR_BUFFER_TOO_SMALL && status != CHIP_ERROR_OTA_FETCH_ALREADY_SCHEDULED; +} + +void OTADataAccumulator::Init(uint32_t threshold) +{ + mThreshold = threshold; + mBufferOffset = 0; + mBuffer.Alloc(mThreshold); +} + +void OTADataAccumulator::Clear() +{ + mThreshold = 0; + mBufferOffset = 0; + mBuffer.Free(); +} + +CHIP_ERROR OTADataAccumulator::Accumulate(ByteSpan & block) +{ + uint32_t numBytes = chip::min(mThreshold - mBufferOffset, static_cast<uint32_t>(block.size())); + memcpy(&mBuffer[mBufferOffset], block.data(), numBytes); + mBufferOffset += numBytes; + block = block.SubSpan(numBytes); + + if (mBufferOffset < mThreshold) + { + return CHIP_ERROR_BUFFER_TOO_SMALL; + } + + return CHIP_NO_ERROR; +} + +#if OTA_ENCRYPTION_ENABLE +CHIP_ERROR OTATlvProcessor::vOtaProcessInternalEncryption(MutableByteSpan & block) +{ + uint8_t iv[16]; + uint8_t key[kOTAEncryptionKeyLength]; + uint8_t dataOut[16] = { 0 }; + uint32_t u32IVCount; + uint32_t Offset = 0; + uint8_t data; + tsReg128 sKey; + aesContext_t Context; + + memcpy(iv, au8Iv, sizeof(au8Iv)); + + u32IVCount = (((uint32_t) iv[12]) << 24) | (((uint32_t) iv[13]) << 16) | (((uint32_t) iv[14]) << 8) | (iv[15]); + u32IVCount += (mIVOffset >> 4); + + iv[12] = (uint8_t) ((u32IVCount >> 24) & 0xff); + iv[13] = (uint8_t) ((u32IVCount >> 16) & 0xff); + iv[14] = (uint8_t) ((u32IVCount >> 8) & 0xff); + iv[15] = (uint8_t) (u32IVCount & 0xff); + + if (Encoding::HexToBytes(OTA_ENCRYPTION_KEY, strlen(OTA_ENCRYPTION_KEY), key, kOTAEncryptionKeyLength) != + kOTAEncryptionKeyLength) + { + // Failed to convert the OTAEncryptionKey string to octstr type value + return CHIP_ERROR_INVALID_STRING_LENGTH; + } + + ByteSpan KEY = ByteSpan(key); + Encoding::LittleEndian::Reader reader_key(KEY.data(), KEY.size()); + ReturnErrorOnFailure(reader_key.Read32(&sKey.u32register0) + .Read32(&sKey.u32register1) + .Read32(&sKey.u32register2) + .Read32(&sKey.u32register3) + .StatusCode()); + + while (Offset + 16 <= block.size()) + { + /*Encrypt the IV*/ + Context.mode = AES_MODE_ECB_ENCRYPT; + Context.pSoftwareKey = (uint32_t *) &sKey; + AES_128_ProcessBlocks(&Context, (uint32_t *) &iv[0], (uint32_t *) &dataOut[0], 1); + + /* Decrypt a block of the buffer */ + for (uint8_t i = 0; i < 16; i++) + { + data = block[Offset + i] ^ dataOut[i]; + memcpy(&block[Offset + i], &data, sizeof(uint8_t)); + } + + /* increment the IV for the next block */ + u32IVCount++; + + iv[12] = (uint8_t) ((u32IVCount >> 24) & 0xff); + iv[13] = (uint8_t) ((u32IVCount >> 16) & 0xff); + iv[14] = (uint8_t) ((u32IVCount >> 8) & 0xff); + iv[15] = (uint8_t) (u32IVCount & 0xff); + + Offset += 16; /* increment the buffer offset */ + mIVOffset += 16; + } + + return CHIP_NO_ERROR; +} +#endif +} // namespace chip diff --git a/src/platform/nxp/common/legacy/OTATlvProcessor.h b/src/platform/nxp/common/legacy/OTATlvProcessor.h new file mode 100644 index 00000000000000..f1faef7e8eecf9 --- /dev/null +++ b/src/platform/nxp/common/legacy/OTATlvProcessor.h @@ -0,0 +1,180 @@ +/* + * + * Copyright (c) 2023 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 <lib/core/Optional.h> +#include <lib/support/ScopedBuffer.h> +#include <lib/support/Span.h> + +namespace chip { + +#define CHIP_ERROR_TLV_PROCESSOR(e) \ + ChipError(ChipError::Range::kLastRange, ((uint8_t) ChipError::Range::kLastRange << 3) | e, __FILE__, __LINE__) + +#define CHIP_ERROR_OTA_CHANGE_PROCESSOR CHIP_ERROR_TLV_PROCESSOR(0x02) +#define CHIP_ERROR_OTA_PROCESSOR_NOT_REGISTERED CHIP_ERROR_TLV_PROCESSOR(0x03) +#define CHIP_ERROR_OTA_PROCESSOR_ALREADY_REGISTERED CHIP_ERROR_TLV_PROCESSOR(0x04) +#define CHIP_ERROR_OTA_PROCESSOR_CLIENT_INIT CHIP_ERROR_TLV_PROCESSOR(0x05) +#define CHIP_ERROR_OTA_PROCESSOR_MAKE_ROOM CHIP_ERROR_TLV_PROCESSOR(0x06) +#define CHIP_ERROR_OTA_PROCESSOR_PUSH_CHUNK CHIP_ERROR_TLV_PROCESSOR(0x07) +#define CHIP_ERROR_OTA_PROCESSOR_IMG_AUTH CHIP_ERROR_TLV_PROCESSOR(0x08) +#define CHIP_ERROR_OTA_FETCH_ALREADY_SCHEDULED CHIP_ERROR_TLV_PROCESSOR(0x09) +#define CHIP_ERROR_OTA_PROCESSOR_IMG_COMMIT CHIP_ERROR_TLV_PROCESSOR(0x0A) +#define CHIP_ERROR_OTA_PROCESSOR_CB_NOT_REGISTERED CHIP_ERROR_TLV_PROCESSOR(0x0B) +#define CHIP_ERROR_OTA_PROCESSOR_EEPROM_OFFSET CHIP_ERROR_TLV_PROCESSOR(0x0C) +#define CHIP_ERROR_OTA_PROCESSOR_EXTERNAL_STORAGE CHIP_ERROR_TLV_PROCESSOR(0x0D) +#define CHIP_ERROR_OTA_PROCESSOR_START_IMAGE CHIP_ERROR_TLV_PROCESSOR(0x0E) +#define CHIP_ERROR_OTA_PROCESSOR_DO_NOT_APPLY CHIP_ERROR_TLV_PROCESSOR(0x0F) + +// Descriptor constants +constexpr size_t kVersionStringSize = 64; +constexpr size_t kBuildDateSize = 64; + +constexpr uint16_t requestedOtaMaxBlockSize = 1024; + +/** + * Used alongside RegisterDescriptorCallback to register + * a custom descriptor processing function with a certain + * TLV processor. + */ +typedef CHIP_ERROR (*ProcessDescriptor)(void * descriptor); + +struct OTATlvHeader +{ + uint32_t tag; + uint32_t length; +}; + +/** + * This class defines an interface for a Matter TLV processor. + * Instances of derived classes can be registered as processors + * in OTAImageProcessorImpl. Based on the TLV type, a certain + * processor is used to process subsequent blocks until the number + * of bytes found in the metadata is processed. In case a block contains + * data from two different TLVs, the processor should ensure the remaining + * data is returned in the block passed as input. + * The default processors: application, SSBL and factory data are registered + * in OTAImageProcessorImpl::Init through OtaHookInit. + * Applications should use OTAImageProcessorImpl::RegisterProcessor + * to register additional processors. + */ +class OTATlvProcessor +{ +public: + enum class ApplyState : uint8_t + { + kApply = 0, + kDoNotApply + }; + + virtual ~OTATlvProcessor() {} + + virtual CHIP_ERROR Init() = 0; + virtual CHIP_ERROR Clear() = 0; + virtual CHIP_ERROR AbortAction() = 0; + virtual CHIP_ERROR ExitAction() { return CHIP_NO_ERROR; } + virtual CHIP_ERROR ApplyAction(); + + CHIP_ERROR Process(ByteSpan & block); + void RegisterDescriptorCallback(ProcessDescriptor callback) { mCallbackProcessDescriptor = callback; } + void SetLength(uint32_t length) { mLength = length; } + void SetWasSelected(bool selected) { mWasSelected = selected; } + bool WasSelected() { return mWasSelected; } +#if OTA_ENCRYPTION_ENABLE + CHIP_ERROR vOtaProcessInternalEncryption(MutableByteSpan & block); +#endif + +protected: + /** + * @brief Process custom TLV payload + * + * The method takes subsequent chunks of the Matter OTA image file and processes them. + * If more image chunks are needed, CHIP_ERROR_BUFFER_TOO_SMALL error is returned. + * Other error codes indicate that an error occurred during processing. Fetching + * next data is scheduled automatically by OTAImageProcessorImpl if the return value + * is neither an error code, nor CHIP_ERROR_OTA_FETCH_ALREADY_SCHEDULED (which implies the + * scheduling is done inside ProcessInternal or will be done in the future, through a + * callback). + * + * @param block Byte span containing a subsequent Matter OTA image chunk. When the method + * returns CHIP_NO_ERROR, the byte span is used to return a remaining part + * of the chunk, not used by current TLV processor. + * + * @retval CHIP_NO_ERROR Block was processed successfully. + * @retval CHIP_ERROR_BUFFER_TOO_SMALL Provided buffers are insufficient to decode some + * metadata (e.g. a descriptor). + * @retval CHIP_ERROR_OTA_FETCH_ALREADY_SCHEDULED Should be returned if ProcessInternal schedules + * fetching next data (e.g. through a callback). + * @retval Error code Something went wrong. Current OTA process will be + * canceled. + */ + virtual CHIP_ERROR ProcessInternal(ByteSpan & block) = 0; + + void ClearInternal(); + + bool IsError(CHIP_ERROR & status); + +#if OTA_ENCRYPTION_ENABLE + /*ota decryption*/ + uint32_t mIVOffset = 0; + /* Expected byte size of the OTAEncryptionKeyLength */ + static constexpr size_t kOTAEncryptionKeyLength = 16; +#endif + uint32_t mLength = 0; + uint32_t mProcessedLength = 0; + bool mWasSelected = false; + + /** + * @brief A flag to account for corner cases during OTA apply + * + * Used by the default ApplyAction implementation. + * + * If something goes wrong during ExitAction of the TLV processor, + * then mApplyState should be set to kDoNotApply and the image processor + * should abort. In this case, the BDX transfer was already finished + * and calling CancelImageUpdate will not abort the transfer, hence + * the device will reboot even though it should not have. If ApplyAction + * fails during HandleApply, then the process will be aborted. + */ + ApplyState mApplyState = ApplyState::kApply; + ProcessDescriptor mCallbackProcessDescriptor = nullptr; +}; + +/** + * This class can be used to accumulate data until a given threshold. + * Should be used by OTATlvProcessor derived classes if they need + * metadata accumulation (e.g. for custom header decoding). + */ +class OTADataAccumulator +{ +public: + void Init(uint32_t threshold); + void Clear(); + CHIP_ERROR Accumulate(ByteSpan & block); + + inline uint8_t * data() { return mBuffer.Get(); } + inline uint32_t GetThreshold() { return mThreshold; } + +private: + uint32_t mThreshold; + uint32_t mBufferOffset; + Platform::ScopedMemoryBuffer<uint8_t> mBuffer; +}; + +} // namespace chip diff --git a/src/platform/nxp/common/legacy/OTA_README.md b/src/platform/nxp/common/legacy/OTA_README.md new file mode 100644 index 00000000000000..0c9715b4610ff8 --- /dev/null +++ b/src/platform/nxp/common/legacy/OTA_README.md @@ -0,0 +1,149 @@ +# K32W OTA + +The OTA processing is now delegated to instances of `OTATlvProcessor` derived +classes. These instances are registered with the `OTAImageProcessorImpl` +instance, which manages the selection of processors that should process the next +blocks, until a full TLV block was transferred. + +The application is able to define its own processors, thus extending the default +OTA functionality. The application can also opt to disable the default +processors (application, SSBL and factory data). + +Please note that if an OTA image containing multiple TLV is transferred, then +the action for each TLV is applied sequentially, If one of the actions fails, +the remaining actions will not be applied and OTA abort is called. TBD: should +all actions be applied only if there is no error? Or should each action be +applied separately? + +## Default processors + +The default processors for K32W0 are already implemented in: + +- `OTAFirmwareProcessor` for application/SSBL update. Enabled by default. +- `OTAFactoryDataProcessor` for factory data update. Disabled by default, user + has to specify `chip_ota_enable_factory_data_processor=1` in the build args. + +Some SDK OTA module flags are defined to support additional features: + +- `gOTAAllowCustomStartAddress=1` - enable `EEPROM` offset value. Used + internally by SDK OTA module. +- `gOTAUseCustomOtaEntry=1` - support custom OTA entry for multi-image. +- `gOTACustomOtaEntryMemory=1` - K32W0 uses `OTACustomStorage_ExtFlash` (1) by + default. + +## Implementing custom processors + +A custom processor should implement the abstract interface defined in +`OTATlvProcessor.h`. Below is a compact version: + +``` +class OTATlvProcessor +{ +public: + virtual CHIP_ERROR Init() = 0; + virtual CHIP_ERROR Clear() = 0; + virtual CHIP_ERROR ApplyAction() = 0; + virtual CHIP_ERROR AbortAction() = 0; + virtual CHIP_ERROR ExitAction(); + + CHIP_ERROR Process(ByteSpan & block); + void RegisterDescriptorCallback(ProcessDescriptor callback); +protected: + virtual CHIP_ERROR ProcessInternal(ByteSpan & block) = 0; +}; + +``` + +Some details regarding the interface: + +- `Init` will be called whenever the processor is selected. +- `Clear` will be called when abort occurs or after the apply action takes + place. +- `ApplyAction` will be called in `OTAImageProcessorImpl::HandleApply`, before + the board is reset. +- `AbortAction` will be called in `OTAImageProcessorImpl::HandleAbort`. + Processors should reset state here. +- `ExitAction` is optional and should be implemented by the processors that + want to execute an action after all data has been transferred, but before + `HandleApply` is called. It's called before the new processor selection + takes place. This is useful in the context of multiple TLV transferred in a + single OTA process. +- `Process` is the public API used inside `OTAImageProcessorImpl` for data + processing. This is a wrapper over `ProcessInternal`, which can return + `CHIP_OTA_CHANGE_PROCESSOR` to notify a new processor should be selected for + the remaining data. +- `RegisterDescriptorCallback` can be used to register a callback for + processing the descriptor. It's optional. +- `ProcessInternal` should return: _ `CHIP_NO_ERROR` if block was processed + successfully. _ `CHIP_ERROR_BUFFER_TOO_SMALL` if current block doesn't + contain all necessary data. This can happen when a TLV value field has a + header, but it is split across two blocks. \* + `CHIP_OTA_FETCH_ALREADY_SCHEDULED` if block was processed successfully and + the fetching is already scheduled by the processor. This happens in the + default application processor, because the next data fetching is scheduled + through a callback (called when enough external flash was erased). + +Furthermore, a processor can use an instance of `OTADataAccumulator` to +accumulate data until a given threshold. This is useful when a custom payload +contains metadata that need parsing: accumulate data until the threshold is +reached or return `CHIP_ERROR_BUFFER_TOO_SMALL` to signal +`OTAImageProcessorImpl` more data is needed. + +``` +/** + * This class can be used to accumulate data until a given threshold. + * Should be used by OTATlvProcessor derived classes if they need + * metadata accumulation (e.g. for custom header decoding). + */ +class OTADataAccumulator +{ +public: + void Init(uint32_t threshold); + void Clear(); + CHIP_ERROR Accumulate(ByteSpan & block); + + inline uint8_t* data() { return mBuffer.Get(); } + +private: + uint32_t mThreshold; + uint32_t mBufferOffset; + Platform::ScopedMemoryBuffer<uint8_t> mBuffer; +}; +``` + +## SSBL max entries example + +`CONFIG_CHIP_K32W0_MAX_ENTRIES_TEST` can be set to 1 to enable max entries test. +There will be 8 additional processors registered in default `OtaHooks` +implementation. The OTA image should be generated with the +`create_ota_images.sh` script from `./scripts/tools/nxp/ota/examples`. + +## Factory data restore mechanism + +Prior to factory data update, the old factory data is backed up in external +flash. If anything interrupts the update (e.g. power loss), there is a slight +chance the internal flash factory data section is erased and has to be restored +at next boot. The `FactoryDataProvider` offers a default restore mechanism and +support for registering additional restore mechanisms or overwriting the default +one. + +Prior to factory data update, the old factory data is backed up in external +flash. If anything interrupts the update (e.g. power loss), there is a slight +chance the internal flash factory data section is erased and has to be restored +at next boot. The `FactoryDataProvider` offers a default restore mechanism and +support for registering additional restore mechanisms or overwriting the default +one. + +Restore mechanisms are just functions that have this signature: +`CHIP_ERROR (*)(void)`. Any such function can be registered through +`FactoryDataProvider::RegisterRestoreMechanism`. + +The default restore mechanism is implemented as a weak function: +`FactoryDataDefaultRestoreMechanism`. It is registered in +`FactoryDataProvider::Init`, before factory data validation, and it can be +overwritten at application level. When doing the actual restore, the mechanisms +are called in the order they were registered. + +Please note that the restore mechanisms registration order matters. Once a +restore mechanism is successful (`CHIP_NO_ERROR` is returned), the restore +process has finished and subsequent restore mechanisms will not be called. diff --git a/src/platform/nxp/k32w/k32w0/DefaultTestEventTriggerDelegate.cpp b/src/platform/nxp/k32w/k32w0/DefaultTestEventTriggerDelegate.cpp deleted file mode 100644 index 69935bb024559d..00000000000000 --- a/src/platform/nxp/k32w/k32w0/DefaultTestEventTriggerDelegate.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - * - * 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 "DefaultTestEventTriggerDelegate.h" - -#include <lib/support/CodeUtils.h> -#include <lib/support/logging/CHIPLogging.h> - -namespace chip { - -bool DefaultTestEventTriggerDelegate::DoesEnableKeyMatch(const ByteSpan & enableKey) const -{ - return !mEnableKey.empty() && mEnableKey.data_equal(enableKey); -} - -} // namespace chip diff --git a/src/platform/nxp/k32w/k32w0/DefaultTestEventTriggerDelegate.h b/src/platform/nxp/k32w/k32w0/DefaultTestEventTriggerDelegate.h deleted file mode 100644 index 0bfd4c5b0fa725..00000000000000 --- a/src/platform/nxp/k32w/k32w0/DefaultTestEventTriggerDelegate.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * - * 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. - */ - -#pragma once - -#include <app/TestEventTriggerDelegate.h> - -namespace chip { - -class DefaultTestEventTriggerDelegate : public TestEventTriggerDelegate -{ -public: - explicit DefaultTestEventTriggerDelegate(const ByteSpan & enableKey) : mEnableKey(enableKey) {} - - bool DoesEnableKeyMatch(const ByteSpan & enableKey) const override; - -private: - ByteSpan mEnableKey; -}; - -} // namespace chip diff --git a/src/platform/nxp/k32w/k32w0/BLEManagerImpl.cpp b/src/platform/nxp/k32w0/BLEManagerImpl.cpp similarity index 98% rename from src/platform/nxp/k32w/k32w0/BLEManagerImpl.cpp rename to src/platform/nxp/k32w0/BLEManagerImpl.cpp index af56961cf23dc1..aa56e06a8d5598 100644 --- a/src/platform/nxp/k32w/k32w0/BLEManagerImpl.cpp +++ b/src/platform/nxp/k32w0/BLEManagerImpl.cpp @@ -37,7 +37,7 @@ osaEventId_t mControllerTaskEvent; extern msgQueue_t gApp2Host_TaskQueue; extern msgQueue_t gHci2Host_TaskQueue; -#include <platform/nxp/k32w/k32w0/BLEManagerImpl.h> +#include <platform/nxp/k32w0/BLEManagerImpl.h> extern "C" bool_t Ble_ConfigureHostStackConfig(void); diff --git a/src/platform/nxp/k32w/k32w0/BLEManagerImpl.h b/src/platform/nxp/k32w0/BLEManagerImpl.h similarity index 97% rename from src/platform/nxp/k32w/k32w0/BLEManagerImpl.h rename to src/platform/nxp/k32w0/BLEManagerImpl.h index eb8a25804804d1..686eb1e3f703ee 100644 --- a/src/platform/nxp/k32w/k32w0/BLEManagerImpl.h +++ b/src/platform/nxp/k32w0/BLEManagerImpl.h @@ -25,7 +25,7 @@ #include "ble_host_task_config.h" #include "controller_interface.h" -#include <src/platform/nxp/k32w/common/BLEManagerCommon.h> +#include <src/platform/nxp/common/legacy/BLEManagerCommon.h> /* host task configuration */ #define HOST_TASK_PRIORITY (4U) diff --git a/src/platform/nxp/k32w/k32w0/BUILD.gn b/src/platform/nxp/k32w0/BUILD.gn similarity index 77% rename from src/platform/nxp/k32w/k32w0/BUILD.gn rename to src/platform/nxp/k32w0/BUILD.gn index 76af2760bc9051..41a80a77a7aa53 100644 --- a/src/platform/nxp/k32w/k32w0/BUILD.gn +++ b/src/platform/nxp/k32w0/BUILD.gn @@ -19,17 +19,18 @@ import("${chip_root}/src/platform/device.gni") import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") assert(chip_device_platform == "nxp") -assert(nxp_platform == "k32w/k32w0") +assert(nxp_platform == "k32w0") if (chip_enable_openthread) { import("//build_overrides/openthread.gni") } static_library("nxp_platform") { + defines = [] sources = [ - "../../../SingletonConfigurationManager.cpp", - "../common/BLEManagerCommon.cpp", - "../common/BLEManagerCommon.h", + "../../SingletonConfigurationManager.cpp", + "../common/legacy/BLEManagerCommon.cpp", + "../common/legacy/BLEManagerCommon.h", "BLEManagerImpl.cpp", "BLEManagerImpl.h", "CHIPDevicePlatformConfig.h", @@ -38,8 +39,6 @@ static_library("nxp_platform") { "ConfigurationManagerImpl.h", "ConnectivityManagerImpl.cpp", "ConnectivityManagerImpl.h", - "DefaultTestEventTriggerDelegate.cpp", - "DefaultTestEventTriggerDelegate.h", "DiagnosticDataProviderImpl.cpp", "DiagnosticDataProviderImpl.h", "K32W0Config.cpp", @@ -60,12 +59,12 @@ static_library("nxp_platform") { "${chip_root}/src/credentials/examples/DeviceAttestationCredsExample.h", "${chip_root}/src/credentials/examples/ExampleDACs.h", "${chip_root}/src/credentials/examples/ExamplePAI.h", - "${chip_root}/src/platform/nxp/k32w/k32w0/BLEManagerImpl.h", + "${chip_root}/src/platform/nxp/k32w0/BLEManagerImpl.h", ] if (chip_with_factory_data == 1) { sources += [ - "../common/FactoryDataProvider.cpp", + "FactoryDataProvider.cpp", "FactoryDataProviderImpl.cpp", ] public += [ @@ -79,13 +78,13 @@ static_library("nxp_platform") { } if (chip_enable_ota_requestor) { - public += [ "../common/OTAImageProcessorImpl.h" ] + public += [ "../common/legacy/OTAImageProcessorImpl.h" ] sources += [ - "../common/OTAImageProcessorImpl.cpp", - "../common/OTAImageProcessorImpl.h", - "../common/OTATlvProcessor.cpp", - "../common/OTATlvProcessor.h", + "../common/legacy/OTAImageProcessorImpl.cpp", + "../common/legacy/OTAImageProcessorImpl.h", + "../common/legacy/OTATlvProcessor.cpp", + "../common/legacy/OTATlvProcessor.h", ] if (chip_enable_ota_firmware_processor == 1) { @@ -107,10 +106,7 @@ static_library("nxp_platform") { deps = [ "${chip_root}/src/platform/logging:headers" ] - public_deps = [ - "${chip_root}/src/app:test-event-trigger", - "${chip_root}/src/platform:platform_base", - ] + public_deps = [ "${chip_root}/src/platform:platform_base" ] if (chip_crypto == "platform") { if (chip_crypto_flavor == "tinycrypt") { @@ -120,7 +116,7 @@ static_library("nxp_platform") { } if (chip_crypto_flavor == "NXP-Ultrafast-P256") { - sources += [ "${chip_root}/src/platform/nxp/k32w/k32w0/crypto/CHIPCryptoPALNXPUltrafastP256.cpp" ] + sources += [ "${chip_root}/src/platform/nxp/k32w0/crypto/CHIPCryptoPALNXPUltrafastP256.cpp" ] public_deps += [ "${mbedtls_root}:mbedtls", @@ -131,16 +127,16 @@ static_library("nxp_platform") { if (chip_enable_openthread) { sources += [ - "../../../OpenThread/OpenThreadUtils.cpp", + "../../OpenThread/OpenThreadUtils.cpp", "ThreadStackManagerImpl.cpp", "ThreadStackManagerImpl.h", ] if (chip_mdns == "platform") { sources += [ - "../../../OpenThread/DnssdImpl.cpp", - "../../../OpenThread/OpenThreadDnssdImpl.cpp", - "../../../OpenThread/OpenThreadDnssdImpl.h", + "../../OpenThread/DnssdImpl.cpp", + "../../OpenThread/OpenThreadDnssdImpl.cpp", + "../../OpenThread/OpenThreadDnssdImpl.h", ] deps += [ "${chip_root}/src/lib/dnssd:platform_header" ] } diff --git a/src/platform/nxp/k32w/k32w0/BlePlatformConfig.h b/src/platform/nxp/k32w0/BlePlatformConfig.h similarity index 100% rename from src/platform/nxp/k32w/k32w0/BlePlatformConfig.h rename to src/platform/nxp/k32w0/BlePlatformConfig.h diff --git a/src/platform/nxp/k32w/k32w0/CHIPDevicePlatformConfig.h b/src/platform/nxp/k32w0/CHIPDevicePlatformConfig.h similarity index 97% rename from src/platform/nxp/k32w/k32w0/CHIPDevicePlatformConfig.h rename to src/platform/nxp/k32w0/CHIPDevicePlatformConfig.h index faa283ffbe41dc..523d6e8941232d 100644 --- a/src/platform/nxp/k32w/k32w0/CHIPDevicePlatformConfig.h +++ b/src/platform/nxp/k32w0/CHIPDevicePlatformConfig.h @@ -135,14 +135,14 @@ #endif // CONFIG_CHIP_K32W0_KVS_MOVE_KEYS_TO_SPECIFIC_STORAGE /** - * @def CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR + * @def CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR * * Enables default OTA TLV factory data processor. * Disabled by default. */ -#ifndef CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR -#define CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR 0 -#endif // CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR +#ifndef CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR +#define CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR 0 +#endif // CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR /** * @def CHIP_DEVICE_LAYER_ENABLE_PDM_LOGS @@ -211,4 +211,4 @@ #define CHIP_DEVICE_CONFIG_ENABLE_TEST_SETUP_PARAMS 1 -#include <platform/nxp/k32w/common/CHIPDevicePlatformRamStorageConfig.h> +#include <platform/nxp/k32w0/CHIPDevicePlatformRamStorageConfig.h> diff --git a/src/platform/nxp/k32w/k32w0/CHIPDevicePlatformEvent.h b/src/platform/nxp/k32w0/CHIPDevicePlatformEvent.h similarity index 100% rename from src/platform/nxp/k32w/k32w0/CHIPDevicePlatformEvent.h rename to src/platform/nxp/k32w0/CHIPDevicePlatformEvent.h diff --git a/src/platform/nxp/k32w0/CHIPDevicePlatformRamStorageConfig.h b/src/platform/nxp/k32w0/CHIPDevicePlatformRamStorageConfig.h new file mode 100644 index 00000000000000..51ee8c4d27ee79 --- /dev/null +++ b/src/platform/nxp/k32w0/CHIPDevicePlatformRamStorageConfig.h @@ -0,0 +1,185 @@ +/* + * + * 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. + */ + +/** + * @file + * Configuration of RAM storage metadata: key IDs and NVM IDs. + */ + +#pragma once + +/* Base key IDs used when creating new keys for RAM storage instances. */ +/** + * @def kKeyId_Factory + * + * Base key id used for factory RAM storage. + */ +#ifndef kKeyId_Factory +#define kKeyId_Factory (uint8_t) 0x01 +#endif + +/** + * @def kKeyId_Config + * + * Base key id used for config RAM storage. + */ +#ifndef kKeyId_Config +#define kKeyId_Config (uint8_t) 0x02 +#endif + +/** + * @def kKeyId_Counter + * + * Base key id used for counter RAM storage. + */ +#ifndef kKeyId_Counter +#define kKeyId_Counter (uint8_t) 0x03 +#endif + +/** + * @def kKeyId_KvsKeys + * + * Base key id used for KVS keys RAM storage. + */ +#ifndef kKeyId_KvsKeys +#define kKeyId_KvsKeys (uint8_t) 0x04 +#endif + +/** + * @def kKeyId_KvsValues + * + * Base key id used for KVS values RAM storage. + */ +#ifndef kKeyId_KvsValues +#define kKeyId_KvsValues (uint8_t) 0x05 +#endif + +/* PDM IDs used when defining RAM storage instances or RAM buffers (OT). */ +/** + * @def kNvmId_Factory + * + * PDM ID used for factory RAM storage. + */ +#ifndef kNvmId_Factory +#define kNvmId_Factory (uint16_t) 0x5001 +#endif + +/** + * @def kNvmId_Config + * + * PDM ID used for config RAM storage. + */ +#ifndef kNvmId_Config +#define kNvmId_Config (uint16_t) 0x5002 +#endif + +/** + * @def kNvmId_Counter + * + * PDM ID used for counter RAM storage. + */ +#ifndef kNvmId_Counter +#define kNvmId_Counter (uint16_t) 0x5003 +#endif + +/** + * @def kNvmId_KvsKeys + * + * PDM ID used for KVS keys RAM storage. + */ +#ifndef kNvmId_KvsKeys +#define kNvmId_KvsKeys (uint16_t) 0x6000 +#endif + +/** + * @def kNvmId_KvsValues + * + * PDM ID used for KVS values RAM storage. + * KVS buffer can become quite big, so this PDM + * id is used as base id for subsequent PDM ids + * used to store data in chunks of PDM page size. + * This will use the extended search feature, so + * subsequent PDM ids should not be used. + */ +#ifndef kNvmId_KvsValues +#define kNvmId_KvsValues (uint16_t) 0x6001 +#endif + +/** + * @def kNvmId_KvsSubscription + * + * PDM ID used for KVS subscription RAM storage. + * It will store both keys and values for those keys. + */ +#ifndef kNvmId_KvsSubscription +#define kNvmId_KvsSubscription (uint16_t) 0x6100 +#endif + +/** + * @def kNvmId_KvsGroups + * + * PDM ID used for KVS groups RAM storage. + * It will store both keys and values for those keys. + * This will use the extended search feature, so + * subsequent PDM ids should not be used. + */ +#ifndef kNvmId_KvsGroups +#define kNvmId_KvsGroups (uint16_t) 0x6200 +#endif + +/** + * @def kNvmId_KvsAcl + * + * PDM ID used for KVS groups RAM storage. + * It will store both keys and values for those keys. + * This will use the extended search feature, so + * subsequent PDM ids should not be used. + */ +#ifndef kNvmId_KvsAcl +#define kNvmId_KvsAcl (uint16_t) 0x6300 +#endif + +/** + * @def kNvmId_OTConfigData + * + * PDM ID used for OT RAM buffer. + */ +#ifndef kNvmId_OTConfigData +#define kNvmId_OTConfigData (uint16_t) 0x4F00 +#endif + +/** + * @def kNvmId_ApplicationBase + * + * Base PDM ID to be used by applications to define their own + * PDM IDs by using an offset. + */ +#ifndef kNvmId_ApplicationBase +#define kNvmId_ApplicationBase (uint16_t) 0xA000 +#endif + +#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA +/** + * @def kNvmId_FactoryDataBackup + * + * PDM ID used for factory data backup in FactoryDataProvider. + */ +#ifndef kNvmId_FactoryDataBackup +#define kNvmId_FactoryDataBackup (uint16_t) 0x7000 +#endif +#endif // CONFIG_CHIP_LOAD_REAL_FACTORY_DATA diff --git a/src/platform/nxp/k32w/k32w0/CHIPPlatformConfig.h b/src/platform/nxp/k32w0/CHIPPlatformConfig.h similarity index 100% rename from src/platform/nxp/k32w/k32w0/CHIPPlatformConfig.h rename to src/platform/nxp/k32w0/CHIPPlatformConfig.h diff --git a/src/platform/nxp/k32w/k32w0/ConfigurationManagerImpl.cpp b/src/platform/nxp/k32w0/ConfigurationManagerImpl.cpp similarity index 98% rename from src/platform/nxp/k32w/k32w0/ConfigurationManagerImpl.cpp rename to src/platform/nxp/k32w0/ConfigurationManagerImpl.cpp index b8477051faeade..7343c75b5d5865 100644 --- a/src/platform/nxp/k32w/k32w0/ConfigurationManagerImpl.cpp +++ b/src/platform/nxp/k32w0/ConfigurationManagerImpl.cpp @@ -29,8 +29,8 @@ #include <platform/ConfigurationManager.h> #include <platform/DiagnosticDataProvider.h> #include <platform/internal/GenericConfigurationManagerImpl.ipp> -#include <platform/nxp/k32w/k32w0/K32W0Config.h> -#include <platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.h> +#include <platform/nxp/k32w0/K32W0Config.h> +#include <platform/nxp/k32w0/KeyValueStoreManagerImpl.h> #include "fsl_power.h" #include "fsl_reset.h" diff --git a/src/platform/nxp/k32w/k32w0/ConfigurationManagerImpl.h b/src/platform/nxp/k32w0/ConfigurationManagerImpl.h similarity index 98% rename from src/platform/nxp/k32w/k32w0/ConfigurationManagerImpl.h rename to src/platform/nxp/k32w0/ConfigurationManagerImpl.h index 8fded100d00a87..c7cf2366ca97cb 100644 --- a/src/platform/nxp/k32w/k32w0/ConfigurationManagerImpl.h +++ b/src/platform/nxp/k32w0/ConfigurationManagerImpl.h @@ -26,7 +26,7 @@ #pragma once #include <platform/internal/GenericConfigurationManagerImpl.h> -#include <platform/nxp/k32w/k32w0/K32W0Config.h> +#include <platform/nxp/k32w0/K32W0Config.h> namespace chip { namespace DeviceLayer { diff --git a/src/platform/nxp/k32w/k32w0/ConnectivityManagerImpl.cpp b/src/platform/nxp/k32w0/ConnectivityManagerImpl.cpp similarity index 100% rename from src/platform/nxp/k32w/k32w0/ConnectivityManagerImpl.cpp rename to src/platform/nxp/k32w0/ConnectivityManagerImpl.cpp diff --git a/src/platform/nxp/k32w/k32w0/ConnectivityManagerImpl.h b/src/platform/nxp/k32w0/ConnectivityManagerImpl.h similarity index 100% rename from src/platform/nxp/k32w/k32w0/ConnectivityManagerImpl.h rename to src/platform/nxp/k32w0/ConnectivityManagerImpl.h diff --git a/src/platform/nxp/k32w/k32w0/DiagnosticDataProviderImpl.cpp b/src/platform/nxp/k32w0/DiagnosticDataProviderImpl.cpp similarity index 99% rename from src/platform/nxp/k32w/k32w0/DiagnosticDataProviderImpl.cpp rename to src/platform/nxp/k32w0/DiagnosticDataProviderImpl.cpp index b3e02f3f64cb71..8cf924d1a63424 100644 --- a/src/platform/nxp/k32w/k32w0/DiagnosticDataProviderImpl.cpp +++ b/src/platform/nxp/k32w0/DiagnosticDataProviderImpl.cpp @@ -25,7 +25,7 @@ #include <crypto/CHIPCryptoPAL.h> #include <platform/DiagnosticDataProvider.h> -#include <platform/nxp/k32w/k32w0/DiagnosticDataProviderImpl.h> +#include <platform/nxp/k32w0/DiagnosticDataProviderImpl.h> #if CHIP_SYSTEM_CONFIG_USE_LWIP #include <lwip/tcpip.h> diff --git a/src/platform/nxp/k32w/k32w0/DiagnosticDataProviderImpl.h b/src/platform/nxp/k32w0/DiagnosticDataProviderImpl.h similarity index 100% rename from src/platform/nxp/k32w/k32w0/DiagnosticDataProviderImpl.h rename to src/platform/nxp/k32w0/DiagnosticDataProviderImpl.h diff --git a/src/platform/nxp/k32w0/FactoryDataProvider.cpp b/src/platform/nxp/k32w0/FactoryDataProvider.cpp new file mode 100644 index 00000000000000..23f8ffe7c0586b --- /dev/null +++ b/src/platform/nxp/k32w0/FactoryDataProvider.cpp @@ -0,0 +1,368 @@ +/* + * + * 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. + */ + +#if (!CONFIG_CHIP_LOAD_REAL_FACTORY_DATA || !(defined CONFIG_CHIP_LOAD_REAL_FACTORY_DATA)) +#include <credentials/examples/DeviceAttestationCredsExample.h> +#include <credentials/examples/ExampleDACs.h> +#include <credentials/examples/ExamplePAI.h> +#endif + +#include <credentials/CHIPCert.h> +#include <credentials/CertificationDeclaration.h> +#include <crypto/CHIPCryptoPAL.h> +#include <lib/core/CHIPError.h> +#include <lib/core/TLV.h> +#include <lib/support/Base64.h> +#include <lib/support/Span.h> +#include <platform/ConfigurationManager.h> +#include <platform/nxp/k32w0/FactoryDataProvider.h> + +#include <cctype> + +namespace chip { +namespace DeviceLayer { + +static constexpr size_t kSpake2pSerializedVerifier_MaxBase64Len = + BASE64_ENCODED_LEN(chip::Crypto::kSpake2p_VerifierSerialized_Length) + 1; +static constexpr size_t kSpake2pSalt_MaxBase64Len = BASE64_ENCODED_LEN(chip::Crypto::kSpake2p_Max_PBKDF_Salt_Length) + 1; +/* Secure subsystem private key blob size is 32 + 24 = 56. + * DAC private key may be used to store an SSS exported blob instead of the private key. + */ +static constexpr size_t kDacPrivateKey_MaxLen = Crypto::kP256_PrivateKey_Length + 24; + +uint32_t FactoryDataProvider::kFactoryDataStart = (uint32_t) __MATTER_FACTORY_DATA_START; +uint32_t FactoryDataProvider::kFactoryDataSize = (uint32_t) __MATTER_FACTORY_DATA_SIZE; +uint32_t FactoryDataProvider::kFactoryDataPayloadStart = kFactoryDataStart + sizeof(FactoryDataProvider::Header); + +FactoryDataProvider::~FactoryDataProvider() {} + +CHIP_ERROR FactoryDataProvider::Validate() +{ + uint8_t output[Crypto::kSHA256_Hash_Length] = { 0 }; + + memcpy(&mHeader, (void *) kFactoryDataStart, sizeof(Header)); + ReturnErrorCodeIf(mHeader.hashId != kHashId, CHIP_FACTORY_DATA_HASH_ID); + + ReturnErrorOnFailure(Crypto::Hash_SHA256((uint8_t *) kFactoryDataPayloadStart, mHeader.size, output)); + ReturnErrorCodeIf(memcmp(output, mHeader.hash, kHashLen) != 0, CHIP_FACTORY_DATA_SHA_CHECK); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::SearchForId(uint8_t searchedType, uint8_t * pBuf, size_t bufLength, uint16_t & length, + uint32_t * offset) +{ + uint32_t addr = kFactoryDataPayloadStart; + uint8_t type = 0; + + while (addr < (kFactoryDataPayloadStart + mHeader.size)) + { + memcpy(&type, (void *) addr, sizeof(type)); + memcpy(&length, (void *) (addr + 1), sizeof(length)); + + if (searchedType == type) + { + ReturnErrorCodeIf(bufLength < length, CHIP_ERROR_BUFFER_TOO_SMALL); + memcpy(pBuf, (void *) (addr + kValueOffset), length); + + if (offset) + *offset = (addr - kFactoryDataPayloadStart); + + return CHIP_NO_ERROR; + } + else + { + /* Jump past 3 bytes of length and then use length to jump to next data */ + addr = addr + kValueOffset + length; + } + } + + return CHIP_ERROR_NOT_FOUND; +} + +CHIP_ERROR FactoryDataProvider::GetCertificationDeclaration(MutableByteSpan & outBuffer) +{ +#if CHIP_USE_DEVICE_CONFIG_CERTIFICATION_DECLARATION + constexpr uint8_t kCdForAllExamples[] = CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION; + + return CopySpanToMutableSpan(ByteSpan{ kCdForAllExamples }, outBuffer); +#else + uint16_t declarationSize = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kCertDeclarationId, outBuffer.data(), outBuffer.size(), declarationSize)); + outBuffer.reduce_size(declarationSize); + + return CHIP_NO_ERROR; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) +{ + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & outBuffer) +{ + uint16_t certificateSize = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kDacCertificateId, outBuffer.data(), outBuffer.size(), certificateSize)); + outBuffer.reduce_size(certificateSize); + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) +{ + uint16_t certificateSize = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kPaiCertificateId, outBuffer.data(), outBuffer.size(), certificateSize)); + outBuffer.reduce_size(certificateSize); + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) +{ + return SignWithDacKey(messageToSign, outSignBuffer); +} + +CHIP_ERROR FactoryDataProvider::GetSetupDiscriminator(uint16_t & setupDiscriminator) +{ + uint32_t discriminator = 0; + uint16_t temp = 0; + + ReturnErrorOnFailure(SearchForId(FactoryDataId::kDiscriminatorId, (uint8_t *) &discriminator, sizeof(discriminator), temp)); + setupDiscriminator = (uint16_t) (discriminator & 0x0000FFFF); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::SetSetupDiscriminator(uint16_t setupDiscriminator) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR FactoryDataProvider::GetSpake2pIterationCount(uint32_t & iterationCount) +{ + uint16_t temp = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kIcId, (uint8_t *) &iterationCount, sizeof(iterationCount), temp)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) +{ + char saltB64[kSpake2pSalt_MaxBase64Len] = { 0 }; + uint16_t saltB64Len = 0; + + ReturnErrorOnFailure(SearchForId(FactoryDataId::kSaltId, (uint8_t *) (&saltB64[0]), sizeof(saltB64), saltB64Len)); + size_t saltLen = chip::Base64Decode32(saltB64, saltB64Len, reinterpret_cast<uint8_t *>(saltB64)); + + ReturnErrorCodeIf(saltLen > saltBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + memcpy(saltBuf.data(), saltB64, saltLen); + saltBuf.reduce_size(saltLen); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) +{ + char verifierB64[kSpake2pSerializedVerifier_MaxBase64Len] = { 0 }; + uint16_t verifierB64Len = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kVerifierId, (uint8_t *) &verifierB64[0], sizeof(verifierB64), verifierB64Len)); + + verifierLen = chip::Base64Decode32(verifierB64, verifierB64Len, reinterpret_cast<uint8_t *>(verifierB64)); + ReturnErrorCodeIf(verifierLen > verifierBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + memcpy(verifierBuf.data(), verifierB64, verifierLen); + verifierBuf.reduce_size(verifierLen); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetSetupPasscode(uint32_t & setupPasscode) +{ + uint16_t length = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kSetupPasscodeId, (uint8_t *) &setupPasscode, sizeof(setupPasscode), length)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::SetSetupPasscode(uint32_t setupPasscode) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR FactoryDataProvider::GetVendorName(char * buf, size_t bufSize) +{ + uint16_t length = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kVendorNameId, (uint8_t *) buf, bufSize, length)); + buf[length] = '\0'; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetVendorId(uint16_t & vendorId) +{ + uint16_t length = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kVidId, (uint8_t *) &vendorId, sizeof(vendorId), length)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetProductName(char * buf, size_t bufSize) +{ + uint16_t length = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kProductNameId, (uint8_t *) buf, bufSize, length)); + buf[length] = '\0'; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetProductId(uint16_t & productId) +{ + uint16_t length = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kPidId, (uint8_t *) &productId, sizeof(productId), length)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetPartNumber(char * buf, size_t bufSize) +{ + uint16_t length = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kPartNumber, (uint8_t *) buf, bufSize, length)); + buf[length] = '\0'; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetProductURL(char * buf, size_t bufSize) +{ + uint16_t length = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kProductURL, (uint8_t *) buf, bufSize, length)); + buf[length] = '\0'; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetProductLabel(char * buf, size_t bufSize) +{ + uint16_t length = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kProductLabel, (uint8_t *) buf, bufSize, length)); + buf[length] = '\0'; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetSerialNumber(char * buf, size_t bufSize) +{ + uint16_t length = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kSerialNumberId, (uint8_t *) buf, bufSize, length)); + buf[length] = '\0'; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) +{ + uint16_t length = 0; + uint8_t date[ConfigurationManager::kMaxManufacturingDateLength]; + + ReturnErrorOnFailure( + SearchForId(FactoryDataId::kManufacturingDateId, date, ConfigurationManager::kMaxManufacturingDateLength, length)); + date[length] = '\0'; + + if (length == 10 && isdigit(date[0]) && isdigit(date[1]) && isdigit(date[2]) && isdigit(date[3]) && date[4] == '-' && + isdigit(date[5]) && isdigit(date[6]) && date[7] == '-' && isdigit(date[8]) && isdigit(date[9])) + { + year = 1000 * (date[0] - '0') + 100 * (date[1] - '0') + 10 * (date[2] - '0') + date[3] - '0'; + month = 10 * (date[5] - '0') + date[6] - '0'; + day = 10 * (date[8] - '0') + date[9] - '0'; + } + else + { + ChipLogError(DeviceLayer, "Manufacturing date is not formatted correctly: YYYY-MM-DD."); + return CHIP_ERROR_INVALID_ARGUMENT; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetHardwareVersion(uint16_t & hardwareVersion) +{ + uint16_t length = 0; + ReturnErrorOnFailure( + SearchForId(FactoryDataId::kHardwareVersionId, (uint8_t *) &hardwareVersion, sizeof(hardwareVersion), length)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetHardwareVersionString(char * buf, size_t bufSize) +{ + uint16_t length = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kHardwareVersionStrId, (uint8_t *) buf, bufSize, length)); + buf[length] = '\0'; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) +{ + CHIP_ERROR err = CHIP_ERROR_NOT_IMPLEMENTED; +#if CHIP_ENABLE_ROTATING_DEVICE_ID + static_assert(ConfigurationManager::kRotatingDeviceIDUniqueIDLength >= ConfigurationManager::kMinRotatingDeviceIDUniqueIDLength, + "Length of unique ID for rotating device ID is smaller than minimum."); + uint16_t uniqueIdLen = 0; + err = SearchForId(FactoryDataId::kUniqueId, (uint8_t *) uniqueIdSpan.data(), uniqueIdSpan.size(), uniqueIdLen); +#if defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID) + if (err != CHIP_NO_ERROR) + { + constexpr uint8_t uniqueId[] = CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID; + + ReturnErrorCodeIf(sizeof(uniqueId) > uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + memcpy(uniqueIdSpan.data(), uniqueId, sizeof(uniqueId)); + uniqueIdLen = sizeof(uniqueId); + err = CHIP_NO_ERROR; + } +#endif // CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID + ReturnErrorOnFailure(err); + uniqueIdSpan.reduce_size(uniqueIdLen); +#endif + + return err; +} + +CHIP_ERROR FactoryDataProvider::GetProductFinish(app::Clusters::BasicInformation::ProductFinishEnum * finish) +{ + uint8_t productFinish; + uint16_t length = 0; + auto err = SearchForId(FactoryDataId::kProductFinish, &productFinish, sizeof(productFinish), length); + ReturnErrorCodeIf(err != CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); + + *finish = static_cast<app::Clusters::BasicInformation::ProductFinishEnum>(productFinish); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetProductPrimaryColor(app::Clusters::BasicInformation::ColorEnum * primaryColor) +{ + uint8_t color; + uint16_t length = 0; + auto err = SearchForId(FactoryDataId::kProductPrimaryColor, &color, sizeof(color), length); + ReturnErrorCodeIf(err != CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); + + *primaryColor = static_cast<app::Clusters::BasicInformation::ColorEnum>(color); + + return CHIP_NO_ERROR; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/k32w0/FactoryDataProvider.h b/src/platform/nxp/k32w0/FactoryDataProvider.h new file mode 100644 index 00000000000000..8a76a84800baab --- /dev/null +++ b/src/platform/nxp/k32w0/FactoryDataProvider.h @@ -0,0 +1,158 @@ +/* + * + * 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. + */ +#pragma once + +#include <credentials/DeviceAttestationCredsProvider.h> +#include <platform/CommissionableDataProvider.h> +#include <platform/internal/GenericDeviceInstanceInfoProvider.h> +#include <src/lib/core/CHIPError.h> + +#include <vector> + +#include "CHIPPlatformConfig.h" + +#include <vector> + +/* Grab symbol for the base address from the linker file. */ +extern uint32_t __MATTER_FACTORY_DATA_START[]; +extern uint32_t __MATTER_FACTORY_DATA_SIZE[]; + +namespace chip { +namespace DeviceLayer { + +#define CHIP_FACTORY_DATA_ERROR(e) \ + ChipError(ChipError::Range::kLastRange, ((uint8_t) ChipError::Range::kLastRange << 2) | e, __FILE__, __LINE__) + +#define CHIP_FACTORY_DATA_SHA_CHECK CHIP_FACTORY_DATA_ERROR(0x01) +#define CHIP_FACTORY_DATA_HEADER_READ CHIP_FACTORY_DATA_ERROR(0x02) +#define CHIP_FACTORY_DATA_HASH_ID CHIP_FACTORY_DATA_ERROR(0x03) +#define CHIP_FACTORY_DATA_PDM_RESTORE CHIP_FACTORY_DATA_ERROR(0x04) +#define CHIP_FACTORY_DATA_NULL CHIP_FACTORY_DATA_ERROR(0x05) +#define CHIP_FACTORY_DATA_FLASH_ERASE CHIP_FACTORY_DATA_ERROR(0x06) +#define CHIP_FACTORY_DATA_FLASH_PROGRAM CHIP_FACTORY_DATA_ERROR(0x07) +#define CHIP_FACTORY_DATA_INTERNAL_FLASH_READ CHIP_FACTORY_DATA_ERROR(0x08) +#define CHIP_FACTORY_DATA_PDM_SAVE_RECORD CHIP_FACTORY_DATA_ERROR(0x09) +#define CHIP_FACTORY_DATA_PDM_READ_RECORD CHIP_FACTORY_DATA_ERROR(0x0A) +#define CHIP_FACTORY_DATA_RESTORE_MECHANISM CHIP_FACTORY_DATA_ERROR(0x0B) + +// Forward declaration to define the getter for factory data provider impl instance +class FactoryDataProviderImpl; + +/** + * @brief This class provides Commissionable data, Device Attestation Credentials, + * and Device Instance Info. + */ + +class FactoryDataProvider : public DeviceInstanceInfoProvider, + public CommissionableDataProvider, + public Credentials::DeviceAttestationCredentialsProvider +{ +public: + struct Header + { + uint32_t hashId; + uint32_t size; + uint8_t hash[4]; + }; + + // Default factory data IDs + enum FactoryDataId + { + kVerifierId = 1, + kSaltId, + kIcId, + kDacPrivateKeyId, + kDacCertificateId, + kPaiCertificateId, + kDiscriminatorId, + kSetupPasscodeId, + kVidId, + kPidId, + kCertDeclarationId, + kVendorNameId, + kProductNameId, + kSerialNumberId, + kManufacturingDateId, + kHardwareVersionId, + kHardwareVersionStrId, + kUniqueId, + kPartNumber, + kProductURL, + kProductLabel, + kProductFinish, + kProductPrimaryColor, + kMaxId + }; + + static uint32_t kFactoryDataStart; + static uint32_t kFactoryDataSize; + static uint32_t kFactoryDataPayloadStart; + static constexpr uint32_t kLengthOffset = 1; + static constexpr uint32_t kValueOffset = 3; + static constexpr uint32_t kHashLen = 4; + static constexpr size_t kHashId = 0xCE47BA5E; + + virtual ~FactoryDataProvider(); + + virtual CHIP_ERROR Init() = 0; + virtual CHIP_ERROR SignWithDacKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) = 0; + CHIP_ERROR Validate(); + + CHIP_ERROR SearchForId(uint8_t searchedType, uint8_t * pBuf, size_t bufLength, uint16_t & length, uint32_t * offset = nullptr); + + // ===== Members functions that implement the CommissionableDataProvider + CHIP_ERROR GetSetupDiscriminator(uint16_t & setupDiscriminator) override; + CHIP_ERROR SetSetupDiscriminator(uint16_t setupDiscriminator) override; + CHIP_ERROR GetSpake2pIterationCount(uint32_t & iterationCount) override; + CHIP_ERROR GetSpake2pSalt(MutableByteSpan & saltBuf) override; + CHIP_ERROR GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) override; + CHIP_ERROR GetSetupPasscode(uint32_t & setupPasscode) override; + CHIP_ERROR SetSetupPasscode(uint32_t setupPasscode) override; + + // ===== Members functions that implement the DeviceAttestationCredentialsProvider + CHIP_ERROR GetCertificationDeclaration(MutableByteSpan & outBuffer) override; + CHIP_ERROR GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) override; + CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & outBuffer) override; + CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) override; + CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) override; + + // ===== Members functions that implement the GenericDeviceInstanceInfoProvider + CHIP_ERROR GetVendorName(char * buf, size_t bufSize) override; + CHIP_ERROR GetVendorId(uint16_t & vendorId) override; + CHIP_ERROR GetProductName(char * buf, size_t bufSize) override; + CHIP_ERROR GetProductId(uint16_t & productId) override; + CHIP_ERROR GetPartNumber(char * buf, size_t bufSize) override; + CHIP_ERROR GetProductURL(char * buf, size_t bufSize) override; + CHIP_ERROR GetProductLabel(char * buf, size_t bufSize) override; + CHIP_ERROR GetHardwareVersionString(char * buf, size_t bufSize) override; + CHIP_ERROR GetSerialNumber(char * buf, size_t bufSize) override; + CHIP_ERROR GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) override; + CHIP_ERROR GetHardwareVersion(uint16_t & hardwareVersion) override; + CHIP_ERROR GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) override; + CHIP_ERROR GetProductFinish(app::Clusters::BasicInformation::ProductFinishEnum * finish) override; + CHIP_ERROR GetProductPrimaryColor(app::Clusters::BasicInformation::ColorEnum * primaryColor) override; + +protected: + Header mHeader; +}; + +extern FactoryDataProvider & FactoryDataPrvd(); + +extern FactoryDataProviderImpl & FactoryDataPrvdImpl(); + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/k32w/k32w0/FactoryDataProviderImpl.cpp b/src/platform/nxp/k32w0/FactoryDataProviderImpl.cpp similarity index 94% rename from src/platform/nxp/k32w/k32w0/FactoryDataProviderImpl.cpp rename to src/platform/nxp/k32w0/FactoryDataProviderImpl.cpp index dc6acd3b619272..93c09adf5c749d 100644 --- a/src/platform/nxp/k32w/k32w0/FactoryDataProviderImpl.cpp +++ b/src/platform/nxp/k32w0/FactoryDataProviderImpl.cpp @@ -17,9 +17,9 @@ #include <crypto/CHIPCryptoPAL.h> #include <lib/core/CHIPError.h> -#include <platform/nxp/k32w/k32w0/FactoryDataProviderImpl.h> +#include <platform/nxp/k32w0/FactoryDataProviderImpl.h> -#if CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR extern "C" { #include "Flash_Adapter.h" } @@ -31,7 +31,7 @@ namespace DeviceLayer { FactoryDataProviderImpl::FactoryDataProviderImpl() { -#if CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR RegisterRestoreMechanism(FactoryDataDefaultRestoreMechanism); #endif } @@ -40,7 +40,7 @@ CHIP_ERROR FactoryDataProviderImpl::Init() { CHIP_ERROR error = CHIP_NO_ERROR; -#if CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR error = ValidateWithRestore(); #else error = Validate(); @@ -91,7 +91,7 @@ CHIP_ERROR FactoryDataProviderImpl::SignWithDacKey(const ByteSpan & messageToSig return error; } -#if CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR extern "C" WEAK CHIP_ERROR FactoryDataDefaultRestoreMechanism() { CHIP_ERROR error = CHIP_NO_ERROR; @@ -170,7 +170,7 @@ void FactoryDataProviderImpl::RegisterRestoreMechanism(RestoreMechanism restore) { mRestoreMechanisms.insert(mRestoreMechanisms.end(), restore); } -#endif // CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR +#endif // CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/nxp/k32w/k32w0/FactoryDataProviderImpl.h b/src/platform/nxp/k32w0/FactoryDataProviderImpl.h similarity index 88% rename from src/platform/nxp/k32w/k32w0/FactoryDataProviderImpl.h rename to src/platform/nxp/k32w0/FactoryDataProviderImpl.h index b359a6d3f196cd..afeb802352bc7b 100644 --- a/src/platform/nxp/k32w/k32w0/FactoryDataProviderImpl.h +++ b/src/platform/nxp/k32w0/FactoryDataProviderImpl.h @@ -16,7 +16,7 @@ */ #pragma once -#include <platform/nxp/k32w/common/FactoryDataProvider.h> +#include <platform/nxp/k32w0/FactoryDataProvider.h> #include <vector> namespace chip { @@ -24,7 +24,7 @@ namespace DeviceLayer { /** * This class provides K32W0 specific factory data features. - * CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR - enables factory data OTA + * CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR - enables factory data OTA */ class FactoryDataProviderImpl : public FactoryDataProvider @@ -35,7 +35,7 @@ class FactoryDataProviderImpl : public FactoryDataProvider CHIP_ERROR Init() override; CHIP_ERROR SignWithDacKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) override; -#if CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR using RestoreMechanism = CHIP_ERROR (*)(void); static CHIP_ERROR UpdateData(uint8_t * pBuf); diff --git a/src/platform/nxp/k32w/k32w0/InetPlatformConfig.h b/src/platform/nxp/k32w0/InetPlatformConfig.h similarity index 100% rename from src/platform/nxp/k32w/k32w0/InetPlatformConfig.h rename to src/platform/nxp/k32w0/InetPlatformConfig.h diff --git a/src/platform/nxp/k32w/k32w0/K32W0Config.cpp b/src/platform/nxp/k32w0/K32W0Config.cpp similarity index 99% rename from src/platform/nxp/k32w/k32w0/K32W0Config.cpp rename to src/platform/nxp/k32w0/K32W0Config.cpp index 850a1b7398ef06..2054ef5da619bf 100644 --- a/src/platform/nxp/k32w/k32w0/K32W0Config.cpp +++ b/src/platform/nxp/k32w0/K32W0Config.cpp @@ -25,7 +25,7 @@ /* this file behaves like a config.h, comes first */ #include <platform/internal/CHIPDeviceLayerInternal.h> -#include <platform/nxp/k32w/k32w0/K32W0Config.h> +#include <platform/nxp/k32w0/K32W0Config.h> #include <lib/core/CHIPEncoding.h> #include <platform/internal/testing/ConfigUnitTest.h> diff --git a/src/platform/nxp/k32w/k32w0/K32W0Config.h b/src/platform/nxp/k32w0/K32W0Config.h similarity index 98% rename from src/platform/nxp/k32w/k32w0/K32W0Config.h rename to src/platform/nxp/k32w0/K32W0Config.h index e364c045c25b1c..7080e62e747bf1 100644 --- a/src/platform/nxp/k32w/k32w0/K32W0Config.h +++ b/src/platform/nxp/k32w0/K32W0Config.h @@ -20,7 +20,7 @@ #include <functional> #include <platform/internal/CHIPDeviceLayerInternal.h> -#include <platform/nxp/k32w/k32w0/RamStorage.h> +#include <platform/nxp/k32w0/RamStorage.h> namespace chip { namespace DeviceLayer { diff --git a/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.cpp b/src/platform/nxp/k32w0/KeyValueStoreManagerImpl.cpp similarity index 93% rename from src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.cpp rename to src/platform/nxp/k32w0/KeyValueStoreManagerImpl.cpp index 8dbf3e5bd71903..50f900583769f7 100644 --- a/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.cpp +++ b/src/platform/nxp/k32w0/KeyValueStoreManagerImpl.cpp @@ -25,9 +25,9 @@ #include <lib/support/CHIPMem.h> #include <platform/KeyValueStoreManager.h> -#include <platform/nxp/k32w/k32w0/K32W0Config.h> -#include <platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.h> -#include <platform/nxp/k32w/k32w0/RamStorage.h> +#include <platform/nxp/k32w0/K32W0Config.h> +#include <platform/nxp/k32w0/KeyValueStoreManagerImpl.h> +#include <platform/nxp/k32w0/RamStorage.h> #include <string> namespace chip { @@ -41,6 +41,7 @@ Internal::RamStorage KeyValueStoreManagerImpl::sKeysStorage = { kNvmId_K Internal::RamStorage KeyValueStoreManagerImpl::sValuesStorage = { kNvmId_KvsValues, "Values" }; Internal::RamStorage KeyValueStoreManagerImpl::sSubscriptionStorage = { kNvmId_KvsSubscription, "Subscriptions" }; Internal::RamStorage KeyValueStoreManagerImpl::sGroupsStorage = { kNvmId_KvsGroups, "Groups" }; +Internal::RamStorage KeyValueStoreManagerImpl::sAclStorage = { kNvmId_KvsAcl, "Acl" }; KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance; @@ -63,6 +64,12 @@ static inline bool IsKeyRelatedToSubscriptions(const char * key) return _key.find("g/su") == 0; } +static inline bool IsKeyRelatedToAcl(const char * key) +{ + std::string _key(key); + return _key.find("/ac/") != std::string::npos; +} + static Internal::RamStorage * GetValStorage(const char * key) { Internal::RamStorage * storage = nullptr; @@ -70,6 +77,7 @@ static Internal::RamStorage * GetValStorage(const char * key) storage = IsKeyRelatedToSubscriptions(key) ? &KeyValueStoreManagerImpl::sSubscriptionStorage : &KeyValueStoreManagerImpl::sValuesStorage; storage = IsKeyRelatedToGroups(key) ? &KeyValueStoreManagerImpl::sGroupsStorage : storage; + storage = IsKeyRelatedToAcl(key) ? &KeyValueStoreManagerImpl::sAclStorage : storage; return storage; } @@ -81,6 +89,7 @@ static Internal::RamStorage * GetKeyStorage(const char * key) storage = IsKeyRelatedToSubscriptions(key) ? &KeyValueStoreManagerImpl::sSubscriptionStorage : &KeyValueStoreManagerImpl::sKeysStorage; storage = IsKeyRelatedToGroups(key) ? &KeyValueStoreManagerImpl::sGroupsStorage : storage; + storage = IsKeyRelatedToAcl(key) ? &KeyValueStoreManagerImpl::sAclStorage : storage; return storage; } @@ -145,6 +154,12 @@ CHIP_ERROR KeyValueStoreManagerImpl::Init() ChipLogProgress(DeviceLayer, "Cannot init KVS groups storage with id: %d. Error: %s", kNvmId_KvsGroups, ErrorStr(err)); } + err = sAclStorage.Init(Internal::RamStorage::kRamBufferInitialSize, true); + if (err != CHIP_NO_ERROR) + { + ChipLogProgress(DeviceLayer, "Cannot init KVS acl storage with id: %d. Error: %s", kNvmId_KvsAcl, ErrorStr(err)); + } + #if CONFIG_CHIP_K32W0_KVS_MOVE_KEYS_TO_SPECIFIC_STORAGE ChipLogProgress(DeviceLayer, "Moving some keys to dedicated storage"); MoveKeysAndValues(); diff --git a/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.h b/src/platform/nxp/k32w0/KeyValueStoreManagerImpl.h similarity index 95% rename from src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.h rename to src/platform/nxp/k32w0/KeyValueStoreManagerImpl.h index 718b92df6beb39..57d877beaeaaf9 100644 --- a/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.h +++ b/src/platform/nxp/k32w0/KeyValueStoreManagerImpl.h @@ -24,7 +24,7 @@ #pragma once -#include <platform/nxp/k32w/k32w0/RamStorage.h> +#include <platform/nxp/k32w0/RamStorage.h> namespace chip { namespace DeviceLayer { @@ -41,6 +41,8 @@ class KeyValueStoreManagerImpl final : public KeyValueStoreManager static Internal::RamStorage sSubscriptionStorage; /* Storage for KVS groups keys and values. Cleared during factory reset. */ static Internal::RamStorage sGroupsStorage; + /* Storage for KVS ACL keys and values. Cleared during factory reset. */ + static Internal::RamStorage sAclStorage; // Allow the KeyValueStoreManager interface class to delegate method calls to // the implementation methods provided by this class. diff --git a/src/platform/nxp/k32w/k32w0/Logging.cpp b/src/platform/nxp/k32w0/Logging.cpp similarity index 100% rename from src/platform/nxp/k32w/k32w0/Logging.cpp rename to src/platform/nxp/k32w0/Logging.cpp diff --git a/src/platform/nxp/k32w/k32w0/LowPowerHooks.cpp b/src/platform/nxp/k32w0/LowPowerHooks.cpp similarity index 100% rename from src/platform/nxp/k32w/k32w0/LowPowerHooks.cpp rename to src/platform/nxp/k32w0/LowPowerHooks.cpp diff --git a/src/platform/nxp/k32w/k32w0/NFCManagerImpl.cpp b/src/platform/nxp/k32w0/NFCManagerImpl.cpp similarity index 100% rename from src/platform/nxp/k32w/k32w0/NFCManagerImpl.cpp rename to src/platform/nxp/k32w0/NFCManagerImpl.cpp diff --git a/src/platform/nxp/k32w/k32w0/NFCManagerImpl.h b/src/platform/nxp/k32w0/NFCManagerImpl.h similarity index 100% rename from src/platform/nxp/k32w/k32w0/NFCManagerImpl.h rename to src/platform/nxp/k32w0/NFCManagerImpl.h diff --git a/src/platform/nxp/k32w/k32w0/OTAFactoryDataProcessor.cpp b/src/platform/nxp/k32w0/OTAFactoryDataProcessor.cpp similarity index 97% rename from src/platform/nxp/k32w/k32w0/OTAFactoryDataProcessor.cpp rename to src/platform/nxp/k32w0/OTAFactoryDataProcessor.cpp index d40d2ae3c17f5a..b6777c7dc32820 100644 --- a/src/platform/nxp/k32w/k32w0/OTAFactoryDataProcessor.cpp +++ b/src/platform/nxp/k32w0/OTAFactoryDataProcessor.cpp @@ -18,9 +18,10 @@ #include <lib/core/TLV.h> #include <platform/internal/CHIPDeviceLayerInternal.h> -#include <platform/nxp/k32w/common/CHIPDevicePlatformRamStorageConfig.h> -#include <platform/nxp/k32w/k32w0/CHIPDevicePlatformConfig.h> -#include <platform/nxp/k32w/k32w0/OTAFactoryDataProcessor.h> +#include <platform/nxp/common/legacy/CHIPDevicePlatformRamStorageConfig.h> +#include <platform/nxp/k32w0/CHIPDevicePlatformConfig.h> +#include <platform/nxp/k32w0/FactoryDataProviderImpl.h> +#include <platform/nxp/k32w0/OTAFactoryDataProcessor.h> #include "PDM.h" #include "fsl_flash.h" diff --git a/src/platform/nxp/k32w/k32w0/OTAFactoryDataProcessor.h b/src/platform/nxp/k32w0/OTAFactoryDataProcessor.h similarity index 93% rename from src/platform/nxp/k32w/k32w0/OTAFactoryDataProcessor.h rename to src/platform/nxp/k32w0/OTAFactoryDataProcessor.h index 8682d0bcc1e9dc..3109e64a8d0ae3 100644 --- a/src/platform/nxp/k32w/k32w0/OTAFactoryDataProcessor.h +++ b/src/platform/nxp/k32w0/OTAFactoryDataProcessor.h @@ -21,9 +21,9 @@ #include <lib/core/Optional.h> #include <lib/support/ScopedBuffer.h> #include <lib/support/Span.h> -#include <platform/nxp/k32w/common/FactoryDataProvider.h> -#include <platform/nxp/k32w/common/OTATlvProcessor.h> -#include <platform/nxp/k32w/k32w0/FactoryDataProviderImpl.h> +#include <platform/nxp/common/legacy/OTATlvProcessor.h> +#include <platform/nxp/k32w0/FactoryDataProvider.h> +#include <platform/nxp/k32w0/FactoryDataProviderImpl.h> namespace chip { diff --git a/src/platform/nxp/k32w/k32w0/OTAFirmwareProcessor.cpp b/src/platform/nxp/k32w0/OTAFirmwareProcessor.cpp similarity index 96% rename from src/platform/nxp/k32w/k32w0/OTAFirmwareProcessor.cpp rename to src/platform/nxp/k32w0/OTAFirmwareProcessor.cpp index f63aa745378851..c7a1a2bbf435dd 100644 --- a/src/platform/nxp/k32w/k32w0/OTAFirmwareProcessor.cpp +++ b/src/platform/nxp/k32w0/OTAFirmwareProcessor.cpp @@ -17,9 +17,9 @@ */ #include <platform/internal/CHIPDeviceLayerInternal.h> -#include <platform/nxp/k32w/common/OTAImageProcessorImpl.h> -#include <platform/nxp/k32w/k32w0/CHIPDevicePlatformConfig.h> -#include <platform/nxp/k32w/k32w0/OTAFirmwareProcessor.h> +#include <platform/nxp/common/legacy/OTAImageProcessorImpl.h> +#include <platform/nxp/k32w0/CHIPDevicePlatformConfig.h> +#include <platform/nxp/k32w0/OTAFirmwareProcessor.h> #include "OtaSupport.h" #include "OtaUtils.h" diff --git a/src/platform/nxp/k32w/k32w0/OTAFirmwareProcessor.h b/src/platform/nxp/k32w0/OTAFirmwareProcessor.h similarity index 96% rename from src/platform/nxp/k32w/k32w0/OTAFirmwareProcessor.h rename to src/platform/nxp/k32w0/OTAFirmwareProcessor.h index 5a1092ef5fbc46..444243f0c885d0 100644 --- a/src/platform/nxp/k32w/k32w0/OTAFirmwareProcessor.h +++ b/src/platform/nxp/k32w0/OTAFirmwareProcessor.h @@ -19,7 +19,7 @@ #pragma once #include <lib/support/Span.h> -#include <platform/nxp/k32w/common/OTATlvProcessor.h> +#include <platform/nxp/common/legacy/OTATlvProcessor.h> namespace chip { diff --git a/src/platform/nxp/k32w/k32w0/OTAHooks.cpp b/src/platform/nxp/k32w0/OTAHooks.cpp similarity index 87% rename from src/platform/nxp/k32w/k32w0/OTAHooks.cpp rename to src/platform/nxp/k32w0/OTAHooks.cpp index a00ae428a0f40d..30df88177ffdc6 100644 --- a/src/platform/nxp/k32w/k32w0/OTAHooks.cpp +++ b/src/platform/nxp/k32w0/OTAHooks.cpp @@ -16,16 +16,16 @@ * limitations under the License. */ -#include <platform/nxp/k32w/common/OTAImageProcessorImpl.h> +#include <platform/nxp/common/legacy/OTAImageProcessorImpl.h> #include <src/include/platform/CHIPDeviceLayer.h> #include <src/app/clusters/ota-requestor/OTARequestorInterface.h> -#include <platform/nxp/k32w/k32w0/CHIPDevicePlatformConfig.h> -#include <platform/nxp/k32w/k32w0/OTAFirmwareProcessor.h> -#if CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR -#include <platform/nxp/k32w/k32w0/OTAFactoryDataProcessor.h> -#endif // CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR +#include <platform/nxp/k32w0/CHIPDevicePlatformConfig.h> +#include <platform/nxp/k32w0/OTAFirmwareProcessor.h> +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR +#include <platform/nxp/k32w0/OTAFactoryDataProcessor.h> +#endif // CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR #include "OtaSupport.h" @@ -51,9 +51,9 @@ extern "C" WEAK CHIP_ERROR OtaHookInit() { static chip::OTAFirmwareProcessor sApplicationProcessor; static chip::OTAFirmwareProcessor sBootloaderProcessor; -#if CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR static chip::OTAFactoryDataProcessor sFactoryDataProcessor; -#endif // CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR +#endif // CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR #if CONFIG_CHIP_K32W0_MAX_ENTRIES_TEST static chip::OTAFirmwareProcessor processors[8]; #endif @@ -64,9 +64,9 @@ extern "C" WEAK CHIP_ERROR OtaHookInit() auto & imageProcessor = chip::OTAImageProcessorImpl::GetDefaultInstance(); ReturnErrorOnFailure(imageProcessor.RegisterProcessor(1, &sApplicationProcessor)); ReturnErrorOnFailure(imageProcessor.RegisterProcessor(2, &sBootloaderProcessor)); -#if CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR ReturnErrorOnFailure(imageProcessor.RegisterProcessor(3, &sFactoryDataProcessor)); -#endif // CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR +#endif // CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR #if CONFIG_CHIP_K32W0_MAX_ENTRIES_TEST for (auto i = 0; i < 8; i++) { diff --git a/src/platform/nxp/k32w/k32w0/PlatformManagerImpl.cpp b/src/platform/nxp/k32w0/PlatformManagerImpl.cpp similarity index 98% rename from src/platform/nxp/k32w/k32w0/PlatformManagerImpl.cpp rename to src/platform/nxp/k32w0/PlatformManagerImpl.cpp index 198f9318ba41fb..1a98552cb7e0d9 100644 --- a/src/platform/nxp/k32w/k32w0/PlatformManagerImpl.cpp +++ b/src/platform/nxp/k32w0/PlatformManagerImpl.cpp @@ -29,8 +29,8 @@ #include <openthread-system.h> #include <platform/PlatformManager.h> #include <platform/internal/GenericPlatformManagerImpl_FreeRTOS.ipp> -#include <platform/nxp/k32w/k32w0/DiagnosticDataProviderImpl.h> -#include <platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.h> +#include <platform/nxp/k32w0/DiagnosticDataProviderImpl.h> +#include <platform/nxp/k32w0/KeyValueStoreManagerImpl.h> #if CHIP_SYSTEM_CONFIG_USE_LWIP #include <lwip/tcpip.h> diff --git a/src/platform/nxp/k32w/k32w0/PlatformManagerImpl.h b/src/platform/nxp/k32w0/PlatformManagerImpl.h similarity index 100% rename from src/platform/nxp/k32w/k32w0/PlatformManagerImpl.h rename to src/platform/nxp/k32w0/PlatformManagerImpl.h diff --git a/src/platform/nxp/k32w/k32w0/RamStorage.cpp b/src/platform/nxp/k32w0/RamStorage.cpp similarity index 99% rename from src/platform/nxp/k32w/k32w0/RamStorage.cpp rename to src/platform/nxp/k32w0/RamStorage.cpp index ea32a7f9c525c8..a478a582b98fb1 100644 --- a/src/platform/nxp/k32w/k32w0/RamStorage.cpp +++ b/src/platform/nxp/k32w0/RamStorage.cpp @@ -18,7 +18,7 @@ #include <openthread/platform/memory.h> #include <platform/internal/CHIPDeviceLayerInternal.h> -#include <platform/nxp/k32w/k32w0/RamStorage.h> +#include <platform/nxp/k32w0/RamStorage.h> #include "pdm_ram_storage_glue.h" diff --git a/src/platform/nxp/k32w/k32w0/RamStorage.h b/src/platform/nxp/k32w0/RamStorage.h similarity index 100% rename from src/platform/nxp/k32w/k32w0/RamStorage.h rename to src/platform/nxp/k32w0/RamStorage.h diff --git a/src/platform/nxp/k32w/k32w0/SystemPlatformConfig.h b/src/platform/nxp/k32w0/SystemPlatformConfig.h similarity index 100% rename from src/platform/nxp/k32w/k32w0/SystemPlatformConfig.h rename to src/platform/nxp/k32w0/SystemPlatformConfig.h diff --git a/src/platform/nxp/k32w/k32w0/SystemTimeSupport.cpp b/src/platform/nxp/k32w0/SystemTimeSupport.cpp similarity index 100% rename from src/platform/nxp/k32w/k32w0/SystemTimeSupport.cpp rename to src/platform/nxp/k32w0/SystemTimeSupport.cpp diff --git a/src/platform/nxp/k32w/k32w0/ThreadStackManagerImpl.cpp b/src/platform/nxp/k32w0/ThreadStackManagerImpl.cpp similarity index 100% rename from src/platform/nxp/k32w/k32w0/ThreadStackManagerImpl.cpp rename to src/platform/nxp/k32w0/ThreadStackManagerImpl.cpp diff --git a/src/platform/nxp/k32w/k32w0/ThreadStackManagerImpl.h b/src/platform/nxp/k32w0/ThreadStackManagerImpl.h similarity index 100% rename from src/platform/nxp/k32w/k32w0/ThreadStackManagerImpl.h rename to src/platform/nxp/k32w0/ThreadStackManagerImpl.h diff --git a/src/platform/nxp/k32w/k32w0/args.gni b/src/platform/nxp/k32w0/args.gni similarity index 89% rename from src/platform/nxp/k32w/k32w0/args.gni rename to src/platform/nxp/k32w0/args.gni index 5f90c8248e207a..1076eea4f4cf7f 100644 --- a/src/platform/nxp/k32w/k32w0/args.gni +++ b/src/platform/nxp/k32w0/args.gni @@ -16,15 +16,14 @@ import("//build_overrides/chip.gni") import("//build_overrides/nxp_sdk.gni") import("//build_overrides/openthread.gni") -nxp_platform = "k32w/k32w0" +nxp_platform = "k32w0" nxp_sdk_name = "k32w0_sdk" nxp_device_layer = "nxp/${nxp_platform}" nxp_use_lwip = false nxp_use_mbedtls_port = false if (getenv("NXP_K32W0_SDK_ROOT") == "") { - k32w0_sdk_root = - "${nxp_sdk_matter_support_root}/github_sdk/k32w0_sdk/repo/core" + k32w0_sdk_root = "${nxp_sdk_matter_support_root}/github_sdk/k32w0/repo" } else { k32w0_sdk_root = getenv("NXP_K32W0_SDK_ROOT") } @@ -72,6 +71,6 @@ openthread_external_mbedtls = mbedtls_target openthread_project_core_config_file = "OpenThreadConfig.h" openthread_core_config_platform_check_file = "openthread-core-k32w061-config-check.h" -openthread_core_config_deps = [ "${chip_root}/examples/platform/nxp/k32w/k32w0:openthread_core_config_k32w0_chip_examples" ] +openthread_core_config_deps = [ "${nxp_sdk_matter_support_root}/examples/platform/k32w0:openthread_core_config_k32w0_chip_examples" ] -openthread_external_platform = "${chip_root}/third_party/openthread/platforms/nxp/k32w/k32w0:libopenthread-k32w0" +openthread_external_platform = "${chip_root}/third_party/openthread/platforms/nxp/k32w0:libopenthread-k32w0" diff --git a/src/platform/nxp/k32w/k32w0/ble_function_mux.c b/src/platform/nxp/k32w0/ble_function_mux.c similarity index 100% rename from src/platform/nxp/k32w/k32w0/ble_function_mux.c rename to src/platform/nxp/k32w0/ble_function_mux.c diff --git a/src/platform/nxp/k32w/k32w0/ble_function_mux.h b/src/platform/nxp/k32w0/ble_function_mux.h similarity index 100% rename from src/platform/nxp/k32w/k32w0/ble_function_mux.h rename to src/platform/nxp/k32w0/ble_function_mux.h diff --git a/src/platform/nxp/k32w/k32w0/crypto/CHIPCryptoPALNXPUltrafastP256.cpp b/src/platform/nxp/k32w0/crypto/CHIPCryptoPALNXPUltrafastP256.cpp similarity index 100% rename from src/platform/nxp/k32w/k32w0/crypto/CHIPCryptoPALNXPUltrafastP256.cpp rename to src/platform/nxp/k32w0/crypto/CHIPCryptoPALNXPUltrafastP256.cpp diff --git a/src/platform/nxp/k32w/k32w0/gatt_db.h b/src/platform/nxp/k32w0/gatt_db.h similarity index 100% rename from src/platform/nxp/k32w/k32w0/gatt_db.h rename to src/platform/nxp/k32w0/gatt_db.h diff --git a/src/platform/nxp/k32w/k32w0/gatt_uuid128.h b/src/platform/nxp/k32w0/gatt_uuid128.h similarity index 100% rename from src/platform/nxp/k32w/k32w0/gatt_uuid128.h rename to src/platform/nxp/k32w0/gatt_uuid128.h diff --git a/src/platform/nxp/k32w/k32w0/k32w0-chip-mbedtls-config.h b/src/platform/nxp/k32w0/k32w0-chip-mbedtls-config.h similarity index 100% rename from src/platform/nxp/k32w/k32w0/k32w0-chip-mbedtls-config.h rename to src/platform/nxp/k32w0/k32w0-chip-mbedtls-config.h diff --git a/third_party/nxp/nxp_matter_support b/third_party/nxp/nxp_matter_support index ac504a0cc38963..e6deaf56001387 160000 --- a/third_party/nxp/nxp_matter_support +++ b/third_party/nxp/nxp_matter_support @@ -1 +1 @@ -Subproject commit ac504a0cc389632c0e26b4f04e65914d3a9ba8bd +Subproject commit e6deaf5600138763ea68418e34bc62a02d1aef0d diff --git a/third_party/openthread/platforms/nxp/k32w/k32w0/BUILD.gn b/third_party/openthread/platforms/nxp/k32w0/BUILD.gn similarity index 92% rename from third_party/openthread/platforms/nxp/k32w/k32w0/BUILD.gn rename to third_party/openthread/platforms/nxp/k32w0/BUILD.gn index 7ebd860e571371..bf9ed42e894965 100644 --- a/third_party/openthread/platforms/nxp/k32w/k32w0/BUILD.gn +++ b/third_party/openthread/platforms/nxp/k32w0/BUILD.gn @@ -30,7 +30,7 @@ config("openthread_k32w0_config") { "${openthread_nxp_root}/src/k32w0/platform", "${openthread_nxp_root}/src/common", ] - include_dirs += [ "${chip_root}/examples/platform/nxp/k32w/k32w0" ] + include_dirs += [ "${nxp_sdk_matter_support_root}/examples/platform/k32w0" ] if (is_clang) { cflags = [ "-Wno-format-nonliteral" ] @@ -46,7 +46,7 @@ config("openthread_k32w0_config") { source_set("openthread_core_config_k32w0") { sources = [ - "${chip_root}/examples/platform/nxp/k32w/k32w0/app/project_include/OpenThreadConfig.h", + "${nxp_sdk_matter_support_root}/examples/platform/k32w0/app/project_include/OpenThreadConfig.h", "${openthread_nxp_root}/src/k32w0/k32w061/openthread-core-k32w061-config-check.h", ] @@ -95,7 +95,7 @@ source_set("libopenthread-k32w0") { "${nxp_sdk_build_root}:nxp_sdk", "${nxp_sdk_build_root}/${nxp_sdk_name}:mbedtls", "${openthread_root}/src/core:libopenthread_core_headers", - "../../..:libopenthread-platform", - "../../..:libopenthread-platform-utils", + "../..:libopenthread-platform", + "../..:libopenthread-platform-utils", ] }