From 9b39b0687921632bb4ade5b2c4997faae92f2fe1 Mon Sep 17 00:00:00 2001 From: andrei-menzopol <96489227+andrei-menzopol@users.noreply.github.com> Date: Tue, 13 Feb 2024 21:44:50 +0200 Subject: [PATCH] [NXP][K32W] k32w1 sdk 2.12.6 updates & k32w0 small fixes (#31924) * [common] Remove k32w1 device_platform, use nxp instead Signed-off-by: Andrei Menzopol Signed-off-by: Marius Tache * [K32W1] Build, OTA, Diagnostic changes Signed-off-by: Doru Gucea Signed-off-by: Marius Tache Signed-off-by: Andrei Menzopol * [K32W1] Rename SNT files to ELEMU * [K32W] Add OPENTHREAD_PLATFORM_CORE_CONFIG_FILE define Signed-off-by: Marius Tache * [K32W1] Fix MBEDTLS build flags conflict between Matter vs. OpenThread Matter uses a multithread flavor of MBEDTLS while OpenThread uses a single thread flavor. This triggers a dangerous situation where Matter, OpenThread and MBEDTLS don't agree on the size of various data structures exchanged through the interface which later leads to memory access violations. This update fixes the build configuration so that OpenThread also uses the multithread flavor of MBEDTLS. Signed-off-by: Marian Chereji * [NXP] Update ot-nxp commit-id Signed-off-by: Andrei Menzopol * [K32W0] Add necessary check for env variable When computing the path for the signing script, the existence of env variable NXP_K32W0_SDK_ROOT should be checked first to avoid issues. Signed-off-by: marius-alex-tache * [K32W1] Remove ResetWatermarks empty implementation Signed-off-by: Marius Tache * [K32W1] Set rotating device id unique id length to max by default Signed-off-by: Marius Tache * [K32W1] Fix an issue with __wrap_realloc Current memory manager is MML, which has realloc support. Removed old function that was relevant only in FreeRTOS memory manager (heap4/5) context. Signed-off-by: Marius Tache * [K32W1] Accomodate low power API update PWR_AllowDeviceToSleep/PWR_DisallowDeviceToSleep API reintroduced in SDK. power.c removed from ot-nxp. Signed-off-by: Marius Tache * [K32W1] Clear keys from counter area when factory resetting Signed-off-by: Marius Tache * [K32W1] Use MML API for heap memory consumption statistics WTRMRK feature of the Software Diagnostic Cluster will be implemented once the memory manager will implement the needed API. Signed-off-by: Marius Tache * [K32W1] Remove duplicated code in crypto PAL P256Keypair members were moved into protected scope, so derived classes (P256KeypairSSS) can access these members. Signed-off-by: Marius Tache * [K32W1] Call PLATFORM_InitTimerManager before PLATFORM_InitBLE since this function won't be initializing the timer manager anymore * [K32W1] Post events from ISR correctly Signed-off-by: Marius Tache * [K32W1] MML realloc should be protected from task switching Signed-off-by: Marius Tache * [K32W1] Add initial FactoryDataProviderImpl Signed-off-by: Marius Tache * [K32W1] Update certification declaration in apps Signed-off-by: Marius Tache * [K32W1] Update README files in apps Signed-off-by: Marius Tache * [K32W1] Add DAC private key convert declaration TBD Signed-off-by: Marius Tache * [k32w1] Fix usage of deprecated factory data provider fields Signed-off-by: marius-alex-tache * [COMMON] Add dac_key_use_sss_blob option dac_key_use_sss_blob can be used to select which data the private key area stores: plaintext/encrypted private key or an SSS exported blob. The option is False by default. Signed-off-by: Marius Tache * [K32W1] Add SSS API usage Signed-off-by: Marius Tache * [K32W1] Add chip_convert_dac_private_key option chip_convert_dac_private_key can be used to enable one-time-only conversion of the DAC private key to an SSS encrypted blob. Signed-off-by: Marius Tache * [K32W1] Add jlink conversion script example Signed-off-by: Marius Tache * [K32W1] Update readme to point to docs guide Signed-off-by: Marius Tache * [K32W1] Remove unused mbedtls modules Signed-off-by: Marius Tache * [K32W1] Factory data section should only be reserved in factory data context Signed-off-by: Marius Tache * [K32W1] Add destructor to free SSS object context Signed-off-by: Marius Tache * [K32W1] Add verbose logging for conversion steps Signed-off-by: Marius Tache * [K32W1] Restore NVM sector number The underlying issue, for which the increase in NVM sectors was a workaround, was solved. Signed-off-by: Andrei Menzopol * [K32W1] Add BLE ResetController function Signed-off-by: Andrei Menzopol * [K32W1] Allocate OT buffers from SMU2 When using use_smu2_dynamic=true, OpenThread buffers will be allocated from a 13KB SMU2 region after a successful commissioning process until a factory reset is done. * Add SMU2 namespace in SMU2Manager.h/.cpp * Add build changes * Add allocator changes * Add necessary OpenThread config defines * Add gn parameter/defines for each SMU2 usecase Signed-off-by: Andrei Menzopol * [K32W1] Offload SHA256 operations to S200 * Offload simple sha256, simple hmac sha256, update/finish sha256, update/finish hmac sha256 from Matter and OT. * Implement solution for long sha256 that uses context save/export/restore mechanism. This solution saves the intermediate data on heap and computes the hash on demand (by calling GetDigest). * Put changes under define/gn parameter use_hw_sha256 as they increase timings (due to hardware accelerator initialization time) and use a significant amount of heap. Signed-off-by: Andrei Menzopol * [K32W1] Simplify HW DRBG/TRNG usage S200 TRNG is already used though otPlatEntropyGet from OT. Simplify Matter and OT DRBG usage of HW TRNG by not using mbedtls entropy. Signed-off-by: Andrei Menzopol * [K32W1] Offload AES operations to S200 * Offload AES-CCM from Matter. * Offload AES-ECB from OT. * Use software AES-CCM when Additional authentical data len is zero. * Put changes under define/gn parameter use_hw_aes as they increase timings (due to hardware accelerator initialization time). Signed-off-by: Andrei Menzopol * [K32W1] Fix duplicated flag Signed-off-by: Marius Tache * [COMMON] Add pw RPC support The pw RPC integration should be usable by all NXP platforms that support SerialManager, since the pw_sys_io backend uses streamer_nxp.cpp for serial communication. A scope is defined in pw_rpc_server.gni to be used by all apps by forwarding the variables in the application executable scope: forward_variables_from(pw_rpc_server, "*") Logging and RPC communication share the same serial port. Logging should be inspected in chip-console, which manages the HDLC channels. Signed-off-by: Marius Tache * [COMMON] Update streamer to read RX data ASAP Moved reading the RX FIFO inside the actual interrupt handler, to avoid time penalty when notifying the consumer task (RPC/App CLI). The data is instead stored in a cache buffer and read once the task is unblocked through notifying by the ISR. Signed-off-by: Marius Tache * [K32W1] Enable pw RPC on lighting app To build with RPC enabled, the user should generate the files: gn gen out/debug --args='import("//with_pw_rpc.gni") treat_warnings_as_errors=false' pw RPC requires c++ 17. Some example commands are written in the README, under section `Running RPC console`. Signed-off-by: Marius Tache * [COMMON] Revert streamer implementation and add UART DMA support pw RPC requires UART DMA to avoid missing commands and errors related to frame integrity checks. Applications that enable RPC support should use UART DMA (if possible). Signed-off-by: Marius Tache * [K32W1] Use UART DMA for pw RPC Signed-off-by: Marius Tache * k32w1: enable sit icd Signed-off-by: Doru Gucea * [K32W1] Implement watermark feature using MML API Signed-off-by: Marius Tache * [K32W1] Update free SMU2 region in linker script The SMU2 free region shrank due to addition of lowpower flag in NBU. This overlap might affect Matter instances placed in SMU2 region. Signed-off-by: Andrei Menzopol * [K32W1] Fix TotalOperatingHours attribute reset The UpTime attribute of the GeneralDiagnostics cluster was being reset periodically due to the limited range of the LPTMR timestamp (32 bits). To fix it, support for a 64bit timestamp was added to the NXP OpenThread library and now Matter can use the "otPlatTimeGet()" API to acquire the timestamp in microseconds. Signed-off-by: Marian Chereji * [K32W1] Fix LP current draw for Contact Sensor App after framework changes After framework changes with reintroducing PWR_AllowDeviceToSleep & PWR_DisallowDeviceToSleep functions, Contact Sensor application does not enter into low power anymore after BLE connection event. Adding PWR_DisallowDeviceToSleep call at connection event before PWR_AllowDeviceToSleep as framework request. Signed-off-by: Marius Vilvoi * [K32W] Send a report before resetting the device during OTA State-transition event from Downloading to Applying was not successfully sent to a subscriber during OTA because the device would reset before actually sending the ReportData message. Added an explicit call to sync send a report if any events were logged. This is managed by the ReportingEnginge. Signed-off-by: marius-alex-tache * [K32W] Create dedicated zap file for contact sensor Signed-off-by: Andrei Menzopol * [K32W1] Switch to dedicated zap file The common zap file configuration has many optional cluster enabled that are not needed in our contact-sensor reference app Signed-off-by: Andrei Menzopol * [K32W] Change lighting-app root node revision to 2 Signed-off-by: Andrei Menzopol * [K32W1] Adjust rambuffer size and KVS max number of keys Signed-off-by: Andrei Menzopol * [K32W1] Add CleanReset API Clean reset ensures: * Matter event loop is stopped. * Shutdown is called. * Pending operations are completed in NVM. * MCU is reset. Signed-off-by: marius-alex-tache * [K32W1] Change long press SW3 action from OTA query to clean soft reset When long pressing SW3, the reference applications will call the platform manager clean soft reset API. This will reset the MCU after the Matter shutdown procedure is called and all NVM pending operations are finished. Signed-off-by: marius-alex-tache * [K32W] define CHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER Signed-off-by: Andrei Menzopol * [K32W] Update docker image version Signed-off-by: Andrei Menzopol * Restyled by whitespace * Restyled by clang-format * Restyled by prettier-markdown * Fix spelling Signed-off-by: Andrei Menzopol * [K32W] Update contact-sensor-app zap files Signed-off-by: Andrei Menzopol * [K32W] Remove deprecated code Signed-off-by: marius-alex-tache * [K32W1] Fix gn check errors Signed-off-by: marius-alex-tache * [K32W1] Fix build Signed-off-by: Andrei Menzopol * Restyled by gn * [K32W1] Fix lints Signed-off-by: Andrei Menzopol * [NXP] Update ot-nxp commit-id Signed-off-by: Andrei Menzopol * [NXP] Update matter zap file Signed-off-by: Andrei Menzopol --------- Signed-off-by: Andrei Menzopol Signed-off-by: Marius Tache Signed-off-by: Doru Gucea Signed-off-by: Marian Chereji Signed-off-by: marius-alex-tache Signed-off-by: Marius Vilvoi Co-authored-by: Yanis Viola Co-authored-by: Marius Tache Co-authored-by: Marian Chereji Co-authored-by: Yassine El-aissaoui Co-authored-by: Doru Gucea Co-authored-by: Marius Vilvoi Co-authored-by: Restyled.io --- .github/workflows/examples-k32w.yaml | 2 +- config/nxp/lib/pw_rpc/BUILD.gn | 38 + config/nxp/lib/pw_rpc/pw_rpc.gni | 28 + .../common/pigweed/nxp/PigweedLoggerMutex.cpp | 27 + .../common/pigweed/nxp/PigweedLoggerMutex.h | 36 + .../contact-sensor-app/nxp/k32w/k32w1/.gn | 3 + .../nxp/k32w/k32w1/BUILD.gn | 17 +- .../nxp/k32w/k32w1/README.md | 14 +- .../nxp/k32w/k32w1/args.gni | 5 +- .../k32w/k32w1/include/CHIPProjectConfig.h | 65 +- .../nxp/k32w/k32w1/main/AppTask.cpp | 42 +- .../nxp/k32w/k32w1/main/include/AppTask.h | 10 +- .../nxp/k32w/k32w1/main/include/app_config.h | 4 +- examples/contact-sensor-app/nxp/zap/BUILD.gn | 25 + .../nxp/zap/contact-sensor-app.matter | 1646 ++++++++ .../nxp/zap/contact-sensor-app.zap | 3576 +++++++++++++++++ examples/lighting-app/nxp/k32w/k32w1/.gn | 3 + examples/lighting-app/nxp/k32w/k32w1/BUILD.gn | 51 +- .../lighting-app/nxp/k32w/k32w1/README.md | 43 +- examples/lighting-app/nxp/k32w/k32w1/args.gni | 1 - .../k32w/k32w1/include/CHIPProjectConfig.h | 54 + .../nxp/k32w/k32w1/main/AppTask.cpp | 73 +- .../nxp/k32w/k32w1/main/include/AppTask.h | 11 +- .../nxp/k32w/k32w1/main/include/app_config.h | 4 +- .../lighting-app/nxp/k32w/k32w1/main/main.cpp | 16 + .../nxp/k32w/k32w1/with_pw_rpc.gni | 33 + .../nxp/zap/lighting-on-off.matter | 2 +- .../lighting-app/nxp/zap/lighting-on-off.zap | 5 +- examples/platform/nxp/PigweedLogger.cpp | 111 + examples/platform/nxp/PigweedLogger.h | 30 + examples/platform/nxp/Rpc.cpp | 144 + examples/platform/nxp/Rpc.h | 30 + .../nxp/k32w/k32w0/scripts/sign-outdir.py | 2 +- examples/platform/nxp/k32w/k32w1/BUILD.gn | 6 +- examples/platform/nxp/k32w/k32w1/app/args.gni | 5 - .../nxp/k32w/k32w1/app/ldscripts/k32w1_app.ld | 2 +- .../nxp/k32w/k32w1/app/support/BUILD.gn | 2 +- .../k32w/k32w1/app/support/FreeRtosHooks.c | 6 +- .../nxp/k32w/k32w1/app/support/Memconfig.cpp | 58 +- examples/platform/nxp/pw_rpc_server.gni | 62 + examples/platform/nxp/pw_sys_io/BUILD.gn | 42 + .../nxp/pw_sys_io/public/pw_sys_io_nxp/init.h | 27 + examples/platform/nxp/pw_sys_io/sys_io_nxp.cc | 78 + .../nxp/factory_data_generator/custom.py | 13 +- .../nxp/factory_data_generator/generate.py | 4 +- .../example_convert_dac_private_key.jlink | 16 + src/lib/shell/streamer_nxp.cpp | 74 +- src/lwip/BUILD.gn | 16 +- src/platform/BUILD.gn | 7 +- src/platform/device.gni | 11 +- .../nxp/k32w/common/BLEManagerCommon.cpp | 2 +- .../nxp/k32w/common/BLEManagerCommon.h | 1 + .../nxp/k32w/common/OTAImageProcessorImpl.cpp | 2 +- .../nxp/k32w/common/OTATlvProcessor.h | 6 +- .../nxp/k32w/k32w0/CHIPDevicePlatformConfig.h | 2 + .../nxp/k32w/k32w1/BLEManagerImpl.cpp | 19 + src/platform/nxp/k32w/k32w1/BLEManagerImpl.h | 6 + src/platform/nxp/k32w/k32w1/BUILD.gn | 48 +- .../nxp/k32w/k32w1/CHIPCryptoPalK32W1.cpp | 262 +- .../nxp/k32w/k32w1/CHIPDevicePlatformConfig.h | 24 + .../nxp/k32w/k32w1/CHIPPlatformConfig.h | 24 + .../k32w/k32w1/ConfigurationManagerImpl.cpp | 8 +- .../k32w/k32w1/DiagnosticDataProviderImpl.cpp | 29 +- .../k32w/k32w1/DiagnosticDataProviderImpl.h | 1 + .../k32w/k32w1/FactoryDataProviderImpl.cpp | 304 ++ .../nxp/k32w/k32w1/FactoryDataProviderImpl.h | 109 + src/platform/nxp/k32w/k32w1/K32W1Config.cpp | 3 +- .../K32W1PersistentStorageOpKeystore.cpp | 108 +- .../k32w1/K32W1PersistentStorageOpKeystore.h | 36 +- .../k32w/k32w1/KeyValueStoreManagerImpl.cpp | 2 +- src/platform/nxp/k32w/k32w1/Logging.cpp | 10 + src/platform/nxp/k32w/k32w1/LowPowerHooks.cpp | 4 +- src/platform/nxp/k32w/k32w1/OTAHooks.cpp | 2 +- .../nxp/k32w/k32w1/PlatformManagerImpl.cpp | 14 +- .../nxp/k32w/k32w1/PlatformManagerImpl.h | 1 + src/platform/nxp/k32w/k32w1/SMU2Manager.cpp | 165 + src/platform/nxp/k32w/k32w1/SMU2Manager.h | 39 + .../nxp/k32w/k32w1/SystemTimeSupport.cpp | 8 +- .../nxp/k32w/k32w1/ThreadStackManagerImpl.cpp | 8 + src/platform/nxp/k32w/k32w1/args.gni | 26 +- src/system/BUILD.gn | 5 - third_party/nxp/k32w1_sdk/BUILD.gn | 18 +- third_party/nxp/k32w1_sdk/k32w1_sdk.gni | 99 +- third_party/nxp/k32w1_sdk/nxp_arm.gni | 23 + third_party/nxp/k32w1_sdk/nxp_executable.gni | 34 + third_party/openthread/ot-nxp | 2 +- .../platforms/nxp/k32w/k32w1/BUILD.gn | 28 +- 87 files changed, 7594 insertions(+), 468 deletions(-) create mode 100644 config/nxp/lib/pw_rpc/BUILD.gn create mode 100644 config/nxp/lib/pw_rpc/pw_rpc.gni create mode 100644 examples/common/pigweed/nxp/PigweedLoggerMutex.cpp create mode 100644 examples/common/pigweed/nxp/PigweedLoggerMutex.h create mode 100644 examples/contact-sensor-app/nxp/zap/BUILD.gn create mode 100644 examples/contact-sensor-app/nxp/zap/contact-sensor-app.matter create mode 100644 examples/contact-sensor-app/nxp/zap/contact-sensor-app.zap create mode 100644 examples/lighting-app/nxp/k32w/k32w1/with_pw_rpc.gni create mode 100644 examples/platform/nxp/PigweedLogger.cpp create mode 100644 examples/platform/nxp/PigweedLogger.h create mode 100644 examples/platform/nxp/Rpc.cpp create mode 100644 examples/platform/nxp/Rpc.h create mode 100644 examples/platform/nxp/pw_rpc_server.gni create mode 100644 examples/platform/nxp/pw_sys_io/BUILD.gn create mode 100644 examples/platform/nxp/pw_sys_io/public/pw_sys_io_nxp/init.h create mode 100644 examples/platform/nxp/pw_sys_io/sys_io_nxp.cc create mode 100644 scripts/tools/nxp/factory_data_generator/k32w1/example_convert_dac_private_key.jlink create mode 100644 src/platform/nxp/k32w/k32w1/FactoryDataProviderImpl.cpp create mode 100644 src/platform/nxp/k32w/k32w1/FactoryDataProviderImpl.h create mode 100644 src/platform/nxp/k32w/k32w1/SMU2Manager.cpp create mode 100644 src/platform/nxp/k32w/k32w1/SMU2Manager.h create mode 100644 third_party/nxp/k32w1_sdk/nxp_arm.gni create mode 100644 third_party/nxp/k32w1_sdk/nxp_executable.gni diff --git a/.github/workflows/examples-k32w.yaml b/.github/workflows/examples-k32w.yaml index 363111a26c0a9c..be2d372e88c177 100644 --- a/.github/workflows/examples-k32w.yaml +++ b/.github/workflows/examples-k32w.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-k32w:32 + image: ghcr.io/project-chip/chip-build-k32w:33 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/config/nxp/lib/pw_rpc/BUILD.gn b/config/nxp/lib/pw_rpc/BUILD.gn new file mode 100644 index 00000000000000..05962da9299912 --- /dev/null +++ b/config/nxp/lib/pw_rpc/BUILD.gn @@ -0,0 +1,38 @@ +# Copyright (c) 2023 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/pigweed.gni") +import("$dir_pw_build/target_types.gni") + +static_library("pw_rpc") { + output_name = "libPwRpc" + + public_configs = [ "${dir_pigweed}/pw_hdlc:default_config" ] + deps = [ + "$dir_pw_rpc:server", + "$dir_pw_rpc/nanopb:echo_service", + "${chip_root}/examples/platform/nxp/pw_sys_io:pw_sys_io_nxp", + "${dir_pigweed}/pw_hdlc:pw_rpc", + dir_pw_assert, + dir_pw_hdlc, + dir_pw_log, + ] + + deps += pw_build_LINK_DEPS + + output_dir = "${root_out_dir}/lib" + + complete_static_lib = true +} diff --git a/config/nxp/lib/pw_rpc/pw_rpc.gni b/config/nxp/lib/pw_rpc/pw_rpc.gni new file mode 100644 index 00000000000000..68255db8bb96da --- /dev/null +++ b/config/nxp/lib/pw_rpc/pw_rpc.gni @@ -0,0 +1,28 @@ +# Copyright (c) 2023 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/pigweed.gni") + +pw_log_BACKEND = "$dir_pw_log_basic" +pw_assert_BACKEND = "$dir_pw_assert_log:check_backend" +pw_rpc_CONFIG = "$dir_pw_rpc:disable_global_mutex" +pw_sys_io_BACKEND = "${chip_root}/examples/platform/nxp/pw_sys_io:pw_sys_io_nxp" + +pw_build_LINK_DEPS = [ + "$dir_pw_assert:impl", + "$dir_pw_log:impl", +] + +dir_pw_third_party_nanopb = "${chip_root}/third_party/nanopb/repo" diff --git a/examples/common/pigweed/nxp/PigweedLoggerMutex.cpp b/examples/common/pigweed/nxp/PigweedLoggerMutex.cpp new file mode 100644 index 00000000000000..ce5f5a9be0d21d --- /dev/null +++ b/examples/common/pigweed/nxp/PigweedLoggerMutex.cpp @@ -0,0 +1,27 @@ +/* + * + * 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 "PigweedLoggerMutex.h" + +namespace chip { +namespace rpc { + +PigweedLoggerMutex logger_mutex; + +} // namespace rpc +} // namespace chip diff --git a/examples/common/pigweed/nxp/PigweedLoggerMutex.h b/examples/common/pigweed/nxp/PigweedLoggerMutex.h new file mode 100644 index 00000000000000..ecad8995bad61c --- /dev/null +++ b/examples/common/pigweed/nxp/PigweedLoggerMutex.h @@ -0,0 +1,36 @@ +/* + * + * Copyright (c) 2023 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 "PigweedLogger.h" +#include "RpcService.h" + +namespace chip { +namespace rpc { +class PigweedLoggerMutex : public chip::rpc::Mutex +{ + +public: + void Lock() override { PigweedLogger::Lock(); } + void Unlock() override { PigweedLogger::Unlock(); } +}; + +extern PigweedLoggerMutex logger_mutex; + +} // namespace rpc +} // namespace chip diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/.gn b/examples/contact-sensor-app/nxp/k32w/k32w1/.gn index dec954b4b9ff69..1e848295f6aa5b 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/.gn +++ b/examples/contact-sensor-app/nxp/k32w/k32w1/.gn @@ -26,4 +26,7 @@ default_args = { target_os = "freertos" import("//args.gni") + + # Import default platform configs + import("${chip_root}/src/platform/nxp/k32w/k32w1/args.gni") } diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/BUILD.gn b/examples/contact-sensor-app/nxp/k32w/k32w1/BUILD.gn index 1404ad8dd36a1c..ed49c7bdd4f7a3 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/BUILD.gn +++ b/examples/contact-sensor-app/nxp/k32w/k32w1/BUILD.gn @@ -14,15 +14,19 @@ # limitations under the License. import("//build_overrides/chip.gni") -import("//build_overrides/k32w1_sdk.gni") +import("//build_overrides/nxp_sdk.gni") import("//build_overrides/openthread.gni") -import("${k32w1_sdk_build_root}/k32w1_executable.gni") -import("${k32w1_sdk_build_root}/k32w1_sdk.gni") +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +import("${nxp_sdk_build_root}/${nxp_sdk_name}/nxp_executable.gni") + +import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") import("${chip_root}/src/crypto/crypto.gni") import("${chip_root}/src/lib/core/core.gni") import("${chip_root}/src/platform/device.gni") +import("${chip_root}/src/platform/nxp/${nxp_platform}/args.gni") declare_args() { chip_software_version = 0 @@ -85,7 +89,7 @@ k32w1_executable("contact_sensor_app") { deps = [ ":sdk", "${chip_root}/examples/common/QRCode", - "${chip_root}/examples/contact-sensor-app/contact-sensor-common", + "${chip_root}/examples/contact-sensor-app/nxp/zap", "${chip_root}/examples/providers:device_info_provider", "${chip_root}/src/lib", "${chip_root}/src/platform:syscalls_stub", @@ -116,7 +120,6 @@ k32w1_executable("contact_sensor_app") { ldflags = [ "-Wl,--defsym=__heap_size__=0", "-Wl,--defsym=__stack_size__=0x480", - "-Wl,--defsym=gNvmSectors=8", "-Wl,--defsym=lp_ram_lower_limit=0x04000000", "-Wl,--defsym=lp_ram_upper_limit=0x2001C000", "-Wl,-print-memory-usage", @@ -124,6 +127,10 @@ k32w1_executable("contact_sensor_app") { "-T" + rebase_path(ldscript, root_build_dir), ] + if (chip_with_factory_data == 1) { + ldflags += [ "-Wl,--defsym=gUseFactoryData_d=1" ] + } + output_dir = root_out_dir } diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/README.md b/examples/contact-sensor-app/nxp/k32w/k32w1/README.md index da6e3eb00f2f66..28983f45c89578 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/README.md +++ b/examples/contact-sensor-app/nxp/k32w/k32w1/README.md @@ -19,6 +19,7 @@ into an existing Matter network and can be controlled by this network. - [Bluetooth LE Rendezvous](#bluetooth-le-rendezvous) - [Device UI](#device-ui) - [Building](#building) +- [Manufacturing data](#manufacturing-data) - [Flashing](#flashing) - [Flashing the NBU image](#flashing-the-nbu-image) - [Flashing the host image](#flashing-the-host-image) @@ -108,7 +109,9 @@ initiate a reboot. The reset action can be cancelled by press SW2 button at any point before the 6 second limit. **Button SW3** can be used to change the state of the simulated contact sensor. -The button behaves as a toggle, swapping the state every time it is pressed. +The button behaves as a toggle, swapping the state every time it is short +pressed. When long pressed, it does a clean soft reset that takes into account +Matter shutdown procedure. ## Building @@ -134,8 +137,17 @@ In case that Openthread CLI is needed, chip_with_ot_cli build argument must be set to 1. After a successful build, the `elf` and `srec` files are found in `out/debug/` - +`see the files prefixed with chip-k32w1-contact-example`. After a successful +build, the `elf` and `srec` files are found in `out/debug/` - `see the files prefixed with chip-k32w1-contact-example`. +## Manufacturing data + +Use `chip_with_factory_data=1` in the gn build command to enable factory data. + +For a full guide on manufacturing flow, please see +[Guide for writing manufacturing data on NXP devices](../../../../../docs/guides/nxp_manufacturing_flow.md). + ## Flashing Two images must be written to the board: one for the host (CM33) and one for the diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/args.gni b/examples/contact-sensor-app/nxp/k32w/k32w1/args.gni index c0497aa27421d2..18c41cb457bc86 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/args.gni +++ b/examples/contact-sensor-app/nxp/k32w/k32w1/args.gni @@ -15,7 +15,6 @@ import("//build_overrides/chip.gni") import("${chip_root}/config/standalone/args.gni") -import("${chip_root}/examples/platform/nxp/k32w/k32w1/args.gni") # SDK target. This is overridden to add our SDK app_config.h & defines. k32w1_sdk_target = get_label_info(":sdk", "label_no_toolchain") @@ -23,3 +22,7 @@ k32w1_sdk_target = get_label_info(":sdk", "label_no_toolchain") chip_enable_ota_requestor = true chip_stack_lock_tracking = "fatal" chip_enable_ble = true + +chip_enable_icd_server = true +chip_persist_subscriptions = true +chip_subscription_timeout_resumption = true diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h b/examples/contact-sensor-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h index af3a7067c99e1a..8846799ed6edc9 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h +++ b/examples/contact-sensor-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h @@ -28,6 +28,58 @@ #pragma once +// Use hard-coded test certificates already embedded in generic chip code => set it to 0 +// Use real/development certificates => set it to 1 + file the provisioning section from +// the internal flash +#ifndef CONFIG_CHIP_LOAD_REAL_FACTORY_DATA +#define CONFIG_CHIP_LOAD_REAL_FACTORY_DATA 0 +#endif + +#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA + +// VID/PID for product => will be used by Basic Information Cluster +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0x1037 +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0xA221 + +// Set the following define to use the Certification Declaration from below and not use it stored in factory data section +#ifndef CHIP_USE_DEVICE_CONFIG_CERTIFICATION_DECLARATION +#define CHIP_USE_DEVICE_CONFIG_CERTIFICATION_DECLARATION 0 +#endif + +#ifndef CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION +//-> format_version = 1 +//-> vendor_id = 0x1037 +//-> product_id_array = [ 0xA221 ] +//-> device_type_id = 0x0015 +//-> certificate_id = "ZIG20142ZB330003-24" +//-> security_level = 0 +//-> security_information = 0 +//-> version_number = 0x2694 +//-> certification_type = 1 +//-> dac_origin_vendor_id is not present +//-> dac_origin_product_id is not present +#define CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION \ + { \ + 0x30, 0x81, 0xe7, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x81, 0xd9, 0x30, 0x81, 0xd6, \ + 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, \ + 0x44, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x37, 0x04, 0x35, 0x15, 0x24, 0x00, \ + 0x01, 0x25, 0x01, 0x37, 0x10, 0x36, 0x02, 0x05, 0x21, 0xa2, 0x18, 0x24, 0x03, 0x15, 0x2c, 0x04, 0x13, 0x5a, 0x49, \ + 0x47, 0x32, 0x30, 0x31, 0x34, 0x32, 0x5a, 0x42, 0x33, 0x33, 0x30, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x34, 0x24, 0x05, \ + 0x00, 0x24, 0x06, 0x00, 0x25, 0x07, 0x76, 0x98, 0x24, 0x08, 0x01, 0x18, 0x31, 0x7c, 0x30, 0x7a, 0x02, 0x01, 0x03, \ + 0x80, 0x14, 0x62, 0xfa, 0x82, 0x33, 0x59, 0xac, 0xfa, 0xa9, 0x96, 0x3e, 0x1c, 0xfa, 0x14, 0x0a, 0xdd, 0xf5, 0x04, \ + 0xf3, 0x71, 0x60, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x0a, 0x06, \ + 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x46, 0x30, 0x44, 0x02, 0x20, 0x1b, 0xf3, 0x13, 0x9b, \ + 0x39, 0xb8, 0x3e, 0x87, 0xde, 0x2e, 0xdf, 0x51, 0xfb, 0xa3, 0xba, 0xcb, 0xc7, 0x4e, 0xef, 0x16, 0x6b, 0xa1, 0x04, \ + 0xa0, 0x05, 0x7f, 0xc3, 0xd4, 0x15, 0x84, 0xd0, 0x44, 0x02, 0x20, 0x32, 0x98, 0xe2, 0x3c, 0x31, 0x16, 0x63, 0x60, \ + 0x2e, 0x58, 0x93, 0x87, 0x50, 0x9e, 0x29, 0x10, 0x9d, 0xe5, 0x9b, 0xcd, 0xab, 0x64, 0x43, 0x08, 0xd6, 0xf6, 0x6f, \ + 0x46, 0x7d, 0x22, 0x24, 0x42 \ + } + +// All remaining data will be pulled from the provisioning region of flash. +#endif + +#else + /** * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID * @@ -56,18 +108,7 @@ */ #define CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER "TEST_SN" -/** - * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID - * - * 0xFFF1: Test vendor. - */ -#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0xFFF1 - -/** - * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID - * - */ -#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8006 +#endif // CONFIG_CHIP_LOAD_REAL_FACTORY_DATA /** * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/main/AppTask.cpp b/examples/contact-sensor-app/nxp/k32w/k32w1/main/AppTask.cpp index aa448bf454f2cb..b1aa6792340fce 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/main/AppTask.cpp +++ b/examples/contact-sensor-app/nxp/k32w/k32w1/main/AppTask.cpp @@ -94,6 +94,9 @@ using namespace chip; using namespace chip::app; AppTask AppTask::sAppTask; +#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA +static AppTask::FactoryDataProvider sFactoryDataProvider; +#endif static Identify gIdentify = { chip::EndpointId{ 1 }, AppTask::OnIdentifyStart, AppTask::OnIdentifyStop, Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator }; @@ -150,8 +153,14 @@ CHIP_ERROR AppTask::Init() // Init ZCL Data Model and start server PlatformMgr().ScheduleWork(InitServer, 0); - // Initialize device attestation config +#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA + ReturnErrorOnFailure(sFactoryDataProvider.Init()); + SetDeviceInstanceInfoProvider(&sFactoryDataProvider); + SetDeviceAttestationCredentialsProvider(&sFactoryDataProvider); + SetCommissionableDataProvider(&sFactoryDataProvider); +#else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif // CONFIG_CHIP_LOAD_REAL_FACTORY_DATA // QR code will be used with CHIP Tool AppTask::PrintOnboardingInfo(); @@ -358,7 +367,7 @@ void AppTask::AppTaskMain(void * pvParameter) void AppTask::ButtonEventHandler(uint8_t pin_no, uint8_t button_action) { - if ((pin_no != RESET_BUTTON) && (pin_no != CONTACT_SENSOR_BUTTON) && (pin_no != OTA_BUTTON) && (pin_no != BLE_BUTTON)) + if ((pin_no != RESET_BUTTON) && (pin_no != CONTACT_SENSOR_BUTTON) && (pin_no != SOFT_RESET_BUTTON) && (pin_no != BLE_BUTTON)) { return; } @@ -376,10 +385,10 @@ void AppTask::ButtonEventHandler(uint8_t pin_no, uint8_t button_action) { button_event.Handler = ContactActionEventHandler; } - else if (pin_no == OTA_BUTTON) + else if (pin_no == SOFT_RESET_BUTTON) { - // Starting OTA by button functionality is not used. - // button_event.Handler = OTAHandler; + // Soft reset ensures that platform manager shutdown procedure is called. + button_event.Handler = SoftResetHandler; } else if (pin_no == BLE_BUTTON) { @@ -432,7 +441,7 @@ button_status_t AppTask::KBD_Callback(void * buttonHandle, button_callback_messa case CONTACT_SENSOR_BUTTON: K32W_LOG("pb2 long press"); - ButtonEventHandler(OTA_BUTTON, OTA_BUTTON_PUSH); + ButtonEventHandler(SOFT_RESET_BUTTON, SOFT_RESET_BUTTON_PUSH); break; } break; @@ -561,29 +570,14 @@ void AppTask::ContactActionEventHandler(void * aGenericEvent) } } -void AppTask::OTAHandler(void * aGenericEvent) +void AppTask::SoftResetHandler(void * aGenericEvent) { AppEvent * aEvent = (AppEvent *) aGenericEvent; - if (aEvent->ButtonEvent.PinNo != OTA_BUTTON) + if (aEvent->ButtonEvent.PinNo != SOFT_RESET_BUTTON) return; -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - if (sAppTask.mFunction != Function::kNoneSelected) - { - K32W_LOG("Another function is scheduled. Could not initiate OTA!"); - return; - } - - PlatformMgr().ScheduleWork(StartOTAQuery, 0); -#endif -} - -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR -void AppTask::StartOTAQuery(intptr_t arg) -{ - GetRequestorInstance()->TriggerImmediateQuery(); + PlatformMgrImpl().CleanReset(); } -#endif void AppTask::BleHandler(void * aGenericEvent) { diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/AppTask.h b/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/AppTask.h index 47b644769cfb63..bc19b0a9862ebd 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/AppTask.h +++ b/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/AppTask.h @@ -30,6 +30,10 @@ #include #include +#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA +#include +#endif + #include "FreeRTOS.h" #include "fsl_component_button.h" #include "timers.h" @@ -45,6 +49,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); @@ -74,7 +81,7 @@ class AppTask static void FunctionTimerEventHandler(void * aGenericEvent); static button_status_t KBD_Callback(void * buttonHandle, button_callback_message_t * message, void * callbackParam); static void HandleKeyboard(void); - static void OTAHandler(void * aGenericEvent); + static void SoftResetHandler(void * aGenericEvent); static void BleHandler(void * aGenericEvent); static void BleStartAdvertising(intptr_t arg); static void ContactActionEventHandler(void * aGenericEvent); @@ -89,7 +96,6 @@ class AppTask #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR static void InitOTA(intptr_t arg); - static void StartOTAQuery(intptr_t arg); #endif static void UpdateClusterStateInternal(intptr_t arg); diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/app_config.h b/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/app_config.h index b62ce79567e8db..fbcf14fe7d88d7 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/app_config.h +++ b/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/app_config.h @@ -23,12 +23,12 @@ #define RESET_BUTTON 1 #define CONTACT_SENSOR_BUTTON 2 -#define OTA_BUTTON 3 +#define SOFT_RESET_BUTTON 3 #define BLE_BUTTON 4 #define RESET_BUTTON_PUSH 1 #define CONTACT_SENSOR_BUTTON_PUSH 2 -#define OTA_BUTTON_PUSH 3 +#define SOFT_RESET_BUTTON_PUSH 3 #define BLE_BUTTON_PUSH 4 #define APP_BUTTON_PUSH 1 diff --git a/examples/contact-sensor-app/nxp/zap/BUILD.gn b/examples/contact-sensor-app/nxp/zap/BUILD.gn new file mode 100644 index 00000000000000..be4913cf3552ee --- /dev/null +++ b/examples/contact-sensor-app/nxp/zap/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright (c) 2023 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}/examples/common/pigweed/pigweed_rpcs.gni") +import("${chip_root}/src/app/chip_data_model.gni") + +chip_data_model("zap") { + zap_file = "contact-sensor-app.zap" + + zap_pregenerated_dir = + "${chip_root}/zzz_generated/contact-sensor-app/nxp/zap-generated" + is_server = true +} diff --git a/examples/contact-sensor-app/nxp/zap/contact-sensor-app.matter b/examples/contact-sensor-app/nxp/zap/contact-sensor-app.matter new file mode 100644 index 00000000000000..03736833bb02d3 --- /dev/null +++ b/examples/contact-sensor-app/nxp/zap/contact-sensor-app.matter @@ -0,0 +1,1646 @@ +// This IDL was generated automatically by ZAP. +// It is for view/code review purposes only. + +/** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ +cluster Identify = 3 { + revision 4; + + enum EffectIdentifierEnum : enum8 { + kBlink = 0; + kBreathe = 1; + kOkay = 2; + kChannelChange = 11; + kFinishEffect = 254; + kStopEffect = 255; + } + + enum EffectVariantEnum : enum8 { + kDefault = 0; + } + + enum IdentifyTypeEnum : enum8 { + kNone = 0; + kLightOutput = 1; + kVisibleIndicator = 2; + kAudibleBeep = 3; + kDisplay = 4; + kActuator = 5; + } + + attribute int16u identifyTime = 0; + readonly attribute IdentifyTypeEnum identifyType = 1; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct IdentifyRequest { + int16u identifyTime = 0; + } + + request struct TriggerEffectRequest { + EffectIdentifierEnum effectIdentifier = 0; + EffectVariantEnum effectVariant = 1; + } + + /** Command description for Identify */ + command access(invoke: manage) Identify(IdentifyRequest): DefaultSuccess = 0; + /** Command description for TriggerEffect */ + command access(invoke: manage) TriggerEffect(TriggerEffectRequest): DefaultSuccess = 64; +} + +/** The Descriptor Cluster is meant to replace the support from the Zigbee Device Object (ZDO) for describing a node, its endpoints and clusters. */ +cluster Descriptor = 29 { + revision 2; + + bitmap Feature : bitmap32 { + kTagList = 0x1; + } + + struct DeviceTypeStruct { + devtype_id deviceType = 0; + int16u revision = 1; + } + + struct SemanticTagStruct { + nullable vendor_id mfgCode = 0; + enum8 namespaceID = 1; + enum8 tag = 2; + optional nullable char_string label = 3; + } + + readonly attribute DeviceTypeStruct deviceTypeList[] = 0; + readonly attribute cluster_id serverList[] = 1; + readonly attribute cluster_id clientList[] = 2; + readonly attribute endpoint_no partsList[] = 3; + readonly attribute optional SemanticTagStruct tagList[] = 4; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** The Access Control Cluster exposes a data model view of a + Node's Access Control List (ACL), which codifies the rules used to manage + and enforce Access Control for the Node's endpoints and their associated + cluster instances. */ +cluster AccessControl = 31 { + revision 1; // NOTE: Default/not specifically set + + enum AccessControlEntryAuthModeEnum : enum8 { + kPASE = 1; + kCASE = 2; + kGroup = 3; + } + + enum AccessControlEntryPrivilegeEnum : enum8 { + kView = 1; + kProxyView = 2; + kOperate = 3; + kManage = 4; + kAdminister = 5; + } + + enum ChangeTypeEnum : enum8 { + kChanged = 0; + kAdded = 1; + kRemoved = 2; + } + + struct AccessControlTargetStruct { + nullable cluster_id cluster = 0; + nullable endpoint_no endpoint = 1; + nullable devtype_id deviceType = 2; + } + + fabric_scoped struct AccessControlEntryStruct { + fabric_sensitive AccessControlEntryPrivilegeEnum privilege = 1; + fabric_sensitive AccessControlEntryAuthModeEnum authMode = 2; + nullable fabric_sensitive int64u subjects[] = 3; + nullable fabric_sensitive AccessControlTargetStruct targets[] = 4; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct AccessControlExtensionStruct { + fabric_sensitive octet_string<128> data = 1; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlEntryChanged = 0 { + nullable node_id adminNodeID = 1; + nullable int16u adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable AccessControlEntryStruct latestValue = 4; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlExtensionChanged = 1 { + nullable node_id adminNodeID = 1; + nullable int16u adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable AccessControlExtensionStruct latestValue = 4; + fabric_idx fabricIndex = 254; + } + + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; + attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; + readonly attribute int16u subjectsPerAccessControlEntry = 2; + readonly attribute int16u targetsPerAccessControlEntry = 3; + readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** This cluster provides attributes and events for determining basic information about Nodes, which supports both + Commissioning and operational determination of Node characteristics, such as Vendor ID, Product ID and serial number, + which apply to the whole Node. Also allows setting user device information such as location. */ +cluster BasicInformation = 40 { + revision 3; + + enum ColorEnum : enum8 { + kBlack = 0; + kNavy = 1; + kGreen = 2; + kTeal = 3; + kMaroon = 4; + kPurple = 5; + kOlive = 6; + kGray = 7; + kBlue = 8; + kLime = 9; + kAqua = 10; + kRed = 11; + kFuchsia = 12; + kYellow = 13; + kWhite = 14; + kNickel = 15; + kChrome = 16; + kBrass = 17; + kCopper = 18; + kSilver = 19; + kGold = 20; + } + + enum ProductFinishEnum : enum8 { + kOther = 0; + kMatte = 1; + kSatin = 2; + kPolished = 3; + kRugged = 4; + kFabric = 5; + } + + struct CapabilityMinimaStruct { + int16u caseSessionsPerFabric = 0; + int16u subscriptionsPerFabric = 1; + } + + struct ProductAppearanceStruct { + ProductFinishEnum finish = 0; + nullable ColorEnum primaryColor = 1; + } + + critical event StartUp = 0 { + int32u softwareVersion = 0; + } + + critical event ShutDown = 1 { + } + + info event Leave = 2 { + fabric_idx fabricIndex = 0; + } + + info event ReachableChanged = 3 { + boolean reachableNewValue = 0; + } + + readonly attribute int16u dataModelRevision = 0; + readonly attribute char_string<32> vendorName = 1; + readonly attribute vendor_id vendorID = 2; + readonly attribute char_string<32> productName = 3; + readonly attribute int16u productID = 4; + attribute access(write: manage) char_string<32> nodeLabel = 5; + attribute access(write: administer) char_string<2> location = 6; + readonly attribute int16u hardwareVersion = 7; + readonly attribute char_string<64> hardwareVersionString = 8; + readonly attribute int32u softwareVersion = 9; + readonly attribute char_string<64> softwareVersionString = 10; + readonly attribute optional char_string<16> manufacturingDate = 11; + readonly attribute optional char_string<32> partNumber = 12; + readonly attribute optional long_char_string<256> productURL = 13; + readonly attribute optional char_string<64> productLabel = 14; + readonly attribute optional char_string<32> serialNumber = 15; + attribute access(write: manage) optional boolean localConfigDisabled = 16; + readonly attribute optional boolean reachable = 17; + readonly attribute optional char_string<32> uniqueID = 18; + readonly attribute CapabilityMinimaStruct capabilityMinima = 19; + readonly attribute optional ProductAppearanceStruct productAppearance = 20; + readonly attribute int32u specificationVersion = 21; + readonly attribute int16u maxPathsPerInvoke = 22; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + command MfgSpecificPing(): DefaultSuccess = 0; +} + +/** Provides an interface for providing OTA software updates */ +cluster OtaSoftwareUpdateProvider = 41 { + revision 1; // NOTE: Default/not specifically set + + enum ApplyUpdateActionEnum : enum8 { + kProceed = 0; + kAwaitNextAction = 1; + kDiscontinue = 2; + } + + enum DownloadProtocolEnum : enum8 { + kBDXSynchronous = 0; + kBDXAsynchronous = 1; + kHTTPS = 2; + kVendorSpecific = 3; + } + + enum StatusEnum : enum8 { + kUpdateAvailable = 0; + kBusy = 1; + kNotAvailable = 2; + kDownloadProtocolNotSupported = 3; + } + + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct QueryImageRequest { + vendor_id vendorID = 0; + int16u productID = 1; + int32u softwareVersion = 2; + DownloadProtocolEnum protocolsSupported[] = 3; + optional int16u hardwareVersion = 4; + optional char_string<2> location = 5; + optional boolean requestorCanConsent = 6; + optional octet_string<512> metadataForProvider = 7; + } + + response struct QueryImageResponse = 1 { + StatusEnum status = 0; + optional int32u delayedActionTime = 1; + optional char_string<256> imageURI = 2; + optional int32u softwareVersion = 3; + optional char_string<64> softwareVersionString = 4; + optional octet_string<32> updateToken = 5; + optional boolean userConsentNeeded = 6; + optional octet_string<512> metadataForRequestor = 7; + } + + request struct ApplyUpdateRequestRequest { + octet_string<32> updateToken = 0; + int32u newVersion = 1; + } + + response struct ApplyUpdateResponse = 3 { + ApplyUpdateActionEnum action = 0; + int32u delayedActionTime = 1; + } + + request struct NotifyUpdateAppliedRequest { + octet_string<32> updateToken = 0; + int32u softwareVersion = 1; + } + + /** Determine availability of a new Software Image */ + command QueryImage(QueryImageRequest): QueryImageResponse = 0; + /** Determine next action to take for a downloaded Software Image */ + command ApplyUpdateRequest(ApplyUpdateRequestRequest): ApplyUpdateResponse = 2; + /** Notify OTA Provider that an update was applied */ + command NotifyUpdateApplied(NotifyUpdateAppliedRequest): DefaultSuccess = 4; +} + +/** Provides an interface for downloading and applying OTA software updates */ +cluster OtaSoftwareUpdateRequestor = 42 { + revision 1; // NOTE: Default/not specifically set + + enum AnnouncementReasonEnum : enum8 { + kSimpleAnnouncement = 0; + kUpdateAvailable = 1; + kUrgentUpdateAvailable = 2; + } + + enum ChangeReasonEnum : enum8 { + kUnknown = 0; + kSuccess = 1; + kFailure = 2; + kTimeOut = 3; + kDelayByProvider = 4; + } + + enum UpdateStateEnum : enum8 { + kUnknown = 0; + kIdle = 1; + kQuerying = 2; + kDelayedOnQuery = 3; + kDownloading = 4; + kApplying = 5; + kDelayedOnApply = 6; + kRollingBack = 7; + kDelayedOnUserConsent = 8; + } + + fabric_scoped struct ProviderLocation { + node_id providerNodeID = 1; + endpoint_no endpoint = 2; + fabric_idx fabricIndex = 254; + } + + info event StateTransition = 0 { + UpdateStateEnum previousState = 0; + UpdateStateEnum newState = 1; + ChangeReasonEnum reason = 2; + nullable int32u targetSoftwareVersion = 3; + } + + critical event VersionApplied = 1 { + int32u softwareVersion = 0; + int16u productID = 1; + } + + info event DownloadError = 2 { + int32u softwareVersion = 0; + int64u bytesDownloaded = 1; + nullable int8u progressPercent = 2; + nullable int64s platformCode = 3; + } + + attribute access(write: administer) ProviderLocation defaultOTAProviders[] = 0; + readonly attribute boolean updatePossible = 1; + readonly attribute UpdateStateEnum updateState = 2; + readonly attribute nullable int8u updateStateProgress = 3; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct AnnounceOTAProviderRequest { + node_id providerNodeID = 0; + vendor_id vendorID = 1; + AnnouncementReasonEnum announcementReason = 2; + optional octet_string<512> metadataForNode = 3; + endpoint_no endpoint = 4; + } + + /** Announce the presence of an OTA Provider */ + command AnnounceOTAProvider(AnnounceOTAProviderRequest): DefaultSuccess = 0; +} + +/** This cluster is used to manage global aspects of the Commissioning flow. */ +cluster GeneralCommissioning = 48 { + revision 1; // NOTE: Default/not specifically set + + enum CommissioningErrorEnum : enum8 { + kOK = 0; + kValueOutsideRange = 1; + kInvalidAuthentication = 2; + kNoFailSafe = 3; + kBusyWithOtherAdmin = 4; + } + + enum RegulatoryLocationTypeEnum : enum8 { + kIndoor = 0; + kOutdoor = 1; + kIndoorOutdoor = 2; + } + + struct BasicCommissioningInfo { + int16u failSafeExpiryLengthSeconds = 0; + int16u maxCumulativeFailsafeSeconds = 1; + } + + attribute access(write: administer) int64u breadcrumb = 0; + readonly attribute BasicCommissioningInfo basicCommissioningInfo = 1; + readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; + readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; + readonly attribute boolean supportsConcurrentConnection = 4; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ArmFailSafeRequest { + int16u expiryLengthSeconds = 0; + int64u breadcrumb = 1; + } + + response struct ArmFailSafeResponse = 1 { + CommissioningErrorEnum errorCode = 0; + char_string<128> debugText = 1; + } + + request struct SetRegulatoryConfigRequest { + RegulatoryLocationTypeEnum newRegulatoryConfig = 0; + char_string<2> countryCode = 1; + int64u breadcrumb = 2; + } + + response struct SetRegulatoryConfigResponse = 3 { + CommissioningErrorEnum errorCode = 0; + char_string debugText = 1; + } + + response struct CommissioningCompleteResponse = 5 { + CommissioningErrorEnum errorCode = 0; + char_string debugText = 1; + } + + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ + command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; + /** Set the regulatory configuration to be used during commissioning */ + command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; + /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ + fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; +} + +/** Functionality to configure, enable, disable network credentials and access on a Matter device. */ +cluster NetworkCommissioning = 49 { + revision 1; // NOTE: Default/not specifically set + + enum NetworkCommissioningStatusEnum : enum8 { + kSuccess = 0; + kOutOfRange = 1; + kBoundsExceeded = 2; + kNetworkIDNotFound = 3; + kDuplicateNetworkID = 4; + kNetworkNotFound = 5; + kRegulatoryError = 6; + kAuthFailure = 7; + kUnsupportedSecurity = 8; + kOtherConnectionFailure = 9; + kIPV6Failed = 10; + kIPBindFailed = 11; + kUnknownError = 12; + } + + enum WiFiBandEnum : enum8 { + k2G4 = 0; + k3G65 = 1; + k5G = 2; + k6G = 3; + k60G = 4; + k1G = 5; + } + + bitmap Feature : bitmap32 { + kWiFiNetworkInterface = 0x1; + kThreadNetworkInterface = 0x2; + kEthernetNetworkInterface = 0x4; + kPerDeviceCredentials = 0x8; + } + + bitmap ThreadCapabilitiesBitmap : bitmap16 { + kIsBorderRouterCapable = 0x1; + kIsRouterCapable = 0x2; + kIsSleepyEndDeviceCapable = 0x4; + kIsFullThreadDevice = 0x8; + kIsSynchronizedSleepyEndDeviceCapable = 0x10; + } + + bitmap WiFiSecurityBitmap : bitmap8 { + kUnencrypted = 0x1; + kWEP = 0x2; + kWPAPersonal = 0x4; + kWPA2Personal = 0x8; + kWPA3Personal = 0x10; + kWPA3MatterPDC = 0x20; + } + + struct NetworkInfoStruct { + octet_string<32> networkID = 0; + boolean connected = 1; + optional nullable octet_string<20> networkIdentifier = 2; + optional nullable octet_string<20> clientIdentifier = 3; + } + + struct ThreadInterfaceScanResultStruct { + int16u panId = 0; + int64u extendedPanId = 1; + char_string<16> networkName = 2; + int16u channel = 3; + int8u version = 4; + octet_string<8> extendedAddress = 5; + int8s rssi = 6; + int8u lqi = 7; + } + + struct WiFiInterfaceScanResultStruct { + WiFiSecurityBitmap security = 0; + octet_string<32> ssid = 1; + octet_string<6> bssid = 2; + int16u channel = 3; + WiFiBandEnum wiFiBand = 4; + int8s rssi = 5; + } + + readonly attribute access(read: administer) int8u maxNetworks = 0; + readonly attribute access(read: administer) NetworkInfoStruct networks[] = 1; + readonly attribute optional int8u scanMaxTimeSeconds = 2; + readonly attribute optional int8u connectMaxTimeSeconds = 3; + attribute access(write: administer) boolean interfaceEnabled = 4; + readonly attribute access(read: administer) nullable NetworkCommissioningStatusEnum lastNetworkingStatus = 5; + readonly attribute access(read: administer) nullable octet_string<32> lastNetworkID = 6; + readonly attribute access(read: administer) nullable int32s lastConnectErrorValue = 7; + readonly attribute optional WiFiBandEnum supportedWiFiBands[] = 8; + readonly attribute optional ThreadCapabilitiesBitmap supportedThreadFeatures = 9; + readonly attribute optional int16u threadVersion = 10; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ScanNetworksRequest { + optional nullable octet_string<32> ssid = 0; + optional int64u breadcrumb = 1; + } + + response struct ScanNetworksResponse = 1 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string debugText = 1; + optional WiFiInterfaceScanResultStruct wiFiScanResults[] = 2; + optional ThreadInterfaceScanResultStruct threadScanResults[] = 3; + } + + request struct AddOrUpdateWiFiNetworkRequest { + octet_string<32> ssid = 0; + octet_string<64> credentials = 1; + optional int64u breadcrumb = 2; + optional octet_string<140> networkIdentity = 3; + optional octet_string<20> clientIdentifier = 4; + optional octet_string<32> possessionNonce = 5; + } + + request struct AddOrUpdateThreadNetworkRequest { + octet_string<254> operationalDataset = 0; + optional int64u breadcrumb = 1; + } + + request struct RemoveNetworkRequest { + octet_string<32> networkID = 0; + optional int64u breadcrumb = 1; + } + + response struct NetworkConfigResponse = 5 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string<512> debugText = 1; + optional int8u networkIndex = 2; + optional octet_string<140> clientIdentity = 3; + optional octet_string<64> possessionSignature = 4; + } + + request struct ConnectNetworkRequest { + octet_string<32> networkID = 0; + optional int64u breadcrumb = 1; + } + + response struct ConnectNetworkResponse = 7 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string debugText = 1; + nullable int32s errorValue = 2; + } + + request struct ReorderNetworkRequest { + octet_string<32> networkID = 0; + int8u networkIndex = 1; + optional int64u breadcrumb = 2; + } + + request struct QueryIdentityRequest { + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; + } + + response struct QueryIdentityResponse = 10 { + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; + } + + /** Detemine the set of networks the device sees as available. */ + command access(invoke: administer) ScanNetworks(ScanNetworksRequest): ScanNetworksResponse = 0; + /** Add or update the credentials for a given Wi-Fi network. */ + command access(invoke: administer) AddOrUpdateWiFiNetwork(AddOrUpdateWiFiNetworkRequest): NetworkConfigResponse = 2; + /** Add or update the credentials for a given Thread network. */ + command access(invoke: administer) AddOrUpdateThreadNetwork(AddOrUpdateThreadNetworkRequest): NetworkConfigResponse = 3; + /** Remove the definition of a given network (including its credentials). */ + command access(invoke: administer) RemoveNetwork(RemoveNetworkRequest): NetworkConfigResponse = 4; + /** Connect to the specified network, using previously-defined credentials. */ + command access(invoke: administer) ConnectNetwork(ConnectNetworkRequest): ConnectNetworkResponse = 6; + /** Modify the order in which networks will be presented in the Networks attribute. */ + command access(invoke: administer) ReorderNetwork(ReorderNetworkRequest): NetworkConfigResponse = 8; + /** Retrieve details about and optionally proof of possession of a network client identity. */ + command access(invoke: administer) QueryIdentity(QueryIdentityRequest): QueryIdentityResponse = 9; +} + +/** The General Diagnostics Cluster, along with other diagnostics clusters, provide a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems. */ +cluster GeneralDiagnostics = 51 { + revision 2; + + enum BootReasonEnum : enum8 { + kUnspecified = 0; + kPowerOnReboot = 1; + kBrownOutReset = 2; + kSoftwareWatchdogReset = 3; + kHardwareWatchdogReset = 4; + kSoftwareUpdateCompleted = 5; + kSoftwareReset = 6; + } + + enum HardwareFaultEnum : enum8 { + kUnspecified = 0; + kRadio = 1; + kSensor = 2; + kResettableOverTemp = 3; + kNonResettableOverTemp = 4; + kPowerSource = 5; + kVisualDisplayFault = 6; + kAudioOutputFault = 7; + kUserInterfaceFault = 8; + kNonVolatileMemoryError = 9; + kTamperDetected = 10; + } + + enum InterfaceTypeEnum : enum8 { + kUnspecified = 0; + kWiFi = 1; + kEthernet = 2; + kCellular = 3; + kThread = 4; + } + + enum NetworkFaultEnum : enum8 { + kUnspecified = 0; + kHardwareFailure = 1; + kNetworkJammed = 2; + kConnectionFailed = 3; + } + + enum RadioFaultEnum : enum8 { + kUnspecified = 0; + kWiFiFault = 1; + kCellularFault = 2; + kThreadFault = 3; + kNFCFault = 4; + kBLEFault = 5; + kEthernetFault = 6; + } + + bitmap Feature : bitmap32 { + kDataModelTest = 0x1; + } + + struct NetworkInterface { + char_string<32> name = 0; + boolean isOperational = 1; + nullable boolean offPremiseServicesReachableIPv4 = 2; + nullable boolean offPremiseServicesReachableIPv6 = 3; + octet_string<8> hardwareAddress = 4; + octet_string IPv4Addresses[] = 5; + octet_string IPv6Addresses[] = 6; + InterfaceTypeEnum type = 7; + } + + critical event HardwareFaultChange = 0 { + HardwareFaultEnum current[] = 0; + HardwareFaultEnum previous[] = 1; + } + + critical event RadioFaultChange = 1 { + RadioFaultEnum current[] = 0; + RadioFaultEnum previous[] = 1; + } + + critical event NetworkFaultChange = 2 { + NetworkFaultEnum current[] = 0; + NetworkFaultEnum previous[] = 1; + } + + critical event BootReason = 3 { + BootReasonEnum bootReason = 0; + } + + readonly attribute NetworkInterface networkInterfaces[] = 0; + readonly attribute int16u rebootCount = 1; + readonly attribute optional int64u upTime = 2; + readonly attribute optional int32u totalOperationalHours = 3; + readonly attribute optional BootReasonEnum bootReason = 4; + readonly attribute optional HardwareFaultEnum activeHardwareFaults[] = 5; + readonly attribute optional RadioFaultEnum activeRadioFaults[] = 6; + readonly attribute optional NetworkFaultEnum activeNetworkFaults[] = 7; + readonly attribute boolean testEventTriggersEnabled = 8; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct TestEventTriggerRequest { + octet_string<16> enableKey = 0; + int64u eventTrigger = 1; + } + + response struct TimeSnapshotResponse = 2 { + systime_ms systemTimeMs = 0; + nullable posix_ms posixTimeMs = 1; + } + + request struct PayloadTestRequestRequest { + octet_string<16> enableKey = 0; + int8u value = 1; + int16u count = 2; + } + + response struct PayloadTestResponse = 4 { + octet_string payload = 0; + } + + /** Provide a means for certification tests to trigger some test-plan-specific events */ + command access(invoke: manage) TestEventTrigger(TestEventTriggerRequest): DefaultSuccess = 0; + /** Take a snapshot of system time and epoch time. */ + command TimeSnapshot(): TimeSnapshotResponse = 1; + /** Request a variable length payload response. */ + command PayloadTestRequest(PayloadTestRequestRequest): PayloadTestResponse = 3; +} + +/** The Software Diagnostics Cluster provides a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems. */ +cluster SoftwareDiagnostics = 52 { + revision 1; // NOTE: Default/not specifically set + + bitmap Feature : bitmap32 { + kWatermarks = 0x1; + } + + struct ThreadMetricsStruct { + int64u id = 0; + optional char_string<8> name = 1; + optional int32u stackFreeCurrent = 2; + optional int32u stackFreeMinimum = 3; + optional int32u stackSize = 4; + } + + info event SoftwareFault = 0 { + int64u id = 0; + optional char_string name = 1; + optional octet_string faultRecording = 2; + } + + readonly attribute optional ThreadMetricsStruct threadMetrics[] = 0; + readonly attribute optional int64u currentHeapFree = 1; + readonly attribute optional int64u currentHeapUsed = 2; + readonly attribute optional int64u currentHeapHighWatermark = 3; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + /** Reception of this command SHALL reset the values: The StackFreeMinimum field of the ThreadMetrics attribute, CurrentHeapHighWaterMark attribute. */ + command access(invoke: manage) ResetWatermarks(): DefaultSuccess = 0; +} + +/** The Thread Network Diagnostics Cluster provides a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems */ +cluster ThreadNetworkDiagnostics = 53 { + revision 1; // NOTE: Default/not specifically set + + enum ConnectionStatusEnum : enum8 { + kConnected = 0; + kNotConnected = 1; + } + + enum NetworkFaultEnum : enum8 { + kUnspecified = 0; + kLinkDown = 1; + kHardwareFailure = 2; + kNetworkJammed = 3; + } + + enum RoutingRoleEnum : enum8 { + kUnspecified = 0; + kUnassigned = 1; + kSleepyEndDevice = 2; + kEndDevice = 3; + kREED = 4; + kRouter = 5; + kLeader = 6; + } + + bitmap Feature : bitmap32 { + kPacketCounts = 0x1; + kErrorCounts = 0x2; + kMLECounts = 0x4; + kMACCounts = 0x8; + } + + struct NeighborTableStruct { + int64u extAddress = 0; + int32u age = 1; + int16u rloc16 = 2; + int32u linkFrameCounter = 3; + int32u mleFrameCounter = 4; + int8u lqi = 5; + nullable int8s averageRssi = 6; + nullable int8s lastRssi = 7; + int8u frameErrorRate = 8; + int8u messageErrorRate = 9; + boolean rxOnWhenIdle = 10; + boolean fullThreadDevice = 11; + boolean fullNetworkData = 12; + boolean isChild = 13; + } + + struct OperationalDatasetComponents { + boolean activeTimestampPresent = 0; + boolean pendingTimestampPresent = 1; + boolean masterKeyPresent = 2; + boolean networkNamePresent = 3; + boolean extendedPanIdPresent = 4; + boolean meshLocalPrefixPresent = 5; + boolean delayPresent = 6; + boolean panIdPresent = 7; + boolean channelPresent = 8; + boolean pskcPresent = 9; + boolean securityPolicyPresent = 10; + boolean channelMaskPresent = 11; + } + + struct RouteTableStruct { + int64u extAddress = 0; + int16u rloc16 = 1; + int8u routerId = 2; + int8u nextHop = 3; + int8u pathCost = 4; + int8u LQIIn = 5; + int8u LQIOut = 6; + int8u age = 7; + boolean allocated = 8; + boolean linkEstablished = 9; + } + + struct SecurityPolicy { + int16u rotationTime = 0; + int16u flags = 1; + } + + info event ConnectionStatus = 0 { + ConnectionStatusEnum connectionStatus = 0; + } + + info event NetworkFaultChange = 1 { + NetworkFaultEnum current[] = 0; + NetworkFaultEnum previous[] = 1; + } + + readonly attribute nullable int16u channel = 0; + readonly attribute nullable RoutingRoleEnum routingRole = 1; + readonly attribute nullable char_string<16> networkName = 2; + readonly attribute nullable int16u panId = 3; + readonly attribute nullable int64u extendedPanId = 4; + readonly attribute nullable octet_string<17> meshLocalPrefix = 5; + readonly attribute optional int64u overrunCount = 6; + readonly attribute NeighborTableStruct neighborTable[] = 7; + readonly attribute RouteTableStruct routeTable[] = 8; + readonly attribute nullable int32u partitionId = 9; + readonly attribute nullable int16u weighting = 10; + readonly attribute nullable int16u dataVersion = 11; + readonly attribute nullable int16u stableDataVersion = 12; + readonly attribute nullable int8u leaderRouterId = 13; + readonly attribute optional int16u detachedRoleCount = 14; + readonly attribute optional int16u childRoleCount = 15; + readonly attribute optional int16u routerRoleCount = 16; + readonly attribute optional int16u leaderRoleCount = 17; + readonly attribute optional int16u attachAttemptCount = 18; + readonly attribute optional int16u partitionIdChangeCount = 19; + readonly attribute optional int16u betterPartitionAttachAttemptCount = 20; + readonly attribute optional int16u parentChangeCount = 21; + readonly attribute optional int32u txTotalCount = 22; + readonly attribute optional int32u txUnicastCount = 23; + readonly attribute optional int32u txBroadcastCount = 24; + readonly attribute optional int32u txAckRequestedCount = 25; + readonly attribute optional int32u txAckedCount = 26; + readonly attribute optional int32u txNoAckRequestedCount = 27; + readonly attribute optional int32u txDataCount = 28; + readonly attribute optional int32u txDataPollCount = 29; + readonly attribute optional int32u txBeaconCount = 30; + readonly attribute optional int32u txBeaconRequestCount = 31; + readonly attribute optional int32u txOtherCount = 32; + readonly attribute optional int32u txRetryCount = 33; + readonly attribute optional int32u txDirectMaxRetryExpiryCount = 34; + readonly attribute optional int32u txIndirectMaxRetryExpiryCount = 35; + readonly attribute optional int32u txErrCcaCount = 36; + readonly attribute optional int32u txErrAbortCount = 37; + readonly attribute optional int32u txErrBusyChannelCount = 38; + readonly attribute optional int32u rxTotalCount = 39; + readonly attribute optional int32u rxUnicastCount = 40; + readonly attribute optional int32u rxBroadcastCount = 41; + readonly attribute optional int32u rxDataCount = 42; + readonly attribute optional int32u rxDataPollCount = 43; + readonly attribute optional int32u rxBeaconCount = 44; + readonly attribute optional int32u rxBeaconRequestCount = 45; + readonly attribute optional int32u rxOtherCount = 46; + readonly attribute optional int32u rxAddressFilteredCount = 47; + readonly attribute optional int32u rxDestAddrFilteredCount = 48; + readonly attribute optional int32u rxDuplicatedCount = 49; + readonly attribute optional int32u rxErrNoFrameCount = 50; + readonly attribute optional int32u rxErrUnknownNeighborCount = 51; + readonly attribute optional int32u rxErrInvalidSrcAddrCount = 52; + readonly attribute optional int32u rxErrSecCount = 53; + readonly attribute optional int32u rxErrFcsCount = 54; + readonly attribute optional int32u rxErrOtherCount = 55; + readonly attribute optional nullable int64u activeTimestamp = 56; + readonly attribute optional nullable int64u pendingTimestamp = 57; + readonly attribute optional nullable int32u delay = 58; + readonly attribute nullable SecurityPolicy securityPolicy = 59; + readonly attribute nullable octet_string<4> channelPage0Mask = 60; + readonly attribute nullable OperationalDatasetComponents operationalDatasetComponents = 61; + readonly attribute NetworkFaultEnum activeNetworkFaultsList[] = 62; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + /** Reception of this command SHALL reset the OverrunCount attributes to 0 */ + command access(invoke: manage) ResetCounts(): DefaultSuccess = 0; +} + +/** Commands to trigger a Node to allow a new Administrator to commission it. */ +cluster AdministratorCommissioning = 60 { + revision 1; // NOTE: Default/not specifically set + + enum CommissioningWindowStatusEnum : enum8 { + kWindowNotOpen = 0; + kEnhancedWindowOpen = 1; + kBasicWindowOpen = 2; + } + + enum StatusCode : enum8 { + kBusy = 2; + kPAKEParameterError = 3; + kWindowNotOpen = 4; + } + + bitmap Feature : bitmap32 { + kBasic = 0x1; + } + + readonly attribute CommissioningWindowStatusEnum windowStatus = 0; + readonly attribute nullable fabric_idx adminFabricIndex = 1; + readonly attribute nullable vendor_id adminVendorId = 2; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct OpenCommissioningWindowRequest { + int16u commissioningTimeout = 0; + octet_string PAKEPasscodeVerifier = 1; + int16u discriminator = 2; + int32u iterations = 3; + octet_string<32> salt = 4; + } + + request struct OpenBasicCommissioningWindowRequest { + int16u commissioningTimeout = 0; + } + + /** This command is used by a current Administrator to instruct a Node to go into commissioning mode using enhanced commissioning method. */ + timed command access(invoke: administer) OpenCommissioningWindow(OpenCommissioningWindowRequest): DefaultSuccess = 0; + /** This command is used by a current Administrator to instruct a Node to go into commissioning mode using basic commissioning method, if the node supports it. */ + timed command access(invoke: administer) OpenBasicCommissioningWindow(OpenBasicCommissioningWindowRequest): DefaultSuccess = 1; + /** This command is used by a current Administrator to instruct a Node to revoke any active Open Commissioning Window or Open Basic Commissioning Window command. */ + timed command access(invoke: administer) RevokeCommissioning(): DefaultSuccess = 2; +} + +/** This cluster is used to add or remove Operational Credentials on a Commissionee or Node, as well as manage the associated Fabrics. */ +cluster OperationalCredentials = 62 { + revision 1; // NOTE: Default/not specifically set + + enum CertificateChainTypeEnum : enum8 { + kDACCertificate = 1; + kPAICertificate = 2; + } + + enum NodeOperationalCertStatusEnum : enum8 { + kOK = 0; + kInvalidPublicKey = 1; + kInvalidNodeOpId = 2; + kInvalidNOC = 3; + kMissingCsr = 4; + kTableFull = 5; + kInvalidAdminSubject = 6; + kFabricConflict = 9; + kLabelConflict = 10; + kInvalidFabricIndex = 11; + } + + fabric_scoped struct FabricDescriptorStruct { + octet_string<65> rootPublicKey = 1; + vendor_id vendorID = 2; + fabric_id fabricID = 3; + node_id nodeID = 4; + char_string<32> label = 5; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct NOCStruct { + fabric_sensitive octet_string noc = 1; + nullable fabric_sensitive octet_string icac = 2; + fabric_idx fabricIndex = 254; + } + + readonly attribute access(read: administer) NOCStruct NOCs[] = 0; + readonly attribute FabricDescriptorStruct fabrics[] = 1; + readonly attribute int8u supportedFabrics = 2; + readonly attribute int8u commissionedFabrics = 3; + readonly attribute octet_string trustedRootCertificates[] = 4; + readonly attribute int8u currentFabricIndex = 5; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct AttestationRequestRequest { + octet_string<32> attestationNonce = 0; + } + + response struct AttestationResponse = 1 { + octet_string<900> attestationElements = 0; + octet_string<64> attestationSignature = 1; + } + + request struct CertificateChainRequestRequest { + CertificateChainTypeEnum certificateType = 0; + } + + response struct CertificateChainResponse = 3 { + octet_string<600> certificate = 0; + } + + request struct CSRRequestRequest { + octet_string<32> CSRNonce = 0; + optional boolean isForUpdateNOC = 1; + } + + response struct CSRResponse = 5 { + octet_string NOCSRElements = 0; + octet_string attestationSignature = 1; + } + + request struct AddNOCRequest { + octet_string<400> NOCValue = 0; + optional octet_string<400> ICACValue = 1; + octet_string<16> IPKValue = 2; + int64u caseAdminSubject = 3; + vendor_id adminVendorId = 4; + } + + request struct UpdateNOCRequest { + octet_string NOCValue = 0; + optional octet_string ICACValue = 1; + } + + response struct NOCResponse = 8 { + NodeOperationalCertStatusEnum statusCode = 0; + optional fabric_idx fabricIndex = 1; + optional char_string<128> debugText = 2; + } + + request struct UpdateFabricLabelRequest { + char_string<32> label = 0; + } + + request struct RemoveFabricRequest { + fabric_idx fabricIndex = 0; + } + + request struct AddTrustedRootCertificateRequest { + octet_string rootCACertificate = 0; + } + + /** Sender is requesting attestation information from the receiver. */ + command access(invoke: administer) AttestationRequest(AttestationRequestRequest): AttestationResponse = 0; + /** Sender is requesting a device attestation certificate from the receiver. */ + command access(invoke: administer) CertificateChainRequest(CertificateChainRequestRequest): CertificateChainResponse = 2; + /** Sender is requesting a certificate signing request (CSR) from the receiver. */ + command access(invoke: administer) CSRRequest(CSRRequestRequest): CSRResponse = 4; + /** Sender is requesting to add the new node operational certificates. */ + command access(invoke: administer) AddNOC(AddNOCRequest): NOCResponse = 6; + /** Sender is requesting to update the node operational certificates. */ + fabric command access(invoke: administer) UpdateNOC(UpdateNOCRequest): NOCResponse = 7; + /** This command SHALL be used by an Administrative Node to set the user-visible Label field for a given Fabric, as reflected by entries in the Fabrics attribute. */ + fabric command access(invoke: administer) UpdateFabricLabel(UpdateFabricLabelRequest): NOCResponse = 9; + /** This command is used by Administrative Nodes to remove a given fabric index and delete all associated fabric-scoped data. */ + command access(invoke: administer) RemoveFabric(RemoveFabricRequest): NOCResponse = 10; + /** This command SHALL add a Trusted Root CA Certificate, provided as its CHIP Certificate representation. */ + command access(invoke: administer) AddTrustedRootCertificate(AddTrustedRootCertificateRequest): DefaultSuccess = 11; +} + +/** The Group Key Management Cluster is the mechanism by which group keys are managed. */ +cluster GroupKeyManagement = 63 { + revision 1; // NOTE: Default/not specifically set + + enum GroupKeySecurityPolicyEnum : enum8 { + kTrustFirst = 0; + kCacheAndSync = 1; + } + + bitmap Feature : bitmap32 { + kCacheAndSync = 0x1; + } + + fabric_scoped struct GroupInfoMapStruct { + group_id groupId = 1; + endpoint_no endpoints[] = 2; + optional char_string<16> groupName = 3; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct GroupKeyMapStruct { + group_id groupId = 1; + int16u groupKeySetID = 2; + fabric_idx fabricIndex = 254; + } + + struct GroupKeySetStruct { + int16u groupKeySetID = 0; + GroupKeySecurityPolicyEnum groupKeySecurityPolicy = 1; + nullable octet_string<16> epochKey0 = 2; + nullable epoch_us epochStartTime0 = 3; + nullable octet_string<16> epochKey1 = 4; + nullable epoch_us epochStartTime1 = 5; + nullable octet_string<16> epochKey2 = 6; + nullable epoch_us epochStartTime2 = 7; + } + + attribute access(write: manage) GroupKeyMapStruct groupKeyMap[] = 0; + readonly attribute GroupInfoMapStruct groupTable[] = 1; + readonly attribute int16u maxGroupsPerFabric = 2; + readonly attribute int16u maxGroupKeysPerFabric = 3; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct KeySetWriteRequest { + GroupKeySetStruct groupKeySet = 0; + } + + request struct KeySetReadRequest { + int16u groupKeySetID = 0; + } + + response struct KeySetReadResponse = 2 { + GroupKeySetStruct groupKeySet = 0; + } + + request struct KeySetRemoveRequest { + int16u groupKeySetID = 0; + } + + response struct KeySetReadAllIndicesResponse = 5 { + int16u groupKeySetIDs[] = 0; + } + + /** Write a new set of keys for the given key set id. */ + fabric command access(invoke: administer) KeySetWrite(KeySetWriteRequest): DefaultSuccess = 0; + /** Read the keys for a given key set id. */ + fabric command access(invoke: administer) KeySetRead(KeySetReadRequest): KeySetReadResponse = 1; + /** Revoke a Root Key from a Group */ + fabric command access(invoke: administer) KeySetRemove(KeySetRemoveRequest): DefaultSuccess = 3; + /** Return the list of Group Key Sets associated with the accessing fabric */ + fabric command access(invoke: administer) KeySetReadAllIndices(): KeySetReadAllIndicesResponse = 4; +} + +/** This cluster provides an interface to a boolean state called StateValue. */ +cluster BooleanState = 69 { + revision 1; + + info event StateChange = 0 { + boolean stateValue = 0; + } + + readonly attribute boolean stateValue = 0; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** Allows servers to ensure that listed clients are notified when a server is available for communication. */ +cluster IcdManagement = 70 { + revision 2; + + enum OperatingModeEnum : enum8 { + kSIT = 0; + kLIT = 1; + } + + bitmap Feature : bitmap32 { + kCheckInProtocolSupport = 0x1; + kUserActiveModeTrigger = 0x2; + kLongIdleTimeSupport = 0x4; + } + + bitmap UserActiveModeTriggerBitmap : bitmap32 { + kPowerCycle = 0x1; + kSettingsMenu = 0x2; + kCustomInstruction = 0x4; + kDeviceManual = 0x8; + kActuateSensor = 0x10; + kActuateSensorSeconds = 0x20; + kActuateSensorTimes = 0x40; + kActuateSensorLightsBlink = 0x80; + kResetButton = 0x100; + kResetButtonLightsBlink = 0x200; + kResetButtonSeconds = 0x400; + kResetButtonTimes = 0x800; + kSetupButton = 0x1000; + kSetupButtonSeconds = 0x2000; + kSetupButtonLightsBlink = 0x4000; + kSetupButtonTimes = 0x8000; + kAppDefinedButton = 0x10000; + } + + fabric_scoped struct MonitoringRegistrationStruct { + fabric_sensitive node_id checkInNodeID = 1; + fabric_sensitive int64u monitoredSubject = 2; + fabric_idx fabricIndex = 254; + } + + readonly attribute int32u idleModeDuration = 0; + readonly attribute int32u activeModeDuration = 1; + readonly attribute int16u activeModeThreshold = 2; + readonly attribute access(read: administer) optional MonitoringRegistrationStruct registeredClients[] = 3; + readonly attribute access(read: administer) optional int32u ICDCounter = 4; + readonly attribute optional int16u clientsSupportedPerFabric = 5; + readonly attribute optional UserActiveModeTriggerBitmap userActiveModeTriggerHint = 6; + readonly attribute optional char_string<128> userActiveModeTriggerInstruction = 7; + readonly attribute optional OperatingModeEnum operatingMode = 8; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct RegisterClientRequest { + node_id checkInNodeID = 0; + int64u monitoredSubject = 1; + octet_string<16> key = 2; + optional octet_string<16> verificationKey = 3; + } + + response struct RegisterClientResponse = 1 { + int32u ICDCounter = 0; + } + + request struct UnregisterClientRequest { + node_id checkInNodeID = 0; + optional octet_string<16> verificationKey = 1; + } + + response struct StayActiveResponse = 4 { + int32u promisedActiveDuration = 0; + } + + /** Register a client to the end device */ + fabric command access(invoke: manage) RegisterClient(RegisterClientRequest): RegisterClientResponse = 0; + /** Unregister a client from an end device */ + fabric command access(invoke: manage) UnregisterClient(UnregisterClientRequest): DefaultSuccess = 2; + /** Request the end device to stay in Active Mode for an additional ActiveModeThreshold */ + command access(invoke: manage) StayActiveRequest(): StayActiveResponse = 3; +} + +endpoint 0 { + device type ma_rootdevice = 22, version 2; + + binding cluster OtaSoftwareUpdateProvider; + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster AccessControl { + emits event AccessControlEntryChanged; + emits event AccessControlExtensionChanged; + callback attribute acl; + callback attribute subjectsPerAccessControlEntry; + callback attribute targetsPerAccessControlEntry; + callback attribute accessControlEntriesPerFabric; + callback attribute attributeList; + ram attribute featureMap default = 0; + callback attribute clusterRevision; + } + + server cluster BasicInformation { + emits event StartUp; + emits event ShutDown; + emits event Leave; + callback attribute dataModelRevision; + callback attribute vendorName; + callback attribute vendorID; + callback attribute productName; + callback attribute productID; + persist attribute nodeLabel; + callback attribute location; + callback attribute hardwareVersion; + callback attribute hardwareVersionString; + callback attribute softwareVersion; + callback attribute softwareVersionString; + callback attribute capabilityMinima; + callback attribute specificationVersion; + callback attribute maxPathsPerInvoke; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 2; + } + + server cluster OtaSoftwareUpdateRequestor { + emits event StateTransition; + emits event VersionApplied; + emits event DownloadError; + callback attribute defaultOTAProviders; + ram attribute updatePossible default = 1; + ram attribute updateState default = 0; + ram attribute updateStateProgress default = 0; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command AnnounceOTAProvider; + } + + server cluster GeneralCommissioning { + ram attribute breadcrumb default = 0x0000000000000000; + callback attribute basicCommissioningInfo; + callback attribute regulatoryConfig; + callback attribute locationCapability; + callback attribute supportsConcurrentConnection; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command ArmFailSafe; + handle command ArmFailSafeResponse; + handle command SetRegulatoryConfig; + handle command SetRegulatoryConfigResponse; + handle command CommissioningComplete; + handle command CommissioningCompleteResponse; + } + + server cluster NetworkCommissioning { + ram attribute maxNetworks; + callback attribute networks; + ram attribute scanMaxTimeSeconds; + ram attribute connectMaxTimeSeconds; + ram attribute interfaceEnabled; + ram attribute lastNetworkingStatus; + ram attribute lastNetworkID; + ram attribute lastConnectErrorValue; + ram attribute featureMap default = 2; + ram attribute clusterRevision default = 1; + + handle command ScanNetworks; + handle command ScanNetworksResponse; + handle command AddOrUpdateThreadNetwork; + handle command RemoveNetwork; + handle command NetworkConfigResponse; + handle command ConnectNetwork; + handle command ConnectNetworkResponse; + handle command ReorderNetwork; + } + + server cluster GeneralDiagnostics { + emits event BootReason; + callback attribute networkInterfaces; + callback attribute rebootCount; + callback attribute activeNetworkFaults; + callback attribute testEventTriggersEnabled default = false; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command TestEventTrigger; + } + + server cluster SoftwareDiagnostics { + callback attribute threadMetrics; + callback attribute currentHeapFree; + callback attribute currentHeapUsed; + callback attribute currentHeapHighWatermark; + callback attribute featureMap; + ram attribute clusterRevision default = 1; + + handle command ResetWatermarks; + } + + server cluster ThreadNetworkDiagnostics { + callback attribute channel; + callback attribute routingRole; + callback attribute networkName; + callback attribute panId; + callback attribute extendedPanId; + callback attribute meshLocalPrefix; + callback attribute overrunCount; + callback attribute neighborTable; + callback attribute routeTable; + callback attribute partitionId; + callback attribute weighting; + callback attribute dataVersion; + callback attribute stableDataVersion; + callback attribute leaderRouterId; + callback attribute detachedRoleCount; + callback attribute childRoleCount; + callback attribute routerRoleCount; + callback attribute leaderRoleCount; + callback attribute attachAttemptCount; + callback attribute partitionIdChangeCount; + callback attribute betterPartitionAttachAttemptCount; + callback attribute parentChangeCount; + callback attribute txTotalCount; + callback attribute txUnicastCount; + callback attribute txBroadcastCount; + callback attribute txAckRequestedCount; + callback attribute txAckedCount; + callback attribute txNoAckRequestedCount; + callback attribute txDataCount; + callback attribute txDataPollCount; + callback attribute txBeaconCount; + callback attribute txBeaconRequestCount; + callback attribute txOtherCount; + callback attribute txRetryCount; + callback attribute txDirectMaxRetryExpiryCount; + callback attribute txIndirectMaxRetryExpiryCount; + callback attribute txErrCcaCount; + callback attribute txErrAbortCount; + callback attribute txErrBusyChannelCount; + callback attribute rxTotalCount; + callback attribute rxUnicastCount; + callback attribute rxBroadcastCount; + callback attribute rxDataCount; + callback attribute rxDataPollCount; + callback attribute rxBeaconCount; + callback attribute rxBeaconRequestCount; + callback attribute rxOtherCount; + callback attribute rxAddressFilteredCount; + callback attribute rxDestAddrFilteredCount; + callback attribute rxDuplicatedCount; + callback attribute rxErrNoFrameCount; + callback attribute rxErrUnknownNeighborCount; + callback attribute rxErrInvalidSrcAddrCount; + callback attribute rxErrSecCount; + callback attribute rxErrFcsCount; + callback attribute rxErrOtherCount; + callback attribute securityPolicy; + callback attribute channelPage0Mask; + callback attribute operationalDatasetComponents; + callback attribute activeNetworkFaultsList; + ram attribute featureMap default = 0x000F; + ram attribute clusterRevision default = 1; + + handle command ResetCounts; + } + + server cluster AdministratorCommissioning { + callback attribute windowStatus; + callback attribute adminFabricIndex; + callback attribute adminVendorId; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command OpenCommissioningWindow; + handle command RevokeCommissioning; + } + + server cluster OperationalCredentials { + callback attribute NOCs; + callback attribute fabrics; + callback attribute supportedFabrics; + callback attribute commissionedFabrics; + callback attribute trustedRootCertificates; + callback attribute currentFabricIndex; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command AttestationRequest; + handle command AttestationResponse; + handle command CertificateChainRequest; + handle command CertificateChainResponse; + handle command CSRRequest; + handle command CSRResponse; + handle command AddNOC; + handle command UpdateNOC; + handle command NOCResponse; + handle command UpdateFabricLabel; + handle command RemoveFabric; + handle command AddTrustedRootCertificate; + } + + server cluster GroupKeyManagement { + callback attribute groupKeyMap; + callback attribute groupTable; + callback attribute maxGroupsPerFabric; + callback attribute maxGroupKeysPerFabric; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command KeySetWrite; + handle command KeySetRead; + handle command KeySetReadResponse; + handle command KeySetRemove; + handle command KeySetReadAllIndices; + handle command KeySetReadAllIndicesResponse; + } + + server cluster IcdManagement { + callback attribute idleModeDuration; + callback attribute activeModeDuration; + callback attribute activeModeThreshold; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0x0000; + ram attribute clusterRevision default = 1; + } +} +endpoint 1 { + device type ma_contactsensor = 21, version 1; + + + server cluster Identify { + ram attribute identifyTime default = 0x0000; + ram attribute identifyType default = 0x0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 4; + + handle command Identify; + handle command TriggerEffect; + } + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster BooleanState { + emits event StateChange; + ram attribute stateValue default = 0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } +} + + diff --git a/examples/contact-sensor-app/nxp/zap/contact-sensor-app.zap b/examples/contact-sensor-app/nxp/zap/contact-sensor-app.zap new file mode 100644 index 00000000000000..bf037957bd2629 --- /dev/null +++ b/examples/contact-sensor-app/nxp/zap/contact-sensor-app.zap @@ -0,0 +1,3576 @@ +{ + "fileFormat": 2, + "featureLevel": 99, + "creator": "zap", + "keyValuePairs": [ + { + "key": "commandDiscovery", + "value": "1" + }, + { + "key": "defaultResponsePolicy", + "value": "always" + }, + { + "key": "manufacturerCodes", + "value": "0x1002" + } + ], + "package": [ + { + "pathRelativity": "relativeToZap", + "path": "../../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", + "category": "matter", + "version": 1, + "description": "Matter SDK ZCL data" + }, + { + "pathRelativity": "relativeToZap", + "path": "../../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "version": "chip-v1" + } + ], + "endpointTypes": [ + { + "id": 1, + "name": "MA-rootdevice", + "deviceTypeRef": { + "code": 22, + "profileId": 259, + "label": "MA-rootdevice", + "name": "MA-rootdevice" + }, + "deviceTypes": [ + { + "code": 22, + "profileId": 259, + "label": "MA-rootdevice", + "name": "MA-rootdevice" + } + ], + "deviceVersions": [ + 2 + ], + "deviceIdentifiers": [ + 22 + ], + "deviceTypeName": "MA-rootdevice", + "deviceTypeCode": 22, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Access Control", + "code": 31, + "mfgCode": null, + "define": "ACCESS_CONTROL_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "ACL", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SubjectsPerAccessControlEntry", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TargetsPerAccessControlEntry", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AccessControlEntriesPerFabric", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "AccessControlEntryChanged", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "AccessControlExtensionChanged", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Basic Information", + "code": 40, + "mfgCode": null, + "define": "BASIC_INFORMATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DataModelRevision", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorName", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorID", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "vendor_id", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductName", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductID", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NodeLabel", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "NVM", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Location", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersion", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersionString", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersion", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersionString", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CapabilityMinima", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "CapabilityMinimaStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SpecificationVersion", + "code": 21, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxPathsPerInvoke", + "code": 22, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "StartUp", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "ShutDown", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "Leave", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "OTA Software Update Provider", + "code": 41, + "mfgCode": null, + "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER", + "side": "client", + "enabled": 1, + "commands": [ + { + "name": "QueryImage", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "QueryImageResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ApplyUpdateRequest", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ApplyUpdateResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NotifyUpdateApplied", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "OTA Software Update Requestor", + "code": 42, + "mfgCode": null, + "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "AnnounceOTAProvider", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "DefaultOTAProviders", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "UpdatePossible", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpdateState", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "UpdateStateEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpdateStateProgress", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "StateTransition", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "VersionApplied", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "DownloadError", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "General Commissioning", + "code": 48, + "mfgCode": null, + "define": "GENERAL_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ArmFailSafe", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ArmFailSafeResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetRegulatoryConfig", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetRegulatoryConfigResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CommissioningComplete", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CommissioningCompleteResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "Breadcrumb", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "BasicCommissioningInfo", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "BasicCommissioningInfo", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RegulatoryConfig", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "RegulatoryLocationTypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LocationCapability", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "RegulatoryLocationTypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportsConcurrentConnection", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Network Commissioning", + "code": 49, + "mfgCode": null, + "define": "NETWORK_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ScanNetworks", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ScanNetworksResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "AddOrUpdateThreadNetwork", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveNetwork", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NetworkConfigResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ConnectNetwork", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ConnectNetworkResponse", + "code": 7, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ReorderNetwork", + "code": 8, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "MaxNetworks", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Networks", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ScanMaxTimeSeconds", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ConnectMaxTimeSeconds", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "InterfaceEnabled", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkingStatus", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "NetworkCommissioningStatusEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkID", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastConnectErrorValue", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int32s", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "General Diagnostics", + "code": 51, + "mfgCode": null, + "define": "GENERAL_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "TestEventTrigger", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "NetworkInterfaces", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RebootCount", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ActiveNetworkFaults", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TestEventTriggersEnabled", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "false", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "BootReason", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Software Diagnostics", + "code": 52, + "mfgCode": null, + "define": "SOFTWARE_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ResetWatermarks", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "ThreadMetrics", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentHeapFree", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentHeapUsed", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentHeapHighWatermark", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Thread Network Diagnostics", + "code": 53, + "mfgCode": null, + "define": "THREAD_NETWORK_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ResetCounts", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "Channel", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RoutingRole", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "RoutingRoleEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NetworkName", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PanId", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ExtendedPanId", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "MeshLocalPrefix", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "OverrunCount", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NeighborTable", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RouteTable", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PartitionId", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Weighting", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "DataVersion", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "StableDataVersion", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "LeaderRouterId", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "DetachedRoleCount", + "code": 14, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ChildRoleCount", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RouterRoleCount", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "LeaderRoleCount", + "code": 17, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "AttachAttemptCount", + "code": 18, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PartitionIdChangeCount", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "BetterPartitionAttachAttemptCount", + "code": 20, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ParentChangeCount", + "code": 21, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxTotalCount", + "code": 22, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxUnicastCount", + "code": 23, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxBroadcastCount", + "code": 24, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxAckRequestedCount", + "code": 25, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxAckedCount", + "code": 26, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxNoAckRequestedCount", + "code": 27, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxDataCount", + "code": 28, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxDataPollCount", + "code": 29, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxBeaconCount", + "code": 30, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxBeaconRequestCount", + "code": 31, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxOtherCount", + "code": 32, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxRetryCount", + "code": 33, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxDirectMaxRetryExpiryCount", + "code": 34, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxIndirectMaxRetryExpiryCount", + "code": 35, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxErrCcaCount", + "code": 36, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxErrAbortCount", + "code": 37, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxErrBusyChannelCount", + "code": 38, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxTotalCount", + "code": 39, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxUnicastCount", + "code": 40, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxBroadcastCount", + "code": 41, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxDataCount", + "code": 42, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxDataPollCount", + "code": 43, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxBeaconCount", + "code": 44, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxBeaconRequestCount", + "code": 45, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxOtherCount", + "code": 46, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxAddressFilteredCount", + "code": 47, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxDestAddrFilteredCount", + "code": 48, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxDuplicatedCount", + "code": 49, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrNoFrameCount", + "code": 50, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrUnknownNeighborCount", + "code": 51, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrInvalidSrcAddrCount", + "code": 52, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrSecCount", + "code": 53, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrFcsCount", + "code": 54, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrOtherCount", + "code": 55, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SecurityPolicy", + "code": 59, + "mfgCode": null, + "side": "server", + "type": "SecurityPolicy", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ChannelPage0Mask", + "code": 60, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "OperationalDatasetComponents", + "code": 61, + "mfgCode": null, + "side": "server", + "type": "OperationalDatasetComponents", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ActiveNetworkFaultsList", + "code": 62, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x000F", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Administrator Commissioning", + "code": 60, + "mfgCode": null, + "define": "ADMINISTRATOR_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "OpenCommissioningWindow", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RevokeCommissioning", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "WindowStatus", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "CommissioningWindowStatusEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AdminFabricIndex", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "fabric_idx", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AdminVendorId", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "vendor_id", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Operational Credentials", + "code": 62, + "mfgCode": null, + "define": "OPERATIONAL_CREDENTIALS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "AttestationRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AttestationResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CertificateChainRequest", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CertificateChainResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CSRRequest", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CSRResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "AddNOC", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "UpdateNOC", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NOCResponse", + "code": 8, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "UpdateFabricLabel", + "code": 9, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveFabric", + "code": 10, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddTrustedRootCertificate", + "code": 11, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "NOCs", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Fabrics", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SupportedFabrics", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CommissionedFabrics", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TrustedRootCertificates", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CurrentFabricIndex", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Group Key Management", + "code": 63, + "mfgCode": null, + "define": "GROUP_KEY_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "KeySetWrite", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetRead", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "KeySetRemove", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadAllIndices", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadAllIndicesResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "GroupKeyMap", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GroupTable", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxGroupsPerFabric", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxGroupKeysPerFabric", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "ICD Management", + "code": 70, + "mfgCode": null, + "define": "ICD_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "IdleModeDuration", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveModeDuration", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveModeThreshold", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + } + ] + }, + { + "id": 2, + "name": "MA-dimmablelight", + "deviceTypeRef": { + "code": 21, + "profileId": 259, + "label": "MA-contactsensor", + "name": "MA-contactsensor" + }, + "deviceTypes": [ + { + "code": 21, + "profileId": 259, + "label": "MA-contactsensor", + "name": "MA-contactsensor" + } + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 21 + ], + "deviceTypeName": "MA-contactsensor", + "deviceTypeCode": 21, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Identify", + "code": 3, + "mfgCode": null, + "define": "IDENTIFY_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "Identify", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "IdentifyTime", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "IdentifyType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "IdentifyTypeEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Boolean State", + "code": 69, + "mfgCode": null, + "define": "BOOLEAN_STATE_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "StateValue", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "StateChange", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + } + ] + } + ], + "endpoints": [ + { + "endpointTypeName": "MA-rootdevice", + "endpointTypeIndex": 0, + "profileId": 259, + "endpointId": 0, + "networkId": 0 + }, + { + "endpointTypeName": "MA-dimmablelight", + "endpointTypeIndex": 1, + "profileId": 259, + "endpointId": 1, + "networkId": 0 + } + ], + "log": [] +} \ No newline at end of file diff --git a/examples/lighting-app/nxp/k32w/k32w1/.gn b/examples/lighting-app/nxp/k32w/k32w1/.gn index 3d48789e30ab3d..a88f6f5aa7cb3f 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/.gn +++ b/examples/lighting-app/nxp/k32w/k32w1/.gn @@ -25,4 +25,7 @@ default_args = { target_os = "freertos" import("//args.gni") + + # Import default platform configs + import("${chip_root}/src/platform/nxp/k32w/k32w1/args.gni") } diff --git a/examples/lighting-app/nxp/k32w/k32w1/BUILD.gn b/examples/lighting-app/nxp/k32w/k32w1/BUILD.gn index a7643a9f847931..2f327213533e94 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/BUILD.gn +++ b/examples/lighting-app/nxp/k32w/k32w1/BUILD.gn @@ -13,15 +13,26 @@ # limitations under the License. import("//build_overrides/chip.gni") -import("//build_overrides/k32w1_sdk.gni") +import("//build_overrides/nxp_sdk.gni") import("//build_overrides/openthread.gni") +import("${nxp_sdk_build_root}/nxp_sdk.gni") -import("${k32w1_sdk_build_root}/k32w1_executable.gni") -import("${k32w1_sdk_build_root}/k32w1_sdk.gni") +import("${nxp_sdk_build_root}/${nxp_sdk_name}/nxp_executable.gni") + +import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") import("${chip_root}/src/crypto/crypto.gni") import("${chip_root}/src/lib/core/core.gni") import("${chip_root}/src/platform/device.gni") +import("${chip_root}/src/platform/nxp/${nxp_platform}/args.gni") + +import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni") + +if (chip_enable_pw_rpc) { + import("//build_overrides/pigweed.gni") + import("$dir_pw_build/target_types.gni") + import("${chip_root}/examples/platform/nxp/pw_rpc_server.gni") +} declare_args() { chip_software_version = 0 @@ -65,12 +76,30 @@ k32w1_sdk("sdk") { "CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION=${chip_software_version}", ] } + + if (chip_enable_pw_rpc) { + defines += [ + "PW_RPC_ENABLED", + "STREAMER_UART_FLUSH_DELAY_MS=0", + "STREAMER_UART_SERIAL_MANAGER_RING_BUFFER_SIZE=512", + "BOARD_APP_UART_CLK_FREQ=96000000", + ] + } } k32w1_executable("light_app") { output_name = "chip-k32w1-light-example" - sources = [ + sources = [] + deps = [] + + if (chip_enable_pw_rpc) { + forward_variables_from(pw_rpc_server, "*") + } else { + cflags = [ "-Wconversion" ] + } + + sources += [ "${k32w1_platform_dir}/util/LEDWidget.cpp", "${k32w1_platform_dir}/util/include/LEDWidget.h", "main/AppTask.cpp", @@ -84,7 +113,7 @@ k32w1_executable("light_app") { public = [ "${chip_root}/src/platform/nxp/k32w/k32w1/DefaultTestEventTriggerDelegate.h" ] - deps = [ + deps += [ ":sdk", "${chip_root}/examples/common/QRCode", "${chip_root}/examples/lighting-app/nxp/zap/", @@ -107,9 +136,7 @@ k32w1_executable("light_app") { ] } - cflags = [ "-Wconversion" ] - - if (use_smu2_as_system_memory) { + if (use_smu2_static) { ldscript = "${k32w1_platform_dir}/app/ldscripts/k32w1_app.ld" base_ldscript_dir = "${k32w1_sdk_root}/middleware/wireless/framework/Common/devices/kw45_k32w1/gcc" } else { @@ -121,13 +148,17 @@ k32w1_executable("light_app") { ldflags = [ "-Wl,--defsym=__heap_size__=0", "-Wl,--defsym=__stack_size__=0x480", - "-Wl,--defsym=gNvmSectors=8", + "-Wl,--defsym=gUseFactoryData_d=1", "-Wl,-print-memory-usage", "-Wl,--no-warn-rwx-segments", "-T" + rebase_path(ldscript, root_build_dir), ] - if (use_smu2_as_system_memory) { + if (chip_with_factory_data == 1) { + ldflags += [ "-Wl,--defsym=gUseFactoryData_d=1" ] + } + + if (use_smu2_static) { ldflags += [ "-L" + rebase_path(base_ldscript_dir, root_build_dir) ] } diff --git a/examples/lighting-app/nxp/k32w/k32w1/README.md b/examples/lighting-app/nxp/k32w/k32w1/README.md index 92dca287111449..253c21e04eafbb 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/README.md +++ b/examples/lighting-app/nxp/k32w/k32w1/README.md @@ -22,6 +22,7 @@ into an existing Matter network and can be controlled by this network. - [Device UI](#device-ui) - [Building](#building) - [SMU2](#smu2-memory) +- [Manufacturing data](#manufacturing-data) - [Flashing](#flashing) - [Flashing the NBU image](#flashing-the-nbu-image) - [Flashing the host image](#flashing-the-host-image) @@ -33,6 +34,8 @@ into an existing Matter network and can be controlled by this network. - [Running OTA](#running-ota) - [Known issues](#known-issues) +- [Running RPC console](#running-rpc-console) + ## Introduction @@ -112,7 +115,8 @@ point before the 6 second limit. **Button SW3** can be used to change the state of the simulated light bulb. This can be used to mimic a user manually operating a switch. The button behaves as a -toggle, swapping the state every time it is pressed. +toggle, swapping the state every time it is short pressed. When long pressed, it +does a clean soft reset that takes into account Matter shutdown procedure. ## Building @@ -147,8 +151,8 @@ see the files prefixed with `chip-k32w1-light-example`. Some Matter instances and global variables can be placed in the `NBU` `SMU2` memory. When compiling with OpenThread FTD support (`chip_openthread_ftd=true`) -and with `use_smu2_as_system_memory=true`, the following components are placed -in `SMU2` memory: +and with `use_smu2_static=true`, the following components are placed in `SMU2` +memory: - `gImageProcessor` from `OTAImageProcessorImpl.cpp`. - `gApplicationProcessor` from `OTAHooks.cpp`. @@ -161,8 +165,18 @@ changed, the names must be updated in `k32w1_app.ld`. See [k32w1_app.ld](../../../../platform/nxp/k32w/k32w1/app/ldscripts/k32w1_app.ld) for names and `SMU2` memory range size. -To use the `SMU2` Memory an optimized `NBU` binary is also needed. See -[Flashing the NBU image](#flashing-the-nbu-image). +The OpenThread buffers can be allocated from a 13KB `SMU2` range after a +successful commissioning process until a factory reset is initiated. This way, +the OpenThread buffers will be dynamically allocated instead of statically, +freeing some `SRAM`. To enable this feature compile with OpenThread FTD support +(`chip_openthread_ftd=true`) and with `use_smu2_dynamic=true`. + +## Manufacturing data + +Use `chip_with_factory_data=1` in the gn build command to enable factory data. + +For a full guide on manufacturing flow, please see +[Guide for writing manufacturing data on NXP devices](../../../../../docs/guides/nxp_manufacturing_flow.md). ## Flashing @@ -423,3 +437,22 @@ user@computer1:~/connectedhomeip$ sudo ifconfig eth0 -multicast - If Wi-Fi is used on a RPI4, then a 5Ghz network should be selected. Otherwise, issues related to BLE-WiFi combo may appear. + +## Running RPC console + +To build example with RPC enabled, use the following gn command: +`gn gen out/debug --args='import("//with_pw_rpc.gni") treat_warnings_as_errors=false'` + +The application runs an RPC server and processes events coming from an RPC +client. An example of an RPC client is the `chip-console`, which can be accessed +by running: +`chip-console --device /dev/tty. -b 115200 -o pw_log.out` + +The console should already have been installed in the virtual environment. From +the `chip-console`, a user can send specific commands to the device, e.g.: + +- To toggle the LED (`#define LIGHT_BUTTON 2` in `app_config.h`) + `rpcs.chip.rpc.Button.Event(idx=2)` +- To start BLE advertising (`#define BLE_BUTTON 4` in `app_config.h`) + `rpcs.chip.rpc.Button.Event(idx=4)` +- To reboot the device `rpcs.chip.rpc.Device.Reboot()` diff --git a/examples/lighting-app/nxp/k32w/k32w1/args.gni b/examples/lighting-app/nxp/k32w/k32w1/args.gni index 4efb6421f5ca02..a06e5828acdc45 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/args.gni +++ b/examples/lighting-app/nxp/k32w/k32w1/args.gni @@ -13,7 +13,6 @@ # limitations under the License. import("//build_overrides/chip.gni") -import("${chip_root}/examples/platform/nxp/k32w/k32w1/args.gni") # SDK target. This is overridden to add our SDK app_config.h & defines. k32w1_sdk_target = get_label_info(":sdk", "label_no_toolchain") diff --git a/examples/lighting-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h b/examples/lighting-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h index 07d8b6a92f5e69..536b822d776377 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h +++ b/examples/lighting-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h @@ -34,6 +34,58 @@ // including message encryption. Because of this they MUST NEVER BE ENABLED IN PRODUCTION BUILDS. #define CHIP_CONFIG_SECURITY_TEST_MODE 0 +// Use hard-coded test certificates already embedded in generic chip code => set it to 0 +// Use real/development certificates => set it to 1 + file the provisioning section from +// the internal flash +#ifndef CONFIG_CHIP_LOAD_REAL_FACTORY_DATA +#define CONFIG_CHIP_LOAD_REAL_FACTORY_DATA 0 +#endif + +#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA + +// VID/PID for product => will be used by Basic Information Cluster +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0x1037 +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0xA221 + +// Set the following define to use the Certification Declaration from below and not use it stored in factory data section +#ifndef CHIP_USE_DEVICE_CONFIG_CERTIFICATION_DECLARATION +#define CHIP_USE_DEVICE_CONFIG_CERTIFICATION_DECLARATION 0 +#endif + +#ifndef CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION +//-> format_version = 1 +//-> vendor_id = 0x1037 +//-> product_id_array = [ 0xA221 ] +//-> device_type_id = 0x0100 +//-> certificate_id = "ZIG20142ZB330003-24" +//-> security_level = 0 +//-> security_information = 0 +//-> version_number = 0x2694 +//-> certification_type = 1 +//-> dac_origin_vendor_id is not present +//-> dac_origin_product_id is not present +#define CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION \ + { \ + 0x30, 0x81, 0xe9, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x81, 0xdb, 0x30, 0x81, 0xd8, \ + 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, \ + 0x45, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x38, 0x04, 0x36, 0x15, 0x24, 0x00, \ + 0x01, 0x25, 0x01, 0x37, 0x10, 0x36, 0x02, 0x05, 0x21, 0xa2, 0x18, 0x25, 0x03, 0x00, 0x01, 0x2c, 0x04, 0x13, 0x5a, \ + 0x49, 0x47, 0x32, 0x30, 0x31, 0x34, 0x32, 0x5a, 0x42, 0x33, 0x33, 0x30, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x34, 0x24, \ + 0x05, 0x00, 0x24, 0x06, 0x00, 0x25, 0x07, 0x76, 0x98, 0x24, 0x08, 0x01, 0x18, 0x31, 0x7d, 0x30, 0x7b, 0x02, 0x01, \ + 0x03, 0x80, 0x14, 0x62, 0xfa, 0x82, 0x33, 0x59, 0xac, 0xfa, 0xa9, 0x96, 0x3e, 0x1c, 0xfa, 0x14, 0x0a, 0xdd, 0xf5, \ + 0x04, 0xf3, 0x71, 0x60, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x0a, \ + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02, 0x21, 0x00, 0x93, 0x77, \ + 0x28, 0xd2, 0xd5, 0x36, 0xea, 0x09, 0xe4, 0xc5, 0xbc, 0x87, 0xa5, 0xa2, 0x44, 0x57, 0xf0, 0xed, 0x24, 0x66, 0xe7, \ + 0x50, 0x61, 0x1b, 0xe1, 0x17, 0x7c, 0x55, 0x0a, 0x83, 0xfa, 0xc3, 0x02, 0x20, 0x21, 0x6c, 0x60, 0x67, 0x4e, 0x3f, \ + 0xbe, 0x30, 0x38, 0xd4, 0x5e, 0x86, 0x1d, 0xe1, 0xe7, 0x6f, 0x7b, 0x1d, 0xd4, 0xfe, 0xbf, 0x79, 0x5a, 0x4e, 0x07, \ + 0x83, 0x46, 0xca, 0x94, 0x92, 0x5f, 0x14 \ + } + +// All remaining data will be pulled from the provisioning region of flash. +#endif + +#else + /** * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID * @@ -63,6 +115,8 @@ */ #define CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER "TEST_SN" +#endif // CONFIG_CHIP_LOAD_REAL_FACTORY_DATA + /** * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION * diff --git a/examples/lighting-app/nxp/k32w/k32w1/main/AppTask.cpp b/examples/lighting-app/nxp/k32w/k32w1/main/AppTask.cpp index 4851e8d33432b3..944d68857983e1 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/main/AppTask.cpp +++ b/examples/lighting-app/nxp/k32w/k32w1/main/AppTask.cpp @@ -30,6 +30,9 @@ #include #include #include +#if defined(USE_SMU2_DYNAMIC) +#include +#endif #include #include @@ -88,6 +91,9 @@ using namespace chip; using namespace chip::app; AppTask AppTask::sAppTask; +#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA +static AppTask::FactoryDataProvider sFactoryDataProvider; +#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. @@ -135,8 +141,14 @@ CHIP_ERROR AppTask::Init() // Init ZCL Data Model and start server PlatformMgr().ScheduleWork(InitServer, 0); - // Initialize device attestation config +#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA + ReturnErrorOnFailure(sFactoryDataProvider.Init()); + SetDeviceInstanceInfoProvider(&sFactoryDataProvider); + SetDeviceAttestationCredentialsProvider(&sFactoryDataProvider); + SetCommissionableDataProvider(&sFactoryDataProvider); +#else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif // CONFIG_CHIP_LOAD_REAL_FACTORY_DATA // QR code will be used with CHIP Tool AppTask::PrintOnboardingInfo(); @@ -213,6 +225,10 @@ void AppTask::InitServer(intptr_t arg) initParams.operationalKeystore = &sK32W1PersistentStorageOpKeystore; #endif +#if defined(USE_SMU2_DYNAMIC) + VerifyOrDie(SMU2::Init(initParams.persistentStorageDelegate) == CHIP_NO_ERROR); +#endif + // Init ZCL Data Model and start server static DefaultTestEventTriggerDelegate sTestEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate; @@ -339,7 +355,7 @@ void AppTask::AppTaskMain(void * pvParameter) void AppTask::ButtonEventHandler(uint8_t pin_no, uint8_t button_action) { - if ((pin_no != RESET_BUTTON) && (pin_no != LIGHT_BUTTON) && (pin_no != OTA_BUTTON) && (pin_no != BLE_BUTTON)) + if ((pin_no != RESET_BUTTON) && (pin_no != LIGHT_BUTTON) && (pin_no != SOFT_RESET_BUTTON) && (pin_no != BLE_BUTTON)) { return; } @@ -353,9 +369,10 @@ void AppTask::ButtonEventHandler(uint8_t pin_no, uint8_t button_action) { button_event.Handler = LightActionEventHandler; } - else if (pin_no == OTA_BUTTON) + else if (pin_no == SOFT_RESET_BUTTON) { - // button_event.Handler = OTAHandler; + // Soft reset ensures that platform manager shutdown procedure is called. + button_event.Handler = SoftResetHandler; } else if (pin_no == BLE_BUTTON) { @@ -379,7 +396,7 @@ button_status_t AppTask::KBD_Callback(void * buttonHandle, button_callback_messa switch (pinNb) { case BLE_BUTTON: - K32W_LOG("pb1 short press"); + // K32W_LOG("pb1 short press"); if (sAppTask.mResetTimerActive) { ButtonEventHandler(BLE_BUTTON, RESET_BUTTON_PUSH); @@ -391,7 +408,7 @@ button_status_t AppTask::KBD_Callback(void * buttonHandle, button_callback_messa break; case LIGHT_BUTTON: - K32W_LOG("pb2 short press"); + // K32W_LOG("pb2 short press"); ButtonEventHandler(LIGHT_BUTTON, LIGHT_BUTTON_PUSH); break; } @@ -401,13 +418,13 @@ button_status_t AppTask::KBD_Callback(void * buttonHandle, button_callback_messa switch (pinNb) { case BLE_BUTTON: - K32W_LOG("pb1 long press"); + // K32W_LOG("pb1 long press"); ButtonEventHandler(BLE_BUTTON, RESET_BUTTON_PUSH); break; case LIGHT_BUTTON: - K32W_LOG("pb2 long press"); - ButtonEventHandler(OTA_BUTTON, OTA_BUTTON_PUSH); + // K32W_LOG("pb2 long press"); + ButtonEventHandler(SOFT_RESET_BUTTON, SOFT_RESET_BUTTON_PUSH); break; } break; @@ -529,29 +546,14 @@ void AppTask::LightActionEventHandler(AppEvent * aEvent) } } -void AppTask::OTAHandler(AppEvent * aEvent) +void AppTask::SoftResetHandler(AppEvent * aEvent) { - if (aEvent->ButtonEvent.PinNo != OTA_BUTTON) + if (aEvent->ButtonEvent.PinNo != SOFT_RESET_BUTTON) return; -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - if (sAppTask.mFunction != kFunction_NoneSelected) - { - K32W_LOG("Another function is scheduled. Could not initiate OTA!"); - return; - } - - PlatformMgr().ScheduleWork(StartOTAQuery, 0); -#endif + PlatformMgrImpl().CleanReset(); } -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR -void AppTask::StartOTAQuery(intptr_t arg) -{ - GetRequestorInstance()->TriggerImmediateQuery(); -} -#endif - void AppTask::BleHandler(AppEvent * aEvent) { if (aEvent->ButtonEvent.PinNo != BLE_BUTTON) @@ -807,11 +809,24 @@ void AppTask::PostTurnOnActionRequest(int32_t aActor, LightingManager::Action_t void AppTask::PostEvent(const AppEvent * aEvent) { + portBASE_TYPE taskToWake = pdFALSE; if (sAppEventQueue != NULL) { - if (!xQueueSend(sAppEventQueue, aEvent, 1)) + if (__get_IPSR()) + { + if (!xQueueSendToFrontFromISR(sAppEventQueue, aEvent, &taskToWake)) + { + K32W_LOG("Failed to post event to app task event queue"); + } + + portYIELD_FROM_ISR(taskToWake); + } + else { - K32W_LOG("Failed to post event to app task event queue"); + if (!xQueueSend(sAppEventQueue, aEvent, 1)) + { + K32W_LOG("Failed to post event to app task event queue"); + } } } } diff --git a/examples/lighting-app/nxp/k32w/k32w1/main/include/AppTask.h b/examples/lighting-app/nxp/k32w/k32w1/main/include/AppTask.h index db81edf168c41e..b5201da2477862 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/main/include/AppTask.h +++ b/examples/lighting-app/nxp/k32w/k32w1/main/include/AppTask.h @@ -27,6 +27,10 @@ #include #include +#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA +#include +#endif + #include "FreeRTOS.h" #include "fsl_component_button.h" #include "timers.h" @@ -42,6 +46,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); @@ -56,6 +63,7 @@ class AppTask static void OnIdentifyStop(Identify * identify); static void OnTriggerEffect(Identify * identify); static void OnTriggerEffectComplete(chip::System::Layer * systemLayer, void * appState); + static void ButtonEventHandler(uint8_t pin_no, uint8_t button_action); private: friend AppTask & GetAppTask(void); @@ -71,14 +79,13 @@ class AppTask static void FunctionTimerEventHandler(AppEvent * aEvent); static button_status_t KBD_Callback(void * buttonHandle, button_callback_message_t * message, void * callbackParam); - static void OTAHandler(AppEvent * aEvent); + static void SoftResetHandler(AppEvent * aEvent); static void BleHandler(AppEvent * aEvent); static void BleStartAdvertising(intptr_t arg); static void LightActionEventHandler(AppEvent * aEvent); static void ResetActionEventHandler(AppEvent * aEvent); static void InstallEventHandler(AppEvent * aEvent); - static void ButtonEventHandler(uint8_t pin_no, uint8_t button_action); static void TimerEventHandler(TimerHandle_t xTimer); static void MatterEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); diff --git a/examples/lighting-app/nxp/k32w/k32w1/main/include/app_config.h b/examples/lighting-app/nxp/k32w/k32w1/main/include/app_config.h index ff938f494b089d..1478b53b11aba1 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/main/include/app_config.h +++ b/examples/lighting-app/nxp/k32w/k32w1/main/include/app_config.h @@ -22,12 +22,12 @@ #define RESET_BUTTON 1 #define LIGHT_BUTTON 2 -#define OTA_BUTTON 3 +#define SOFT_RESET_BUTTON 3 #define BLE_BUTTON 4 #define RESET_BUTTON_PUSH 1 #define LIGHT_BUTTON_PUSH 2 -#define OTA_BUTTON_PUSH 3 +#define SOFT_RESET_BUTTON_PUSH 3 #define BLE_BUTTON_PUSH 4 #define APP_BUTTON_PUSH 1 diff --git a/examples/lighting-app/nxp/k32w/k32w1/main/main.cpp b/examples/lighting-app/nxp/k32w/k32w1/main/main.cpp index 7ebd3f3ed3b1b7..53a6efbbb3ffd5 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/main/main.cpp +++ b/examples/lighting-app/nxp/k32w/k32w1/main/main.cpp @@ -35,6 +35,7 @@ #include "FreeRtosHooks.h" #include "app_config.h" +#include "pin_mux.h" using namespace ::chip; using namespace ::chip::Inet; @@ -43,6 +44,10 @@ using namespace ::chip::Logging; #include +#if PW_RPC_ENABLED +#include "Rpc.h" +#endif + typedef void (*InitFunc)(void); extern InitFunc __init_array_start; extern InitFunc __init_array_end; @@ -69,6 +74,17 @@ extern "C" void main_task(void const * argument) /* Used for HW initializations */ otSysInit(0, NULL); +#if PW_RPC_ENABLED + /* set clock */ + CLOCK_SetIpSrc(kCLOCK_Lpuart1, kCLOCK_IpSrcFro192M); + /* enable clock */ + CLOCK_EnableClock(kCLOCK_Lpuart1); + + BOARD_InitPinLPUART1_TX(); + BOARD_InitPinLPUART1_RX(); + chip::rpc::Init(); +#endif + K32W_LOG("Welcome to NXP Lighting Demo App"); /* Mbedtls Threading support is needed because both diff --git a/examples/lighting-app/nxp/k32w/k32w1/with_pw_rpc.gni b/examples/lighting-app/nxp/k32w/k32w1/with_pw_rpc.gni new file mode 100644 index 00000000000000..d6bea63f8402c0 --- /dev/null +++ b/examples/lighting-app/nxp/k32w/k32w1/with_pw_rpc.gni @@ -0,0 +1,33 @@ +# Copyright (c) 2023 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. + +# add this gni as import in your build args to use pigweed in the example +# 'import("//with_pw_rpc.gni")' + +import("//build_overrides/chip.gni") +import("${chip_root}/config/nxp/lib/pw_rpc/pw_rpc.gni") +import("${chip_root}/examples/platform/nxp/k32w/k32w1/args.gni") + +k32w1_sdk_target = get_label_info(":sdk", "label_no_toolchain") + +chip_enable_ota_requestor = true +chip_stack_lock_tracking = "fatal" +chip_enable_ble = true +chip_enable_pw_rpc = true +chip_with_ot_cli = 0 +is_debug = false +chip_openthread_ftd = true +chip_crypto = "platform" + +cpp_standard = "gnu++17" diff --git a/examples/lighting-app/nxp/zap/lighting-on-off.matter b/examples/lighting-app/nxp/zap/lighting-on-off.matter index 9f4e9c51e5e5c3..5241ba629863ab 100644 --- a/examples/lighting-app/nxp/zap/lighting-on-off.matter +++ b/examples/lighting-app/nxp/zap/lighting-on-off.matter @@ -1522,7 +1522,7 @@ cluster GroupKeyManagement = 63 { } endpoint 0 { - device type ma_rootdevice = 22, version 1; + device type ma_rootdevice = 22, version 2; binding cluster OtaSoftwareUpdateProvider; diff --git a/examples/lighting-app/nxp/zap/lighting-on-off.zap b/examples/lighting-app/nxp/zap/lighting-on-off.zap index e7f1d48c378d29..8873c5e9732c85 100644 --- a/examples/lighting-app/nxp/zap/lighting-on-off.zap +++ b/examples/lighting-app/nxp/zap/lighting-on-off.zap @@ -51,7 +51,7 @@ } ], "deviceVersions": [ - 1 + 2 ], "deviceIdentifiers": [ 22 @@ -3994,5 +3994,6 @@ "endpointId": 1, "networkId": 0 } - ] + ], + "log": [] } \ No newline at end of file diff --git a/examples/platform/nxp/PigweedLogger.cpp b/examples/platform/nxp/PigweedLogger.cpp new file mode 100644 index 00000000000000..8e7bf277e320fb --- /dev/null +++ b/examples/platform/nxp/PigweedLogger.cpp @@ -0,0 +1,111 @@ +/* + * + * 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. + */ + +/* + * @file PigweedLogger.cpp + * + * This file contains basic string writing function, based on Pigweed HDLC + * over UART transport. It allows to send log messages even if the application + * needs to use HDLC/UART for another purpose like the RPC server. + */ + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "PigweedLogger.h" + +namespace PigweedLogger { +namespace { + +constexpr uint8_t kLogHdlcAddress = 1; // Send log messages to HDLC address 1 (other than RPC communication) +constexpr size_t kWriteBufferSize = 256; // Buffer for constructing HDLC frames + +// Exclusive access to the backend is needed to make sure that log messages coming +// from different threads are not interwoven. +SemaphoreHandle_t sLoggerLock; + +static pw::stream::SysIoWriter sWriter; +static size_t sWriteBufferPos; +static char sWriteBuffer[kWriteBufferSize]; + +static void send(void) +{ + pw::hdlc::WriteUIFrame(kLogHdlcAddress, pw::as_bytes(pw::span(sWriteBuffer, sWriteBufferPos)), sWriter); + sWriteBufferPos = 0; +} + +} // namespace + +void Init(void) +{ + sLoggerLock = xSemaphoreCreateMutex(); + assert(sLoggerLock != NULL); + + pw_sys_io_Init(); +} + +int PutString(const char * buffer, size_t size) +{ + assert(sWriteBufferPos < kWriteBufferSize); + assert(size < kWriteBufferSize); + + Lock(); + + for (size_t i = 0; i < size; ++i) + { + // Send each line excluding "\r\n" in a separate frame + + if (buffer[i] == '\r') + continue; + + if (buffer[i] == '\n') + { + send(); + continue; + } + + sWriteBuffer[sWriteBufferPos++] = buffer[i]; + + if (sWriteBufferPos == kWriteBufferSize) + send(); + } + + Unlock(); + + return size; +} + +void Lock() +{ + xSemaphoreTake(sLoggerLock, portMAX_DELAY); +} + +void Unlock() +{ + xSemaphoreGive(sLoggerLock); +} + +} // namespace PigweedLogger diff --git a/examples/platform/nxp/PigweedLogger.h b/examples/platform/nxp/PigweedLogger.h new file mode 100644 index 00000000000000..8ea1da5dbae92b --- /dev/null +++ b/examples/platform/nxp/PigweedLogger.h @@ -0,0 +1,30 @@ +/* + * 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 + +namespace PigweedLogger { + +void Init(void); +int PutString(const char * buffer, size_t size); + +void Lock(); +void Unlock(); + +} // namespace PigweedLogger diff --git a/examples/platform/nxp/Rpc.cpp b/examples/platform/nxp/Rpc.cpp new file mode 100644 index 00000000000000..d9bf744382627c --- /dev/null +++ b/examples/platform/nxp/Rpc.cpp @@ -0,0 +1,144 @@ +/* + * + * 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 "AppTask.h" +#include "FreeRTOS.h" +#include "PigweedLogger.h" +#include "PigweedLoggerMutex.h" +#include "pigweed/RpcService.h" +#include "task.h" + +#if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE +#include "pigweed/rpc_services/Attributes.h" +#endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE + +#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE +#include "pigweed/rpc_services/Button.h" +#endif // defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE + +#if defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +#include "pigweed/rpc_services/Device.h" +#endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE + +#if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE +#include "pigweed/rpc_services/Lighting.h" +#endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE + +#if defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE +#include "pigweed/rpc_services/Locking.h" +#endif // defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE + +#define RPC_TASK_STACK_SIZE 2048 +#define RPC_TASK_PRIORITY 1 +TaskHandle_t RpcTaskHandle; + +namespace chip { +namespace rpc { + +#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE +class NxpButton final : public Button +{ +public: + pw::Status Event(const chip_rpc_ButtonEvent & request, pw_protobuf_Empty & response) override + { + GetAppTask().ButtonEventHandler(request.idx, request.idx); + return pw::OkStatus(); + } +}; +#endif // defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE + +#if defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +class NxpDevice final : public Device +{ +public: + pw::Status Reboot(const pw_protobuf_Empty & request, pw_protobuf_Empty & response) override + { + mRebootTimer = xTimerCreate("Reboot", kRebootTimerPeriodTicks, false, nullptr, RebootHandler); + xTimerStart(mRebootTimer, pdMS_TO_TICKS(0)); + return pw::OkStatus(); + } + +private: + static constexpr TickType_t kRebootTimerPeriodTicks = 300; + TimerHandle_t mRebootTimer; + + static void RebootHandler(TimerHandle_t) { NVIC_SystemReset(); } +}; +#endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE + +namespace { + +#if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE +Attributes attributes_service; +#endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE + +#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE +NxpButton button_service; +#endif // defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE + +#if defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +NxpDevice device_service; +#endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE + +#if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE +Lighting lighting_service; +#endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE + +#if defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE +Locking locking; +#endif // defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE + +void RegisterServices(pw::rpc::Server & server) +{ +#if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE + server.RegisterService(attributes_service); +#endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE + +#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE + server.RegisterService(button_service); +#endif // defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE + +#if defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE + server.RegisterService(device_service); +#endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE + +#if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE + server.RegisterService(lighting_service); +#endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE + +#if defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE + server.RegisterService(locking); +#endif // defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE +} + +} // namespace + +void RunRpcService(void *) +{ + Start(RegisterServices, &logger_mutex); +} + +void Init() +{ + PigweedLogger::Init(); + + xTaskCreate(RunRpcService, "RPC_TASK", RPC_TASK_STACK_SIZE, nullptr, RPC_TASK_PRIORITY, &RpcTaskHandle); +} + +} // namespace rpc +} // namespace chip diff --git a/examples/platform/nxp/Rpc.h b/examples/platform/nxp/Rpc.h new file mode 100644 index 00000000000000..741fe7982883cc --- /dev/null +++ b/examples/platform/nxp/Rpc.h @@ -0,0 +1,30 @@ +/* + * + * 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 + +namespace chip { +namespace rpc { + +class LightingService; + +void Init(); +void RunRpcService(void *); + +} // namespace rpc +} // namespace chip diff --git a/examples/platform/nxp/k32w/k32w0/scripts/sign-outdir.py b/examples/platform/nxp/k32w/k32w0/scripts/sign-outdir.py index dfaf912ae5283d..ea4a888c9e3555 100644 --- a/examples/platform/nxp/k32w/k32w0/scripts/sign-outdir.py +++ b/examples/platform/nxp/k32w/k32w0/scripts/sign-outdir.py @@ -4,7 +4,7 @@ def main(args): - if os.environ["NXP_K32W0_SDK_ROOT"] != "": + 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.getcwd() + "/../../../../../../../third_party/nxp/k32w0_sdk/repo/core/tools/imagetool/sign_images.sh" diff --git a/examples/platform/nxp/k32w/k32w1/BUILD.gn b/examples/platform/nxp/k32w/k32w1/BUILD.gn index 0a980406bce075..5cd2a8b31392c2 100644 --- a/examples/platform/nxp/k32w/k32w1/BUILD.gn +++ b/examples/platform/nxp/k32w/k32w1/BUILD.gn @@ -13,9 +13,11 @@ # limitations under the License. import("//build_overrides/chip.gni") -import("//build_overrides/k32w1_sdk.gni") +import("//build_overrides/nxp_sdk.gni") -import("${k32w1_sdk_build_root}/k32w1_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 = [ diff --git a/examples/platform/nxp/k32w/k32w1/app/args.gni b/examples/platform/nxp/k32w/k32w1/app/args.gni index c09510c14df229..2705c251fb807d 100644 --- a/examples/platform/nxp/k32w/k32w1/app/args.gni +++ b/examples/platform/nxp/k32w/k32w1/app/args.gni @@ -16,11 +16,6 @@ import("//build_overrides/chip.gni") import("${chip_root}/src/platform/nxp/k32w/k32w1/args.gni") -arm_float_abi = "hard" -arm_cpu = "cortex-m33" -arm_fpu = "fpv5-sp-d16" -arm_arch = "armv8-m.main+dsp+fp" - openthread_project_core_config_file = "OpenThreadConfig.h" chip_ble_project_config_include = "" diff --git a/examples/platform/nxp/k32w/k32w1/app/ldscripts/k32w1_app.ld b/examples/platform/nxp/k32w/k32w1/app/ldscripts/k32w1_app.ld index de9c882af9fed4..ac8f7bd65d0950 100644 --- a/examples/platform/nxp/k32w/k32w1/app/ldscripts/k32w1_app.ld +++ b/examples/platform/nxp/k32w/k32w1/app/ldscripts/k32w1_app.ld @@ -14,7 +14,7 @@ ** limitations under the License. */ -m_smu2_data_start = 0x489C0000; +m_smu2_data_start = 0x489C0080; m_smu2_data_end = 0x489C537B; m_smu2_data_size = m_smu2_data_end - m_smu2_data_start + 1; diff --git a/examples/platform/nxp/k32w/k32w1/app/support/BUILD.gn b/examples/platform/nxp/k32w/k32w1/app/support/BUILD.gn index dafa6de4d3d31d..dc688edc2c78ed 100644 --- a/examples/platform/nxp/k32w/k32w1/app/support/BUILD.gn +++ b/examples/platform/nxp/k32w/k32w1/app/support/BUILD.gn @@ -13,7 +13,7 @@ # limitations under the License. import("//build_overrides/chip.gni") -import("//build_overrides/k32w1_sdk.gni") +import("//build_overrides/nxp_sdk.gni") config("support_config") { include_dirs = [ "../../../../.." ] diff --git a/examples/platform/nxp/k32w/k32w1/app/support/FreeRtosHooks.c b/examples/platform/nxp/k32w/k32w1/app/support/FreeRtosHooks.c index 83549b1dc1f04a..a7c78a77440e03 100644 --- a/examples/platform/nxp/k32w/k32w1/app/support/FreeRtosHooks.c +++ b/examples/platform/nxp/k32w/k32w1/app/support/FreeRtosHooks.c @@ -51,10 +51,6 @@ #define APP_DBG_LOG(...) #endif -#if (configUSE_TICKLESS_IDLE != 0) -extern uint64_t PWR_TryEnterLowPower(uint64_t timeoutUs); -#endif - static inline void mutex_init(mbedtls_threading_mutex_t * p_mutex) { assert(p_mutex != NULL); @@ -123,7 +119,7 @@ void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime) if (abortIdle == false) { /* Enter low power with a maximal timeout */ - actualIdleTimeUs = PWR_TryEnterLowPower(expectedIdleTimeUs); + actualIdleTimeUs = PWR_EnterLowPower(expectedIdleTimeUs); /* Re enable systicks and compensate systick timebase */ PWR_SysticksPostProcess(expectedIdleTimeUs, actualIdleTimeUs); diff --git a/examples/platform/nxp/k32w/k32w1/app/support/Memconfig.cpp b/examples/platform/nxp/k32w/k32w1/app/support/Memconfig.cpp index e5acf5ea3ceecb..e05281fdee4f4d 100644 --- a/examples/platform/nxp/k32w/k32w1/app/support/Memconfig.cpp +++ b/examples/platform/nxp/k32w/k32w1/app/support/Memconfig.cpp @@ -40,6 +40,8 @@ #include #endif // CHIP_CONFIG_MEMORY_DEBUG_DMALLOC +#include "fsl_component_mem_manager.h" + /* Assumes 8bit bytes! */ #define heapBITS_PER_BYTE ((size_t) 8) @@ -64,42 +66,6 @@ static size_t xBlockAllocatedBit = ((size_t) 1) << ((sizeof(size_t) * heapBITS_P 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); @@ -135,34 +101,22 @@ void * __wrap_calloc(size_t num, size_t size) 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); + /* MML will only realloc a new pointer if the size is greater than old pointer size.*/ + vTaskSuspendAll(); + new_ptr = MEM_BufferRealloc(ptr, new_size); + xTaskResumeAll(); if (!new_ptr) { ChipLogError(DeviceLayer, "__wrap_realloc: Could not allocate memory!"); return NULL; } - - memset(reinterpret_cast(new_ptr) + old_ptr_size, 0, (new_size - old_ptr_size)); - memcpy(new_ptr, ptr, old_ptr_size); } - vPortFree(ptr); - return new_ptr; } diff --git a/examples/platform/nxp/pw_rpc_server.gni b/examples/platform/nxp/pw_rpc_server.gni new file mode 100644 index 00000000000000..0ec2d3b121b2d5 --- /dev/null +++ b/examples/platform/nxp/pw_rpc_server.gni @@ -0,0 +1,62 @@ +# Copyright (c) 2023 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/pigweed.gni") + +import("$dir_pw_build/target_types.gni") +import("${chip_root}/src/platform/device.gni") + +nxp_platform_dir = "${chip_root}/examples/platform/nxp" + +# Define a scope for pw RPC server dependencies. +# This .gni file should be imported by applications that want to use pw RPC. +# These variables shall be copied in the final executable target by adding +# forward_variables_from(pw_rpc_server, "*") in the beginning of the target scope. +pw_rpc_server = { + sources = [ + "${chip_root}/examples/common/pigweed/RpcService.cpp", + "${chip_root}/examples/common/pigweed/nxp/PigweedLoggerMutex.cpp", + "${nxp_platform_dir}/PigweedLogger.cpp", + "${nxp_platform_dir}/Rpc.cpp", + ] + + include_dirs = [ + "${chip_root}/examples/common", + "${chip_root}/examples/common/pigweed", + "${chip_root}/examples/common/pigweed/nxp", + "${nxp_platform_dir}", + ] + + defines = [ + "PW_RPC_ENABLED", + "PW_RPC_ATTRIBUTE_SERVICE=1", + "PW_RPC_BUTTON_SERVICE=1", + "PW_RPC_DEVICE_SERVICE=1", + "PW_RPC_LIGHTING_SERVICE=1", + ] + + deps = [ + "$dir_pw_hdlc:rpc_channel_output", + "$dir_pw_stream:sys_io_stream", + "$dir_pw_trace", + "${chip_root}/config/nxp/lib/pw_rpc:pw_rpc", + "${chip_root}/examples/common/pigweed:attributes_service.nanopb_rpc", + "${chip_root}/examples/common/pigweed:button_service.nanopb_rpc", + "${chip_root}/examples/common/pigweed:device_service.nanopb_rpc", + "${chip_root}/examples/common/pigweed:lighting_service.nanopb_rpc", + "${nxp_platform_dir}/pw_sys_io:pw_sys_io_nxp", + ] + deps += pw_build_LINK_DEPS +} diff --git a/examples/platform/nxp/pw_sys_io/BUILD.gn b/examples/platform/nxp/pw_sys_io/BUILD.gn new file mode 100644 index 00000000000000..ed3d35246093f1 --- /dev/null +++ b/examples/platform/nxp/pw_sys_io/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright (c) 2023 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("//build_overrides/pigweed.gni") + +import("$dir_pw_build/target_types.gni") +import("${chip_root}/src/platform/device.gni") + +config("default_config") { + include_dirs = [ + "public", + "${chip_root}/src/", + ] +} + +pw_source_set("pw_sys_io_nxp") { + sources = [ + "${chip_root}/src/lib/shell/streamer_nxp.cpp", + "sys_io_nxp.cc", + ] + + deps = [ + "$dir_pw_sys_io:default_putget_bytes", + "$dir_pw_sys_io:facade", + "${nxp_sdk_build_root}/${nxp_sdk_name}:nxp_sdk", + ] + + public_configs = [ ":default_config" ] +} diff --git a/examples/platform/nxp/pw_sys_io/public/pw_sys_io_nxp/init.h b/examples/platform/nxp/pw_sys_io/public/pw_sys_io_nxp/init.h new file mode 100644 index 00000000000000..47d18772638d5f --- /dev/null +++ b/examples/platform/nxp/pw_sys_io/public/pw_sys_io_nxp/init.h @@ -0,0 +1,27 @@ +/* + * + * Copyright (c) 2023 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 "pw_preprocessor/util.h" + +PW_EXTERN_C_START + +// The actual implement of PreMainInit() in sys_io_BACKEND. +void pw_sys_io_Init(); + +PW_EXTERN_C_END diff --git a/examples/platform/nxp/pw_sys_io/sys_io_nxp.cc b/examples/platform/nxp/pw_sys_io/sys_io_nxp.cc new file mode 100644 index 00000000000000..8e729f0986bbb3 --- /dev/null +++ b/examples/platform/nxp/pw_sys_io/sys_io_nxp.cc @@ -0,0 +1,78 @@ +/* + * + * Copyright (c) 2023 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 + +#include +#include +#include +#include + +#include + +int16_t console_getchar(char * chr) +{ + auto * streamer = chip::Shell::streamer_get(); + return static_cast(streamer->read_cb(nullptr, chr, 1)); +} + +int16_t console_putchar(const char * chr) +{ + auto * streamer = chip::Shell::streamer_get(); + return static_cast(streamer->write_cb(nullptr, chr, 1)); +} + +extern "C" void pw_sys_io_Init() +{ + auto * streamer = chip::Shell::streamer_get(); + streamer->init_cb(nullptr); +} + +namespace pw::sys_io { + +Status ReadByte(std::byte * dest) +{ + if (!dest) + return Status::InvalidArgument(); + + int16_t ret = console_getchar(reinterpret_cast(dest)); + return ret < 0 ? Status::FailedPrecondition() : OkStatus(); +} + +Status WriteByte(std::byte b) +{ + int16_t ret = console_putchar(reinterpret_cast(&b)); + return ret < 0 ? Status::FailedPrecondition() : OkStatus(); +} + +// Writes a string using pw::sys_io, and add newline characters at the end. +StatusWithSize WriteLine(const std::string_view & s) +{ + size_t chars_written = 0; + StatusWithSize result = WriteBytes(pw::as_bytes(pw::span(s))); + if (!result.ok()) + { + return result; + } + chars_written += result.size(); + result = WriteBytes(pw::as_bytes(pw::span("\r\n", 2))); + chars_written += result.size(); + + return StatusWithSize(result.status(), chars_written); +} + +} // namespace pw::sys_io diff --git a/scripts/tools/nxp/factory_data_generator/custom.py b/scripts/tools/nxp/factory_data_generator/custom.py index 13b1a34fc98c12..e2f7584e2d7fa2 100644 --- a/scripts/tools/nxp/factory_data_generator/custom.py +++ b/scripts/tools/nxp/factory_data_generator/custom.py @@ -96,11 +96,14 @@ def encode(self): assert (self.private_key is not None) return self.private_key - def generate_private_key(self, password): - keys = load_der_private_key(self.val, password, backend=default_backend()) - self.private_key = keys.private_numbers().private_value.to_bytes( - 32, byteorder='big' - ) + def generate_private_key(self, password, use_sss_blob=False): + if use_sss_blob: + self.private_key = self.val + else: + keys = load_der_private_key(self.val, password, backend=default_backend()) + self.private_key = keys.private_numbers().private_value.to_bytes( + 32, byteorder='big' + ) class DacCert(FileArgument): diff --git a/scripts/tools/nxp/factory_data_generator/generate.py b/scripts/tools/nxp/factory_data_generator/generate.py index a203ac9dee749e..1fb7d91edeedaf 100755 --- a/scripts/tools/nxp/factory_data_generator/generate.py +++ b/scripts/tools/nxp/factory_data_generator/generate.py @@ -78,7 +78,7 @@ def __init__(self, args): self.spake2p = Spake2p() if self.args.spake2p_verifier is None: self.spake2p.generate(self.args) - self.args.dac_key.generate_private_key(self.args.dac_key_password) + self.args.dac_key.generate_private_key(self.args.dac_key_password, self.args.dac_key_use_sss_blob) def _validate_args(self): if self.args.dac_key_password is None: @@ -217,6 +217,8 @@ def main(): optional.add_argument("--dac_key_password", type=str, help="[path] Password to decode DAC Key if available") + optional.add_argument("--dac_key_use_sss_blob", action='store_true', + help="[bool] If present, DAC private key area is populated by an encrypted blob") optional.add_argument("--spake2p_verifier", type=Verifier, help="[base64 str] Already generated spake2p verifier") optional.add_argument("--aes128_key", diff --git a/scripts/tools/nxp/factory_data_generator/k32w1/example_convert_dac_private_key.jlink b/scripts/tools/nxp/factory_data_generator/k32w1/example_convert_dac_private_key.jlink new file mode 100644 index 00000000000000..d31c1370933ace --- /dev/null +++ b/scripts/tools/nxp/factory_data_generator/k32w1/example_convert_dac_private_key.jlink @@ -0,0 +1,16 @@ +reset +halt +// Factory data size is one internal flash sector (8K). +// Factory data address is retrieved from the map file. +erase 0xec000 0xee000 noreset +// Load factory data and conversion application, then +// wait for 10 seconds and load the "real" application. +loadfile factory_data.bin 0xec000 +loadfile chip-k32w1-light-example-before-conversion.srec +reset +go +Sleep 10000 +loadfile chip-k32w1-light-example-after-conversion.srec +reset +go +quit \ No newline at end of file diff --git a/src/lib/shell/streamer_nxp.cpp b/src/lib/shell/streamer_nxp.cpp index b499b40c0f72e8..aed4796902942a 100644 --- a/src/lib/shell/streamer_nxp.cpp +++ b/src/lib/shell/streamer_nxp.cpp @@ -25,7 +25,6 @@ /* Includes */ /* -------------------------------------------------------------------------- */ -#include #include #include @@ -65,6 +64,25 @@ #endif #endif +// pw RPC uses UART DMA by default +#ifdef PW_RPC_ENABLED +#define CONSUMER_TASK_HANDLE RpcTaskHandle +#ifndef STREAMER_UART_USE_DMA +#define STREAMER_UART_USE_DMA 1 +#endif +#else +#define CONSUMER_TASK_HANDLE AppMatterCliTaskHandle +#ifndef STREAMER_UART_USE_DMA +#define STREAMER_UART_USE_DMA 0 +#endif +#endif // PW_RPC_ENABLED + +#if STREAMER_UART_USE_DMA +typedef serial_port_uart_dma_config_t streamer_serial_port_uart_config_t; +#else +typedef serial_port_uart_config_t streamer_serial_port_uart_config_t; +#endif + /* -------------------------------------------------------------------------- */ /* Private prototypes */ /* -------------------------------------------------------------------------- */ @@ -82,23 +100,33 @@ static SERIAL_MANAGER_READ_HANDLE_DEFINE(streamerSerialReadHandle); static volatile int txCount = 0; static bool readDone = true; -static serial_port_uart_config_t uartConfig = { .clockRate = BOARD_APP_UART_CLK_FREQ, - .baudRate = BOARD_DEBUG_UART_BAUDRATE, - .parityMode = kSerialManager_UartParityDisabled, - .stopBitCount = kSerialManager_UartOneStopBit, - .enableRx = 1, - .enableTx = 1, - .enableRxRTS = 0, - .enableTxCTS = 0, - .instance = BOARD_APP_UART_INSTANCE }; +static streamer_serial_port_uart_config_t uartConfig = { .clockRate = BOARD_APP_UART_CLK_FREQ, + .baudRate = BOARD_DEBUG_UART_BAUDRATE, + .parityMode = kSerialManager_UartParityDisabled, + .stopBitCount = kSerialManager_UartOneStopBit, + .enableRx = 1, + .enableTx = 1, + .enableRxRTS = 0, + .enableTxCTS = 0, + .instance = BOARD_APP_UART_INSTANCE, +#if STREAMER_UART_USE_DMA + .dma_instance = 0, + .rx_channel = 1, + .tx_channel = 0 +#endif +}; static uint8_t s_ringBuffer[STREAMER_UART_SERIAL_MANAGER_RING_BUFFER_SIZE]; static const serial_manager_config_t s_serialManagerConfig = { .ringBuffer = &s_ringBuffer[0], .ringBufferSize = STREAMER_UART_SERIAL_MANAGER_RING_BUFFER_SIZE, - .type = BOARD_DEBUG_UART_TYPE, - .blockType = kSerialManager_NonBlocking, - .portConfig = (serial_port_uart_config_t *) &uartConfig, +#if STREAMER_UART_USE_DMA + .type = kSerialPort_UartDma, +#else + .type = BOARD_DEBUG_UART_TYPE, +#endif + .blockType = kSerialManager_NonBlocking, + .portConfig = (serial_port_uart_config_t *) &uartConfig, }; /* -------------------------------------------------------------------------- */ @@ -107,7 +135,6 @@ static const serial_manager_config_t s_serialManagerConfig = { namespace chip { namespace Shell { -namespace { int streamer_nxp_init(streamer_t * streamer) { @@ -119,7 +146,12 @@ int streamer_nxp_init(streamer_t * streamer) BOARD_CLIAttachClk(); #endif - uartConfig.clockRate = BOARD_APP_UART_CLK_FREQ; +#if STREAMER_UART_USE_DMA + dma_channel_mux_configure_t dma_channel_mux; + dma_channel_mux.dma_dmamux_configure.dma_tx_channel_mux = kDmaRequestLPUART1Tx; + dma_channel_mux.dma_dmamux_configure.dma_rx_channel_mux = kDmaRequestLPUART1Rx; + uartConfig.dma_channel_mux_configure = &dma_channel_mux; +#endif /* * Make sure to disable interrupts while initializating the serial manager interface @@ -192,8 +224,8 @@ ssize_t streamer_nxp_write(streamer_t * streamer, const char * buffer, size_t le intMask = DisableGlobalIRQ(); txCount++; - status = - SerialManager_WriteNonBlocking((serial_write_handle_t) streamerSerialWriteHandle, (uint8_t *) buffer, (uint32_t) length); + status = SerialManager_WriteNonBlocking((serial_write_handle_t) streamerSerialWriteHandle, + (uint8_t *) (const_cast(buffer)), (uint32_t) length); EnableGlobalIRQ(intMask); if (status == kStatus_SerialManager_Success) { @@ -214,7 +246,6 @@ static streamer_t streamer_nxp = { .read_cb = streamer_nxp_read, .write_cb = streamer_nxp_write, }; -} // namespace streamer_t * streamer_get(void) { @@ -227,13 +258,14 @@ streamer_t * streamer_get(void) /* -------------------------------------------------------------------------- */ /* Private functions */ /* -------------------------------------------------------------------------- */ -extern TaskHandle_t AppMatterCliTaskHandle; +extern TaskHandle_t CONSUMER_TASK_HANDLE; + static void Uart_RxCallBack(void * pData, serial_manager_callback_message_t * message, serial_manager_status_t status) { - if (AppMatterCliTaskHandle != NULL) + if (CONSUMER_TASK_HANDLE != NULL) { /* notify the main loop that a RX buffer is available */ - xTaskNotifyGive(AppMatterCliTaskHandle); + xTaskNotifyGive(CONSUMER_TASK_HANDLE); } } diff --git a/src/lwip/BUILD.gn b/src/lwip/BUILD.gn index 755b3049174f7c..c51383a944dc80 100644 --- a/src/lwip/BUILD.gn +++ b/src/lwip/BUILD.gn @@ -30,12 +30,12 @@ if (lwip_platform == "") { assert(lwip_platform == "external" || lwip_platform == "standalone" || lwip_platform == "cc13xx_26xx" || lwip_platform == "cc32xx" || lwip_platform == "nxp" || lwip_platform == "silabs" || - lwip_platform == "k32w0" || lwip_platform == "k32w1" || - lwip_platform == "qpg" || lwip_platform == "mbed" || - lwip_platform == "psoc6" || lwip_platform == "cyw30739" || - lwip_platform == "bl602" || lwip_platform == "mw320" || - lwip_platform == "bl702" || lwip_platform == "bl702l" || - lwip_platform == "mt793x" || lwip_platform == "asr", + lwip_platform == "k32w0" || lwip_platform == "qpg" || + lwip_platform == "mbed" || lwip_platform == "psoc6" || + lwip_platform == "cyw30739" || lwip_platform == "bl602" || + lwip_platform == "mw320" || lwip_platform == "bl702" || + lwip_platform == "bl702l" || lwip_platform == "mt793x" || + lwip_platform == "asr", "Unsupported lwIP platform: ${lwip_platform}") if (lwip_platform != "external") { @@ -56,8 +56,6 @@ if (lwip_platform == "cc13xx_26xx") { import("${qpg_sdk_build_root}/qpg_sdk.gni") } else if (lwip_platform == "k32w0") { import("//build_overrides/k32w0_sdk.gni") -} else if (lwip_platform == "k32w1") { - import("//build_overrides/k32w1_sdk.gni") } else if (lwip_platform == "psoc6") { import("//build_overrides/psoc6.gni") } else if (lwip_platform == "cyw30739") { @@ -235,8 +233,6 @@ if (current_os == "zephyr" || current_os == "mbed") { public_deps += [ "${chip_root}/src/lib/support" ] } else if (lwip_platform == "k32w0") { public_deps += [ "${k32w0_sdk_build_root}:k32w0_sdk" ] - } else if (lwip_platform == "k32w1") { - public_deps += [ "${k32w1_sdk_build_root}:k32w1_sdk" ] } else if (lwip_platform == "cyw30739") { public_deps += [ "${cyw30739_sdk_build_root}:cyw30739_sdk" ] } else if (lwip_platform == "bl702") { diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn index c6b1aae23ee40f..3c1f56da771786 100644 --- a/src/platform/BUILD.gn +++ b/src/platform/BUILD.gn @@ -214,9 +214,6 @@ if (chip_device_platform != "none" && chip_device_platform != "external") { } else if (chip_device_platform == "k32w0") { device_layer_target_define = "K32W" defines += [ "CHIP_DEVICE_LAYER_TARGET=nxp/k32w/k32w0" ] - } else if (chip_device_platform == "k32w1") { - device_layer_target_define = "K32W" - defines += [ "CHIP_DEVICE_LAYER_TARGET=nxp/k32w/k32w1" ] } else if (chip_device_platform == "nxp") { import("//build_overrides/nxp_sdk.gni") import("${nxp_sdk_build_root}/nxp_sdk.gni") @@ -537,8 +534,6 @@ if (chip_device_platform != "none") { _platform_target = "ESP32" } else if (chip_device_platform == "k32w0") { _platform_target = "nxp/k32w/k32w0" - } else if (chip_device_platform == "k32w1") { - _platform_target = "nxp/k32w/k32w1" } else if (chip_device_platform == "linux") { _platform_target = "Linux" } else if (chip_device_platform == "nrfconnect") { @@ -546,7 +541,7 @@ if (chip_device_platform != "none") { } else if (chip_device_platform == "qpg") { _platform_target = "qpg" } else if (chip_device_platform == "nxp") { - _platform_target = "nxp" + _platform_target = "nxp/${nxp_platform}:nxp_platform" } else if (chip_device_platform == "nxp_zephyr") { _platform_target = "nxp/zephyr:nxp_zephyr" } else if (chip_device_platform == "telink") { diff --git a/src/platform/device.gni b/src/platform/device.gni index aa81c50e4a5fcc..933b730186ec85 100644 --- a/src/platform/device.gni +++ b/src/platform/device.gni @@ -16,7 +16,7 @@ import("//build_overrides/chip.gni") import("${chip_root}/src/ble/ble.gni") declare_args() { - # Device platform layer: cc13x2_26x2, cc13x4_26x4, cc32xx, darwin, efr32, esp32, external, freertos, linux, nrfconnect, k32w0, k32w1, qpg, tizen, cyw30739, bl602, mw320, zephyr, beken, openiotsdk, none. + # Device platform layer: cc13x2_26x2, cc13x4_26x4, cc32xx, darwin, efr32, esp32, external, freertos, linux, nrfconnect, k32w0, nxp, qpg, tizen, cyw30739, bl602, mw320, zephyr, beken, openiotsdk, none. chip_device_platform = "auto" chip_platform_target = "" @@ -51,9 +51,8 @@ declare_args() { chip_device_platform == "linux" || chip_device_platform == "qpg" || chip_device_platform == "cc13x2_26x2" || chip_device_platform == "cc13x4_26x4" || - chip_device_platform == "k32w0" || chip_device_platform == "k32w1" || - chip_device_platform == "tizen" || chip_device_platform == "stm32" || - chip_device_platform == "webos" + chip_device_platform == "k32w0" || chip_device_platform == "tizen" || + chip_device_platform == "stm32" || chip_device_platform == "webos" } declare_args() { @@ -152,8 +151,6 @@ if (chip_device_platform == "cc13x2_26x2") { _chip_device_layer = "qpg" } else if (chip_device_platform == "k32w0") { _chip_device_layer = "nxp/k32w/k32w0" -} else if (chip_device_platform == "k32w1") { - _chip_device_layer = "nxp/k32w/k32w1" } else if (chip_device_platform == "nxp") { import("//build_overrides/nxp_sdk.gni") import("${nxp_sdk_build_root}/nxp_sdk.gni") @@ -255,7 +252,7 @@ assert( chip_device_platform == "external" || chip_device_platform == "linux" || chip_device_platform == "tizen" || chip_device_platform == "nrfconnect" || chip_device_platform == "nxp" || - chip_device_platform == "k32w0" || chip_device_platform == "k32w1" || + chip_device_platform == "k32w0" || chip_device_platform == "nxp_zephyr" || chip_device_platform == "qpg" || chip_device_platform == "telink" || chip_device_platform == "mbed" || chip_device_platform == "psoc6" || chip_device_platform == "android" || diff --git a/src/platform/nxp/k32w/common/BLEManagerCommon.cpp b/src/platform/nxp/k32w/common/BLEManagerCommon.cpp index d6aa5f2e939251..40f9bc5c7d7abf 100644 --- a/src/platform/nxp/k32w/common/BLEManagerCommon.cpp +++ b/src/platform/nxp/k32w/common/BLEManagerCommon.cpp @@ -949,7 +949,7 @@ void BLEManagerCommon::HandleConnectionCloseEvent(blekw_msg_t * msg) mDeviceConnected = false; ChipDeviceEvent event; - event.Type = DeviceEventType::kCHIPoBLEConnectionError; + event.Type = DeviceEventType::kCHIPoBLEConnectionClosed; event.CHIPoBLEConnectionError.ConId = deviceId; event.CHIPoBLEConnectionError.Reason = BLE_ERROR_REMOTE_DEVICE_DISCONNECTED; diff --git a/src/platform/nxp/k32w/common/BLEManagerCommon.h b/src/platform/nxp/k32w/common/BLEManagerCommon.h index 32ccdd762cdea4..628d9b5324aa46 100644 --- a/src/platform/nxp/k32w/common/BLEManagerCommon.h +++ b/src/platform/nxp/k32w/common/BLEManagerCommon.h @@ -233,6 +233,7 @@ class BLEManagerCommon : public BLEManager, protected BleLayer, private BlePlatf 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; diff --git a/src/platform/nxp/k32w/common/OTAImageProcessorImpl.cpp b/src/platform/nxp/k32w/common/OTAImageProcessorImpl.cpp index 946c0c37f83d87..591d082ea992f7 100644 --- a/src/platform/nxp/k32w/common/OTAImageProcessorImpl.cpp +++ b/src/platform/nxp/k32w/common/OTAImageProcessorImpl.cpp @@ -308,7 +308,7 @@ CHIP_ERROR OTAImageProcessorImpl::ConfirmCurrentImage() CHIP_ERROR OTAImageProcessorImpl::SetBlock(ByteSpan & block) { - if (block.empty()) + if (!IsSpanUsable(block)) { return CHIP_NO_ERROR; } diff --git a/src/platform/nxp/k32w/common/OTATlvProcessor.h b/src/platform/nxp/k32w/common/OTATlvProcessor.h index 13a2df115d90d9..65d1d68830f2b8 100644 --- a/src/platform/nxp/k32w/common/OTATlvProcessor.h +++ b/src/platform/nxp/k32w/common/OTATlvProcessor.h @@ -43,10 +43,10 @@ namespace chip { #define CHIP_OTA_PROCESSOR_START_IMAGE CHIP_ERROR_TLV_PROCESSOR(0x0E) // Descriptor constants -inline constexpr size_t kVersionStringSize = 64; -inline constexpr size_t kBuildDateSize = 64; +constexpr size_t kVersionStringSize = 64; +constexpr size_t kBuildDateSize = 64; -inline constexpr uint16_t requestedOtaMaxBlockSize = 1024; +constexpr uint16_t requestedOtaMaxBlockSize = 1024; /** * Used alongside RegisterDescriptorCallback to register diff --git a/src/platform/nxp/k32w/k32w0/CHIPDevicePlatformConfig.h b/src/platform/nxp/k32w/k32w0/CHIPDevicePlatformConfig.h index 0c849ccc4989aa..a584e0c79afbbb 100644 --- a/src/platform/nxp/k32w/k32w0/CHIPDevicePlatformConfig.h +++ b/src/platform/nxp/k32w/k32w0/CHIPDevicePlatformConfig.h @@ -47,6 +47,8 @@ #define CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID_LENGTH 32 #endif +#define CHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER + // ========== Platform-specific Configuration ========= // These are configuration options that are unique to the K32W platform. diff --git a/src/platform/nxp/k32w/k32w1/BLEManagerImpl.cpp b/src/platform/nxp/k32w/k32w1/BLEManagerImpl.cpp index 95a69b717c4af0..88d5c00400193c 100644 --- a/src/platform/nxp/k32w/k32w1/BLEManagerImpl.cpp +++ b/src/platform/nxp/k32w/k32w1/BLEManagerImpl.cpp @@ -30,6 +30,8 @@ OSA_EVENT_HANDLE_DEFINE(gHost_TaskEvent); #include +extern "C" bleResult_t Hci_Reset(void); + namespace chip { namespace DeviceLayer { namespace Internal { @@ -45,6 +47,8 @@ CHIP_ERROR BLEManagerImpl::InitHostController(BLECallbackDelegate::GapGenericCal { CHIP_ERROR err = CHIP_NO_ERROR; + VerifyOrExit(PLATFORM_InitTimerManager() >= 0, err = CHIP_ERROR_INCORRECT_STATE); + PLATFORM_InitBle(); (void) RNG_Init(); @@ -73,6 +77,21 @@ CHIP_ERROR BLEManagerImpl::InitHostController(BLECallbackDelegate::GapGenericCal return err; } +CHIP_ERROR BLEManagerImpl::ResetController() +{ + bleResult_t res = Hci_Reset(); + if (res != gBleSuccess_c) + { + ChipLogProgress(DeviceLayer, "Failed to reset controller %d", res); + return CHIP_ERROR_INTERNAL; + } + + /* Wait for function to complete */ + PLATFORM_Delay(HCI_RESET_WAIT_TIME_US); + + return CHIP_NO_ERROR; +} + void BLEManagerImpl::Host_Task(osaTaskParam_t argument) { Host_TaskHandler((void *) NULL); diff --git a/src/platform/nxp/k32w/k32w1/BLEManagerImpl.h b/src/platform/nxp/k32w/k32w1/BLEManagerImpl.h index bef927c8275350..59bda33db0051f 100644 --- a/src/platform/nxp/k32w/k32w1/BLEManagerImpl.h +++ b/src/platform/nxp/k32w/k32w1/BLEManagerImpl.h @@ -23,6 +23,7 @@ #include "RNG_Interface.h" #include "fwk_messaging.h" #include "fwk_os_abs.h" +#include "fwk_platform.h" #include "fwk_platform_ble.h" #include "hci_transport.h" @@ -36,6 +37,10 @@ #define HOST_TASK_PRIORITY (4U) #define HOST_TASK_STACK_SIZE (gHost_TaskStackSize_c / sizeof(StackType_t)) +#ifndef HCI_RESET_WAIT_TIME_US +#define HCI_RESET_WAIT_TIME_US 30000 +#endif + namespace chip { namespace DeviceLayer { namespace Internal { @@ -51,6 +56,7 @@ class BLEManagerImpl final : public BLEManagerCommon CHIP_ERROR InitHostController(BLECallbackDelegate::GapGenericCallback cb_fp) override; BLEManagerCommon * GetImplInstance() override; + CHIP_ERROR ResetController() override; private: static BLEManagerImpl sInstance; diff --git a/src/platform/nxp/k32w/k32w1/BUILD.gn b/src/platform/nxp/k32w/k32w1/BUILD.gn index 8ad11928178bb7..bb3e74dc034527 100644 --- a/src/platform/nxp/k32w/k32w1/BUILD.gn +++ b/src/platform/nxp/k32w/k32w1/BUILD.gn @@ -13,12 +13,13 @@ # limitations under the License. import("//build_overrides/chip.gni") -import("//build_overrides/k32w1_sdk.gni") +import("//build_overrides/nxp_sdk.gni") import("${chip_root}/src/crypto/crypto.gni") import("${chip_root}/src/platform/device.gni") -import("${k32w1_sdk_build_root}/k32w1_sdk.gni") +import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") -assert(chip_device_platform == "k32w1") +assert(chip_device_platform == "nxp") +assert(nxp_platform == "k32w/k32w1") if (chip_enable_openthread) { import("//build_overrides/openthread.gni") @@ -28,7 +29,7 @@ if (chip_crypto == "platform") { import("//build_overrides/mbedtls.gni") } -static_library("k32w1") { +static_library("nxp_platform") { sources = [ "../../../SingletonConfigurationManager.cpp", "../common/BLEManagerCommon.cpp", @@ -58,7 +59,15 @@ static_library("k32w1") { "ram_storage.h", ] - public = [ "${chip_root}/src/platform/nxp/k32w/k32w1/BLEManagerImpl.h" ] + public = [ + "${chip_root}/src/credentials/DeviceAttestationCredsProvider.h", + "${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/k32w1/BLEManagerImpl.h", + "${chip_root}/src/platform/nxp/k32w/k32w1/BLEManagerImpl.h", + "${chip_root}/src/platform/nxp/k32w/k32w1/SMU2Manager.h", + ] public_deps = [ "${chip_root}/src/platform:platform_base" ] @@ -87,10 +96,25 @@ static_library("k32w1") { "K32W1PersistentStorageOpKeystore.h", ] + if (chip_with_factory_data == 1) { + sources += [ + "../common/FactoryDataProvider.cpp", + "FactoryDataProviderImpl.cpp", + ] + public += [ + "${chip_root}/src/credentials/CHIPCert.h", + "${chip_root}/src/credentials/CertificationDeclaration.h", + ] + + if (chip_convert_dac_private_key == 1) { + defines = [ "CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY=1" ] + } + } + public_deps += [ "${mbedtls_root}:mbedtls" ] } - deps = [ "${chip_root}/src/platform/logging:headers" ] + deps = [] if (chip_enable_openthread) { sources += [ @@ -107,7 +131,17 @@ static_library("k32w1") { ] deps += [ "${chip_root}/src/lib/dnssd:platform_header" ] } + + if (use_smu2_dynamic) { + sources += [ + "SMU2Manager.cpp", + "SMU2Manager.h", + ] + } } - public_deps += [ "${chip_root}/src/crypto" ] + public_deps += [ + "${chip_root}/src/crypto", + "${chip_root}/src/platform/logging:headers", + ] } diff --git a/src/platform/nxp/k32w/k32w1/CHIPCryptoPalK32W1.cpp b/src/platform/nxp/k32w/k32w1/CHIPCryptoPalK32W1.cpp index f10198b9b955c3..5eab6bb0c8c706 100644 --- a/src/platform/nxp/k32w/k32w1/CHIPCryptoPalK32W1.cpp +++ b/src/platform/nxp/k32w/k32w1/CHIPCryptoPalK32W1.cpp @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -55,8 +54,10 @@ #include -#include "SecLib_ecp256.h" #include "sss_crypto.h" +extern "C" { +#include "SecLib.h" +} namespace chip { namespace Crypto { @@ -82,10 +83,10 @@ typedef struct bool mInitialized; bool mDRBGSeeded; mbedtls_ctr_drbg_context mDRBGCtxt; - mbedtls_entropy_context mEntropy; -} EntropyContext; + entropy_source fn_source; +} DRBGContext; -static EntropyContext gsEntropyContext; +static DRBGContext gsDrbgContext; static void _log_mbedTLS_error(int error_code) { @@ -141,19 +142,32 @@ CHIP_ERROR AES_CCM_encrypt(const uint8_t * plaintext, size_t plaintext_length, c { VerifyOrExit(aad != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT); } - - // Size of key is expressed in bits, hence the multiplication by 8. - result = mbedtls_ccm_setkey(&context, MBEDTLS_CIPHER_ID_AES, key.As(), - sizeof(Symmetric128BitsKeyByteArray) * 8); - VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL); - - // Encrypt - result = mbedtls_ccm_encrypt_and_tag(&context, plaintext_length, Uint8::to_const_uchar(nonce), nonce_length, - Uint8::to_const_uchar(aad), aad_length, Uint8::to_const_uchar(plaintext), - Uint8::to_uchar(ciphertext), Uint8::to_uchar(tag), tag_length); - _log_mbedTLS_error(result); - VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL); - +#if defined(USE_HW_AES) + if (!aad_length) + { +#endif + // Size of key is expressed in bits, hence the multiplication by 8. + result = mbedtls_ccm_setkey(&context, MBEDTLS_CIPHER_ID_AES, key.As(), + sizeof(Symmetric128BitsKeyByteArray) * 8); + VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL); + + // Encrypt + result = mbedtls_ccm_encrypt_and_tag(&context, plaintext_length, Uint8::to_const_uchar(nonce), nonce_length, + Uint8::to_const_uchar(aad), aad_length, Uint8::to_const_uchar(plaintext), + Uint8::to_uchar(ciphertext), Uint8::to_uchar(tag), tag_length); + _log_mbedTLS_error(result); + VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL); +#if defined(USE_HW_AES) + } + else + { + // Encrypt + result = AES_128_CCM(Uint8::to_const_uchar(plaintext), plaintext_length, Uint8::to_const_uchar(aad), aad_length, + Uint8::to_const_uchar(nonce), nonce_length, key.As(), ciphertext, tag, + tag_length, gSecLib_CCM_Encrypt_c); + VerifyOrExit(result == kStatus_Success, error = CHIP_ERROR_INTERNAL); + } +#endif exit: mbedtls_ccm_free(&context); return error; @@ -179,19 +193,32 @@ CHIP_ERROR AES_CCM_decrypt(const uint8_t * ciphertext, size_t ciphertext_len, co { VerifyOrExit(aad != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT); } - - // Size of key is expressed in bits, hence the multiplication by 8. - result = mbedtls_ccm_setkey(&context, MBEDTLS_CIPHER_ID_AES, key.As(), - sizeof(Symmetric128BitsKeyByteArray) * 8); - VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL); - - // Decrypt - result = mbedtls_ccm_auth_decrypt(&context, ciphertext_len, Uint8::to_const_uchar(nonce), nonce_length, - Uint8::to_const_uchar(aad), aad_len, Uint8::to_const_uchar(ciphertext), - Uint8::to_uchar(plaintext), Uint8::to_const_uchar(tag), tag_length); - _log_mbedTLS_error(result); - VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL); - +#if defined(USE_HW_AES) + if (!aad_len) + { +#endif + // Size of key is expressed in bits, hence the multiplication by 8. + result = mbedtls_ccm_setkey(&context, MBEDTLS_CIPHER_ID_AES, key.As(), + sizeof(Symmetric128BitsKeyByteArray) * 8); + VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL); + + // Decrypt + result = mbedtls_ccm_auth_decrypt(&context, ciphertext_len, Uint8::to_const_uchar(nonce), nonce_length, + Uint8::to_const_uchar(aad), aad_len, Uint8::to_const_uchar(ciphertext), + Uint8::to_uchar(plaintext), Uint8::to_const_uchar(tag), tag_length); + _log_mbedTLS_error(result); + VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL); +#if defined(USE_HW_AES) + } + else + { + // Decrypt + result = AES_128_CCM(Uint8::to_const_uchar(ciphertext), ciphertext_len, Uint8::to_const_uchar(aad), aad_len, + Uint8::to_const_uchar(nonce), nonce_length, key.As(), plaintext, + (uint8_t *) tag, tag_length, gSecLib_CCM_Decrypt_c); + VerifyOrExit(result == kStatus_Success, error = CHIP_ERROR_INTERNAL); + } +#endif exit: mbedtls_ccm_free(&context); return error; @@ -203,6 +230,9 @@ CHIP_ERROR Hash_SHA256(const uint8_t * data, const size_t data_length, uint8_t * VerifyOrReturnError(data != nullptr, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(out_buffer != nullptr, CHIP_ERROR_INVALID_ARGUMENT); +#if defined(USE_HW_SHA256) + SHA256_Hash(Uint8::to_const_uchar(data), data_length, Uint8::to_uchar(out_buffer)); +#else #if (MBEDTLS_VERSION_NUMBER >= 0x03000000) const int result = mbedtls_sha256(Uint8::to_const_uchar(data), data_length, Uint8::to_uchar(out_buffer), 0); #else @@ -210,6 +240,7 @@ CHIP_ERROR Hash_SHA256(const uint8_t * data, const size_t data_length, uint8_t * #endif VerifyOrReturnError(result == 0, CHIP_ERROR_INTERNAL); +#endif return CHIP_NO_ERROR; } @@ -230,6 +261,36 @@ CHIP_ERROR Hash_SHA1(const uint8_t * data, const size_t data_length, uint8_t * o return CHIP_NO_ERROR; } +#if defined(USE_HW_SHA256) +/* + * These structures are used to save the intermediate + * non-hashed data on heap (in a linked list) + * and compute the hash on demand. + * This solution bypases the sha256 context save/restore + * S200 limitation. + * */ +typedef struct sha256_node +{ + uint8_t * data; + uint16_t size; + sha256_node * next; +} sha256_node; + +typedef struct S200_context +{ + void * sss_context; + sha256_node * head; + sha256_node * tail; +} S200_context; + +static_assert(kMAX_Hash_SHA256_Context_Size >= sizeof(S200_context), + "kMAX_Hash_SHA256_Context_Size is too small for the size of underlying mbedtls_sha256_context"); + +static inline S200_context * to_inner_hash_sha256_context(HashSHA256OpaqueContext * context) +{ + return SafePointerCast(context); +} +#else static_assert(kMAX_Hash_SHA256_Context_Size >= sizeof(mbedtls_sha256_context), "kMAX_Hash_SHA256_Context_Size is too small for the size of underlying mbedtls_sha256_context"); @@ -237,52 +298,120 @@ static inline mbedtls_sha256_context * to_inner_hash_sha256_context(HashSHA256Op { return SafePointerCast(context); } +#endif Hash_SHA256_stream::Hash_SHA256_stream(void) { +#if defined(USE_HW_SHA256) + S200_context * context = to_inner_hash_sha256_context(&mContext); + + context->sss_context = nullptr; + context->head = nullptr; + context->tail = nullptr; +#else mbedtls_sha256_context * context = to_inner_hash_sha256_context(&mContext); mbedtls_sha256_init(context); +#endif } Hash_SHA256_stream::~Hash_SHA256_stream(void) { +#if defined(USE_HW_SHA256) + S200_context * context = to_inner_hash_sha256_context(&mContext); + + context->sss_context = nullptr; + context->head = nullptr; + context->tail = nullptr; +#else mbedtls_sha256_context * context = to_inner_hash_sha256_context(&mContext); mbedtls_sha256_free(context); +#endif Clear(); } CHIP_ERROR Hash_SHA256_stream::Begin(void) { +#if defined(USE_HW_SHA256) + S200_context * context = to_inner_hash_sha256_context(&mContext); + context->sss_context = SHA256_AllocCtx(); + + SHA256_Init(context->sss_context); +#else mbedtls_sha256_context * const context = to_inner_hash_sha256_context(&mContext); #if (MBEDTLS_VERSION_NUMBER >= 0x03000000) - const int result = mbedtls_sha256_starts(context, 0); + const int result = mbedtls_sha256_starts(context, 0); #else const int result = mbedtls_sha256_starts_ret(context, 0); #endif VerifyOrReturnError(result == 0, CHIP_ERROR_INTERNAL); +#endif return CHIP_NO_ERROR; } CHIP_ERROR Hash_SHA256_stream::AddData(const ByteSpan data) { +#if defined(USE_HW_SHA256) + S200_context * context = to_inner_hash_sha256_context(&mContext); + sha256_node * node = nullptr; + + VerifyOrReturnError(context->sss_context != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + + SHA256_HashUpdate(context->sss_context, Uint8::to_const_uchar(data.data()), data.size()); + + node = (sha256_node *) malloc(sizeof(sha256_node)); + node->size = data.size(); + node->data = (uint8_t *) malloc(data.size()); + node->next = nullptr; + memcpy(node->data, Uint8::to_const_uchar(data.data()), node->size); + + if (context->head == nullptr) + { + context->head = node; + context->tail = node; + } + else + { + context->tail->next = node; + } +#else mbedtls_sha256_context * const context = to_inner_hash_sha256_context(&mContext); #if (MBEDTLS_VERSION_NUMBER >= 0x03000000) - const int result = mbedtls_sha256_update(context, Uint8::to_const_uchar(data.data()), data.size()); + const int result = mbedtls_sha256_update(context, Uint8::to_const_uchar(data.data()), data.size()); #else const int result = mbedtls_sha256_update_ret(context, Uint8::to_const_uchar(data.data()), data.size()); #endif VerifyOrReturnError(result == 0, CHIP_ERROR_INTERNAL); +#endif return CHIP_NO_ERROR; } CHIP_ERROR Hash_SHA256_stream::GetDigest(MutableByteSpan & out_buffer) { + CHIP_ERROR result = CHIP_NO_ERROR; + +#if defined(USE_HW_SHA256) + S200_context * context = to_inner_hash_sha256_context(&mContext); + sha256_node * node = context->head; + void * ctx = SHA256_AllocCtx(); + + SHA256_Init(ctx); + + while (node) + { + SHA256_HashUpdate(ctx, node->data, node->size); + node = node->next; + } + + SHA256_HashFinish(ctx, Uint8::to_uchar(out_buffer.data())); + + SHA256_FreeCtx(ctx); +#else mbedtls_sha256_context * context = to_inner_hash_sha256_context(&mContext); // Back-up context as we are about to finalize the hash to extract digest. @@ -291,28 +420,46 @@ CHIP_ERROR Hash_SHA256_stream::GetDigest(MutableByteSpan & out_buffer) mbedtls_sha256_clone(&previous_ctx, context); // Pad + compute digest, then finalize context. It is restored next line to continue. - CHIP_ERROR result = Finish(out_buffer); + result = Finish(out_buffer); // Restore context prior to finalization. mbedtls_sha256_clone(context, &previous_ctx); mbedtls_sha256_free(&previous_ctx); +#endif return result; } CHIP_ERROR Hash_SHA256_stream::Finish(MutableByteSpan & out_buffer) { +#if defined(USE_HW_SHA256) + S200_context * context = to_inner_hash_sha256_context(&mContext); + + sha256_node * node = nullptr; + + SHA256_HashFinish(context->sss_context, Uint8::to_uchar(out_buffer.data())); + SHA256_FreeCtx(context->sss_context); + + while (context->head) + { + node = context->head; + context->head = context->head->next; + free(node->data); + free(node); + } +#else VerifyOrReturnError(out_buffer.size() >= kSHA256_Hash_Length, CHIP_ERROR_BUFFER_TOO_SMALL); mbedtls_sha256_context * const context = to_inner_hash_sha256_context(&mContext); #if (MBEDTLS_VERSION_NUMBER >= 0x03000000) - const int result = mbedtls_sha256_finish(context, Uint8::to_uchar(out_buffer.data())); + const int result = mbedtls_sha256_finish(context, Uint8::to_uchar(out_buffer.data())); #else const int result = mbedtls_sha256_finish_ret(context, Uint8::to_uchar(out_buffer.data())); #endif VerifyOrReturnError(result == 0, CHIP_ERROR_INTERNAL); - out_buffer = out_buffer.SubSpan(0, kSHA256_Hash_Length); + out_buffer = out_buffer.SubSpan(0, kSHA256_Hash_Length); +#endif return CHIP_NO_ERROR; } @@ -360,6 +507,10 @@ CHIP_ERROR HMAC_sha::HMAC_SHA256(const uint8_t * key, size_t key_length, const u VerifyOrReturnError(out_length >= kSHA256_Hash_Length, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(out_buffer != nullptr, CHIP_ERROR_INVALID_ARGUMENT); +#if defined(USE_HW_SHA256) + ::HMAC_SHA256(Uint8::to_const_uchar(key), (uint32_t) key_length, Uint8::to_const_uchar(message), (uint32_t) message_length, + out_buffer); +#else const mbedtls_md_info_t * const md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); VerifyOrReturnError(md != nullptr, CHIP_ERROR_INTERNAL); @@ -368,6 +519,7 @@ CHIP_ERROR HMAC_sha::HMAC_SHA256(const uint8_t * key, size_t key_length, const u _log_mbedTLS_error(result); VerifyOrReturnError(result == 0, CHIP_ERROR_INTERNAL); +#endif return CHIP_NO_ERROR; } @@ -423,50 +575,47 @@ CHIP_ERROR PBKDF2_sha256::pbkdf2_sha256(const uint8_t * password, size_t plen, c return error; } -static EntropyContext * get_entropy_context() +static int strong_entropy_func(void * data, uint8_t * output, size_t len) { - if (!gsEntropyContext.mInitialized) - { - mbedtls_entropy_init(&gsEntropyContext.mEntropy); - mbedtls_ctr_drbg_init(&gsEntropyContext.mDRBGCtxt); + int result = -1; + size_t olen; - gsEntropyContext.mInitialized = true; + if (gsDrbgContext.fn_source) + { + result = gsDrbgContext.fn_source(data, output, len, &olen); } - - return &gsEntropyContext; + return result; } static mbedtls_ctr_drbg_context * get_drbg_context() { - EntropyContext * const context = get_entropy_context(); + if (!gsDrbgContext.mInitialized) + { + mbedtls_ctr_drbg_init(&gsDrbgContext.mDRBGCtxt); - mbedtls_ctr_drbg_context * const drbgCtxt = &context->mDRBGCtxt; + gsDrbgContext.mInitialized = true; + } - if (!context->mDRBGSeeded) + if (!gsDrbgContext.mDRBGSeeded) { - const int status = mbedtls_ctr_drbg_seed(drbgCtxt, mbedtls_entropy_func, &context->mEntropy, nullptr, 0); + const int status = mbedtls_ctr_drbg_seed(&gsDrbgContext.mDRBGCtxt, strong_entropy_func, nullptr, nullptr, 0); if (status != 0) { _log_mbedTLS_error(status); return nullptr; } - context->mDRBGSeeded = true; + gsDrbgContext.mDRBGSeeded = true; } - return drbgCtxt; + return &gsDrbgContext.mDRBGCtxt; } CHIP_ERROR add_entropy_source(entropy_source fn_source, void * p_source, size_t threshold) { VerifyOrReturnError(fn_source != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + gsDrbgContext.fn_source = fn_source; - EntropyContext * const entropy_ctxt = get_entropy_context(); - VerifyOrReturnError(entropy_ctxt != nullptr, CHIP_ERROR_INTERNAL); - - const int result = - mbedtls_entropy_add_source(&entropy_ctxt->mEntropy, fn_source, p_source, threshold, MBEDTLS_ENTROPY_SOURCE_STRONG); - VerifyOrReturnError(result == 0, CHIP_ERROR_INTERNAL); return CHIP_NO_ERROR; } @@ -774,6 +923,7 @@ CHIP_ERROR P256Keypair::Deserialize(P256SerializedKeypair & input) exit: return error; } + void P256Keypair::Clear() { if (mInitialized) diff --git a/src/platform/nxp/k32w/k32w1/CHIPDevicePlatformConfig.h b/src/platform/nxp/k32w/k32w1/CHIPDevicePlatformConfig.h index 60a1498cff9444..52dec0809f618d 100644 --- a/src/platform/nxp/k32w/k32w1/CHIPDevicePlatformConfig.h +++ b/src/platform/nxp/k32w/k32w1/CHIPDevicePlatformConfig.h @@ -44,6 +44,18 @@ #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 0 // #define CHIP_DEVICE_CONFIG_PERSISTED_STORAGE_GLOBAL_EIDC_KEY 2 +/** + * @def CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID_LENGTH + * + * Set unique id to maximum length if not defined to ensure the actual unique + * id is retrieved instead of the default one (if factory data read fails). + */ +#ifndef CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID_LENGTH +#define CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID_LENGTH 32 +#endif + +#define CHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER + // ========== Platform-specific Configuration ========= // These are configuration options that are unique to the K32W platform. @@ -114,4 +126,16 @@ #define CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT 1 #endif +#if CHIP_DEVICE_CONFIG_ENABLE_SED + +#ifndef CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL +#define CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL chip::System::Clock::Milliseconds32(NXP_OT_IDLE_INTERVAL) +#endif // CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL + +#ifndef CHIP_DEVICE_CONFIG_ICD_FAST_POLL_INTERVAL +#define CHIP_DEVICE_CONFIG_ICD_FAST_POLL_INTERVAL chip::System::Clock::Milliseconds32(NXP_OT_ACTIVE_INTERVAL) +#endif // CHIP_DEVICE_CONFIG_ICD_FAST_POLL_INTERVAL + +#endif + #define CHIP_DEVICE_CONFIG_ENABLE_TEST_SETUP_PARAMS 1 diff --git a/src/platform/nxp/k32w/k32w1/CHIPPlatformConfig.h b/src/platform/nxp/k32w/k32w1/CHIPPlatformConfig.h index b8ae07689e14bb..cacc28dd4a60d6 100644 --- a/src/platform/nxp/k32w/k32w1/CHIPPlatformConfig.h +++ b/src/platform/nxp/k32w/k32w1/CHIPPlatformConfig.h @@ -76,3 +76,27 @@ #ifndef WDM_PUBLISHER_MAX_NOTIFIES_IN_FLIGHT #define WDM_PUBLISHER_MAX_NOTIFIES_IN_FLIGHT 2 #endif // WDM_PUBLISHER_MAX_NOTIFIES_IN_FLIGHT + +#if NXP_ICD_ENABLED + +#ifndef CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC +#define CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC NXP_IDLE_MODE_INTERVAL +#endif // CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC + +#ifndef CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS +#define CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS NXP_ACTIVE_MODE_INTERVAL +#endif // CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS + +#ifndef CHIP_CONFIG_ICD_ACTIVE_MODE_THRESHOLD_MS +#define CHIP_CONFIG_ICD_ACTIVE_MODE_THRESHOLD_MS NXP_ACTIVE_MODE_THRESHOLD +#endif // CHIP_CONFIG_ICD_ACTIVE_MODE_THRESHOLD_MS + +#ifndef CHIP_CONFIG_ICD_CLIENTS_SUPPORTED_PER_FABRIC +#define CHIP_CONFIG_ICD_CLIENTS_SUPPORTED_PER_FABRIC NXP_ICD_SUPPORTED_CLIENTS_PER_FABRIC +#endif // CHIP_CONFIG_ICD_CLIENTS_SUPPORTED_PER_FABRIC + +#ifndef CHIP_CONFIG_SYNCHRONOUS_REPORTS_ENABLED +#define CHIP_CONFIG_SYNCHRONOUS_REPORTS_ENABLED 1 +#endif + +#endif diff --git a/src/platform/nxp/k32w/k32w1/ConfigurationManagerImpl.cpp b/src/platform/nxp/k32w/k32w1/ConfigurationManagerImpl.cpp index 43aa7fa591b8f0..68a1a4196ed39c 100644 --- a/src/platform/nxp/k32w/k32w1/ConfigurationManagerImpl.cpp +++ b/src/platform/nxp/k32w/k32w1/ConfigurationManagerImpl.cpp @@ -30,6 +30,9 @@ #include #include #include +#if defined(USE_SMU2_DYNAMIC) +#include +#endif // #include #include "fsl_cmc.h" @@ -270,7 +273,10 @@ void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg) ThreadStackMgr().ErasePersistentInfo(); -#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD +#if defined(USE_SMU2_DYNAMIC) + SMU2::Deactivate(); +#endif +#endif // Restart the system. ChipLogProgress(DeviceLayer, "System restarting"); diff --git a/src/platform/nxp/k32w/k32w1/DiagnosticDataProviderImpl.cpp b/src/platform/nxp/k32w/k32w1/DiagnosticDataProviderImpl.cpp index 2b7dd8856c617b..212d0b5ea39fa6 100644 --- a/src/platform/nxp/k32w/k32w1/DiagnosticDataProviderImpl.cpp +++ b/src/platform/nxp/k32w/k32w1/DiagnosticDataProviderImpl.cpp @@ -31,12 +31,11 @@ #include #endif -extern "C" void xPortResetHeapMinimumEverFreeHeapSize(void); - #include - #include +#include "fsl_component_mem_manager.h" + using namespace ::chip::app::Clusters::GeneralDiagnostics; namespace chip { @@ -50,31 +49,31 @@ DiagnosticDataProviderImpl & DiagnosticDataProviderImpl::GetDefaultInstance() CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapFree(uint64_t & currentHeapFree) { - size_t freeHeapSize; + auto freeHeapSize = static_cast(MEM_GetFreeHeapSize()); + currentHeapFree = static_cast(freeHeapSize); - freeHeapSize = xPortGetFreeHeapSize(); - currentHeapFree = static_cast(freeHeapSize); return CHIP_NO_ERROR; } CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapUsed(uint64_t & currentHeapUsed) { - size_t freeHeapSize; - size_t usedHeapSize; + auto freeHeapSize = static_cast(MEM_GetFreeHeapSize()); + currentHeapUsed = static_cast(MinimalHeapSize_c - freeHeapSize); - freeHeapSize = xPortGetFreeHeapSize(); - usedHeapSize = MinimalHeapSize_c - freeHeapSize; - - currentHeapUsed = static_cast(usedHeapSize); return CHIP_NO_ERROR; } CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapHighWatermark(uint64_t & currentHeapHighWatermark) { - size_t highWatermarkHeapSize; + currentHeapHighWatermark = static_cast(MinimalHeapSize_c - MEM_GetFreeHeapSizeLowWaterMark()); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR DiagnosticDataProviderImpl::ResetWatermarks() +{ + MEM_ResetFreeHeapSizeLowWaterMark(); - highWatermarkHeapSize = MinimalHeapSize_c - xPortGetMinimumEverFreeHeapSize(); - currentHeapHighWatermark = static_cast(highWatermarkHeapSize); return CHIP_NO_ERROR; } diff --git a/src/platform/nxp/k32w/k32w1/DiagnosticDataProviderImpl.h b/src/platform/nxp/k32w/k32w1/DiagnosticDataProviderImpl.h index 78cca26b3683ee..33ccbe53efebaa 100644 --- a/src/platform/nxp/k32w/k32w1/DiagnosticDataProviderImpl.h +++ b/src/platform/nxp/k32w/k32w1/DiagnosticDataProviderImpl.h @@ -43,6 +43,7 @@ class DiagnosticDataProviderImpl : public DiagnosticDataProvider CHIP_ERROR GetCurrentHeapFree(uint64_t & currentHeapFree) override; CHIP_ERROR GetCurrentHeapUsed(uint64_t & currentHeapUsed) override; CHIP_ERROR GetCurrentHeapHighWatermark(uint64_t & currentHeapHighWatermark) override; + CHIP_ERROR ResetWatermarks() override; CHIP_ERROR GetThreadMetrics(ThreadMetrics ** threadMetricsOut) override; void ReleaseThreadMetrics(ThreadMetrics * threadMetrics) override; diff --git a/src/platform/nxp/k32w/k32w1/FactoryDataProviderImpl.cpp b/src/platform/nxp/k32w/k32w1/FactoryDataProviderImpl.cpp new file mode 100644 index 00000000000000..10ae6d0dd4ab05 --- /dev/null +++ b/src/platform/nxp/k32w/k32w1/FactoryDataProviderImpl.cpp @@ -0,0 +1,304 @@ +/* + * + * Copyright (c) 2023 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 + +#if CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY +#include "fsl_adapter_flash.h" +#endif + +namespace chip { +namespace DeviceLayer { + +// SSS adds 24 bytes of metadata when creating the blob +static constexpr size_t kSssBlobMetadataLength = 24; +static constexpr size_t kPrivateKeyBlobLength = Crypto::kP256_PrivateKey_Length + kSssBlobMetadataLength; + +FactoryDataProviderImpl::~FactoryDataProviderImpl() +{ + SSS_KEY_OBJ_FREE(&mContext); +} + +CHIP_ERROR FactoryDataProviderImpl::Init() +{ + CHIP_ERROR error = CHIP_NO_ERROR; + uint32_t sum = 0; + +#if CHIP_DEVICE_CONFIG_ENABLE_SSS_API_TEST + SSS_RunApiTest(); +#endif + + if (sum > kFactoryDataSize) + { + ChipLogError(DeviceLayer, "Max size of factory data: %lu is bigger than reserved factory data size: %lu", sum, + kFactoryDataSize); + } + + error = Validate(); + if (error != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Factory data init failed with: %s", ErrorStr(error)); + } + + ReturnErrorOnFailure(SSS_InitContext()); +#if CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY + ReturnErrorOnFailure(SSS_ConvertDacKey()); + ReturnErrorOnFailure(Validate()); +#endif + ReturnErrorOnFailure(SSS_ImportPrivateKeyBlob()); + + return error; +} + +CHIP_ERROR FactoryDataProviderImpl::SignWithDacKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) +{ + Crypto::P256ECDSASignature signature; + + VerifyOrReturnError(IsSpanUsable(outSignBuffer), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(IsSpanUsable(messageToSign), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(outSignBuffer.size() >= signature.Capacity(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(messageToSign.data() != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(messageToSign.size() > 0, CHIP_ERROR_INVALID_ARGUMENT); + + uint8_t digest[Crypto::kSHA256_Hash_Length]; + memset(&digest[0], 0, sizeof(digest)); + + ReturnErrorOnFailure(Crypto::Hash_SHA256(messageToSign.data(), messageToSign.size(), digest)); + ReturnErrorOnFailure(SSS_Sign(digest, signature)); + + return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, outSignBuffer); +} + +CHIP_ERROR FactoryDataProviderImpl::SSS_InitContext() +{ + auto res = sss_sscp_key_object_init(&mContext, &g_keyStore); + VerifyOrReturnError(res == kStatus_SSS_Success, CHIP_ERROR_INTERNAL); + res = sss_sscp_key_object_allocate_handle(&mContext, 0x0u, kSSS_KeyPart_Private, kSSS_CipherType_EC_NIST_P, + Crypto::kP256_PrivateKey_Length, SSS_KEYPROP_OPERATION_ASYM); + VerifyOrReturnError(res == kStatus_SSS_Success, CHIP_ERROR_INTERNAL); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProviderImpl::SSS_ImportPrivateKeyBlob() +{ + uint8_t blob[kPrivateKeyBlobLength] = { 0 }; + uint16_t blobSize = 0; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kDacPrivateKeyId, blob, kPrivateKeyBlobLength, blobSize)); + + auto res = sss_sscp_key_store_import_key(&g_keyStore, &mContext, blob, kPrivateKeyBlobLength, kPrivateKeyBlobLength * 8, + kSSS_blobType_ELKE_blob); + VerifyOrReturnError(res == kStatus_SSS_Success, CHIP_ERROR_INTERNAL); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProviderImpl::SSS_Sign(uint8_t * digest, Crypto::P256ECDSASignature & signature) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + size_t signatureSize = Crypto::kP256_ECDSA_Signature_Length_Raw; + sss_status_t res = kStatus_SSS_Fail; + sss_sscp_asymmetric_t asyc; + + res = sss_sscp_asymmetric_context_init(&asyc, &g_sssSession, &mContext, kAlgorithm_SSS_ECDSA_SHA256, kMode_SSS_Sign); + VerifyOrExit(res == kStatus_SSS_Success, error = CHIP_ERROR_INTERNAL); + res = sss_sscp_asymmetric_sign_digest(&asyc, digest, Crypto::kP256_PrivateKey_Length, signature.Bytes(), &signatureSize); + VerifyOrExit(res == kStatus_SSS_Success, error = CHIP_ERROR_INTERNAL); + signature.SetLength(signatureSize); + +exit: + sss_sscp_asymmetric_context_free(&asyc); + return error; +} + +#if CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY +CHIP_ERROR FactoryDataProviderImpl::SSS_ConvertDacKey() +{ + size_t blobSize = kPrivateKeyBlobLength; + size_t newSize = sizeof(FactoryDataProvider::Header) + mHeader.size + kSssBlobMetadataLength; + uint8_t blob[kPrivateKeyBlobLength] = { 0 }; + uint8_t * data = static_cast(chip::Platform::MemoryAlloc(newSize)); + uint32_t offset = 0; + + VerifyOrReturnError(data != nullptr, CHIP_ERROR_INTERNAL); + + ReturnErrorOnFailure(SSS_ExportBlob(blob, &blobSize, offset)); + ChipLogError(DeviceLayer, "SSS: extracted blob from DAC private key"); + + hal_flash_status_t status = HAL_FlashRead(kFactoryDataStart, newSize - kSssBlobMetadataLength, data); + VerifyOrReturnError(status == kStatus_HAL_Flash_Success, CHIP_ERROR_INTERNAL); + ChipLogError(DeviceLayer, "SSS: cached factory data in RAM"); + + ReturnErrorOnFailure(ReplaceWithBlob(data, blob, blobSize, offset)); + ChipLogError(DeviceLayer, "SSS: replaced DAC private key with secured blob"); + + status = HAL_FlashEraseSector(kFactoryDataStart, kFactoryDataSize); + VerifyOrReturnError(status == kStatus_HAL_Flash_Success, CHIP_ERROR_INTERNAL); + status = HAL_FlashProgramUnaligned(kFactoryDataStart, newSize, data); + VerifyOrReturnError(status == kStatus_HAL_Flash_Success, CHIP_ERROR_INTERNAL); + ChipLogError(DeviceLayer, "SSS: updated factory data"); + + memset(data, 0, newSize); + chip::Platform::MemoryFree(data); + ChipLogError(DeviceLayer, "SSS: sanitized RAM cache"); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProviderImpl::SSS_ExportBlob(uint8_t * data, size_t * dataLen, uint32_t & offset) +{ + uint8_t keyBuf[Crypto::kP256_PrivateKey_Length]; + MutableByteSpan dacPrivateKeySpan(keyBuf); + uint16_t keySize = 0; + + ReturnErrorOnFailure( + SearchForId(FactoryDataId::kDacPrivateKeyId, dacPrivateKeySpan.data(), dacPrivateKeySpan.size(), keySize, &offset)); + dacPrivateKeySpan.reduce_size(keySize); + + auto res = SSS_KEY_STORE_SET_KEY(&mContext, dacPrivateKeySpan.data(), Crypto::kP256_PrivateKey_Length, keySize * 8, + kSSS_KeyPart_Private); + VerifyOrReturnError(res == kStatus_SSS_Success, CHIP_ERROR_INTERNAL); + + res = sss_sscp_key_store_export_key(&g_keyStore, &mContext, data, dataLen, kSSS_blobType_ELKE_blob); + VerifyOrReturnError(res == kStatus_SSS_Success, CHIP_ERROR_INTERNAL); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProviderImpl::ReplaceWithBlob(uint8_t * data, uint8_t * blob, size_t blobLen, uint32_t offset) +{ + size_t newSize = mHeader.size + kSssBlobMetadataLength; + FactoryDataProvider::Header * header = reinterpret_cast(data); + uint8_t * payload = data + sizeof(FactoryDataProvider::Header); + size_t subsequentDataOffset = offset + kValueOffset + Crypto::kP256_PrivateKey_Length; + + memmove(payload + subsequentDataOffset + kSssBlobMetadataLength, payload + subsequentDataOffset, + mHeader.size - subsequentDataOffset); + header->size = newSize; + memcpy(payload + offset + kLengthOffset, (uint16_t *) &blobLen, sizeof(uint16_t)); + memcpy(payload + offset + kValueOffset, blob, blobLen); + + uint8_t hash[Crypto::kSHA256_Hash_Length] = { 0 }; + ReturnErrorOnFailure(Crypto::Hash_SHA256(payload, header->size, hash)); + memcpy(header->hash, hash, sizeof(header->hash)); + + return CHIP_NO_ERROR; +} +#endif // CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY + +#if CHIP_DEVICE_CONFIG_ENABLE_SSS_API_TEST + +#define _assert(condition) \ + if (!condition) \ + { \ + ChipLogError(DeviceLayer, "Condition failed" #condition); \ + while (1) \ + ; \ + } + +void FactoryDataProviderImpl::SSS_RunApiTest() +{ + uint8_t privateKey[Crypto::kP256_PrivateKey_Length] = { 0x18, 0xfe, 0x9a, 0xd9, 0x30, 0xdd, 0x2f, 0x62, 0xbe, 0x99, 0x43, + 0x93, 0xe8, 0xbe, 0x47, 0x28, 0x7f, 0xda, 0x5a, 0x71, 0x86, 0x1b, + 0x0e, 0x3f, 0x91, 0x27, 0x52, 0xd0, 0xba, 0xa7, 0x40, 0x02 }; + + auto error = SSS_InitContext(); + _assert((error == CHIP_NO_ERROR)); + + // Simulate factory data in RAM: create the header + dummy data + DAC private key entry + dummy data + uint8_t type = FactoryDataProvider::FactoryDataId::kDacPrivateKeyId; + uint8_t dummyType = FactoryDataProvider::FactoryDataId::kProductLabel; + uint16_t length = Crypto::kP256_PrivateKey_Length; + uint16_t dummyLength = 3; + uint32_t numberOfDummies = 10; + uint32_t dummySize = numberOfDummies * (sizeof(dummyType) + sizeof(dummyLength) + dummyLength); + uint32_t size = + sizeof(FactoryDataProvider::Header) + dummySize + sizeof(type) + sizeof(length) + kPrivateKeyBlobLength + dummySize; + uint8_t dummyData[3] = { 0xab }; + uint8_t hash[Crypto::kSHA256_Hash_Length] = { 0 }; + mHeader.hashId = FactoryDataProvider::kHashId; + mHeader.size = size - sizeof(FactoryDataProvider::Header); + mHeader.hash[0] = 0xde; + mHeader.hash[1] = 0xad; + mHeader.hash[2] = 0xbe; + mHeader.hash[3] = 0xef; + + uint8_t * factoryData = static_cast(chip::Platform::MemoryAlloc(size)); + _assert((factoryData != nullptr)); + + uint8_t * entry = factoryData + sizeof(mHeader); + for (auto i = 0; i < numberOfDummies; i++) + { + memcpy(entry, (void *) &dummyType, sizeof(dummyType)); + entry += sizeof(type); + memcpy(entry, (void *) &dummyLength, sizeof(dummyLength)); + entry += sizeof(length); + memcpy(entry, dummyData, dummyLength); + entry += dummyLength; + } + memcpy(entry, (void *) &type, sizeof(type)); + entry += sizeof(type); + memcpy(entry, (void *) &length, sizeof(length)); + entry += sizeof(length); + memcpy(entry, privateKey, Crypto::kP256_PrivateKey_Length); + entry += Crypto::kP256_PrivateKey_Length; + for (auto i = 0; i < numberOfDummies; i++) + { + memcpy(entry, (void *) &dummyType, sizeof(dummyType)); + entry += sizeof(type); + memcpy(entry, (void *) &dummyLength, sizeof(dummyLength)); + entry += sizeof(length); + memcpy(entry, dummyData, dummyLength); + entry += dummyLength; + } + + FactoryDataProvider::kFactoryDataPayloadStart = (uint32_t) factoryData + sizeof(FactoryDataProvider::Header); + + uint8_t keyBuf[Crypto::kP256_PrivateKey_Length]; + MutableByteSpan dacPrivateKeySpan(keyBuf); + uint16_t keySize = 0; + error = SearchForId(FactoryDataId::kCertDeclarationId, dacPrivateKeySpan.data(), dacPrivateKeySpan.size(), keySize); + _assert((error == CHIP_ERROR_NOT_FOUND)); + error = SearchForId(FactoryDataId::kDacPrivateKeyId, dacPrivateKeySpan.data(), dacPrivateKeySpan.size(), keySize); + _assert((error == CHIP_NO_ERROR)); + _assert((memcmp(dacPrivateKeySpan.data(), privateKey, Crypto::kP256_PrivateKey_Length) == 0)); + + size_t blobSize = kPrivateKeyBlobLength; + size_t newSize = sizeof(FactoryDataProvider::Header) + mHeader.size + kSssBlobMetadataLength; + uint8_t blob[kPrivateKeyBlobLength] = { 0 }; + + uint32_t offset = 0; + error = SSS_ExportBlob(blob, &blobSize, offset); + _assert((error == CHIP_NO_ERROR)); + error = ReplaceWithBlob(factoryData, blob, blobSize, offset); + _assert((error == CHIP_NO_ERROR)); + FactoryDataProvider::Header * header = reinterpret_cast(factoryData); + _assert((header->size == (mHeader.size + kSssBlobMetadataLength))); + _assert((header->hash[0] != 0xde)); + _assert((header->hash[1] != 0xad)); + _assert((header->hash[2] != 0xbe)); + _assert((header->hash[3] != 0xef)); + + memset(factoryData, 0, size); + chip::Platform::MemoryFree(factoryData); + FactoryDataProvider::kFactoryDataPayloadStart = FactoryDataProvider::kFactoryDataStart + sizeof(FactoryDataProvider::Header); + SSS_KEY_OBJ_FREE(&mContext); +} +#endif // CHIP_DEVICE_CONFIG_ENABLE_SSS_API_TEST + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/k32w/k32w1/FactoryDataProviderImpl.h b/src/platform/nxp/k32w/k32w1/FactoryDataProviderImpl.h new file mode 100644 index 00000000000000..67bef1959ea503 --- /dev/null +++ b/src/platform/nxp/k32w/k32w1/FactoryDataProviderImpl.h @@ -0,0 +1,109 @@ +/* + * + * Copyright (c) 2023 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 +#include + +#include "sss_crypto.h" + +/* This flag should be defined when the factory data contains + * the DAC private key in plain text. It usually occurs in + * manufacturing. + * + * The init phase will use S200 to export an encrypted blob, + * then overwrite the private key section from internal flash. + * + * Should be used one time only for securing the private key. + * The manufacturer will then flash the real image, which shall + * not define this flag. + */ +#ifndef CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY +#define CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY 0 +#endif + +/* This flag should be defined to run SSS_RunApiTest tests. + */ +#ifndef CHIP_DEVICE_CONFIG_ENABLE_SSS_API_TEST +#define CHIP_DEVICE_CONFIG_ENABLE_SSS_API_TEST 0 +#endif + +namespace chip { +namespace DeviceLayer { + +/** + * This class extends the default FactoryDataProvider functionality + * by leveraging the secure subsystem for signing messages. + */ + +class FactoryDataProviderImpl : public FactoryDataProvider +{ +public: + ~FactoryDataProviderImpl(); + + CHIP_ERROR Init() override; + CHIP_ERROR SignWithDacKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) override; + +private: + CHIP_ERROR SSS_InitContext(); + CHIP_ERROR SSS_ImportPrivateKeyBlob(); + CHIP_ERROR SSS_Sign(uint8_t * digest, Crypto::P256ECDSASignature & signature); +#if CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY + /*! + * \brief Convert DAC private key to an SSS encrypted blob and update factory data + * + * @note This API should be called in manufacturing process context to replace + * DAC private key with an SSS encrypted blob. The conversion will be a + * one-time-only operation. + * @retval #CHIP_NO_ERROR if factory data was updated successfully. + */ + CHIP_ERROR SSS_ConvertDacKey(); + + /*! + * \brief Export an SSS encrypted blob from the DAC private key found in factory data + * + * @param data Pointer to an allocated buffer + * @param dataLen Pointer to a variable that will store the blob length + * @param offset Offset of private key from the start of factory data payload address (after header) + * + * @retval #CHIP_NO_ERROR if conversion to blob was successful. + */ + CHIP_ERROR SSS_ExportBlob(uint8_t * data, size_t * dataLen, uint32_t & offset); + + /*! + * \brief Replace DAC private key with the specified SSS encrypted blob + * + * @note A new hash has to be computed and written in the factory data header. + * @param data Pointer to a RAM buffer that duplicates the current factory data + * @param blob Pointer to blob data + * @param blobLen Blob length + * @param offset Offset of private key from the start of factory data payload address (after header) + * Extracted with SSS_ConvertToBlob. + * + * @retval #CHIP_NO_ERROR if conversion to blob was successful. + */ + CHIP_ERROR ReplaceWithBlob(uint8_t * data, uint8_t * blob, size_t blobLen, uint32_t offset); +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_SSS_API_TEST + void SSS_RunApiTest(); +#endif + + sss_sscp_object_t mContext; +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/k32w/k32w1/K32W1Config.cpp b/src/platform/nxp/k32w/k32w1/K32W1Config.cpp index ee41809dcca7b9..489d6363d8f4e9 100644 --- a/src/platform/nxp/k32w/k32w1/K32W1Config.cpp +++ b/src/platform/nxp/k32w/k32w1/K32W1Config.cpp @@ -55,7 +55,7 @@ namespace Internal { #define CHIP_PLAT_NVM_STATIC_ALLOC 1 #endif -#define CHIP_CONFIG_RAM_BUFFER_SIZE 10240 +#define CHIP_CONFIG_RAM_BUFFER_SIZE 14336 #ifndef NVM_ID_CHIP_CONFIG_DATA #define NVM_ID_CHIP_CONFIG_DATA 0xf104 @@ -378,6 +378,7 @@ CHIP_ERROR K32WConfig::FactoryResetConfig(void) CHIP_ERROR err = CHIP_NO_ERROR; FactoryResetConfigInternal(kMinConfigKey_ChipConfig, kMaxConfigKey_ChipConfig); + FactoryResetConfigInternal(kMinConfigKey_ChipCounter, kMaxConfigKey_ChipCounter); FactoryResetConfigInternal(kMinConfigKey_KVSKey, kMaxConfigKey_KVSKey); FactoryResetConfigInternal(kMinConfigKey_KVSValue, kMaxConfigKey_KVSValue); diff --git a/src/platform/nxp/k32w/k32w1/K32W1PersistentStorageOpKeystore.cpp b/src/platform/nxp/k32w/k32w1/K32W1PersistentStorageOpKeystore.cpp index 43560f549ff951..a3a4a480430979 100644 --- a/src/platform/nxp/k32w/k32w1/K32W1PersistentStorageOpKeystore.cpp +++ b/src/platform/nxp/k32w/k32w1/K32W1PersistentStorageOpKeystore.cpp @@ -37,47 +37,21 @@ namespace chip { using namespace chip::Crypto; -CHIP_ERROR P256KeypairSSS::Initialize(Crypto::ECPKeyTarget key_target) +static inline sss_sscp_object_t * to_keypair(P256KeypairContext * context) { - CHIP_ERROR error = CHIP_NO_ERROR; - size_t keyBitsLen = kP256_PrivateKey_Length * 8; - size_t keySize = SSS_ECP_KEY_SZ(kP256_PrivateKey_Length); - - Clear(); - - VerifyOrReturnError(sss_sscp_key_object_init(&mKeyObj, &g_keyStore) == kStatus_SSS_Success, CHIP_ERROR_INTERNAL); - - VerifyOrReturnError(sss_sscp_key_object_allocate_handle( - &mKeyObj, 0x0u, kSSS_KeyPart_Pair, kSSS_CipherType_EC_NIST_P, 3 * kP256_PrivateKey_Length, - SSS_KEYPROP_OPERATION_KDF | SSS_KEYPROP_OPERATION_ASYM) == kStatus_SSS_Success, - error = CHIP_ERROR_INTERNAL); - - VerifyOrExit(SSS_ECP_GENERATE_KEY(&mKeyObj, keyBitsLen) == kStatus_SSS_Success, error = CHIP_ERROR_INTERNAL); - - // The first byte of the public key is the uncompressed marker - Uint8::to_uchar(mPublicKey)[0] = 0x04; - - // Extract public key, write from the second byte - VerifyOrExit(SSS_KEY_STORE_GET_PUBKEY(&mKeyObj, Uint8::to_uchar(mPublicKey) + 1, &keySize, &keyBitsLen) == kStatus_SSS_Success, - CHIP_ERROR_INTERNAL); - - mInitialized = true; - -exit: - if (mInitialized != true) - (void) SSS_KEY_OBJ_FREE(&mKeyObj); - - return error; + return SafePointerCast(context); } CHIP_ERROR P256KeypairSSS::ExportBlob(P256SerializedKeypairSSS & output) const { VerifyOrReturnError(mInitialized, CHIP_ERROR_UNINITIALIZED); + sss_sscp_object_t * keypair = to_keypair(&mKeypair); + size_t keyBlobLen = output.Capacity(); - VerifyOrReturnError(sss_sscp_key_store_export_key(&g_keyStore, &mKeyObj, output.Bytes(), &keyBlobLen, - kSSS_blobType_ELKE_blob) == kStatus_SSS_Success, - CHIP_ERROR_INTERNAL); + auto res = sss_sscp_key_store_export_key(&g_keyStore, keypair, output.Bytes(), &keyBlobLen, kSSS_blobType_ELKE_blob); + VerifyOrReturnError(res == kStatus_SSS_Success, CHIP_ERROR_INTERNAL); + output.SetLength(keyBlobLen); return CHIP_NO_ERROR; @@ -85,77 +59,27 @@ CHIP_ERROR P256KeypairSSS::ExportBlob(P256SerializedKeypairSSS & output) const CHIP_ERROR P256KeypairSSS::ImportBlob(P256SerializedKeypairSSS & input) { - CHIP_ERROR error = CHIP_NO_ERROR; + sss_sscp_object_t * keypair = to_keypair(&mKeypair); if (false == mInitialized) { - VerifyOrExit((sss_sscp_key_object_init(&mKeyObj, &g_keyStore) == kStatus_SSS_Success), error = CHIP_ERROR_INTERNAL); + auto res = sss_sscp_key_object_init(keypair, &g_keyStore); + VerifyOrReturnError(res == kStatus_SSS_Success, CHIP_ERROR_INTERNAL); /* Allocate key handle */ - VerifyOrExit( - (sss_sscp_key_object_allocate_handle(&mKeyObj, 0x0u, kSSS_KeyPart_Pair, kSSS_CipherType_EC_NIST_P, - 3 * kP256_PrivateKey_Length, SSS_KEYPROP_OPERATION_ASYM) == kStatus_SSS_Success), - error = CHIP_ERROR_INTERNAL); + res = sss_sscp_key_object_allocate_handle(keypair, 0x0u, kSSS_KeyPart_Pair, kSSS_CipherType_EC_NIST_P, + 3 * kP256_PrivateKey_Length, SSS_KEYPROP_OPERATION_ASYM); + VerifyOrReturnError(res == kStatus_SSS_Success, CHIP_ERROR_INTERNAL); } - VerifyOrExit((sss_sscp_key_store_import_key(&g_keyStore, &mKeyObj, input.Bytes(), input.Length(), kP256_PrivateKey_Length * 8, + VerifyOrExit((sss_sscp_key_store_import_key(&g_keyStore, keypair, input.Bytes(), input.Length(), kP256_PrivateKey_Length * 8, kSSS_blobType_ELKE_blob) == kStatus_SSS_Success), - error = CHIP_ERROR_INTERNAL); + CHIP_ERROR_INTERNAL); mInitialized = true; exit: - return error; -} - -CHIP_ERROR P256KeypairSSS::ECDSA_sign_msg(const uint8_t * msg, const size_t msg_length, P256ECDSASignature & out_signature) const -{ - CHIP_ERROR error = CHIP_NO_ERROR; - sss_sscp_asymmetric_t asyc; - size_t signatureSize = kP256_ECDSA_Signature_Length_Raw; - - VerifyOrReturnError(mInitialized, CHIP_ERROR_UNINITIALIZED); - VerifyOrReturnError((msg != nullptr) && (msg_length > 0), CHIP_ERROR_INVALID_ARGUMENT); - - uint8_t digest[kSHA256_Hash_Length]; - memset(&digest[0], 0, sizeof(digest)); - ReturnErrorOnFailure(Hash_SHA256(msg, msg_length, &digest[0])); - - VerifyOrExit((sss_sscp_asymmetric_context_init(&asyc, &g_sssSession, &mKeyObj, kAlgorithm_SSS_ECDSA_SHA256, kMode_SSS_Sign) == - kStatus_SSS_Success), - error = CHIP_ERROR_INTERNAL); - VerifyOrExit((sss_sscp_asymmetric_sign_digest(&asyc, digest, kP256_FE_Length, out_signature.Bytes(), &signatureSize) == - kStatus_SSS_Success), - error = CHIP_ERROR_INTERNAL); - VerifyOrExit(out_signature.SetLength(kP256_ECDSA_Signature_Length_Raw) == CHIP_NO_ERROR, error = CHIP_ERROR_INTERNAL); - -exit: - (void) sss_sscp_asymmetric_context_free(&asyc); - return error; -} - -CHIP_ERROR P256KeypairSSS::NewCertificateSigningRequest(uint8_t * out_csr, size_t & csr_length) const -{ - VerifyOrReturnError(mInitialized, CHIP_ERROR_UNINITIALIZED); - - MutableByteSpan csr(out_csr, csr_length); - CHIP_ERROR err = GenerateCertificateSigningRequest(this, csr); - csr_length = (CHIP_NO_ERROR == err) ? csr.size() : 0; - return err; -} - -void P256KeypairSSS::Clear() -{ - if (mInitialized) - { - (void) SSS_KEY_OBJ_FREE(&mKeyObj); - mInitialized = false; - } -} - -P256KeypairSSS::~P256KeypairSSS() -{ - Clear(); + return CHIP_NO_ERROR; } bool K32W1PersistentStorageOpKeystore::HasOpKeypairForFabric(FabricIndex fabricIndex) const diff --git a/src/platform/nxp/k32w/k32w1/K32W1PersistentStorageOpKeystore.h b/src/platform/nxp/k32w/k32w1/K32W1PersistentStorageOpKeystore.h index 6402c235527ff0..c0aeabccd2e724 100644 --- a/src/platform/nxp/k32w/k32w1/K32W1PersistentStorageOpKeystore.h +++ b/src/platform/nxp/k32w/k32w1/K32W1PersistentStorageOpKeystore.h @@ -41,47 +41,17 @@ typedef Crypto::SensitiveDataBuffer P256SerializedKeypai class P256KeypairSSS : public Crypto::P256Keypair { public: - P256KeypairSSS() {} - ~P256KeypairSSS() override; - /** - * @brief Initialize the keypair. + * @brief Export an encrypted blob. * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise **/ - CHIP_ERROR Initialize(Crypto::ECPKeyTarget key_target) override; - CHIP_ERROR ExportBlob(P256SerializedKeypairSSS & output) const; - CHIP_ERROR ImportBlob(P256SerializedKeypairSSS & input); - - /** - * @brief Generate a new Certificate Signing Request (CSR). - * @param csr Newly generated CSR in DER format - * @param csr_length The caller provides the length of input buffer (csr). The function returns the actual length of generated - *CSR. - * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise - **/ - CHIP_ERROR NewCertificateSigningRequest(uint8_t * csr, size_t & csr_length) const override; - /** - * @brief A function to sign a msg using ECDSA - * @param msg Message that needs to be signed - * @param msg_length Length of message - * @param out_signature Buffer that will hold the output signature. The signature consists of: 2 EC elements (r and s), - * in raw point form (see SEC1). + * @brief Import an encrypted blob. * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise **/ - CHIP_ERROR ECDSA_sign_msg(const uint8_t * msg, size_t msg_length, Crypto::P256ECDSASignature & out_signature) const override; - - const Crypto::P256PublicKey & Pubkey() const override { return mPublicKey; } - - /** Release resources associated with this key pair */ - void Clear(); - -private: - Crypto::P256PublicKey mPublicKey; - mutable sss_sscp_object_t mKeyObj; - bool mInitialized = false; + CHIP_ERROR ImportBlob(P256SerializedKeypairSSS & input); }; /** diff --git a/src/platform/nxp/k32w/k32w1/KeyValueStoreManagerImpl.cpp b/src/platform/nxp/k32w/k32w1/KeyValueStoreManagerImpl.cpp index 00f6a9314398bc..6af22df6781d3b 100644 --- a/src/platform/nxp/k32w/k32w1/KeyValueStoreManagerImpl.cpp +++ b/src/platform/nxp/k32w/k32w1/KeyValueStoreManagerImpl.cpp @@ -36,7 +36,7 @@ namespace DeviceLayer { namespace PersistedStorage { /* TODO: adjust these values */ -constexpr size_t kMaxNumberOfKeys = 150; +constexpr size_t kMaxNumberOfKeys = 200; constexpr size_t kMaxKeyValueBytes = 255; KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance; diff --git a/src/platform/nxp/k32w/k32w1/Logging.cpp b/src/platform/nxp/k32w/k32w1/Logging.cpp index 62b5d114379f3a..5c68f4f11dab7a 100644 --- a/src/platform/nxp/k32w/k32w1/Logging.cpp +++ b/src/platform/nxp/k32w/k32w1/Logging.cpp @@ -12,6 +12,10 @@ #include "fsl_debug_console.h" #include +#ifdef PW_RPC_ENABLED +#include +#endif + #define K32W_LOG_MODULE_NAME chip #define EOL_CHARS "\r\n" /* End of Line Characters */ #define EOL_CHARS_LEN 2 /* Length of EOL */ @@ -109,7 +113,9 @@ void ENFORCE_FORMAT(1, 0) GenericLog(const char * format, va_list arg, const cha if (!isLogInitialized) { isLogInitialized = true; +#ifndef PW_RPC_ENABLED otPlatUartEnable(); +#endif } /* Prefix is composed of [Time Reference][Debug String][Module Name String] */ @@ -121,7 +127,11 @@ void ENFORCE_FORMAT(1, 0) GenericLog(const char * format, va_list arg, const cha VerifyOrDie(writtenLen > 0); memcpy(formattedMsg + prefixLen + writtenLen, EOL_CHARS, EOL_CHARS_LEN); +#ifndef PW_RPC_ENABLED otPlatUartSendBlocking((const uint8_t *) formattedMsg, strlen(formattedMsg)); +#else + PigweedLogger::PutString((const char *) formattedMsg, strlen(formattedMsg)); +#endif // Let the application know that a log message has been emitted. chip::DeviceLayer::OnLogOutput(); diff --git a/src/platform/nxp/k32w/k32w1/LowPowerHooks.cpp b/src/platform/nxp/k32w/k32w1/LowPowerHooks.cpp index 752344e5e42cae..bc849b476e57af 100644 --- a/src/platform/nxp/k32w/k32w1/LowPowerHooks.cpp +++ b/src/platform/nxp/k32w/k32w1/LowPowerHooks.cpp @@ -34,12 +34,12 @@ using namespace ::chip::DeviceLayer; extern "C" void App_AllowDeviceToSleep() { - PWR_AllowDeviceToSleep(); + ; } extern "C" void App_DisallowDeviceToSleep() { - PWR_DisallowDeviceToSleep(); + ; } #endif diff --git a/src/platform/nxp/k32w/k32w1/OTAHooks.cpp b/src/platform/nxp/k32w/k32w1/OTAHooks.cpp index b672ed8322177d..c045a111618e49 100644 --- a/src/platform/nxp/k32w/k32w1/OTAHooks.cpp +++ b/src/platform/nxp/k32w/k32w1/OTAHooks.cpp @@ -39,7 +39,7 @@ extern "C" void HAL_ResetMCU(void); #define ResetMCU HAL_ResetMCU -#if USE_SMU2_AS_SYSTEM_MEMORY +#if USE_SMU2_STATIC // The attribute specifier should not be changed. static chip::OTAFirmwareProcessor gApplicationProcessor __attribute__((section(".smu2"))); #else diff --git a/src/platform/nxp/k32w/k32w1/PlatformManagerImpl.cpp b/src/platform/nxp/k32w/k32w1/PlatformManagerImpl.cpp index 53e68779bcecd2..40d747fc8a21d5 100644 --- a/src/platform/nxp/k32w/k32w1/PlatformManagerImpl.cpp +++ b/src/platform/nxp/k32w/k32w1/PlatformManagerImpl.cpp @@ -29,7 +29,8 @@ #include #include #include -#include +#include +#include #if CHIP_SYSTEM_CONFIG_USE_LWIP #include @@ -39,6 +40,8 @@ #include "fwk_platform.h" #include +extern "C" void HAL_ResetMCU(void); + extern uint8_t __data_end__[], m_data0_end[]; memAreaCfg_t data0Heap = { .start_address = (void *) __data_end__, .end_address = (void *) m_data0_end }; @@ -68,6 +71,15 @@ CHIP_ERROR PlatformManagerImpl::InitBoardFwk(void) return CHIP_NO_ERROR; } +void PlatformManagerImpl::CleanReset() +{ + StopEventLoopTask(); + Shutdown(); +#if CHIP_PLAT_NVM_SUPPORT + NvCompletePendingOperations(); +#endif + HAL_ResetMCU(); +} static int app_entropy_source(void * data, unsigned char * output, size_t len, size_t * olen) { diff --git a/src/platform/nxp/k32w/k32w1/PlatformManagerImpl.h b/src/platform/nxp/k32w/k32w1/PlatformManagerImpl.h index 70ece1cdf11f3c..6798cb911ee377 100644 --- a/src/platform/nxp/k32w/k32w1/PlatformManagerImpl.h +++ b/src/platform/nxp/k32w/k32w1/PlatformManagerImpl.h @@ -50,6 +50,7 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener System::Clock::Timestamp GetStartTime() { return mStartTime; } CHIP_ERROR InitBoardFwk(void); + void CleanReset(); private: // ===== Methods that implement the PlatformManager abstract interface. diff --git a/src/platform/nxp/k32w/k32w1/SMU2Manager.cpp b/src/platform/nxp/k32w/k32w1/SMU2Manager.cpp new file mode 100644 index 00000000000000..f4e0216bb8955a --- /dev/null +++ b/src/platform/nxp/k32w/k32w1/SMU2Manager.cpp @@ -0,0 +1,165 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * Copyright (c) 2023 NXP + * 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 the SMU2 namespace for K32W1 platform using the NXP SDK. + * This namespace implements all the necessary function to allocate + * OpenThread buffers from SMU2 region. + */ + +#include "SMU2Manager.h" +#include + +using namespace chip::DeviceLayer; +using namespace chip::DeviceLayer::Internal; + +namespace chip::SMU2 { +namespace { + +static const uint32_t AREA_START = (0x489C5380U); +static const uint32_t AREA_END = (0x489C87FFU); +static const uint32_t AREA_SIZE = (AREA_END - AREA_START); + +uint8_t mAreaId = 0; + +PersistentStorageDelegate * mStorage = nullptr; + +memAreaCfg_t mAreaDescriptor; +bool mDeviceCommissioned = false; +bool mUseAllocator = false; + +StorageKeyName GetSMU2AllocatorKey() +{ + return StorageKeyName::FromConst("nxp/ot-smu2"); +} + +void ResetBLEController() +{ + VerifyOrDie(BLEMgrImpl().ResetController() == CHIP_NO_ERROR); +} + +void RegisterArea(void) +{ + mem_status_t st = kStatus_MemSuccess; + + memset((void *) AREA_START, 0x00, AREA_SIZE); + + mAreaDescriptor.start_address = (void *) AREA_START; + mAreaDescriptor.end_address = (void *) AREA_END; + + st = MEM_RegisterExtendedArea(&mAreaDescriptor, &mAreaId, AREA_FLAGS_POOL_NOT_SHARED); + VerifyOrDie(st == kStatus_MemSuccess); +} + +void UnregisterArea(void) +{ + mem_status_t st = kStatus_MemSuccess; + + st = MEM_UnRegisterExtendedArea(mAreaId); + VerifyOrDie(st == kStatus_MemSuccess); + mAreaId = 0; + + memset((void *) AREA_START, 0x00, AREA_SIZE); +} + +void EventHandler(const ChipDeviceEvent * event, intptr_t) +{ + switch (event->Type) + { + case DeviceEventType::kCommissioningComplete: { + mDeviceCommissioned = true; + break; + } + + case DeviceEventType::kCHIPoBLEConnectionClosed: { + if (mDeviceCommissioned) + { + mUseAllocator = true; + mStorage->SyncSetKeyValue(GetSMU2AllocatorKey().KeyName(), (void *) &mUseAllocator, (uint16_t) sizeof(mUseAllocator)); + ResetBLEController(); + RegisterArea(); + } + break; + } + } +} + +} // anonymous namespace + +CHIP_ERROR Init(PersistentStorageDelegate * storage) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + uint16_t size = (uint16_t) sizeof(mUseAllocator); + mStorage = storage; + + VerifyOrReturnError(storage != nullptr, CHIP_ERROR_INCORRECT_STATE); + + PlatformMgr().AddEventHandler(EventHandler, reinterpret_cast(nullptr)); + + err = mStorage->SyncGetKeyValue(GetSMU2AllocatorKey().KeyName(), (void *) &mUseAllocator, size); + + if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND) + { + mUseAllocator = false; + err = mStorage->SyncSetKeyValue(GetSMU2AllocatorKey().KeyName(), (void *) &mUseAllocator, size); + } + ReturnErrorOnFailure(err); + + if (mUseAllocator) + { + RegisterArea(); + } + + return err; +} + +CHIP_ERROR Deactivate(void) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + if (mUseAllocator) + { + mUseAllocator = false; + err = mStorage->SyncDeleteKeyValue(GetSMU2AllocatorKey().KeyName()); + ReturnErrorOnFailure(err); + + UnregisterArea(); + ResetBLEController(); + } + + return CHIP_NO_ERROR; +} + +void * Allocate(size_t size) +{ + size_t smu2Size = 0; + if (mAreaId) + { + smu2Size = MEM_GetFreeHeapSizeByAreaId(mAreaId); + if (size > smu2Size) + { + mAreaId = 0; + } + } + + return MEM_BufferAllocWithId(size, mAreaId); +} + +} // namespace chip::SMU2 diff --git a/src/platform/nxp/k32w/k32w1/SMU2Manager.h b/src/platform/nxp/k32w/k32w1/SMU2Manager.h new file mode 100644 index 00000000000000..7044d452727476 --- /dev/null +++ b/src/platform/nxp/k32w/k32w1/SMU2Manager.h @@ -0,0 +1,39 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * Copyright (c) 2023 NXP + * 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 the SMU2 namespace for K32W1 platform using the NXP SDK. + * This namespace implements all the necessary function to allocate + * OpenThread buffers from SMU2 region. + */ + +#pragma once + +#include "fsl_component_mem_manager.h" +#include +#include + +namespace chip::SMU2 { + +CHIP_ERROR Init(PersistentStorageDelegate * storage); +CHIP_ERROR Deactivate(void); +void * Allocate(size_t size); + +} // namespace chip::SMU2 diff --git a/src/platform/nxp/k32w/k32w1/SystemTimeSupport.cpp b/src/platform/nxp/k32w/k32w1/SystemTimeSupport.cpp index a61c5d648bc039..7ef2a2ae0fff17 100644 --- a/src/platform/nxp/k32w/k32w1/SystemTimeSupport.cpp +++ b/src/platform/nxp/k32w/k32w1/SystemTimeSupport.cpp @@ -25,7 +25,7 @@ /* this file behaves like a config.h, comes first */ #include -extern "C" uint32_t otPlatAlarmMicroGetNow(void); +#include namespace chip { namespace System { @@ -43,7 +43,7 @@ uint64_t sBootTimeUS = 0; Microseconds64 ClockImpl::GetMonotonicMicroseconds64(void) { - return Clock::Microseconds64(otPlatAlarmMicroGetNow()); + return Clock::Microseconds64(otPlatTimeGet()); } Milliseconds64 ClockImpl::GetMonotonicMilliseconds64(void) @@ -53,12 +53,12 @@ Milliseconds64 ClockImpl::GetMonotonicMilliseconds64(void) uint64_t GetClock_Monotonic(void) { - return otPlatAlarmMicroGetNow(); + return otPlatTimeGet(); } uint64_t GetClock_MonotonicMS(void) { - return (otPlatAlarmMicroGetNow() / 1000); + return (otPlatTimeGet() / 1000); } uint64_t GetClock_MonotonicHiRes(void) diff --git a/src/platform/nxp/k32w/k32w1/ThreadStackManagerImpl.cpp b/src/platform/nxp/k32w/k32w1/ThreadStackManagerImpl.cpp index 7bf96771fb78d7..89c63694fed168 100644 --- a/src/platform/nxp/k32w/k32w1/ThreadStackManagerImpl.cpp +++ b/src/platform/nxp/k32w/k32w1/ThreadStackManagerImpl.cpp @@ -34,6 +34,9 @@ #include #include +#if defined(USE_SMU2_DYNAMIC) +#include +#endif #include namespace chip { @@ -83,6 +86,7 @@ bool ThreadStackManagerImpl::IsInitialized() } // namespace DeviceLayer } // namespace chip +using namespace ::chip; using namespace ::chip::DeviceLayer; /** @@ -113,7 +117,11 @@ extern "C" void * pvPortCallocRtos(size_t num, size_t size) extern "C" void * otPlatCAlloc(size_t aNum, size_t aSize) { +#if defined(USE_SMU2_DYNAMIC) + return SMU2::Allocate(aNum * aSize); +#else return CHIPPlatformMemoryCalloc(aNum, aSize); +#endif } extern "C" void otPlatFree(void * aPtr) diff --git a/src/platform/nxp/k32w/k32w1/args.gni b/src/platform/nxp/k32w/k32w1/args.gni index 4170e95ea6f632..2de35770927a63 100644 --- a/src/platform/nxp/k32w/k32w1/args.gni +++ b/src/platform/nxp/k32w/k32w1/args.gni @@ -13,18 +13,36 @@ # limitations under the License. import("//build_overrides/chip.gni") -import("//build_overrides/k32w1_sdk.gni") +import("//build_overrides/nxp_sdk.gni") import("//build_overrides/openthread.gni") declare_args() { chip_with_ot_cli = 0 chip_with_low_power = 0 + chip_convert_dac_private_key = 0 sdk_release = 1 } -chip_device_platform = "k32w1" +nxp_platform = "k32w/k32w1" +nxp_sdk_name = "k32w1_sdk" +nxp_device_layer = "nxp/${nxp_platform}" +nxp_use_lwip = false +nxp_use_mbedtls_port = false -lwip_platform = "k32w1" +# ARM architecture flags will be set based on NXP board. +arm_platform_config = "${nxp_sdk_build_root}/${nxp_sdk_name}/nxp_arm.gni" + +chip_device_platform = "nxp" + +chip_device_project_config_include = "" +chip_project_config_include = "" +chip_inet_project_config_include = "" +chip_system_project_config_include = "" +chip_ble_project_config_include = "" +chip_project_config_include_dirs = + [ "${chip_root}/examples/platform/${nxp_platform}/app/project_include" ] + +chip_enable_openthread = true chip_inet_config_enable_ipv4 = false @@ -39,7 +57,7 @@ chip_mdns = "platform" chip_system_config_use_open_thread_inet_endpoints = true chip_with_lwip = false -mbedtls_target = "${chip_root}/third_party/nxp/k32w1_sdk:mbedtls" +mbedtls_target = "${nxp_sdk_build_root}/${nxp_sdk_name}:mbedtls" openthread_external_mbedtls = mbedtls_target openthread_project_core_config_file = "OpenThreadConfig.h" diff --git a/src/system/BUILD.gn b/src/system/BUILD.gn index 1389bddc3ca4c0..9f24ad171be72a 100644 --- a/src/system/BUILD.gn +++ b/src/system/BUILD.gn @@ -60,8 +60,6 @@ if (chip_device_platform == "cc13x2_26x2") { import("${qpg_sdk_build_root}/qpg_sdk.gni") } else if (chip_device_platform == "k32w0") { import("//build_overrides/k32w0_sdk.gni") -} else if (chip_device_platform == "k32w1") { - import("//build_overrides/k32w1_sdk.gni") } else if (chip_device_platform == "nxp") { import("//build_overrides/nxp_sdk.gni") } else if (chip_device_platform == "psoc6") { @@ -189,9 +187,6 @@ source_set("system_config_header") { if (chip_device_platform == "k32w0") { public_deps += [ "${k32w0_sdk_build_root}:k32w0_sdk" ] } - if (chip_device_platform == "k32w1") { - public_deps += [ "${k32w1_sdk_build_root}:k32w1_sdk" ] - } if (chip_device_platform == "nxp") { public_deps += [ "${nxp_sdk_build_root}:nxp_sdk" ] } diff --git a/third_party/nxp/k32w1_sdk/BUILD.gn b/third_party/nxp/k32w1_sdk/BUILD.gn index 8173cdd0df7863..9a6cf009555de3 100644 --- a/third_party/nxp/k32w1_sdk/BUILD.gn +++ b/third_party/nxp/k32w1_sdk/BUILD.gn @@ -12,10 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//build_overrides/k32w1_sdk.gni") +import("//build_overrides/nxp_sdk.gni") + import("//build_overrides/mbedtls.gni") -import("${k32w1_sdk_build_root}/k32w1_sdk.gni") +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") + import("${mbedtls_root}/mbedtls.gni") declare_args() { @@ -25,7 +29,7 @@ declare_args() { assert(k32w1_sdk_target != "", "k32w1_sdk_target must be specified") -group("k32w1_sdk") { +group("nxp_sdk") { public_deps = [ k32w1_sdk_target ] } @@ -63,6 +67,12 @@ config("mbedtls_k32w1_config") { ] } + if (chip_crypto == "platform") { + defines += [ + # "MBEDTLS_CCM_ALT", + ] + } + include_dirs = [ chip_root ] } @@ -75,7 +85,7 @@ mbedtls_target("mbedtls") { public_configs = [ ":mbedtls_k32w1_config" ] public_deps = [ - ":k32w1_sdk", + ":nxp_sdk", "${chip_root}/third_party/openthread/platforms/nxp/k32w/k32w1:openthread_mbedtls_config_k32w1", ] } diff --git a/third_party/nxp/k32w1_sdk/k32w1_sdk.gni b/third_party/nxp/k32w1_sdk/k32w1_sdk.gni index 14f355b9da068c..7a8bf40afe7a04 100644 --- a/third_party/nxp/k32w1_sdk/k32w1_sdk.gni +++ b/third_party/nxp/k32w1_sdk/k32w1_sdk.gni @@ -13,27 +13,46 @@ # limitations under the License. import("//build_overrides/build.gni") import("//build_overrides/chip.gni") -import("//build_overrides/k32w1_sdk.gni") + +import("//build_overrides/nxp_sdk.gni") + import("//build_overrides/mbedtls.gni") import("//build_overrides/openthread.gni") import("${build_root}/config/compiler/compiler.gni") import("${chip_root}/src/crypto/crypto.gni") -import("${chip_root}/src/lib/core/core.gni") + import("${chip_root}/src/platform/device.gni") -import("${chip_root}/src/platform/nxp/k32w/k32w1/args.gni") + +import("${chip_root}/src/lib/core/core.gni") +import("${chip_root}/src/platform/nxp/${nxp_platform}/args.gni") + +import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni") declare_args() { # Location of the k32w1 SDK. k32w1_sdk_root = getenv("NXP_K32W1_SDK_ROOT") - use_smu2_as_system_memory = false + use_smu2_static = false + use_smu2_dynamic = false + use_hw_sha256 = false + use_hw_aes = false + + # ICD Matter Configuration flags + chip_ot_idle_interval_ms = 2000 # 2s Idle Intervals + chip_ot_active_interval_ms = 500 # 500ms Active Intervals + + nxp_idle_mode_interval_s = 600 # 10min Idle Mode Interval + nxp_active_mode_interval_ms = 10000 # 10s Active Mode Interval + nxp_active_mode_threshold_ms = 1000 # 1s Active Mode Threshold + nxp_icd_supported_clients_per_fabric = 2 # 2 registration slots per fabric } openthread_nxp_root = "${chip_root}/third_party/openthread/ot-nxp" assert(k32w1_sdk_root != "", "k32w1_sdk_root must be specified") -assert(!(use_smu2_as_system_memory && !chip_openthread_ftd), +assert(!((use_smu2_static && !chip_openthread_ftd) || + (use_smu2_dynamic && !chip_openthread_ftd)), "SMU2 can be used as system memory only with OT-FTD suppport") # Defines an k32w1 SDK build target. @@ -64,7 +83,7 @@ template("k32w1_sdk") { _sdk_include_dirs = [ "${k32w1_sdk_root}/devices/K32W1480", "${k32w1_sdk_root}/CMSIS/Core/Include", - "${k32w1_sdk_root}/platform/drivers/snt", + "${k32w1_sdk_root}/platform/drivers/elemu", "${k32w1_sdk_root}/platform/drivers/spc", "${k32w1_sdk_root}/platform/drivers/ccm32k", "${k32w1_sdk_root}/platform/drivers/wuu", @@ -114,6 +133,7 @@ template("k32w1_sdk") { "${k32w1_sdk_root}/middleware/multicore/rpmsg_lite/lib/include", "${k32w1_sdk_root}/middleware/multicore/rpmsg_lite/lib/include/platform/k32w1", + "${k32w1_sdk_root}/middleware/multicore/rpmsg_lite/lib/include/environment/freertos", "${k32w1_sdk_root}/middleware/multicore/mcmgr/src", "${k32w1_sdk_root}/middleware/wireless/ble_controller/interface", @@ -130,7 +150,7 @@ template("k32w1_sdk") { "${k32w1_sdk_root}/middleware/mbedtls/include/mbedtls", "${k32w1_sdk_root}/middleware/mbedtls/include", "${k32w1_sdk_root}/middleware/secure-subsystem/inc", - "${k32w1_sdk_root}/middleware/secure-subsystem/inc/snt", + "${k32w1_sdk_root}/middleware/secure-subsystem/inc/elemu", "${k32w1_sdk_root}/middleware/secure-subsystem/port/kw45_k4w1", "${k32w1_sdk_root}/middleware/wireless/XCVR/drv", @@ -187,7 +207,6 @@ template("k32w1_sdk") { "SERIAL_MANAGER_NON_BLOCKING_MODE=1", "SERIAL_USE_CONFIGURE_STRUCTURE=1", "SDK_COMPONENT_INTEGRATION=1", - "SERIAL_PORT_TYPE_UART=1", "gSerialManagerMaxInterfaces_c=1", "SDK_OS_FREE_RTOS", "gAppHighSystemClockFrequency_d=1", @@ -206,15 +225,15 @@ template("k32w1_sdk") { "gAppLowpowerEnabled_d=1", "BUTTON_SHORT_PRESS_THRESHOLD=1500", "BUTTON_LONG_PRESS_THRESHOLD=2500", - "SSS_CONFIG_FILE=\"fsl_sss_config_snt.h\"", - "SSCP_CONFIG_FILE=\"fsl_sscp_config_snt.h\"", + "SSS_CONFIG_FILE=\"fsl_sss_config_elemu.h\"", + "SSCP_CONFIG_FILE=\"fsl_sscp_config_elemu.h\"", "SDK_DEBUGCONSOLE=1", "NO_SYSCORECLK_UPD=0", "USE_RTOS=1", "USE_SDK_OSA=0", "FSL_RTOS_FREE_RTOS=1", - "MinimalHeapSize_c=0x8C00", + "MinimalHeapSize_c=0x7C00", "gMemManagerLightExtendHeapAreaUsage=0", "DEBUG_SERIAL_INTERFACE_INSTANCE=0", "APP_SERIAL_INTERFACE_INSTANCE=1", @@ -249,8 +268,23 @@ template("k32w1_sdk") { # gConnectPowerLeveldBm_c "gAdvertisingPowerLeveldBm_c=0", "gConnectPowerLeveldBm_c=0", + + #move these platform specific defines to args.gni + "NXP_OT_IDLE_INTERVAL=${chip_ot_idle_interval_ms}", + "NXP_OT_ACTIVE_INTERVAL=${chip_ot_active_interval_ms}", + "NXP_ICD_ENABLED=1", + "NXP_ACTIVE_MODE_THRESHOLD=${nxp_active_mode_threshold_ms}", + "NXP_ACTIVE_MODE_INTERVAL=${nxp_active_mode_interval_ms}", + "NXP_IDLE_MODE_INTERVAL=${nxp_idle_mode_interval_s}", + "NXP_ICD_SUPPORTED_CLIENTS_PER_FABRIC=${nxp_icd_supported_clients_per_fabric}", ] + if (chip_enable_pw_rpc) { + defines += [ "SERIAL_PORT_TYPE_UART_DMA=1" ] + } else { + defines += [ "SERIAL_PORT_TYPE_UART=1" ] + } + if (chip_with_low_power == 1 && chip_logging == true) { print( "WARNING: enabling logs in low power might break the LP timings. Use at your own risk!") @@ -270,13 +304,25 @@ template("k32w1_sdk") { defines += [ "CHIP_DEVICE_CONFIG_THREAD_ENABLE_CLI=1" ] } - if (use_smu2_as_system_memory) { + if (use_smu2_static) { defines += [ "__STARTUP_CLEAR_SMU2", "USE_SMU2_AS_SYSTEM_MEMORY", + "USE_SMU2_STATIC", + ] + } + + if (use_smu2_dynamic) { + defines += [ + "USE_SMU2_AS_SYSTEM_MEMORY", + "USE_SMU2_DYNAMIC", ] } + if (chip_with_factory_data == 1) { + defines += [ "CONFIG_CHIP_LOAD_REAL_FACTORY_DATA=1" ] + } + if (chip_with_low_power == 1) { defines += [ "chip_with_low_power=1", @@ -304,6 +350,14 @@ template("k32w1_sdk") { ] } + if (use_hw_sha256) { + defines += [ "USE_HW_SHA256" ] + } + + if (use_hw_aes) { + defines += [ "USE_HW_AES" ] + } + if (defined(invoker.defines)) { defines += invoker.defines } @@ -348,6 +402,7 @@ template("k32w1_sdk") { "${k32w1_sdk_root}/devices/K32W1480/drivers/fsl_clock.c", "${k32w1_sdk_root}/devices/K32W1480/drivers/fsl_cmc.c", "${k32w1_sdk_root}/devices/K32W1480/drivers/fsl_crc.c", + "${k32w1_sdk_root}/devices/K32W1480/drivers/fsl_elemu.c", "${k32w1_sdk_root}/devices/K32W1480/drivers/fsl_gpio.c", "${k32w1_sdk_root}/devices/K32W1480/drivers/fsl_imu.c", "${k32w1_sdk_root}/devices/K32W1480/drivers/fsl_k4_controller.c", @@ -356,7 +411,6 @@ template("k32w1_sdk") { "${k32w1_sdk_root}/devices/K32W1480/drivers/fsl_lptmr.c", "${k32w1_sdk_root}/devices/K32W1480/drivers/fsl_lpuart.c", "${k32w1_sdk_root}/devices/K32W1480/drivers/fsl_ltc.c", - "${k32w1_sdk_root}/devices/K32W1480/drivers/fsl_snt.c", "${k32w1_sdk_root}/devices/K32W1480/drivers/fsl_spc.c", "${k32w1_sdk_root}/devices/K32W1480/drivers/fsl_wuu.c", "${k32w1_sdk_root}/devices/K32W1480/utilities/debug_console/fsl_debug_console.c", @@ -364,6 +418,13 @@ template("k32w1_sdk") { "${k32w1_sdk_root}/devices/K32W1480/utilities/str/fsl_str.c", "${k32w1_sdk_root}/middleware/wireless/bluetooth/application/common/matter/ble_init.c", ] + + if (chip_enable_pw_rpc) { + sources += [ + "${k32w1_sdk_root}/devices/K32W1480/drivers/fsl_edma.c", + "${k32w1_sdk_root}/devices/K32W1480/drivers/fsl_lpuart_edma.c", + ] + } } else { sources += [ "${k32w1_sdk_root}/devices/KW45B41Z83/drivers/fsl_clock.c", @@ -371,6 +432,7 @@ template("k32w1_sdk") { "${k32w1_sdk_root}/platform/drivers/ccm32k/fsl_ccm32k.c", "${k32w1_sdk_root}/platform/drivers/cmc/fsl_cmc.c", "${k32w1_sdk_root}/platform/drivers/crc/fsl_crc.c", + "${k32w1_sdk_root}/platform/drivers/elemu/fsl_elemu.c", "${k32w1_sdk_root}/platform/drivers/flash_k4/fsl_k4_controller.c", "${k32w1_sdk_root}/platform/drivers/flash_k4/fsl_k4_flash.c", "${k32w1_sdk_root}/platform/drivers/gpio/fsl_gpio.c", @@ -379,13 +441,19 @@ template("k32w1_sdk") { "${k32w1_sdk_root}/platform/drivers/lptmr/fsl_lptmr.c", "${k32w1_sdk_root}/platform/drivers/lpuart/fsl_lpuart.c", "${k32w1_sdk_root}/platform/drivers/ltc/fsl_ltc.c", - "${k32w1_sdk_root}/platform/drivers/snt/fsl_snt.c", "${k32w1_sdk_root}/platform/drivers/spc/fsl_spc.c", "${k32w1_sdk_root}/platform/drivers/wuu/fsl_wuu.c", "${k32w1_sdk_root}/platform/utilities/assert/fsl_assert.c", "${k32w1_sdk_root}/platform/utilities/debug_console/fsl_debug_console.c", "${k32w1_sdk_root}/platform/utilities/str/fsl_str.c", ] + + if (chip_enable_pw_rpc) { + sources += [ + "${k32w1_sdk_root}/platform/drivers/lpuart/fsl_edma.c", + "${k32w1_sdk_root}/platform/drivers/lpuart/fsl_lpuart_edma.c", + ] + } } sources += [ @@ -422,7 +490,9 @@ template("k32w1_sdk") { "${k32w1_sdk_root}/middleware/multicore/rpmsg_lite/lib/virtio/virtqueue.c", "${k32w1_sdk_root}/middleware/secure-subsystem/port/kw45_k4w1/sss_aes.c", "${k32w1_sdk_root}/middleware/secure-subsystem/port/kw45_k4w1/sss_aes_cmac.c", + "${k32w1_sdk_root}/middleware/secure-subsystem/port/kw45_k4w1/sss_ccm.c", "${k32w1_sdk_root}/middleware/secure-subsystem/port/kw45_k4w1/sss_ecdh.c", + "${k32w1_sdk_root}/middleware/secure-subsystem/port/kw45_k4w1/sss_hmac_sha256.c", "${k32w1_sdk_root}/middleware/secure-subsystem/port/kw45_k4w1/sss_init.c", "${k32w1_sdk_root}/middleware/secure-subsystem/port/kw45_k4w1/sss_sha256.c", "${k32w1_sdk_root}/middleware/secure-subsystem/src/sscp/fsl_sscp_mu.c", @@ -460,6 +530,7 @@ template("k32w1_sdk") { "${k32w1_sdk_root}/middleware/wireless/framework/platform/kw45_k32w1/fwk_platform_extflash.c", "${k32w1_sdk_root}/middleware/wireless/framework/platform/kw45_k32w1/fwk_platform_ics.c", "${k32w1_sdk_root}/middleware/wireless/framework/platform/kw45_k32w1/fwk_platform_lowpower.c", + "${k32w1_sdk_root}/middleware/wireless/framework/platform/kw45_k32w1/fwk_platform_lowpower_timer.c", "${k32w1_sdk_root}/middleware/wireless/framework/platform/kw45_k32w1/fwk_platform_ot.c", "${k32w1_sdk_root}/middleware/wireless/framework/platform/kw45_k32w1/fwk_platform_ota.c", "${k32w1_sdk_root}/middleware/wireless/ieee-802.15.4/ieee_802_15_4/phy/source/PhyTime.c", diff --git a/third_party/nxp/k32w1_sdk/nxp_arm.gni b/third_party/nxp/k32w1_sdk/nxp_arm.gni new file mode 100644 index 00000000000000..78d1036cc8536a --- /dev/null +++ b/third_party/nxp/k32w1_sdk/nxp_arm.gni @@ -0,0 +1,23 @@ +# Copyright (c) 2023 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/nxp_sdk.gni") +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +assert(nxp_platform == "k32w/k32w1", "${nxp_platform} must be k32w/k32w1.") + +arm_arch = "armv8-m.main+dsp+fp" +arm_cpu = "cortex-m33" +arm_fpu = "fpv5-sp-d16" +arm_float_abi = "hard" diff --git a/third_party/nxp/k32w1_sdk/nxp_executable.gni b/third_party/nxp/k32w1_sdk/nxp_executable.gni new file mode 100644 index 00000000000000..bc78dfc13bf95c --- /dev/null +++ b/third_party/nxp/k32w1_sdk/nxp_executable.gni @@ -0,0 +1,34 @@ +# 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/build.gni") +import("//build_overrides/chip.gni") + +import("${build_root}/toolchain/flashable_executable.gni") + +template("k32w1_executable") { + output_base_name = get_path_info(invoker.output_name, "name") + objcopy_image_name = output_base_name + ".srec" + objcopy_image_format = "srec" + objcopy = "arm-none-eabi-objcopy" + + # Copy flashing dependencies to the output directory so that the output + # is collectively self-contained; this allows flashing to work reliably + # even if the build and flashing steps take place on different machines + # or in different containers. + + flashable_executable(target_name) { + forward_variables_from(invoker, "*") + } +} diff --git a/third_party/openthread/ot-nxp b/third_party/openthread/ot-nxp index eb23212ca1e329..0a8fcca1828cac 160000 --- a/third_party/openthread/ot-nxp +++ b/third_party/openthread/ot-nxp @@ -1 +1 @@ -Subproject commit eb23212ca1e329a29c95c29c09438c8f2256d5c6 +Subproject commit 0a8fcca1828cac3e3d70577010c365b4dc8e3d66 diff --git a/third_party/openthread/platforms/nxp/k32w/k32w1/BUILD.gn b/third_party/openthread/platforms/nxp/k32w/k32w1/BUILD.gn index 341c8960ede578..446768b23b778c 100644 --- a/third_party/openthread/platforms/nxp/k32w/k32w1/BUILD.gn +++ b/third_party/openthread/platforms/nxp/k32w/k32w1/BUILD.gn @@ -13,9 +13,12 @@ # limitations under the License. import("//build_overrides/chip.gni") -import("//build_overrides/k32w1_sdk.gni") +import("//build_overrides/nxp_sdk.gni") import("//build_overrides/openthread.gni") -import("${chip_root}/third_party/nxp/k32w1_sdk/k32w1_sdk.gni") + +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") openthread_nxp_root = "${chip_root}/third_party/openthread/ot-nxp" @@ -28,7 +31,16 @@ config("openthread_k32w1_config") { "OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE=1", "MBEDTLS_ENTROPY_HARDWARE_ALT=1", "OPENTHREAD_PLATFORM_CORE_CONFIG_FILE=\"app/project_include/OpenThreadConfig.h\"", + "MBEDTLS_THREADING_C=1", + "MBEDTLS_THREADING_ALT=1", ] + + if (use_smu2_dynamic) { + defines += [ + "OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE=1", + "OPENTHREAD_CONFIG_ENABLE_BUILTIN_MBEDTLS_MANAGEMENT=0", + ] + } } source_set("openthread_core_config_k32w1") { @@ -46,13 +58,13 @@ source_set("openthread_mbedtls_config_k32w1") { source_set("libopenthread-k32w1") { sources = [ + "${openthread_nxp_root}/src/common/crypto.c", "${openthread_nxp_root}/src/common/flash_nvm.c", "${openthread_nxp_root}/src/k32w1/k32w1/alarm.c", "${openthread_nxp_root}/src/k32w1/k32w1/diag.c", "${openthread_nxp_root}/src/k32w1/k32w1/entropy.c", "${openthread_nxp_root}/src/k32w1/k32w1/logging.c", "${openthread_nxp_root}/src/k32w1/k32w1/misc.c", - "${openthread_nxp_root}/src/k32w1/k32w1/power.c", "${openthread_nxp_root}/src/k32w1/k32w1/radio.c", "${openthread_nxp_root}/src/k32w1/k32w1/system.c", "${openthread_nxp_root}/src/k32w1/k32w1/uart.c", @@ -60,6 +72,14 @@ source_set("libopenthread-k32w1") { if (chip_crypto == "platform") { sources += [ "${openthread_nxp_root}/src/k32w1/k32w1/ecdsa_sss.cpp" ] + + if (use_hw_sha256) { + sources += [ "${openthread_nxp_root}/src/k32w1/k32w1/sha256_sss.cpp" ] + } + + if (use_hw_aes) { + sources += [ "${openthread_nxp_root}/src/k32w1/k32w1/aes_sss.cpp" ] + } } if (chip_with_ot_cli == 1) { @@ -68,7 +88,7 @@ source_set("libopenthread-k32w1") { public_deps = [ ":openthread_core_config_k32w1", - "${k32w1_sdk_build_root}:k32w1_sdk", + "${nxp_sdk_build_root}:nxp_sdk", "${openthread_root}/src/core:libopenthread_core_headers", "../../..:libopenthread-platform", "../../..:libopenthread-platform-utils",