diff --git a/.github/workflows/examples-k32w.yaml b/.github/workflows/examples-k32w.yaml index be2d372e88c177..4121768bd4cac5 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:33 + image: ghcr.io/project-chip/chip-build-k32w:38 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: @@ -46,7 +46,7 @@ jobs: - name: Checkout submodules & Bootstrap uses: ./.github/actions/checkout-submodules-and-bootstrap with: - platform: k32w + platform: nxp - name: Set up environment for size reports uses: ./.github/actions/setup-size-reports @@ -59,11 +59,8 @@ jobs: scripts/run_in_build_env.sh "\ ./scripts/build/build_examples.py \ --target k32w-k32w0-light-crypto-platform-tokenizer \ - --target k32w-k32w0-lock-crypto-platform-tokenizer \ - --target k32w-k32w0-lock-crypto-platform-low-power-nologs \ --target k32w-k32w0-contact-crypto-platform-tokenizer \ --target k32w-k32w0-contact-crypto-platform-low-power-nologs \ - --target k32w-k32w0-shell-crypto-platform \ --target k32w-k32w1-light-crypto-platform-openthread-ftd \ --target k32w-k32w1-contact-crypto-platform-low-power-nologs \ build \ @@ -79,12 +76,6 @@ jobs: k32w k32w1+release light \ out/artifacts/k32w-k32w1-light-crypto-platform-openthread-ftd/chip-k32w1-light-example.elf \ /tmp/bloat_reports/ - - name: Get lock size stats - run: | - .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ - k32w k32w0+release lock \ - out/artifacts/k32w-k32w0-lock-crypto-platform-tokenizer/chip-k32w0x-lock-example.elf \ - /tmp/bloat_reports/ - name: Get contact size stats run: | .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ diff --git a/.github/workflows/examples-rw61x.yaml b/.github/workflows/examples-rw61x.yaml new file mode 100644 index 00000000000000..42df03382b9249 --- /dev/null +++ b/.github/workflows/examples-rw61x.yaml @@ -0,0 +1,87 @@ +# 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. + +name: Build example - RW61X + +on: + push: + pull_request: + merge_group: + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }}-${{ (github.event_name == 'pull_request' && github.event.number) || (github.event_name == 'workflow_dispatch' && github.run_number) || github.sha }} + cancel-in-progress: true + +env: + CHIP_NO_LOG_TIMESTAMPS: true + +jobs: + rw61x: + name: RW61X + + env: + BUILD_TYPE: gn_rw61x + + runs-on: ubuntu-latest + if: github.actor != 'restyled-io[bot]' + + container: + image: ghcr.io/project-chip/chip-build-rw61x:37 + volumes: + - "/tmp/bloat_reports:/tmp/bloat_reports" + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Checkout submodules & Bootstrap + uses: ./.github/actions/checkout-submodules-and-bootstrap + with: + platform: rw61x + + - name: Set up environment for size reports + uses: ./.github/actions/setup-size-reports + if: ${{ !env.ACT }} + with: + gh-context: ${{ toJson(github) }} + + - name: Build RW61X all clusters example app + run: | + scripts/run_in_build_env.sh "\ + ./scripts/build/build_examples.py \ + --target rw61x-all-clusters-app-wifi \ + build \ + --copy-artifacts-to out/artifacts \ + " + + - name: Build RW61X thermostat example app + run: | + scripts/run_in_build_env.sh "\ + ./scripts/build/build_examples.py \ + --target rw61x-thermostat-wifi \ + build \ + --copy-artifacts-to out/artifacts \ + " + + - name: Build RW61X laundry-washer example app + run: | + scripts/run_in_build_env.sh "\ + ./scripts/build/build_examples.py \ + --target rw61x-laundry-washer-wifi \ + build \ + --copy-artifacts-to out/artifacts \ + " + - name: Uploading Size Reports + uses: ./.github/actions/upload-size-reports + if: ${{ !env.ACT }} + with: + platform-name: RW61X diff --git a/.gitmodules b/.gitmodules index 06fb7f0e347951..fa3dfcfdaea9aa 100644 --- a/.gitmodules +++ b/.gitmodules @@ -54,16 +54,16 @@ path = third_party/freertos/repo url = https://github.com/FreeRTOS/FreeRTOS-Kernel.git branch = V10.3.1-kernel-only - platforms = ameba,cc13xx_26xx,bouffalolab,esp32,k32w,infineon,qpg,cc32xx + platforms = ameba,cc13xx_26xx,bouffalolab,esp32,infineon,qpg,cc32xx [submodule "simw-top-mini"] path = third_party/simw-top-mini/repo url = https://github.com/NXP/plug-and-trust.git branch = int/CHIPSE_Release - platforms = k32w + platforms = nxp [submodule "third_party/openthread/ot-nxp"] path = third_party/openthread/ot-nxp url = https://github.com/NXP/ot-nxp.git - platforms = k32w + platforms = nxp [submodule "third_party/openthread/ot-qorvo"] path = third_party/openthread/ot-qorvo url = https://github.com/openthread/ot-qorvo.git diff --git a/docs/examples/index.md b/docs/examples/index.md index 2c9a0a4659b3bc..fc82f2a0bc9016 100644 --- a/docs/examples/index.md +++ b/docs/examples/index.md @@ -112,6 +112,15 @@ kotlin-matter-controller/README virtual-device-app/**/README ``` +## Laundry washer example + +```{toctree} +:glob: +:maxdepth: 1 + +laundry-washer-app/**/README +``` + ## Lighting example ```{toctree} diff --git a/docs/guides/nxp_k32w_android_commissioning.md b/docs/guides/nxp_k32w_android_commissioning.md index 3f1c6d1171df3c..b39a2f2afd2c8c 100644 --- a/docs/guides/nxp_k32w_android_commissioning.md +++ b/docs/guides/nxp_k32w_android_commissioning.md @@ -3,7 +3,7 @@ This article describes how to use [CHIPTool](../../examples/android/CHIPTool/README.md) for Android smartphones to commission an NXP K32W061 DK6 running -[NXP K32W Lock/Light Example Application](#building-and-programming-nxp-k32w-locklight-example-application) +[NXP K32W Light Example Application](#building-and-programming-nxp-k32w-light-example-application) onto a CHIP-enabled Thread network.
@@ -12,7 +12,7 @@ onto a CHIP-enabled Thread network. - [Requirements](#requirements) - [Building and programming OpenThread RCP firmware](#building-and-programming-openthread-rcp-firmware) - [Configuring PC as Thread Border Router](#configuring-pc-as-a-thread-border-router) -- [Building and programming NXP K32W Lock/Light Example Application](#building-and-programming-nxp-k32w-locklight-example-application) +- [Building and programming NXP K32W Light Example Application](#building-and-programming-nxp-k32w-light-example-application) - [Building and installing Android CHIPTool](#building-and-installing-android-chiptool) - [Forming a Thread network on the Border Router](#forming-a-thread-network-on-the-border-router) - [Preparing accessory device](#preparing-accessory-device) @@ -44,7 +44,7 @@ with a spare Wi-Fi card and an device. The following diagram shows the connectivity between network components required -to allow communication between devices running the CHIPTool and Lock/Light +to allow communication between devices running the CHIPTool and Light applications: ![nxp_hw_connectivity](../../examples/platform/nxp/k32w/k32w0/doc/images/nxp_hw_connectivity.JPG) @@ -345,11 +345,7 @@ To make your PC work as a Thread Border Router, complete the following tasks:
-## Building and programming NXP K32W Lock/Light Example Application - -See -[NXP K32W Lock Example Application README](../../examples/lock-app/nxp/k32w/k32w0/README.md) -to learn how to build and program the lock example onto an K32W061 DK6. +## Building and programming NXP K32W Light Example Application See [NXP K32W Light Example Application README](../../examples/lighting-app/nxp/k32w/k32w0/README.md) @@ -491,11 +487,10 @@ section, complete the following steps: 2. Verify that the text box on the screen is not empty and contains the IPv6 address of the accessory device. -3. Tap the following buttons to change the lock/light state: +3. Tap the following buttons to change the light state: - - _ON_ and _OFF_ buttons lock/turn on and unlock/turn off the door/light - bulb, respectively. - - _TOGGLE_ changes the lock/light state to the opposite. + - _ON_ and _OFF_ buttons turn on and turn off the light bulb, respectively. + - _TOGGLE_ changes the light state to the opposite. -The _LED D3_ on the device turns on or off based on the changes of the -lock/light state. +The _LED D3_ on the device turns on or off based on the changes of the light +state. diff --git a/docs/guides/nxp_manufacturing_flow.md b/docs/guides/nxp_manufacturing_flow.md index 64bafd53c89329..6cc3005b412289 100644 --- a/docs/guides/nxp_manufacturing_flow.md +++ b/docs/guides/nxp_manufacturing_flow.md @@ -1,8 +1,4 @@ ---- -orphan: true ---- - -# NXP manufacturing data guide +# NXP Manufacturing data By default, the example application is configured to use generic test certificates and provisioning data embedded with the application code. It is @@ -112,30 +108,30 @@ Here is the interpretation of the **required** parameters: --pai_cert -> path to the PAI (der format) location --spake2p_path -> path to the spake2p tool --out -> name of the binary that will be used for storing all the generated data - - ``` Here is the interpretation of the **optional** parameters: ```shell ---dac_key_password -> Password to decode DAC key ---dac_key_use_sss_blob -> Used when --dac_key contains a path to an encrypted blob, instead of the - actual DAC private key. The blob metadata size is 24, so the total length - of the resulting value is private key length (32) + 24 = 56. False by default. ---spake2p_verifier -> SPAKE2+ verifier (passed as base64 encoded string). If this option is set, - all SPAKE2+ inputs will be encoded in the final binary. The spake2p tool - will not be used to generate a new verifier on the fly. ---aes128_key -> 128 bits AES key used to encrypt the whole dataset. Please make sure - that the target application/board supports this feature: it has access to - the private key and implements a mechanism which can be used to decrypt - the factory data information. ---date -> Manufacturing Date (YYYY-MM-DD format) ---part_number -> Part number as string ---product_url -> Product URL as string ---product_label -> Product label as string ---serial_num -> Serial Number ---unique_id -> Unique id used for rotating device id generation +--dac_key_password -> Password to decode DAC key +--dac_key_use_sss_blob -> Used when --dac_key contains a path to an encrypted blob, instead of the + actual DAC private key. The blob metadata size is 24, so the total length + of the resulting value is private key length (32) + 24 = 56. False by default. +--spake2p_verifier -> SPAKE2+ verifier (passed as base64 encoded string). If this option is set, + all SPAKE2+ inputs will be encoded in the final binary. The spake2p tool + will not be used to generate a new verifier on the fly. +--aes128_key -> 128 bits AES key used to encrypt the whole dataset. Please make sure + that the target application/board supports this feature: it has access to + the private key and implements a mechanism which can be used to decrypt + the factory data information. +--date -> Manufacturing Date (YYYY-MM-DD format) +--part_number -> Part number as string +--product_url -> Product URL as string +--product_label -> Product label as string +--serial_num -> Serial Number +--unique_id -> Unique id used for rotating device id generation +--product_finish -> Visible finish of the product +--product_primary_color -> Representative color of the visible parts of the product ``` ## 3. Write provisioning data @@ -157,8 +153,18 @@ loadfile factory_data.bin 0xf4000 where `0xf4000` is the value of `__MATTER_FACTORY_DATA_START` in the corresponding .map file (can be different if using a custom linker script). -For the **RT1060**, **RT1170** and **RW61X** platform, the binary needs to be -written using `MCUXpresso Flash Tool GUI` at the address value corresponding to +For **RW61X** platform, the binary needs to be written in the internal flash at +location given by `__MATTER_FACTORY_DATA_START`, using `JLink`: + +``` +loadfile factory_data.bin 0xBFFF000 +``` + +where `0xBFFF000` is the value of `__FACTORY_DATA_START` in the corresponding +.map file (can be different if using a custom linker script). + +For the **RT1060** and **RT1170** platform, the binary needs to be written using +`MCUXpresso Flash Tool GUI` at the address value corresponding to `__FACTORY_DATA_START` (the map file of the application should be checked to get the exact value). @@ -198,6 +204,8 @@ Also, demo **DAC**, **PAI** and **PAA** certificates needed in case ## 6. Increased security for DAC private key +### 6.1 K32W1 + Supported platforms: - K32W1 - `src/plaftorm/nxp/k32w/k32w1/FactoryDataProviderImpl.h` @@ -242,3 +250,29 @@ python3 ./scripts/tools/nxp/factory_data_generator/generate.py -i 10000 -s UXKLz Please note that `--dac_key` now points to a binary file that contains the encrypted blob. + +### 6.2 RW61X + +Supported platforms: + +- RW61X - `src/plaftorm/nxp/rt/rw61x/FactoryDataProviderImpl.h` + +For platforms that have a secure subsystem (`SE50`), the DAC private key can be +converted to an encrypted blob. This blob will overwrite the DAC private key in +factory data and will be imported in the `SE50` before to sign, by the factory +data provider instance. + +The conversion process shall happen at manufacturing time and should be run one +time only: + +- Write factory data binary. +- Build the application with + `chip_with_factory_data=1 chip_convert_dac_private_key=1` set. +- Write the application to the board and let it run. + +After the conversion process: + +- Make sure the application is built with `chip_with_factory_data=1`, but + without `chip_convert_dac_private_key` arg, since conversion already + happened. +- Write the application to the board. diff --git a/docs/guides/nxp_rw61x_ota_software_update.md b/docs/guides/nxp_rw61x_ota_software_update.md index c3bd5227a054ed..9922909c5d1f7a 100644 --- a/docs/guides/nxp_rw61x_ota_software_update.md +++ b/docs/guides/nxp_rw61x_ota_software_update.md @@ -87,7 +87,8 @@ J-Link > erase 0x8000000, 0x88a0000 ``` - Using MCUXPresso, import the `mcuboot_opensource` demo example from the SDK - previously downloaded. + previously downloaded. The example can be found under the `ota_examples` + folder. ![mcuboot_demo](../../examples/platform/nxp/rt/rw61x/doc/images/mcuboot_demo.PNG) - Before building the demo example, it should be specified that the application to be run by the bootloader is monolithic. As a result, only one @@ -100,7 +101,20 @@ Right click on the Project -> Properties -> C/C++ Build -> Settings -> Tool Sett ![rw610_mcuboot_monolithic](../../examples/platform/nxp/rt/rw61x/doc/images/mcuboot_monolithic_app.PNG) -- Build the demo example project and program it to the target board. +- Build the demo example project. + +``` +Right click on the Project -> Build Project +``` + +- Program the demo example to the target board. + +``` +Right click on the Project -> Debug -> As->SEGGER JLink probes -> OK -> Select elf file +``` + +Note : The mcuboot binary is loaded in flash at address 0x8000000. + - To run the flashed demo, either press the reset button of the device or use the debugger IDE of MCUXpresso. If it runs successfully, the following logs will be displayed on the terminal : @@ -161,14 +175,14 @@ user@ubuntu: python3 imgtool.py sign --key ~/Desktop/SDK_RW612/boards/rdrw612bga Notes : -- If internal SDK is used instead, the key can be found in : - "`~/Desktop/SDK_RW612/middleware/mcuboot_opensource/boot/nxp_mcux_sdk/keys/sign-rsa2048-priv.pem`". -- The arguments `slot-size` and `max-sectors` should be adjusted to the size - of the partitions reserved for the primary and the secondary applications. - (By default the size considered is 4.4 MB) +- The arguments `slot-size` and `max-sectors` are aligned with the size of the + partitions reserved for the primary and the secondary applications. (By + default the size considered is 4.4 MB for each application). If the size of + these partitions are modified, the `slot-size` and `max-sectors` should be + adjusted accordingly. - In this example, the image is signed with the private key provided by the SDK as an example - (`/path_to_sdk/middleware/mcuboot_opensource/boot/nxp_mcux_sdk/keys/sign-rsa2048-priv.pem`), + (`SDK_RW612/boards/rdrw612bga/ota_examples/mcuboot_opensource/keys/sign-rsa2048-priv.pem`), MCUBoot is built with its corresponding public key which would be used to verify the integrity of the image. It is possible to generate a new pair of keys using the following commands. This procedure should be done prior to @@ -187,7 +201,7 @@ user@ubuntu: python3 imgtool.py getpub -k priv_key.pem ``` - The extracted public key can then be copied to the - `/path_to_sdk/middleware/mcuboot_opensource/boot/nxp_mcux_sdk/keys/sign-rsa2048-pub.c`, + `SDK_RW612/boards/rdrw612bga/ota_examples/mcuboot_opensource/keys/sign-rsa2048-pub.c`, given as a value to the rsa_pub_key[] array. The resulting output is the signed binary of the application version "1.0". diff --git a/examples/all-clusters-app/nxp/common/main/AppTask.cpp b/examples/all-clusters-app/nxp/common/main/AppTask.cpp index 9dc60db217cf9a..7f4c1f257d0405 100644 --- a/examples/all-clusters-app/nxp/common/main/AppTask.cpp +++ b/examples/all-clusters-app/nxp/common/main/AppTask.cpp @@ -2,7 +2,7 @@ * * Copyright (c) 2021-2023 Project CHIP Authors * Copyright (c) 2021 Google LLC. - * Copyright 2023 NXP + * Copyright 2023-2024 NXP * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,463 +17,41 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include "AppTask.h" -#include "AppEvent.h" #include "CHIPDeviceManager.h" -#include "DeviceCallbacks.h" -#include "binding-handler.h" -#include "lib/core/ErrorStr.h" -#include -#include -#include - -#if CHIP_DEVICE_CONFIG_ENABLE_WPA -#include -#endif // CHIP_DEVICE_CONFIG_ENABLE_WPA - -#include -#include -#include -#include -#include -#include -#include -#include - +#include "ICDUtil.h" +#include #include -#include "AppFactoryData.h" -#include "AppMatterButton.h" -#include "AppMatterCli.h" - -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR -#include "OTARequestorInitiator.h" -#endif - -#if ENABLE_OTA_PROVIDER -#include -#endif - -#if CHIP_ENABLE_OPENTHREAD -#include -#endif - -#if TCP_DOWNLOAD -#include "TcpDownload.h" -#endif - -#ifndef APP_TASK_STACK_SIZE -#define APP_TASK_STACK_SIZE ((configSTACK_DEPTH_TYPE) 6144 / sizeof(portSTACK_TYPE)) -#endif -#ifndef APP_TASK_PRIORITY -#define APP_TASK_PRIORITY 2 -#endif -#define APP_EVENT_QUEUE_SIZE 10 - -static QueueHandle_t sAppEventQueue; - using namespace chip; -using namespace chip::TLV; -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; -using namespace ::chip::DeviceManager; -using namespace ::chip::app::Clusters; - -chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; - -#if CHIP_DEVICE_CONFIG_ENABLE_WPA -namespace { -chip::app::Clusters::NetworkCommissioning::Instance - sWiFiNetworkCommissioningInstance(0 /* Endpoint Id */, - &(::chip::DeviceLayer::NetworkCommissioning::NXPWiFiDriver::GetInstance())); -} // namespace - -void NetWorkCommissioningInstInit() -{ - sWiFiNetworkCommissioningInstance.Init(); -} -#endif // CHIP_DEVICE_CONFIG_ENABLE_WPA - -AppTask AppTask::sAppTask; - -CHIP_ERROR AppTask::StartAppTask() -{ - CHIP_ERROR err = CHIP_NO_ERROR; - TaskHandle_t taskHandle; - - sAppEventQueue = xQueueCreate(APP_EVENT_QUEUE_SIZE, sizeof(AppEvent)); - if (sAppEventQueue == NULL) - { - err = CHIP_ERROR_NO_MEMORY; - ChipLogError(DeviceLayer, "Failed to allocate app event queue"); - assert(err == CHIP_NO_ERROR); - } - - if (xTaskCreate(&AppTask::AppTaskMain, "AppTaskMain", APP_TASK_STACK_SIZE, &sAppTask, APP_TASK_PRIORITY, &taskHandle) != pdPASS) - { - err = CHIP_ERROR_NO_MEMORY; - ChipLogError(DeviceLayer, "Failed to start app task"); - assert(err == CHIP_NO_ERROR); - } - - return err; -} +using namespace chip::app::Clusters; -#if CHIP_ENABLE_OPENTHREAD -void LockOpenThreadTask(void) +void AllClustersApp::AppTask::PreInitMatterStack() { - chip::DeviceLayer::ThreadStackMgr().LockThreadStack(); + ChipLogProgress(DeviceLayer, "Welcome to NXP All Clusters Demo App"); } -void UnlockOpenThreadTask(void) +void AllClustersApp::AppTask::PostInitMatterStack() { - chip::DeviceLayer::ThreadStackMgr().UnlockThreadStack(); + chip::app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(&chip::NXP::App::GetICDUtil()); } -#endif -void AppTask::InitServer(intptr_t arg) +void AllClustersApp::AppTask::PostInitMatterServerInstance() { - static chip::CommonCaseDeviceServerInitParams initParams; - (void) initParams.InitializeStaticResourcesBeforeServerInit(); - -#if CHIP_ENABLE_OPENTHREAD - // Init ZCL Data Model and start server - chip::Inet::EndPointStateOpenThread::OpenThreadEndpointInitParam nativeParams; - nativeParams.lockCb = LockOpenThreadTask; - nativeParams.unlockCb = UnlockOpenThreadTask; - nativeParams.openThreadInstancePtr = chip::DeviceLayer::ThreadStackMgrImpl().OTInstance(); - initParams.endpointNativeParams = static_cast(&nativeParams); -#endif - VerifyOrDie((chip::Server::GetInstance().Init(initParams)) == CHIP_NO_ERROR); - - gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); - chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); - -#ifdef DEVICE_TYPE_ALL_CLUSTERS // Disable last fixed endpoint, which is used as a placeholder for all of the // supported clusters so that ZAP will generated the requisite code. emberAfEndpointEnableDisable(emberAfEndpointFromIndex(static_cast(emberAfFixedEndpointCount() - 1)), false); -#endif /* DEVICE_TYPE_ALL_CLUSTERS */ - -#if ENABLE_OTA_PROVIDER - InitOTAServer(); -#endif -} - -CHIP_ERROR AppTask::Init() -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - /* Init Chip memory management before the stack */ - chip::Platform::MemoryInit(); - - /* Initialize Matter factory data before initializing the Matter stack */ - err = AppFactoryData_PreMatterStackInit(); - - if (err != CHIP_NO_ERROR) - { - ChipLogError(DeviceLayer, "Pre Factory Data Provider init failed"); - goto exit; - } - - /* - * Initialize the CHIP stack. - * Would also initialize all required platform modules - */ - err = PlatformMgr().InitChipStack(); - if (err != CHIP_NO_ERROR) - { - ChipLogError(DeviceLayer, "PlatformMgr().InitChipStack() failed: %s", ErrorStr(err)); - goto exit; - } - - /* Initialize Matter factory data after initializing the Matter stack */ - err = AppFactoryData_PostMatterStackInit(); - if (err != CHIP_NO_ERROR) - { - ChipLogError(DeviceLayer, "Post Factory Data Provider init failed"); - goto exit; - } - - /* - * Register all application callbacks allowing to be informed of stack events - */ - err = CHIPDeviceManager::GetInstance().Init(&deviceCallbacks); - if (err != CHIP_NO_ERROR) - { - ChipLogError(DeviceLayer, "CHIPDeviceManager.Init() failed: %s", ErrorStr(err)); - goto exit; - } - -#if CHIP_DEVICE_CONFIG_ENABLE_WPA - ConnectivityMgrImpl().StartWiFiManagement(); -#endif - -#if CHIP_ENABLE_OPENTHREAD - err = ThreadStackMgr().InitThreadStack(); - if (err != CHIP_NO_ERROR) - { - ChipLogError(DeviceLayer, "Error during ThreadStackMgr().InitThreadStack()"); - goto exit; - } - - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); - if (err != CHIP_NO_ERROR) - { - goto exit; - } -#endif - - /* - * Schedule an event to the Matter stack to initialize - * the ZCL Data Model and start server - */ - PlatformMgr().ScheduleWork(InitServer, 0); - - /* Init binding handlers */ - err = InitBindingHandlers(); - if (err != CHIP_NO_ERROR) - { - ChipLogError(DeviceLayer, "InitBindingHandlers failed: %s", ErrorStr(err)); - goto exit; - } - -#if CHIP_DEVICE_CONFIG_ENABLE_WPA - NetWorkCommissioningInstInit(); -#endif // CHIP_DEVICE_CONFIG_ENABLE_WPA - -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - /* If an update is under test make it permanent */ - OTARequestorInitiator::Instance().HandleSelfTest(); -#endif - - /* Register Matter CLI cmds */ - err = AppMatterCli_RegisterCommands(); - if (err != CHIP_NO_ERROR) - { - ChipLogError(DeviceLayer, "Error during AppMatterCli_RegisterCommands"); - goto exit; - } - /* Register Matter buttons */ - err = AppMatterButton_registerButtons(); - if (err != CHIP_NO_ERROR) - { - ChipLogError(DeviceLayer, "Error during AppMatterButton_registerButtons"); - goto exit; - } - - err = DisplayDeviceInformation(); - if (err != CHIP_NO_ERROR) - goto exit; - - /* Start a task to run the CHIP Device event loop. */ - err = PlatformMgr().StartEventLoopTask(); - if (err != CHIP_NO_ERROR) - { - ChipLogError(DeviceLayer, "Error during PlatformMgr().StartEventLoopTask()"); - goto exit; - } - -#if CHIP_ENABLE_OPENTHREAD - // Start OpenThread task - err = ThreadStackMgrImpl().StartThreadTask(); - if (err != CHIP_NO_ERROR) - { - ChipLogError(DeviceLayer, "Error during ThreadStackMgrImpl().StartThreadTask()"); - goto exit; - } -#endif - -#if TCP_DOWNLOAD - EnableTcpDownloadComponent(); -#endif - -exit: - return err; -} - -void AppTask::AppTaskMain(void * pvParameter) -{ - AppTask * task = (AppTask *) pvParameter; - CHIP_ERROR err; - AppEvent event; - - ChipLogProgress(DeviceLayer, "Welcome to NXP All Clusters Demo App"); - - err = task->Init(); - if (err != CHIP_NO_ERROR) - { - ChipLogError(DeviceLayer, "AppTask.Init() failed"); - assert(err == CHIP_NO_ERROR); - } - - while (true) - { - BaseType_t eventReceived = xQueueReceive(sAppEventQueue, &event, portMAX_DELAY); - while (eventReceived == pdTRUE) - { - sAppTask.DispatchEvent(&event); - eventReceived = xQueueReceive(sAppEventQueue, &event, 0); - } - } -} - -CHIP_ERROR AppTask::DisplayDeviceInformation(void) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - uint16_t discriminator; - uint32_t setupPasscode; - uint16_t vendorId; - uint16_t productId; - char currentSoftwareVer[ConfigurationManager::kMaxSoftwareVersionStringLength + 1]; - - err = GetCommissionableDataProvider()->GetSetupDiscriminator(discriminator); - if (err != CHIP_NO_ERROR) - { - ChipLogError(DeviceLayer, "Couldn't get discriminator: %s", ErrorStr(err)); - goto exit; - } - ChipLogProgress(DeviceLayer, "Setup discriminator: %u (0x%x)", discriminator, discriminator); - - err = GetCommissionableDataProvider()->GetSetupPasscode(setupPasscode); - if (err != CHIP_NO_ERROR) - { - ChipLogError(DeviceLayer, "Couldn't get setupPasscode: %s", ErrorStr(err)); - goto exit; - } - ChipLogProgress(DeviceLayer, "Setup passcode: %lu (0x%lx)", setupPasscode, setupPasscode); - - err = GetDeviceInstanceInfoProvider()->GetVendorId(vendorId); - if (err != CHIP_NO_ERROR) - { - ChipLogError(DeviceLayer, "Couldn't get vendorId: %s", ErrorStr(err)); - goto exit; - } - ChipLogProgress(DeviceLayer, "Vendor ID: %u (0x%x)", vendorId, vendorId); - - err = GetDeviceInstanceInfoProvider()->GetProductId(productId); - if (err != CHIP_NO_ERROR) - { - ChipLogError(DeviceLayer, "Couldn't get productId: %s", ErrorStr(err)); - goto exit; - } - ChipLogProgress(DeviceLayer, "nProduct ID: %u (0x%x)", productId, productId); - - // QR code will be used with CHIP Tool -#if CONFIG_NETWORK_LAYER_BLE - PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kBLE)); -#else - PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kOnNetwork)); -#endif /* CONFIG_NETWORK_LAYER_BLE */ - - err = ConfigurationMgr().GetSoftwareVersionString(currentSoftwareVer, sizeof(currentSoftwareVer)); - if (err != CHIP_NO_ERROR) - { - ChipLogError(DeviceLayer, "Get current software version error"); - goto exit; - } - - ChipLogProgress(DeviceLayer, "Current Software Version: %s", currentSoftwareVer); - -exit: - return err; -} - -void AppTask::PostEvent(const AppEvent * aEvent) -{ - if (sAppEventQueue != NULL) - { - if (!xQueueSend(sAppEventQueue, aEvent, 0)) - { - ChipLogError(DeviceLayer, "Failed to post event to app task event queue"); - } - } -} - -void AppTask::DispatchEvent(AppEvent * aEvent) -{ - if (aEvent->Handler) - { - aEvent->Handler(aEvent); - } - else - { - ChipLogProgress(DeviceLayer, "Event received with no handler. Dropping event."); - } -} - -void AppTask::StartCommissioning(intptr_t arg) -{ - /* Check the status of the commissioning */ - if (ConfigurationMgr().IsFullyProvisioned()) - { - ChipLogProgress(DeviceLayer, "Device already commissioned"); - } - else if (chip::Server::GetInstance().GetCommissioningWindowManager().IsCommissioningWindowOpen()) - { - ChipLogProgress(DeviceLayer, "Commissioning window already opened"); - } - else - { - chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow(); - } -} - -void AppTask::StopCommissioning(intptr_t arg) -{ - /* Check the status of the commissioning */ - if (ConfigurationMgr().IsFullyProvisioned()) - { - ChipLogProgress(DeviceLayer, "Device already commissioned"); - } - else if (!chip::Server::GetInstance().GetCommissioningWindowManager().IsCommissioningWindowOpen()) - { - ChipLogProgress(DeviceLayer, "Commissioning window not opened"); - } - else - { - chip::Server::GetInstance().GetCommissioningWindowManager().CloseCommissioningWindow(); - } -} - -void AppTask::SwitchCommissioningState(intptr_t arg) -{ - /* Check the status of the commissioning */ - if (ConfigurationMgr().IsFullyProvisioned()) - { - ChipLogProgress(DeviceLayer, "Device already commissioned"); - } - else if (!chip::Server::GetInstance().GetCommissioningWindowManager().IsCommissioningWindowOpen()) - { - chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow(); - } - else - { - chip::Server::GetInstance().GetCommissioningWindowManager().CloseCommissioningWindow(); - } -} - -void AppTask::StartCommissioningHandler(void) -{ - /* Publish an event to the Matter task to always set the commissioning state in the Matter task context */ - PlatformMgr().ScheduleWork(StartCommissioning, 0); -} - -void AppTask::StopCommissioningHandler(void) -{ - /* Publish an event to the Matter task to always set the commissioning state in the Matter task context */ - PlatformMgr().ScheduleWork(StopCommissioning, 0); } -void AppTask::SwitchCommissioningStateHandler(void) +// This returns an instance of this class. +AllClustersApp::AppTask & AllClustersApp::AppTask::GetDefaultInstance() { - /* Publish an event to the Matter task to always set the commissioning state in the Matter task context */ - PlatformMgr().ScheduleWork(SwitchCommissioningState, 0); + static AllClustersApp::AppTask sAppTask; + return sAppTask; } -void AppTask::FactoryResetHandler(void) +chip::NXP::App::AppTaskBase & chip::NXP::App::GetAppTask() { - /* Emit the ShutDown event before factory reset */ - chip::Server::GetInstance().GenerateShutDownEvent(); - chip::Server::GetInstance().ScheduleFactoryReset(); + return AllClustersApp::AppTask::GetDefaultInstance(); } diff --git a/examples/all-clusters-app/nxp/common/main/DeviceCallbacks.cpp b/examples/all-clusters-app/nxp/common/main/DeviceCallbacks.cpp index 419ad3b3003b2e..527fa79702f6fb 100644 --- a/examples/all-clusters-app/nxp/common/main/DeviceCallbacks.cpp +++ b/examples/all-clusters-app/nxp/common/main/DeviceCallbacks.cpp @@ -24,154 +24,96 @@ **/ #include "DeviceCallbacks.h" +#include +#include #include +#include #include #include #include -#if CHIP_ENABLE_OPENTHREAD && CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED -#include "openthread-system.h" -#include "ot_platform_common.h" -#endif /* CHIP_ENABLE_OPENTHREAD && CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED */ -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR -#include "OTARequestorInitiator.h" -#endif +using namespace chip::app; +void OnTriggerEffect(::Identify * identify) +{ + switch (identify->mCurrentEffectIdentifier) + { + case Clusters::Identify::EffectIdentifierEnum::kBlink: + ChipLogProgress(Zcl, "Clusters::Identify::EffectIdentifierEnum::kBlink"); + break; + case Clusters::Identify::EffectIdentifierEnum::kBreathe: + ChipLogProgress(Zcl, "Clusters::Identify::EffectIdentifierEnum::kBreathe"); + break; + case Clusters::Identify::EffectIdentifierEnum::kOkay: + ChipLogProgress(Zcl, "Clusters::Identify::EffectIdentifierEnum::kOkay"); + break; + case Clusters::Identify::EffectIdentifierEnum::kChannelChange: + ChipLogProgress(Zcl, "Clusters::Identify::EffectIdentifierEnum::kChannelChange"); + break; + default: + ChipLogProgress(Zcl, "No identifier effect"); + return; + } +} Identify gIdentify0 = { chip::EndpointId{ 1 }, [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStart"); }, [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStop"); }, - chip::app::Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator, - [](Identify *) { ChipLogProgress(Zcl, "onIdentifyTriggerEffect"); }, + chip::app::Clusters::Identify::IdentifyTypeEnum::kNone, + OnTriggerEffect, }; Identify gIdentify1 = { chip::EndpointId{ 1 }, [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStart"); }, [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStop"); }, - chip::app::Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator, - [](Identify *) { ChipLogProgress(Zcl, "onIdentifyTriggerEffect"); }, + chip::app::Clusters::Identify::IdentifyTypeEnum::kNone, + OnTriggerEffect, }; using namespace ::chip; using namespace ::chip::Inet; using namespace ::chip::System; using namespace ::chip::DeviceLayer; +using namespace chip::app::Clusters; -void DeviceCallbacks::DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) -{ - ChipLogDetail(DeviceLayer, "DeviceEventCallback: 0x%04x", event->Type); - switch (event->Type) - { - case DeviceEventType::kWiFiConnectivityChange: - OnWiFiConnectivityChange(event); - break; - - case DeviceEventType::kInternetConnectivityChange: - OnInternetConnectivityChange(event); - break; - - case DeviceEventType::kInterfaceIpAddressChanged: - OnInterfaceIpAddressChanged(event); - break; - -#if CHIP_ENABLE_OPENTHREAD && CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED - case DeviceEventType::kCommissioningComplete: - DeviceCallbacks::OnComissioningComplete(event); - break; -#endif - case DeviceLayer::DeviceEventType::kDnssdInitialized: - ChipLogProgress(DeviceLayer, "kDnssdInitialized"); -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - /* Initialize OTA Requestor */ - OTARequestorInitiator::Instance().InitOTA(reinterpret_cast(&OTARequestorInitiator::Instance())); -#endif - break; - } -} - -void DeviceCallbacks::PostAttributeChangeCallback(EndpointId endpointId, ClusterId clusterId, AttributeId attributeId, uint8_t type, - uint16_t size, uint8_t * value) +void AllClustersApp::DeviceCallbacks::PostAttributeChangeCallback(EndpointId endpointId, ClusterId clusterId, + AttributeId attributeId, uint8_t type, uint16_t size, + uint8_t * value) { ChipLogProgress(DeviceLayer, "endpointId " ChipLogFormatMEI " clusterId " ChipLogFormatMEI " attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u", ChipLogValueMEI(endpointId), ChipLogValueMEI(clusterId), ChipLogValueMEI(attributeId), type, *value, size); -} - -void DeviceCallbacks::OnWiFiConnectivityChange(const ChipDeviceEvent * event) -{ - if (event->WiFiConnectivityChange.Result == kConnectivity_Established) - { - ChipLogProgress(DeviceLayer, "WiFi connection established"); - } - else if (event->WiFiConnectivityChange.Result == kConnectivity_Lost) + switch (clusterId) { - ChipLogProgress(DeviceLayer, "WiFi connection lost"); + case Clusters::OnOff::Id: + OnOnOffPostAttributeChangeCallback(endpointId, attributeId, value); + break; } } -void DeviceCallbacks::OnInternetConnectivityChange(const ChipDeviceEvent * event) +void AllClustersApp::DeviceCallbacks::OnOnOffPostAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, + uint8_t * value) { - if (event->InternetConnectivityChange.IPv4 == kConnectivity_Established) - { - char ip_addr[Inet::IPAddress::kMaxStringLength]; - event->InternetConnectivityChange.ipAddress.ToString(ip_addr); - ChipLogProgress(DeviceLayer, "Server ready at: %s:%d", ip_addr, CHIP_PORT); - } - else if (event->InternetConnectivityChange.IPv4 == kConnectivity_Lost) - { - ChipLogProgress(DeviceLayer, "Lost IPv4 connectivity..."); - } - if (event->InternetConnectivityChange.IPv6 == kConnectivity_Established) - { - char ip_addr[Inet::IPAddress::kMaxStringLength]; - event->InternetConnectivityChange.ipAddress.ToString(ip_addr); - ChipLogProgress(DeviceLayer, "IPv6 Server ready at: [%s]:%d", ip_addr, CHIP_PORT); - } - else if (event->InternetConnectivityChange.IPv6 == kConnectivity_Lost) + switch (attributeId) { - ChipLogProgress(DeviceLayer, "Lost IPv6 connectivity..."); + case Clusters::OnOff::Attributes::OnOff::Id: + break; + + default:; } } -void DeviceCallbacks::OnInterfaceIpAddressChanged(const ChipDeviceEvent * event) +// This returns an instance of this class. +AllClustersApp::DeviceCallbacks & AllClustersApp::DeviceCallbacks::GetDefaultInstance() { - switch (event->InterfaceIpAddressChanged.Type) - { - case InterfaceIpChangeType::kIpV4_Assigned: - ChipLogProgress(DeviceLayer, "Interface IPv4 address assigned"); - break; - case InterfaceIpChangeType::kIpV4_Lost: - ChipLogProgress(DeviceLayer, "Interface IPv4 address lost"); - break; - case InterfaceIpChangeType::kIpV6_Assigned: - ChipLogProgress(DeviceLayer, "Interface IPv6 address assigned"); - break; - case InterfaceIpChangeType::kIpV6_Lost: - ChipLogProgress(DeviceLayer, "Interface IPv6 address lost"); - break; - } + static AllClustersApp::DeviceCallbacks sDeviceCallbacks; + return sDeviceCallbacks; } -#if CHIP_ENABLE_OPENTHREAD && CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED -void DeviceCallbacks::OnComissioningComplete(const chip::DeviceLayer::ChipDeviceEvent * event) +chip::DeviceManager::CHIPDeviceManagerCallbacks & chip::NXP::App::GetDeviceCallbacks() { - /* - * If a transceiver supporting a multiprotocol scenario is used, a check of the provisioning state is required, - * so that we can inform the transceiver to stop BLE to give the priority to another protocol. - * For example it is the case when a K32W0 transceiver supporting OT+BLE+Zigbee is used. When the device is already provisioned, - * BLE is no more required and the transceiver needs to be informed so that Zigbee can be switched on and BLE switched off. - * - * If a transceiver does not support such vendor property the cmd would be ignored. - */ - if (ConfigurationMgr().IsFullyProvisioned()) - { - ChipLogDetail(DeviceLayer, "Provisioning complete, stopping BLE\n"); - ThreadStackMgrImpl().LockThreadStack(); - PlatformMgrImpl().StopBLEConnectivity(); - ThreadStackMgrImpl().UnlockThreadStack(); - } + return AllClustersApp::DeviceCallbacks::GetDefaultInstance(); } -#endif diff --git a/examples/all-clusters-app/nxp/common/main/include/AppEvent.h b/examples/all-clusters-app/nxp/common/main/include/AppEvent.h index 8047da99982e23..a0dad141a27055 100644 --- a/examples/all-clusters-app/nxp/common/main/include/AppEvent.h +++ b/examples/all-clusters-app/nxp/common/main/include/AppEvent.h @@ -19,7 +19,7 @@ #pragma once struct AppEvent; -typedef void (*EventHandler)(AppEvent *); +using EventHandler = void (*)(const AppEvent &); struct AppEvent { diff --git a/examples/all-clusters-app/nxp/common/main/include/AppTask.h b/examples/all-clusters-app/nxp/common/main/include/AppTask.h index e276e287aa92a6..9bda003e25344a 100644 --- a/examples/all-clusters-app/nxp/common/main/include/AppTask.h +++ b/examples/all-clusters-app/nxp/common/main/include/AppTask.h @@ -2,6 +2,7 @@ * * Copyright (c) 2020 Project CHIP Authors * Copyright (c) 2021-2023 Google LLC. + * Copyright 2024 NXP * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,47 +20,31 @@ #pragma once -#include -#include - -#include "AppEvent.h" -#include "DeviceCallbacks.h" - -class AppTask +#if CONFIG_APP_FREERTOS_OS +#include "AppTaskFreeRTOS.h" +#else +#include "AppTaskZephyr.h" +#endif +namespace AllClustersApp { +#if CONFIG_APP_FREERTOS_OS +class AppTask : public chip::NXP::App::AppTaskFreeRTOS +#else +class AppTask : public chip::NXP::App::AppTaskZephyr +#endif { public: - CHIP_ERROR StartAppTask(); - static void AppTaskMain(void * pvParameter); - - void PostEvent(const AppEvent * event); - - /* Commissioning handlers */ - void StartCommissioningHandler(void); - void StopCommissioningHandler(void); - void SwitchCommissioningStateHandler(void); - - /* FactoryResetHandler */ - void FactoryResetHandler(void); - -private: - DeviceCallbacks deviceCallbacks; - - friend AppTask & GetAppTask(void); - - CHIP_ERROR Init(); - void DispatchEvent(AppEvent * event); - CHIP_ERROR DisplayDeviceInformation(void); - - /* Functions that would be called in the Matter task context */ - static void StartCommissioning(intptr_t arg); - static void StopCommissioning(intptr_t arg); - static void SwitchCommissioningState(intptr_t arg); - static void InitServer(intptr_t arg); - - static AppTask sAppTask; + ~AppTask() override{}; + void PreInitMatterStack(void) override; + void PostInitMatterStack(void) override; + void PostInitMatterServerInstance(void) override; + // This returns an instance of this class. + static AppTask & GetDefaultInstance(); }; - -inline AppTask & GetAppTask(void) -{ - return AppTask::sAppTask; -} +} // namespace AllClustersApp +/** + * Returns the application-specific implementation of the AppTaskBase object. + * + * Applications can use this to gain access to features of the AppTaskBase + * that are specific to the selected application. + */ +chip::NXP::App::AppTaskBase & GetAppTask(); diff --git a/examples/all-clusters-app/nxp/common/main/include/DeviceCallbacks.h b/examples/all-clusters-app/nxp/common/main/include/DeviceCallbacks.h index 2a37a2dfb99a94..748905b52ad736 100644 --- a/examples/all-clusters-app/nxp/common/main/include/DeviceCallbacks.h +++ b/examples/all-clusters-app/nxp/common/main/include/DeviceCallbacks.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020-2023 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,24 +26,27 @@ #pragma once #include "CHIPDeviceManager.h" -#include -#include +#include "CommonDeviceCallbacks.h" -class DeviceCallbacks : public chip::DeviceManager::CHIPDeviceManagerCallbacks +namespace AllClustersApp { +class DeviceCallbacks : public chip::NXP::App::CommonDeviceCallbacks { public: - virtual void DeviceEventCallback(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); - virtual void PostAttributeChangeCallback(chip::EndpointId endpointId, chip::ClusterId clusterId, chip::AttributeId attributeId, - uint8_t type, uint16_t size, uint8_t * value); + // This returns an instance of this class. + static DeviceCallbacks & GetDefaultInstance(); + void PostAttributeChangeCallback(chip::EndpointId endpointId, chip::ClusterId clusterId, chip::AttributeId attributeId, + uint8_t type, uint16_t size, uint8_t * value); private: - void OnWiFiConnectivityChange(const chip::DeviceLayer::ChipDeviceEvent * event); - void OnInternetConnectivityChange(const chip::DeviceLayer::ChipDeviceEvent * event); - void OnSessionEstablished(const chip::DeviceLayer::ChipDeviceEvent * event); - void OnInterfaceIpAddressChanged(const chip::DeviceLayer::ChipDeviceEvent * event); void OnOnOffPostAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value); void OnIdentifyPostAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value); -#if CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED - void OnComissioningComplete(const chip::DeviceLayer::ChipDeviceEvent * event); -#endif }; + +/** + * Returns the application-specific implementation of the CommonDeviceCallbacks object. + * + * Applications can use this to gain access to features of the CommonDeviceCallbacks + * that are specific to the selected application. + */ +chip::DeviceManager::CHIPDeviceManagerCallbacks & GetDeviceCallbacks(); +} // namespace AllClustersApp diff --git a/examples/all-clusters-app/nxp/common/main/main.cpp b/examples/all-clusters-app/nxp/common/main/main.cpp index c2305cf9ac4eb6..b2aadab98ceb8b 100644 --- a/examples/all-clusters-app/nxp/common/main/main.cpp +++ b/examples/all-clusters-app/nxp/common/main/main.cpp @@ -37,7 +37,7 @@ extern "C" int main(int argc, char * argv[]) TaskHandle_t taskHandle; PlatformMgrImpl().HardwareInit(); - GetAppTask().StartAppTask(); + chip::NXP::App::GetAppTask().Start(); vTaskStartScheduler(); } diff --git a/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn b/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn index 6f167c92ce5be2..02cce50f266eb1 100644 --- a/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn +++ b/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn @@ -35,24 +35,42 @@ assert(target_os == "freertos") assert(nxp_platform == "rt/rw61x") declare_args() { - # This defines the device type as a "thermostat" by default, - # use "all-clusters" in order to build the all-clusters-app - nxp_device_type = "thermostat" + # Allows to start the tcp download test app + tcp_download = false + + # Allows to start the wifi connect test app + wifi_connect = false + + # The 2 params below are used only if tcp_download or wifi_connect are true, otherwise they're unused. + wifi_ssid = "" + wifi_password = "" + + # Setup discriminator as argument + setup_discriminator = 3840 } example_platform_dir = "${chip_root}/examples/platform/nxp/${nxp_platform}" +common_example_dir = "${chip_root}/examples/platform/nxp/common" -if (nxp_device_type == "thermostat") { - app_common_folder = "${nxp_device_type}/nxp/zap" -} else { - app_common_folder = "${nxp_device_type}-app/${nxp_device_type}-common" +if (tcp_download == true && wifi_connect == true) { + assert("Cannot enable tcp_download and wifi_connect at the same time!") } +app_common_folder = "all-clusters-app/all-clusters-common" + # Create here the SDK instance. # Particular sources/defines/includes could be added/changed depending on the target application. rt_sdk("sdk") { defines = [] + # To be moved, temporary mbedtls config fix to build app with factory data + if (chip_enable_secure_dac_private_key_storage == 1) { + defines += [ + "MBEDTLS_NIST_KW_C", + "MBEDTLS_PSA_CRYPTO_CLIENT", + ] + } + cflags = [] public_deps = [] public_configs = [] @@ -75,6 +93,15 @@ rt_sdk("sdk") { # Indicate the default path to OpenThreadConfig.h include_dirs += [ "${example_platform_dir}/app/project_include/openthread" ] + + # For matter with BR feature, increase FreeRTOS heap size + if (chip_enable_wifi && chip_enable_openthread) { + defines += [ "configTOTAL_HEAP_SIZE=(size_t)(160 * 1024)" ] + } + + defines += [ + "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setup_discriminator}", + ] } # Create the SDK driver instance. @@ -85,12 +112,18 @@ rw61x_sdk_drivers("sdk_driver") { rt_executable("all_cluster_app") { output_name = "chip-rw61x-all-cluster-example" - defines = [ "CONFIG_RENDEZVOUS_MODE=7" ] + defines = [ + "CONFIG_RENDEZVOUS_MODE=7", + "CONFIG_APP_FREERTOS_OS=1", + ] + + if (chip_enable_openthread) { + defines += [ "CONFIG_NET_L2_OPENTHREAD=1" ] + } include_dirs = [ "../../common/main/include", "../../common/main", - "${chip_root}/examples/all-clusters-app/all-clusters-common/include", "${chip_root}/examples/providers/", ] @@ -98,34 +131,54 @@ rt_executable("all_cluster_app") { sources = [ "${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp", "${chip_root}/examples/providers/DeviceInfoProviderImpl.cpp", - "../../common/main/AppFactoryDataDefaultImpl.cpp", - "../../common/main/AppMatterButtonEmpty.cpp", - "../../common/main/AppMatterCli.cpp", "../../common/main/AppTask.cpp", - "../../common/main/CHIPDeviceManager.cpp", "../../common/main/DeviceCallbacks.cpp", "../../common/main/ZclCallbacks.cpp", "../../common/main/include/AppEvent.h", "../../common/main/include/AppTask.h", - "../../common/main/include/CHIPDeviceManager.h", "../../common/main/include/DeviceCallbacks.h", "../../common/main/main.cpp", ] - deps = [ "${chip_root}/examples/${app_common_folder}" ] - - if (nxp_device_type == "all-clusters") { - defines += [ "DEVICE_TYPE_ALL_CLUSTERS" ] + if (chip_enable_secure_dac_private_key_storage == 1) { + sources += [ + "${example_platform_dir}/factory_data/source/AppFactoryDataExample.cpp", + ] + } else { sources += [ - "${chip_root}/examples/${app_common_folder}/src/EnergyEvseDelegateImpl.cpp", - "${chip_root}/examples/${app_common_folder}/src/EnergyEvseManager.cpp", - "${chip_root}/examples/${app_common_folder}/src/bridged-actions-stub.cpp", - "${chip_root}/examples/${app_common_folder}/src/energy-evse-stub.cpp", - "${chip_root}/examples/${app_common_folder}/src/smco-stub.cpp", - "${chip_root}/examples/${app_common_folder}/src/static-supported-modes-manager.cpp", + "${common_example_dir}/factory_data/source/AppFactoryDataDefaultImpl.cpp", ] } + # App common files + include_dirs += [ + "${common_example_dir}/icd/include", + "${common_example_dir}/matter_button/include", + "${common_example_dir}/matter_cli/include", + "${common_example_dir}/device_manager/include", + "${common_example_dir}/device_callbacks/include", + "${common_example_dir}/app_task/include", + "${common_example_dir}/factory_data/include", + ] + + sources += [ + "${common_example_dir}/app_task/source/AppTaskBase.cpp", + "${common_example_dir}/app_task/source/AppTaskFreeRTOS.cpp", + "${common_example_dir}/device_callbacks/source/CommonDeviceCallbacks.cpp", + "${common_example_dir}/device_manager/source/CHIPDeviceManager.cpp", + "${common_example_dir}/icd/source/ICDUtil.cpp", + "${common_example_dir}/matter_button/source/AppMatterButtonEmpty.cpp", + "${common_example_dir}/matter_cli/source/AppMatterCli.cpp", + ] + + deps = [ "${chip_root}/examples/${app_common_folder}" ] + + sources += [ + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", + ] + if (chip_enable_matter_cli) { defines += [ "ENABLE_CHIP_SHELL" ] deps += [ @@ -135,17 +188,53 @@ rt_executable("all_cluster_app") { } if (chip_enable_ota_requestor) { + include_dirs += [ "${common_example_dir}/ota_requestor/include" ] sources += [ - "${chip_root}/examples/platform/nxp/common/OTARequestorInitiator.cpp", - "${chip_root}/examples/platform/nxp/common/OTARequestorInitiator.h", + "${common_example_dir}/ota_requestor/source/OTARequestorInitiator.cpp", + "${common_example_dir}/ota_requestor/source/OTARequestorInitiatorCommon.cpp", + ] + } + + if (wifi_connect) { + defines += [ + "WIFI_CONNECT_TASK=1", + "WIFI_CONNECT=1", + ] + + if (!chip_enable_matter_cli) { + assert(wifi_ssid != "" && wifi_password != "", + "WiFi SSID and password must be specified at build time!") + } + + if (wifi_ssid != "") { + defines += [ "WIFI_SSID=\"${wifi_ssid}\"" ] + } + + if (wifi_password != "") { + defines += [ "WIFI_PASSWORD=\"${wifi_password}\"" ] + } + + include_dirs += [ "${common_example_dir}/wifi_connect/include" ] + sources += [ "${common_example_dir}/wifi_connect/source/WifiConnect.cpp" ] + } + + if (tcp_download) { + defines += [ "CONFIG_CHIP_TCP_DOWNLOAD=1" ] + defines += [ + "WIFI_CONNECT=1", + "WIFI_SSID=\"${wifi_ssid}\"", + "WIFI_PASSWORD=\"${wifi_password}\"", ] - include_dirs += [ "${chip_root}/examples/platform/nxp/common" ] + + include_dirs += [ "${common_example_dir}/tcp_download_test/include" ] + sources += + [ "${common_example_dir}/tcp_download_test/source/TcpDownload.cpp" ] } # In case a dedicated assert function needs to be supported the flag sdk_fsl_assert_support should be set to false # The would add to the build a dedicated application assert implementation. if (!sdk_fsl_assert_support) { - sources += [ "../../common/main/AppAssert.cpp" ] + sources += [ "${common_example_dir}/app_assert/source/AppAssert.cpp" ] } cflags = [ "-Wconversion" ] diff --git a/examples/all-clusters-app/nxp/rt/rw61x/README.md b/examples/all-clusters-app/nxp/rt/rw61x/README.md index d5b436d9fee8e1..8a6889909dffa3 100644 --- a/examples/all-clusters-app/nxp/rt/rw61x/README.md +++ b/examples/all-clusters-app/nxp/rt/rw61x/README.md @@ -25,13 +25,13 @@ commissioning and different cluster control. The RW61x all-cluster application provides a working demonstration of the RW610/RW612 board integration, built using the Project CHIP codebase and the NXP -RW612 SDK. The example supports basic ZCL commands and acts as a thermostat -device-type. +RW612 SDK. The example supports: - Matter over Wi-Fi - Matter over Openthread +- Matter over Wi-Fi with OpenThread Border Router support. ### Hardware requirements @@ -46,6 +46,12 @@ For Matter over WiFi configuration : - BLE antenna (to plug in Ant1) - Wi-Fi antenna (to plug in Ant2) +For Matter over Wi-Fi with OpenThread Border Router : + +- [`NXP RD-RW612-BGA`] board +- BLE/15.4 antenna (to plug in Ant1) +- Wi-Fi antenna (to plug in Ant2) + ## Building @@ -56,22 +62,26 @@ distribution (the demo-application was compiled on Ubuntu 20.04). - Follow instruction in [BUILDING.md](../../../../../docs/guides/BUILDING.md) to setup the environment to be able to build Matter. -- Download [RD-RW612 SDK v2.13.1](https://mcuxpresso.nxp.com/en/select). +- Download + [RD-RW612 SDK for Project CHIP](https://mcuxpresso.nxp.com/en/select). Creating an nxp.com account is required before being able to download the SDK. Once the account is created, login and follow the steps for downloading SDK. The SDK Builder UI selection should be similar with the one from the - image below. In case you do not have access to the SDK, please ask your NXP - representative. + image below. ![MCUXpresso SDK Download](../../../../platform/nxp/rt/rw61x/doc/images/mcux-sdk-download.PNG) (Note: All SDK components should be selected. If size is an issue Azure RTOS component can be omitted.) + Please refer to Matter release notes for getting the latest released SDK. + - Start building the application. ``` user@ubuntu:~/Desktop/git/connectedhomeip$ export NXP_SDK_ROOT=/home/user/Desktop/SDK_RW612/ +user@ubuntu:~/Desktop/git/connectedhomeip$ scripts/checkout_submodules.py --shallow --platform nxp --recursive +user@ubuntu:~/Desktop/git/connectedhomeip$ source ./scripts/bootstrap.sh user@ubuntu:~/Desktop/git/connectedhomeip$ source ./scripts/activate.sh user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/all-clusters-app/nxp/rt/rw61x/ ``` @@ -87,13 +97,26 @@ user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rw61x #### Building with Matter over Thread configuration on RW612 -- Build the Openthread configuration with BLE commissioning. +- Build Matter-over-Thread configuration with BLE commissioning. ``` user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rw61x$ gn gen --args="chip_enable_openthread=true chip_inet_config_enable_ipv4=false chip_config_network_layer_ble=true is_sdk_package=true" out/debug user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rw61x$ ninja -C out/debug ``` +#### Building with Matter over Wifi + OpenThread Border Router configuration on RW612 + +This configuration requires enabling the Matter CLI in order to control the +Thread network on the Border Router. + +- Build Matter with Border Router configuration with BLE commissioning + (ble-wifi) : + +``` +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rw610$ gn gen --args="chip_enable_wifi=true chip_enable_openthread=true chip_enable_matter_cli=true is_sdk_package=true openthread_root=\"//third_party/connectedhomeip/third_party/openthread/ot-nxp/openthread-br\"" out/debug +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rw610$ ninja -C out/debug +``` + #### General information The resulting output file can be found in @@ -108,8 +131,8 @@ Optional GN options that can be added when building an application: - To switch the SDK type used, the argument `is_=true` must be added to the _gn gen_ command (with being either sdk_package or sdk_internal). -- By default, the RW612 A1 board revision will be chosen. To switch to an A0 - revision, the argument `board_version=\"A0\"` must be added to the _gn gen_ +- By default, the RW612 A1 board revision will be chosen. To switch to an A2 + revision, the argument `board_version=\"A2\"` must be added to the _gn gen_ command. - To build the application in debug mode, the argument `is_debug=true optimize_debug=false` must be added to the _gn gen_ command. @@ -120,7 +143,7 @@ Optional GN options that can be added when building an application: - To build the application with the OTA Requestor enabled, the arguments `chip_enable_ota_requestor=true no_mcuboot=false` must be added to the _gn gen_ command. (More information about the OTA Requestor feature in - [OTA Requestor README](README_OTA_Requestor.md))) + [OTA Requestor README](../../../../../docs/guides/nxp_rw61x_ota_software_update.md) ## Manufacturing data @@ -133,6 +156,21 @@ The all cluster app demonstrates the usage of encrypted Matter manufacturing data storage. Matter manufacturing data should be encrypted using an AES 128 software key before flashing them to the device flash. +Using DAC private key secure usage: Experimental feature, contain some +limitation: potential concurrent access issue during sign with dac key operation +due to the lack of protection between multiple access to `ELS` crypto module. +The argument `chip_enable_secure_dac_private_key_storage=1` must be added to the +_gn gen_ command to enable secure private DAC key usage with S50. +`chip_with_factory_data=1` must have been added to the _gn gen_ command + +DAC private key generation: The argument `chip_convert_dac_private_key=1` must +be added to the _gn gen_ command to enable DAC private plain key conversion to +blob with S50. `chip_enable_secure_dac_private_key_storage=1` must have been +added to the _gn gen_ command + +`ELS` contain concurrent access risks. They must be fixed before enabling it by +default. + ## Flashing and debugging @@ -213,6 +251,16 @@ The "ble-wifi" pairing method can be used in order to commission the device. The "ble-thread" pairing method can be used in order to commission the device. +#### Matter over wifi with openthread border router configuration : + +In order to create or join a Thread network on the Matter Border Router, the +`otcli` commands from the matter CLI can be used. For more information about +using the matter shell, follow instructions from +['Testing the all-clusters application with Matter CLI'](#testing-the-all-clusters-application-with-matter-cli-enabled). + +In this configuration, the device can be commissioned over Wi-Fi with the +'ble-wifi' pairing method. + ### Testing the all-clusters application without Matter CLI: 1. Prepare the board with the flashed `All-cluster application` (as shown @@ -284,6 +332,41 @@ Here are described steps to use the all-cluster-app with the Matter CLI enabled it is described [here](../../../../chip-tool/README.md#using-the-client-to-send-matter-commands). +For Matter with OpenThread Border Router support, the matter CLI can be used to +start/join the Thread network, using the following ot-cli commands. (Note that +setting channel, panid, and network key is not enough anymore because of an Open +Thread stack update. We first need to initialize a new dataset.) + +``` +> otcli dataset init new +Done +> otcli dataset +Active Timestamp: 1 +Channel: 25 +Channel Mask: 0x07fff800 +Ext PAN ID: 42af793f623aab54 +Mesh Local Prefix: fd6e:c358:7078:5a8d::/64 +Network Key: f824658f79d8ca033fbb85ecc3ca91cc +Network Name: OpenThread-b870 +PAN ID: 0xb870 +PSKc: f438a194a5e968cc43cc4b3a6f560ca4 +Security Policy: 672 onrc 0 +Done +> otcli dataset panid 0xabcd +Done +> otcli dataset channel 25 +Done +> otcli dataset commit active +Done +> otcli ifconfig up +Done +> otcli thread start +Done +> otcli state +leader +Done +``` + ## OTA Software Update diff --git a/examples/all-clusters-app/nxp/rt/rw61x/include/config/CHIPProjectConfig.h b/examples/all-clusters-app/nxp/rt/rw61x/include/config/CHIPProjectConfig.h index 9fe84849fd753f..2653e97705fe39 100644 --- a/examples/all-clusters-app/nxp/rt/rw61x/include/config/CHIPProjectConfig.h +++ b/examples/all-clusters-app/nxp/rt/rw61x/include/config/CHIPProjectConfig.h @@ -50,8 +50,13 @@ #if !CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA // Use a default pairing code if one hasn't been provisioned in flash. +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE #define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#endif + +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR #define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 +#endif // Use a default pairing code if one hasn't been provisioned in flash. #define CHIP_DEVICE_CONFIG_USE_TEST_PAIRING_CODE "CHIPUS" diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/.gn b/examples/contact-sensor-app/nxp/k32w/k32w0/.gn index 3d48789e30ab3d..363727423ce903 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/.gn +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/.gn @@ -25,4 +25,7 @@ default_args = { target_os = "freertos" import("//args.gni") + + # Import default platform configs + import("${chip_root}/src/platform/nxp/k32w/k32w0/args.gni") } diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/BUILD.gn b/examples/contact-sensor-app/nxp/k32w/k32w0/BUILD.gn index c9b50a84ceb770..4b9f501690d732 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/BUILD.gn +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/BUILD.gn @@ -13,11 +13,13 @@ # limitations under the License. import("//build_overrides/chip.gni") -import("//build_overrides/k32w0_sdk.gni") +import("//build_overrides/nxp_sdk.gni") import("//build_overrides/openthread.gni") -import("${k32w0_sdk_build_root}/k32w0_executable.gni") -import("${k32w0_sdk_build_root}/k32w0_sdk.gni") +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") +import("${nxp_sdk_build_root}/${nxp_sdk_name}/nxp_executable.gni") import("${chip_root}/src/app/icd/icd.gni") import("${chip_root}/src/crypto/crypto.gni") @@ -27,6 +29,9 @@ import("${chip_root}/src/platform/device.gni") declare_args() { chip_software_version = 0 chip_simple_hash_verification = 0 + + # Setup discriminator as argument + setup_discriminator = 3840 } if (chip_pw_tokenizer_logging) { @@ -71,6 +76,10 @@ k32w0_sdk("sdk") { "CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION=${chip_software_version}", ] } + + defines += [ + "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setup_discriminator}", + ] } k32w0_executable("contact_sensor_app") { @@ -140,6 +149,7 @@ k32w0_executable("contact_sensor_app") { ldflags = [ "-T" + rebase_path(ldscript, root_build_dir), + "-Wl,--defsym=__stack_size__=0x480", "-Wl,-print-memory-usage", ] diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/README.md b/examples/contact-sensor-app/nxp/k32w/k32w0/README.md index c325895886a093..b7ec329d7650d1 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/README.md +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/README.md @@ -40,9 +40,7 @@ network. - [OTA Testing](#ota-testing) - [Known issues ota](#known-issues-ota) - [Low power](#low-power) - - - [Known issues power](#known-issues-low-power) - + - [Known issues low power](#known-issues-low-power) - [Removing SSBL Upgrade region](#removing-ssbl-upgrade-region) @@ -222,7 +220,7 @@ Start building the application: ```bash user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/contact-sensor-app/nxp/k32w/k32w0 -user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w/k32w0$ gn gen out/debug --args="chip_with_OM15082=1 chip_with_ot_cli=0 is_debug=false chip_crypto=\"platform\" chip_with_se05x=0 chip_pw_tokenizer_logging=true" +user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w/k32w0$ gn gen out/debug user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w/k32w0$ ninja -C out/debug ``` @@ -248,6 +246,16 @@ In case the board doesn't have 32KHz crystal fitted, one can use the 32KHz free running oscillator as a clock source. In this case one must set the use_fro_32k argument to 1. +K32W0x1 supports antenna diversity feature, which is a technique that maximizes +the performance of an antenna system, allowing the radio signal to be switched +between two antennas that have very low correlation between their received +signals. Typically, this is achieved by spacing two antennas around 0.25 +wavelengths apart or by using 2 orthogonal types of polarization. This is +controlled by software. K32W0x1 provides an output (`ADO`) on one of `DIO7`, +`DIO9` or `DIO19` and optionally its complement (`ADE`) on `DIO6` that can be +used to control an antenna switch. In order to use this feature, user must set +`use_antenna_diversity` to 1. + In case signing errors are encountered when running the "sign_images.sh" script (run automatically) install the recommanded packages (python version > 3, pip3, pycrypto, pycryptodome): diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/args.gni b/examples/contact-sensor-app/nxp/k32w/k32w0/args.gni index 6e931d00452fcd..e328a6ede9011f 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/args.gni +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/args.gni @@ -14,12 +14,14 @@ import("//build_overrides/chip.gni") import("${chip_root}/config/standalone/args.gni") -import("${chip_root}/examples/platform/nxp/k32w/k32w0/args.gni") # SDK target. This is overridden to add our SDK app_config.h & defines. k32w0_sdk_target = get_label_info(":sdk", "label_no_toolchain") chip_enable_ota_requestor = true +chip_with_ota_encryption = 1 +chip_with_ota_key = "1234567890ABCDEFA1B2C3D4E5F6F1B4" + chip_stack_lock_tracking = "fatal" chip_enable_ble = true @@ -28,3 +30,11 @@ chip_enable_icd_lit = false icd_enforce_sit_slow_poll_limit = true chip_persist_subscriptions = true chip_subscription_timeout_resumption = true + +is_debug = false + +chip_crypto = "platform" +chip_crypto_flavor = "NXP-Ultrafast-P256" +chip_with_ot_cli = 0 +chip_with_OM15082 = 1 +chip_pw_tokenizer_logging = true diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h b/examples/contact-sensor-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h index 72f94878cf328f..301d53824a7e55 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h @@ -92,8 +92,13 @@ #else // Use a default setup PIN code if one hasn't been provisioned in flash. +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE #define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#endif + +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR #define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 +#endif /** * CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/AppTask.cpp b/examples/contact-sensor-app/nxp/k32w/k32w0/main/AppTask.cpp index 17aea9d5897907..81694523876d7e 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/main/AppTask.cpp +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/main/AppTask.cpp @@ -45,7 +45,7 @@ #include #endif -#include "BLEManagerImpl.h" +#include #include "Keyboard.h" #include "LED.h" @@ -452,6 +452,7 @@ void AppTask::ButtonEventHandler(uint8_t pin_no, uint8_t button_action) button_event.Handler = ResetActionEventHandler; } #endif + #if CHIP_ENABLE_LIT if (button_action == USER_ACTIVE_MODE_TRIGGER_PUSH) { diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/BUILD.gn b/examples/contact-sensor-app/nxp/k32w/k32w1/BUILD.gn index e44c1a9c71bd40..400b4003c3d1b9 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/BUILD.gn +++ b/examples/contact-sensor-app/nxp/k32w/k32w1/BUILD.gn @@ -31,10 +31,15 @@ import("${chip_root}/src/platform/nxp/${nxp_platform}/args.gni") declare_args() { chip_software_version = 0 + + # Setup discriminator as argument + setup_discriminator = 3840 + chip_with_diag_logs_demo = true } assert(current_os == "freertos") +common_example_dir = "${chip_root}/examples/platform/nxp/common" k32w1_platform_dir = "${chip_root}/examples/platform/nxp/k32w/k32w1" k32w1_sdk_root = getenv("NXP_K32W1_SDK_ROOT") @@ -70,6 +75,14 @@ k32w1_sdk("sdk") { "CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION=${chip_software_version}", ] } + + defines += [ + "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setup_discriminator}", + ] + + if (chip_with_diag_logs_demo) { + defines += [ "CONFIG_DIAG_LOGS_DEMO=1" ] + } } k32w1_executable("contact_sensor_app") { @@ -89,6 +102,8 @@ k32w1_executable("contact_sensor_app") { "main/main.cpp", ] + include_dirs = [ "${common_example_dir}/diagnostic_logs" ] + deps = [ ":sdk", "${chip_root}/examples/common/QRCode", @@ -99,15 +114,24 @@ k32w1_executable("contact_sensor_app") { "${k32w1_platform_dir}/app/support:freertos_mbedtls_utils", ] + #lit and sit are using different zap files + if (chip_enable_icd_lit) { + deps += [ "${chip_root}/examples/contact-sensor-app/nxp/zap-lit/" ] + + defines += [ "CHIP_ENABLE_LIT=1" ] + } else { + deps += [ "${chip_root}/examples/contact-sensor-app/nxp/zap-sit/" ] + } + if (chip_openthread_ftd) { deps += [ - "${chip_root}/third_party/openthread/repo:libopenthread-cli-ftd", - "${chip_root}/third_party/openthread/repo:libopenthread-ftd", + "${openthread_root}:libopenthread-cli-ftd", + "${openthread_root}:libopenthread-ftd", ] } else { deps += [ - "${chip_root}/third_party/openthread/repo:libopenthread-cli-mtd", - "${chip_root}/third_party/openthread/repo:libopenthread-mtd", + "${openthread_root}:libopenthread-cli-mtd", + "${openthread_root}:libopenthread-mtd", ] } @@ -142,6 +166,13 @@ k32w1_executable("contact_sensor_app") { ldflags += [ "-Wl,--defsym=gUseFactoryData_d=1" ] } + if (chip_with_diag_logs_demo) { + sources += [ + "${common_example_dir}/diagnostic_logs/DiagnosticLogsProviderDelegateImpl.cpp", + "${common_example_dir}/diagnostic_logs/DiagnosticLogsProviderDelegateImpl.h", + ] + } + 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 ff3496d7b862ac..5079e01c6e2400 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/README.md +++ b/examples/contact-sensor-app/nxp/k32w/k32w1/README.md @@ -32,7 +32,7 @@ into an existing Matter network and can be controlled by this network. - [Known issues](#known-issues) - [Low power](#low-power) - + ## Introduction @@ -93,7 +93,7 @@ states are depicted: service connectivity. NOTE: LED2 will be disabled when CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR is -enabled. On K32W1 EVK board, `PTB0` is wired to LED2 also is wired to CS (Chip +enabled. On K32W1 EVK board, `PTB0` is wired to `LED2` also is wired to CS (Chip Select) External Flash Memory. OTA image is stored in external memory because of it's size. If LED2 is enabled then it will affect External Memory CS and OTA will not work. @@ -131,8 +131,9 @@ In order to build the Matter example, we recommend using a Linux distribution ``` user@ubuntu:~/Desktop/git/connectedhomeip$ export NXP_K32W1_SDK_ROOT=/home/user/Desktop/SDK_K32W1/ user@ubuntu:~/Desktop/git/connectedhomeip$ source ./scripts/activate.sh +user@ubuntu:~/Desktop/git/connectedhomeip$ scripts/checkout_submodules.py --shallow --platform nxp --recursive user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/contact-sensor-app/nxp/k32w/k32w1 -user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w/k32w1$ gn gen out/debug --args="chip_with_ot_cli=0 is_debug=false chip_openthread_ftd=false chip_crypto=\"platform\"" +user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w/k32w1$ gn gen out/debug user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w/k32w1$ ninja -C out/debug ``` @@ -140,8 +141,6 @@ 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`. ## Long Idle Time ICD Support @@ -205,7 +204,7 @@ path - [K32W148 board quick start guide](https://www.nxp.com/document/guide/getting-started-with-the-k32w148-development-platform:GS-K32W148EVK) can be used for updating the `NBU/radio` core: -- Section 2.4 – Get Software – install `SPSDK` (Secure Provisioning Command +- Section 2.5 – Get Software – install `SPSDK` (Secure Provisioning Command Line Tool) - Section 3.3 – Updating `NBU` for Wireless examples - use the corresponding `.sb3` file found in the SDK package at path @@ -308,7 +307,7 @@ In `OTAP` application the image only for the CM33 core - keep other settings at default values -### Convert sb3 into ota file +### Convert `sb3` into `ota` file In order to build an OTA image, use NXP wrapper over the standard tool `src/app/ota_image_tool.py`: @@ -325,7 +324,7 @@ Please see more in the [OTA image tool guide](../../../../../scripts/tools/nxp/ota/README.md). Here is an example that generates an OTA image with application update TLV from -a sb3 file: +a `sb3` file: ``` ./scripts/tools/nxp/ota/ota_image_tool.py create -v 0xDEAD -p 0xBEEF -vn 43033 -vs "1.0" -da sha256 --app-input-file ~/binaries/chip-k32w1-43033.sb3 ~/binaries/chip-k32w1-43033.ota diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/args.gni b/examples/contact-sensor-app/nxp/k32w/k32w1/args.gni index b25f000cd85d1c..23e6730b79045c 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/args.gni +++ b/examples/contact-sensor-app/nxp/k32w/k32w1/args.gni @@ -28,3 +28,11 @@ chip_enable_icd_lit = false icd_enforce_sit_slow_poll_limit = true chip_persist_subscriptions = true chip_subscription_timeout_resumption = true + +is_debug = false + +chip_crypto = "platform" +chip_openthread_ftd = false +chip_with_ot_cli = 0 + +chip_with_diag_logs_demo = 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 808b70aad0cab7..0d9a4e3b503bee 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h +++ b/examples/contact-sensor-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h @@ -94,8 +94,13 @@ #define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8006 // Use a default setup PIN code if one hasn't been provisioned in flash. +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE #define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#endif + +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR #define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 +#endif // Use a default pairing code if one hasn't been provisioned in flash. #define CHIP_DEVICE_CONFIG_USE_TEST_PAIRING_CODE "CHIPUS" @@ -186,8 +191,6 @@ #define CHIP_CONFIG_MAX_FABRICS 5 // 5 is the minimum number of supported fabrics #define CHIP_DEVICE_CONFIG_ENABLE_SED 1 -#define CHIP_DEVICE_CONFIG_SED_IDLE_INTERVAL 1000_ms32 -#define CHIP_DEVICE_CONFIG_SED_ACTIVE_INTERVAL 100_ms32 /** * @def CHIP_IM_MAX_NUM_COMMAND_HANDLER @@ -217,3 +220,8 @@ #endif // BUILD_RELEASE #define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 + +#if CONFIG_DIAG_LOGS_DEMO +#define CHIP_CONFIG_ENABLE_BDX_LOG_TRANSFER 1 +#define CHIP_DEVICE_CONFIG_MAX_DIAG_LOG_SIZE 1024 +#endif 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 3e9380254bd428..6f0459178cd173 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/main/AppTask.cpp +++ b/examples/contact-sensor-app/nxp/k32w/k32w1/main/AppTask.cpp @@ -30,6 +30,9 @@ #include #include #include +#if CONFIG_DIAG_LOGS_DEMO +#include "DiagnosticLogsProviderDelegateImpl.h" +#endif #include #include @@ -95,6 +98,9 @@ using namespace ::chip::Credentials; using namespace ::chip::DeviceLayer; using namespace chip; using namespace chip::app; +#if CONFIG_DIAG_LOGS_DEMO +using namespace chip::app::Clusters::DiagnosticLogs; +#endif AppTask AppTask::sAppTask; #if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA @@ -114,6 +120,11 @@ static BDXDownloader gDownloader __attribute__((section(".data"))); constexpr uint16_t requestedOtaBlockSize = 1024; #endif +static pm_notify_element_t appNotifyElement = { + .notifyCallback = AppTask::LowPowerCallback, + .data = NULL, +}; + static void app_gap_callback(gapGenericEvent_t * event) { /* This callback is called in the context of BLE task, so event processing @@ -148,7 +159,15 @@ CHIP_ERROR AppTask::Init() if (ContactSensorMgr().Init() != 0) { K32W_LOG("ContactSensorMgr().Init() failed"); - assert(status == 0); + assert(0); + } + + // Register enter/exit low power application callback. + status_t status = PM_RegisterNotify(kPM_NotifyGroup2, &appNotifyElement); + if (status != kStatus_Success) + { + K32W_LOG("Failed to register low power app callback.") + return APP_ERROR_PM_REGISTER_LP_CALLBACK_FAILED; } PlatformMgr().AddEventHandler(MatterEventHandler, 0); @@ -250,6 +269,24 @@ void AppTask::InitServer(intptr_t arg) nativeParams.openThreadInstancePtr = chip::DeviceLayer::ThreadStackMgrImpl().OTInstance(); initParams.endpointNativeParams = static_cast(&nativeParams); VerifyOrDie((chip::Server::GetInstance().Init(initParams)) == CHIP_NO_ERROR); + +#if CONFIG_DIAG_LOGS_DEMO + char diagLog[CHIP_DEVICE_CONFIG_MAX_DIAG_LOG_SIZE]; + uint16_t diagLogSize = CHIP_DEVICE_CONFIG_MAX_DIAG_LOG_SIZE; + + StorageKeyName keyUser = LogProvider::GetKeyDiagUserSupport(); + StorageKeyName keyNwk = LogProvider::GetKeyDiagNetwork(); + StorageKeyName keyCrash = LogProvider::GetKeyDiagCrashLog(); + + memset(diagLog, 0, diagLogSize); + Server::GetInstance().GetPersistentStorage().SyncSetKeyValue(keyUser.KeyName(), diagLog, diagLogSize); + + memset(diagLog, 1, diagLogSize); + Server::GetInstance().GetPersistentStorage().SyncSetKeyValue(keyNwk.KeyName(), diagLog, diagLogSize); + + memset(diagLog, 2, diagLogSize); + Server::GetInstance().GetPersistentStorage().SyncSetKeyValue(keyCrash.KeyName(), diagLog, diagLogSize); +#endif } void AppTask::PrintOnboardingInfo() @@ -768,6 +805,11 @@ void AppTask::OnIdentifyStop(Identify * identify) } } +status_t AppTask::LowPowerCallback(pm_event_type_t eventType, uint8_t powerState, void * data) +{ + return kStatus_Success; +} + void AppTask::PostContactActionRequest(ContactSensorManager::Action aAction) { AppEvent event; diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/main/ZclCallbacks.cpp b/examples/contact-sensor-app/nxp/k32w/k32w1/main/ZclCallbacks.cpp index e1e35b4cb4ec7e..5937d134194c30 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/main/ZclCallbacks.cpp +++ b/examples/contact-sensor-app/nxp/k32w/k32w1/main/ZclCallbacks.cpp @@ -30,10 +30,18 @@ #include #include +#if CONFIG_DIAG_LOGS_DEMO +#include "DiagnosticLogsProviderDelegateImpl.h" +#include +#endif + using namespace ::chip; using namespace ::chip::app; using namespace ::chip::app::Clusters; using namespace ::chip::app::Clusters::BooleanState; +#if CONFIG_DIAG_LOGS_DEMO +using namespace ::chip::app::Clusters::DiagnosticLogs; +#endif void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & path, uint8_t type, uint16_t size, uint8_t * value) { @@ -96,3 +104,11 @@ void logBooleanStateEvent(bool state) ChipLogProgress(Zcl, "booleanstate: failed to reacord state-change event"); } } + +#if CONFIG_DIAG_LOGS_DEMO +void emberAfDiagnosticLogsClusterInitCallback(chip::EndpointId endpoint) +{ + auto & logProvider = LogProvider::GetInstance(); + DiagnosticLogsServer::Instance().SetDiagnosticLogsProviderDelegate(endpoint, &logProvider); +} +#endif 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 2338131f06c4b0..64842e310561b2 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 @@ -36,6 +36,7 @@ #include "FreeRTOS.h" #include "fsl_component_button.h" +#include "fsl_pm_core.h" #include "timers.h" // Application-defined error codes in the CHIP_ERROR space. @@ -45,6 +46,7 @@ #define APP_ERROR_CREATE_TIMER_FAILED CHIP_APPLICATION_ERROR(0x04) #define APP_ERROR_START_TIMER_FAILED CHIP_APPLICATION_ERROR(0x05) #define APP_ERROR_STOP_TIMER_FAILED CHIP_APPLICATION_ERROR(0x06) +#define APP_ERROR_PM_REGISTER_LP_CALLBACK_FAILED CHIP_APPLICATION_ERROR(0x07) class AppTask { @@ -67,6 +69,8 @@ class AppTask static void OnIdentifyStart(Identify * identify); static void OnIdentifyStop(Identify * identify); + static status_t LowPowerCallback(pm_event_type_t eventType, uint8_t powerState, void * data); + private: friend AppTask & GetAppTask(void); @@ -96,6 +100,7 @@ class AppTask static void TimerEventHandler(TimerHandle_t xTimer); static void MatterEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + void StartTimer(uint32_t aTimeoutInMs); #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR diff --git a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter index fcec6408acfcb8..b3c6233dc7a8e9 100644 --- a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter +++ b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter @@ -659,6 +659,53 @@ cluster NetworkCommissioning = 49 { command access(invoke: administer) QueryIdentity(QueryIdentityRequest): QueryIdentityResponse = 9; } +/** The cluster provides commands for retrieving unstructured diagnostic logs from a Node that may be used to aid in diagnostics. */ +cluster DiagnosticLogs = 50 { + revision 1; // NOTE: Default/not specifically set + + enum IntentEnum : enum8 { + kEndUserSupport = 0; + kNetworkDiag = 1; + kCrashLogs = 2; + } + + enum StatusEnum : enum8 { + kSuccess = 0; + kExhausted = 1; + kNoLogs = 2; + kBusy = 3; + kDenied = 4; + } + + enum TransferProtocolEnum : enum8 { + kResponsePayload = 0; + kBDX = 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 RetrieveLogsRequestRequest { + IntentEnum intent = 0; + TransferProtocolEnum requestedProtocol = 1; + optional char_string<32> transferFileDesignator = 2; + } + + response struct RetrieveLogsResponse = 1 { + StatusEnum status = 0; + long_octet_string logContent = 1; + optional epoch_us UTCTimeStamp = 2; + optional systime_us timeSinceBoot = 3; + } + + /** Retrieving diagnostic logs from a Node */ + command RetrieveLogsRequest(RetrieveLogsRequestRequest): RetrieveLogsResponse = 0; +} + /** 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; @@ -1371,6 +1418,7 @@ endpoint 0 { emits event AccessControlEntryChanged; emits event AccessControlExtensionChanged; callback attribute acl; + callback attribute extension; callback attribute subjectsPerAccessControlEntry; callback attribute targetsPerAccessControlEntry; callback attribute accessControlEntriesPerFabric; @@ -1471,6 +1519,18 @@ endpoint 0 { handle command ReorderNetwork; } + server cluster DiagnosticLogs { + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command RetrieveLogsRequest; + handle command RetrieveLogsResponse; + } + server cluster GeneralDiagnostics { emits event BootReason; callback attribute networkInterfaces; diff --git a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.zap b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.zap index 1e9f3e8bee2875..68b94ef250a67a 100644 --- a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.zap +++ b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.zap @@ -190,6 +190,22 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "Extension", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "SubjectsPerAccessControlEntry", "code": 2, @@ -248,7 +264,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -264,7 +280,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -280,7 +296,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -1480,6 +1496,130 @@ } ] }, + { + "name": "Diagnostic Logs", + "code": 50, + "mfgCode": null, + "define": "DIAGNOSTIC_LOGS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "RetrieveLogsRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RetrieveLogsResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "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": "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 + } + ] + }, { "name": "General Diagnostics", "code": 51, @@ -2805,7 +2945,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -2821,7 +2961,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -2837,7 +2977,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -2853,7 +2993,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter index 3cd88fd42fb0c7..fd15a473ac447b 100644 --- a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter +++ b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter @@ -659,6 +659,53 @@ cluster NetworkCommissioning = 49 { command access(invoke: administer) QueryIdentity(QueryIdentityRequest): QueryIdentityResponse = 9; } +/** The cluster provides commands for retrieving unstructured diagnostic logs from a Node that may be used to aid in diagnostics. */ +cluster DiagnosticLogs = 50 { + revision 1; // NOTE: Default/not specifically set + + enum IntentEnum : enum8 { + kEndUserSupport = 0; + kNetworkDiag = 1; + kCrashLogs = 2; + } + + enum StatusEnum : enum8 { + kSuccess = 0; + kExhausted = 1; + kNoLogs = 2; + kBusy = 3; + kDenied = 4; + } + + enum TransferProtocolEnum : enum8 { + kResponsePayload = 0; + kBDX = 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 RetrieveLogsRequestRequest { + IntentEnum intent = 0; + TransferProtocolEnum requestedProtocol = 1; + optional char_string<32> transferFileDesignator = 2; + } + + response struct RetrieveLogsResponse = 1 { + StatusEnum status = 0; + long_octet_string logContent = 1; + optional epoch_us UTCTimeStamp = 2; + optional systime_us timeSinceBoot = 3; + } + + /** Retrieving diagnostic logs from a Node */ + command RetrieveLogsRequest(RetrieveLogsRequestRequest): RetrieveLogsResponse = 0; +} + /** 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; @@ -1371,6 +1418,7 @@ endpoint 0 { emits event AccessControlEntryChanged; emits event AccessControlExtensionChanged; callback attribute acl; + callback attribute extension; callback attribute subjectsPerAccessControlEntry; callback attribute targetsPerAccessControlEntry; callback attribute accessControlEntriesPerFabric; @@ -1471,6 +1519,18 @@ endpoint 0 { handle command ReorderNetwork; } + server cluster DiagnosticLogs { + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command RetrieveLogsRequest; + handle command RetrieveLogsResponse; + } + server cluster GeneralDiagnostics { emits event BootReason; callback attribute networkInterfaces; diff --git a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.zap b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.zap index e0b5e7995d96fe..a433e8e7bd9c9a 100644 --- a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.zap +++ b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.zap @@ -1,6 +1,6 @@ { "fileFormat": 2, - "featureLevel": 100, + "featureLevel": 99, "creator": "zap", "keyValuePairs": [ { @@ -190,6 +190,22 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "Extension", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "SubjectsPerAccessControlEntry", "code": 2, @@ -1480,6 +1496,130 @@ } ] }, + { + "name": "Diagnostic Logs", + "code": 50, + "mfgCode": null, + "define": "DIAGNOSTIC_LOGS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "RetrieveLogsRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RetrieveLogsResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "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": "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 + } + ] + }, { "name": "General Diagnostics", "code": 51, @@ -4010,16 +4150,14 @@ "endpointTypeIndex": 0, "profileId": 259, "endpointId": 0, - "networkId": 0, - "parentEndpointIdentifier": null + "networkId": 0 }, { "endpointTypeName": "MA-dimmablelight", "endpointTypeIndex": 1, "profileId": 259, "endpointId": 1, - "networkId": 0, - "parentEndpointIdentifier": null + "networkId": 0 } ] } \ No newline at end of file diff --git a/examples/laundry-washer-app/nxp/common/main/AppTask.cpp b/examples/laundry-washer-app/nxp/common/main/AppTask.cpp new file mode 100644 index 00000000000000..1137db82338b6f --- /dev/null +++ b/examples/laundry-washer-app/nxp/common/main/AppTask.cpp @@ -0,0 +1,140 @@ +/* + * + * Copyright (c) 2021-2023 Project CHIP Authors + * Copyright (c) 2021 Google LLC. + * Copyright 2023-2024 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. + */ + +#include "AppTask.h" +#include "CHIPDeviceManager.h" +#include "ICDUtil.h" +#include +#include + +#include "static-supported-temperature-levels.h" +#include + +#ifdef ENABLE_CHIP_SHELL +#include + +using namespace chip::Shell; +#endif /* ENABLE_CHIP_SHELL */ + +using namespace chip; +using namespace chip::app::Clusters; + +app::Clusters::TemperatureControl::AppSupportedTemperatureLevelsDelegate sAppSupportedTemperatureLevelsDelegate; + +CHIP_ERROR cliOpState(int argc, char * argv[]) +{ + if ((argc != 1) && (argc != 2)) + { + ChipLogError(Shell, "Target State is missing"); + return CHIP_ERROR_INVALID_ARGUMENT; + } + if (!strcmp(argv[0], "stop")) + { + ChipLogDetail(Shell, "OpSState : Set to %s state", argv[0]); + OperationalState::GetOperationalStateInstance()->SetOperationalState( + to_underlying(OperationalState::OperationalStateEnum::kStopped)); + } + else if (!strcmp(argv[0], "run")) + { + ChipLogDetail(Shell, "OpSState : Set to %s state", argv[0]); + OperationalState::GetOperationalStateInstance()->SetOperationalState( + to_underlying(OperationalState::OperationalStateEnum::kRunning)); + } + else if (!strcmp(argv[0], "pause")) + { + ChipLogDetail(Shell, "OpSState : Set to %s state", argv[0]); + OperationalState::GetOperationalStateInstance()->SetOperationalState( + to_underlying(OperationalState::OperationalStateEnum::kPaused)); + } + else if (!strcmp(argv[0], "error")) + { + OperationalState::Structs::ErrorStateStruct::Type err; + ChipLogDetail(Shell, "OpSState : Set to %s state", argv[0]); + if (!strcmp(argv[1], "no_error")) + { + ChipLogDetail(Shell, "OpSState_error : Error: %s state", argv[1]); + err.errorStateID = (uint8_t) OperationalState::ErrorStateEnum::kNoError; + } + else if (!strcmp(argv[1], "unable_to_start_or_resume")) + { + ChipLogDetail(Shell, "OpSState_error : Error: %s state", argv[1]); + err.errorStateID = (uint8_t) OperationalState::ErrorStateEnum::kUnableToStartOrResume; + } + else if (!strcmp(argv[1], "unable_to_complete_operation")) + { + ChipLogDetail(Shell, "OpSState_error : Error: %s state", argv[1]); + err.errorStateID = (uint8_t) OperationalState::ErrorStateEnum::kUnableToCompleteOperation; + } + else if (!strcmp(argv[1], "command_invalid_in_state")) + { + ChipLogDetail(Shell, "OpSState_error : Error: %s state", argv[1]); + err.errorStateID = (uint8_t) OperationalState::ErrorStateEnum::kCommandInvalidInState; + } + else + { + ChipLogError(Shell, "Invalid Error State to set"); + return CHIP_ERROR_INVALID_ARGUMENT; + } + OperationalState::GetOperationalStateInstance()->OnOperationalErrorDetected(err); + OperationalState::GetOperationalStateInstance()->SetOperationalState( + to_underlying(OperationalState::OperationalStateEnum::kError)); + } + else + { + ChipLogError(Shell, "Invalid State to set"); + return CHIP_ERROR_INVALID_ARGUMENT; + } + return CHIP_NO_ERROR; +} + +void LaundryWasherApp::AppTask::PreInitMatterStack() +{ + ChipLogProgress(DeviceLayer, "Welcome to NXP laundry washer Demo App"); +} + +void LaundryWasherApp::AppTask::PostInitMatterStack() +{ + chip::app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(&chip::NXP::App::GetICDUtil()); + + app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate); +} + +void LaundryWasherApp::AppTask::AppMatter_RegisterCustomCliCommands() +{ +#ifdef ENABLE_CHIP_SHELL + /* Register application commands */ + static const shell_command_t kCommands[] = { + { .cmd_func = cliOpState, .cmd_name = "opstate", .cmd_help = "Set the Operational State" }, + }; + Engine::Root().RegisterCommands(kCommands, sizeof(kCommands) / sizeof(kCommands[0])); +#endif +} + +// This returns an instance of this class. +LaundryWasherApp::AppTask & LaundryWasherApp::AppTask::GetDefaultInstance() +{ + static LaundryWasherApp::AppTask sAppTask; + return sAppTask; +} + +chip::NXP::App::AppTaskBase & chip::NXP::App::GetAppTask() +{ + return LaundryWasherApp::AppTask::GetDefaultInstance(); +} diff --git a/examples/laundry-washer-app/nxp/common/main/DeviceCallbacks.cpp b/examples/laundry-washer-app/nxp/common/main/DeviceCallbacks.cpp new file mode 100644 index 00000000000000..0d20cf015a7954 --- /dev/null +++ b/examples/laundry-washer-app/nxp/common/main/DeviceCallbacks.cpp @@ -0,0 +1,135 @@ +/* + * + * Copyright (c) 2020-2023 Project CHIP Authors + * Copyright 2024 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 DeviceCallbacks.cpp + * + * Implements all the callbacks to the application from the CHIP Stack + * + **/ +#include "DeviceCallbacks.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace chip::app; +void OnTriggerEffect(::Identify * identify) +{ + switch (identify->mCurrentEffectIdentifier) + { + case Clusters::Identify::EffectIdentifierEnum::kBlink: + ChipLogProgress(Zcl, "Clusters::Identify::EffectIdentifierEnum::kBlink"); + break; + case Clusters::Identify::EffectIdentifierEnum::kBreathe: + ChipLogProgress(Zcl, "Clusters::Identify::EffectIdentifierEnum::kBreathe"); + break; + case Clusters::Identify::EffectIdentifierEnum::kOkay: + ChipLogProgress(Zcl, "Clusters::Identify::EffectIdentifierEnum::kOkay"); + break; + case Clusters::Identify::EffectIdentifierEnum::kChannelChange: + ChipLogProgress(Zcl, "Clusters::Identify::EffectIdentifierEnum::kChannelChange"); + break; + default: + ChipLogProgress(Zcl, "No identifier effect"); + return; + } +} + +Identify gIdentify0 = { + chip::EndpointId{ 1 }, + [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStart"); }, + [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStop"); }, + chip::app::Clusters::Identify::IdentifyTypeEnum::kNone, + OnTriggerEffect, +}; + +Identify gIdentify1 = { + chip::EndpointId{ 1 }, + [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStart"); }, + [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStop"); }, + chip::app::Clusters::Identify::IdentifyTypeEnum::kNone, + OnTriggerEffect, +}; + +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::System; +using namespace ::chip::DeviceLayer; +using namespace chip::app::Clusters; + +void LaundryWasherApp::DeviceCallbacks::PostAttributeChangeCallback(EndpointId endpointId, ClusterId clusterId, + AttributeId attributeId, uint8_t type, uint16_t size, + uint8_t * value) +{ + ChipLogProgress(DeviceLayer, + "endpointId " ChipLogFormatMEI " clusterId " ChipLogFormatMEI " attribute ID: " ChipLogFormatMEI + " Type: %u Value: %u, length %u", + ChipLogValueMEI(endpointId), ChipLogValueMEI(clusterId), ChipLogValueMEI(attributeId), type, *value, size); + switch (clusterId) + { + case Clusters::OnOff::Id: + OnOnOffPostAttributeChangeCallback(endpointId, attributeId, value); + break; + } +} + +void LaundryWasherApp::DeviceCallbacks::OnOnOffPostAttributeChangeCallback(chip::EndpointId endpointId, + chip::AttributeId attributeId, uint8_t * value) +{ + switch (attributeId) + { + case Clusters::OnOff::Attributes::OnOff::Id: + if ((value != nullptr) && (*value == true)) + { + // Update the current mode to OnMode after device is on + ModeBase::Instance * modeInstance = LaundryWasherMode::Instance(); + + if (modeInstance != nullptr) + { + DataModel::Nullable mode = modeInstance->GetOnMode(); + if (mode.IsNull() == false) + { + modeInstance->UpdateCurrentMode(mode.Value()); + } + } + } + break; + + default:; + } +} + +// This returns an instance of this class. +LaundryWasherApp::DeviceCallbacks & LaundryWasherApp::DeviceCallbacks::GetDefaultInstance() +{ + static LaundryWasherApp::DeviceCallbacks sDeviceCallbacks; + return sDeviceCallbacks; +} + +chip::DeviceManager::CHIPDeviceManagerCallbacks & chip::NXP::App::GetDeviceCallbacks() +{ + return LaundryWasherApp::DeviceCallbacks::GetDefaultInstance(); +} diff --git a/examples/laundry-washer-app/nxp/common/main/ZclCallbacks.cpp b/examples/laundry-washer-app/nxp/common/main/ZclCallbacks.cpp new file mode 100644 index 00000000000000..0a26df6424b771 --- /dev/null +++ b/examples/laundry-washer-app/nxp/common/main/ZclCallbacks.cpp @@ -0,0 +1,49 @@ +/* + * + * Copyright (c) 2021-2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "AppTask.h" +#include "CHIPDeviceManager.h" + +#include +#include +#include +#include +#include + +#include "laundry-washer-controls-delegate-impl.h" + +using namespace ::chip; + +void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & path, uint8_t type, uint16_t size, uint8_t * value) +{ + chip::DeviceManager::CHIPDeviceManagerCallbacks * cb = + chip::DeviceManager::CHIPDeviceManager::GetInstance().GetCHIPDeviceManagerCallbacks(); + if (cb != nullptr) + { + // propagate event to device manager + cb->PostAttributeChangeCallback(path.mEndpointId, path.mClusterId, path.mAttributeId, type, size, value); + } +} + +using namespace chip::app::Clusters::LaundryWasherControls; +void emberAfLaundryWasherControlsClusterInitCallback(EndpointId endpoint) +{ + LaundryWasherControlsServer::SetDefaultDelegate(endpoint, &LaundryWasherControlDelegate::getLaundryWasherControlDelegate()); +} diff --git a/examples/shell/nxp/k32w/k32w0/include/AppEvent.h b/examples/laundry-washer-app/nxp/common/main/include/AppEvent.h similarity index 80% rename from examples/shell/nxp/k32w/k32w0/include/AppEvent.h rename to examples/laundry-washer-app/nxp/common/main/include/AppEvent.h index 0e49456b8addd7..a0dad141a27055 100644 --- a/examples/shell/nxp/k32w/k32w0/include/AppEvent.h +++ b/examples/laundry-washer-app/nxp/common/main/include/AppEvent.h @@ -1,5 +1,5 @@ /* - * + * Copyright (c) 2020 Project CHIP Authors * Copyright (c) 2021 Nest Labs, Inc. * All rights reserved. * @@ -19,27 +19,21 @@ #pragma once struct AppEvent; -typedef void (*EventHandler)(AppEvent *); +using EventHandler = void (*)(const AppEvent &); struct AppEvent { enum AppEventTypes { - kEventType_Button = 0, - kEventType_Timer, + kEventType_Timer = 0, kEventType_TurnOn, kEventType_Install, }; - AppEventTypes Type; + uint16_t Type; union { - struct - { - uint8_t PinNo; - uint8_t Action; - } ButtonEvent; struct { void * Context; @@ -48,7 +42,7 @@ struct AppEvent { uint8_t Action; int32_t Actor; - } LightEvent; + } ClusterEvent; }; EventHandler Handler; diff --git a/examples/laundry-washer-app/nxp/common/main/include/AppTask.h b/examples/laundry-washer-app/nxp/common/main/include/AppTask.h new file mode 100644 index 00000000000000..239328f8a1c7ba --- /dev/null +++ b/examples/laundry-washer-app/nxp/common/main/include/AppTask.h @@ -0,0 +1,56 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2021-2023 Google LLC. + * Copyright 2024 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. + */ + +#pragma once + +#if CONFIG_APP_FREERTOS_OS +#include "AppTaskFreeRTOS.h" +#else +#include "AppTaskZephyr.h" +#endif + +namespace LaundryWasherApp { +#if CONFIG_APP_FREERTOS_OS +class AppTask : public chip::NXP::App::AppTaskFreeRTOS +#else +class AppTask : public chip::NXP::App::AppTaskZephyr +#endif +{ +public: + ~AppTask() override{}; + void PreInitMatterStack(void) override; + void PostInitMatterStack(void) override; + void AppMatter_RegisterCustomCliCommands(void) override; + // This returns an instance of this class. + static AppTask & GetDefaultInstance(); + +private: + static AppTask sAppTask; +}; + +} // namespace LaundryWasherApp + +/** + * Returns the application-specific implementation of the AppTaskBase object. + * + * Applications can use this to gain access to features of the AppTaskBase + * that are specific to the selected application. + */ +chip::NXP::App::AppTaskBase & GetAppTask(); diff --git a/examples/laundry-washer-app/nxp/common/main/include/DeviceCallbacks.h b/examples/laundry-washer-app/nxp/common/main/include/DeviceCallbacks.h new file mode 100644 index 00000000000000..0b16761b2f6f18 --- /dev/null +++ b/examples/laundry-washer-app/nxp/common/main/include/DeviceCallbacks.h @@ -0,0 +1,53 @@ +/* + * + * Copyright (c) 2020-2023 Project CHIP Authors + * Copyright 2024 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 DeviceCallbacks.h + * + * Implementations for the DeviceManager callbacks for this application + * + **/ + +#pragma once + +#include "CHIPDeviceManager.h" +#include "CommonDeviceCallbacks.h" + +namespace LaundryWasherApp { +class DeviceCallbacks : public chip::NXP::App::CommonDeviceCallbacks +{ +public: + // This returns an instance of this class. + static DeviceCallbacks & GetDefaultInstance(); + void PostAttributeChangeCallback(chip::EndpointId endpointId, chip::ClusterId clusterId, chip::AttributeId attributeId, + uint8_t type, uint16_t size, uint8_t * value); + +private: + void OnOnOffPostAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value); + void OnIdentifyPostAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value); +}; +} // namespace LaundryWasherApp + +/** + * Returns the application-specific implementation of the CommonDeviceCallbacks object. + * + * Applications can use this to gain access to features of the CommonDeviceCallbacks + * that are specific to the selected application. + */ +chip::DeviceManager::CHIPDeviceManagerCallbacks & GetDeviceCallbacks(); diff --git a/examples/laundry-washer-app/nxp/common/main/include/operational-state-delegate-impl.h b/examples/laundry-washer-app/nxp/common/main/include/operational-state-delegate-impl.h new file mode 100644 index 00000000000000..79f2695eb0a628 --- /dev/null +++ b/examples/laundry-washer-app/nxp/common/main/include/operational-state-delegate-impl.h @@ -0,0 +1,120 @@ +/* + * + * 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 +#include +#include + +namespace chip { +namespace app { +namespace Clusters { + +namespace OperationalState { + +// This is an application level delegate to handle operational state commands according to the specific business logic. +class GenericOperationalStateDelegateImpl : public Delegate +{ +public: + /** + * Get the countdown time. This attribute is not used in this application. + * @return The current countdown time. + */ + app::DataModel::Nullable GetCountdownTime() override { return {}; }; + + /** + * Fills in the provided GenericOperationalState with the state at index `index` if there is one, + * or returns CHIP_ERROR_NOT_FOUND if the index is out of range for the list of states. + * Note: This is used by the SDK to populate the operational state list attribute. If the contents of this list changes, + * the device SHALL call the Instance's ReportOperationalStateListChange method to report that this attribute has changed. + * @param index The index of the state, with 0 representing the first state. + * @param operationalState The GenericOperationalState is filled. + */ + CHIP_ERROR GetOperationalStateAtIndex(size_t index, GenericOperationalState & operationalState) override; + + /** + * Fills in the provided MutableCharSpan with the phase at index `index` if there is one, + * or returns CHIP_ERROR_NOT_FOUND if the index is out of range for the list of phases. + * + * If CHIP_ERROR_NOT_FOUND is returned for index 0, that indicates that the PhaseList attribute is null + * (there are no phases defined at all). + * + * Note: This is used by the SDK to populate the phase list attribute. If the contents of this list changes, the + * device SHALL call the Instance's ReportPhaseListChange method to report that this attribute has changed. + * @param index The index of the phase, with 0 representing the first phase. + * @param operationalPhase The MutableCharSpan is filled. + */ + CHIP_ERROR GetOperationalPhaseAtIndex(size_t index, MutableCharSpan & operationalPhase) override; + + // command callback + /** + * Handle Command Callback in application: Pause + * @param[out] get operational error after callback. + */ + void HandlePauseStateCallback(GenericOperationalError & err) override; + + /** + * Handle Command Callback in application: Resume + * @param[out] get operational error after callback. + */ + void HandleResumeStateCallback(GenericOperationalError & err) override; + + /** + * Handle Command Callback in application: Start + * @param[out] get operational error after callback. + */ + void HandleStartStateCallback(GenericOperationalError & err) override; + + /** + * Handle Command Callback in application: Stop + * @param[out] get operational error after callback. + */ + void HandleStopStateCallback(GenericOperationalError & err) override; + +protected: + Span mOperationalStateList; + Span mOperationalPhaseList; +}; + +// This is an application level delegate to handle operational state commands according to the specific business logic. +class OperationalStateDelegate : public GenericOperationalStateDelegateImpl +{ +private: + const GenericOperationalState opStateList[4] = { + GenericOperationalState(to_underlying(OperationalStateEnum::kStopped)), + GenericOperationalState(to_underlying(OperationalStateEnum::kRunning)), + GenericOperationalState(to_underlying(OperationalStateEnum::kPaused)), + GenericOperationalState(to_underlying(OperationalStateEnum::kError)), + }; + +public: + OperationalStateDelegate() + { + GenericOperationalStateDelegateImpl::mOperationalStateList = Span(opStateList); + } +}; + +Instance * GetOperationalStateInstance(); + +void Shutdown(); + +} // namespace OperationalState +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/laundry-washer-app/nxp/common/main/main.cpp b/examples/laundry-washer-app/nxp/common/main/main.cpp new file mode 100644 index 00000000000000..b2aadab98ceb8b --- /dev/null +++ b/examples/laundry-washer-app/nxp/common/main/main.cpp @@ -0,0 +1,49 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2021-2023 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ================================================================================ +// Main Code +// ================================================================================ + +#include "FreeRTOS.h" +#include +#include +#include + +#if configAPPLICATION_ALLOCATED_HEAP +uint8_t __attribute__((section(".heap"))) ucHeap[configTOTAL_HEAP_SIZE]; +#endif + +using namespace ::chip::DeviceLayer; + +extern "C" int main(int argc, char * argv[]) +{ + TaskHandle_t taskHandle; + + PlatformMgrImpl().HardwareInit(); + chip::NXP::App::GetAppTask().Start(); + vTaskStartScheduler(); +} + +#if (defined(configCHECK_FOR_STACK_OVERFLOW) && (configCHECK_FOR_STACK_OVERFLOW > 0)) +void vApplicationStackOverflowHook(TaskHandle_t xTask, char * pcTaskName) +{ + assert(0); +} +#endif diff --git a/examples/laundry-washer-app/nxp/common/main/operational-state-delegate-impl.cpp b/examples/laundry-washer-app/nxp/common/main/operational-state-delegate-impl.cpp new file mode 100644 index 00000000000000..4a6608842c174d --- /dev/null +++ b/examples/laundry-washer-app/nxp/common/main/operational-state-delegate-impl.cpp @@ -0,0 +1,143 @@ +/* + * + * 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 + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::OperationalState; +using namespace chip::app::Clusters::RvcOperationalState; + +CHIP_ERROR GenericOperationalStateDelegateImpl::GetOperationalStateAtIndex(size_t index, GenericOperationalState & operationalState) +{ + if (index >= mOperationalStateList.size()) + { + return CHIP_ERROR_NOT_FOUND; + } + operationalState = mOperationalStateList[index]; + return CHIP_NO_ERROR; +} + +CHIP_ERROR GenericOperationalStateDelegateImpl::GetOperationalPhaseAtIndex(size_t index, MutableCharSpan & operationalPhase) +{ + if (index >= mOperationalPhaseList.size()) + { + return CHIP_ERROR_NOT_FOUND; + } + return CopyCharSpanToMutableCharSpan(mOperationalPhaseList[index], operationalPhase); +} + +void GenericOperationalStateDelegateImpl::HandlePauseStateCallback(GenericOperationalError & err) +{ + // placeholder implementation + auto error = GetInstance()->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kPaused)); + if (error == CHIP_NO_ERROR) + { + err.Set(to_underlying(ErrorStateEnum::kNoError)); + } + else + { + err.Set(to_underlying(ErrorStateEnum::kUnableToCompleteOperation)); + } +} + +void GenericOperationalStateDelegateImpl::HandleResumeStateCallback(GenericOperationalError & err) +{ + // placeholder implementation + auto error = GetInstance()->SetOperationalState(to_underlying(OperationalStateEnum::kRunning)); + if (error == CHIP_NO_ERROR) + { + err.Set(to_underlying(ErrorStateEnum::kNoError)); + } + else + { + err.Set(to_underlying(ErrorStateEnum::kUnableToCompleteOperation)); + } +} + +void GenericOperationalStateDelegateImpl::HandleStartStateCallback(GenericOperationalError & err) +{ + uint8_t opState = GetInstance()->GetCurrentOperationalState(); + if (opState == to_underlying(OperationalStateEnum::kError)) + { + err.Set(to_underlying(ErrorStateEnum::kUnableToStartOrResume)); + return; + } + // placeholder implementation + auto error = GetInstance()->SetOperationalState(to_underlying(OperationalStateEnum::kRunning)); + if (error == CHIP_NO_ERROR) + { + err.Set(to_underlying(ErrorStateEnum::kNoError)); + } + else + { + err.Set(to_underlying(ErrorStateEnum::kUnableToCompleteOperation)); + } +} + +void GenericOperationalStateDelegateImpl::HandleStopStateCallback(GenericOperationalError & err) +{ + // placeholder implementation + auto error = GetInstance()->SetOperationalState(to_underlying(OperationalStateEnum::kStopped)); + if (error == CHIP_NO_ERROR) + { + err.Set(to_underlying(ErrorStateEnum::kNoError)); + } + else + { + err.Set(to_underlying(ErrorStateEnum::kUnableToCompleteOperation)); + } +} + +// Init Operational State cluster + +static OperationalState::Instance * gOperationalStateInstance = nullptr; +static OperationalStateDelegate * gOperationalStateDelegate = nullptr; + +OperationalState::Instance * OperationalState::GetOperationalStateInstance() +{ + return gOperationalStateInstance; +} + +void OperationalState::Shutdown() +{ + if (gOperationalStateInstance != nullptr) + { + delete gOperationalStateInstance; + gOperationalStateInstance = nullptr; + } + if (gOperationalStateDelegate != nullptr) + { + delete gOperationalStateDelegate; + gOperationalStateDelegate = nullptr; + } +} + +void emberAfOperationalStateClusterInitCallback(chip::EndpointId endpointId) +{ + VerifyOrDie(endpointId == 1); // this cluster is only enabled for endpoint 1. + VerifyOrDie(gOperationalStateInstance == nullptr && gOperationalStateDelegate == nullptr); + + gOperationalStateDelegate = new OperationalStateDelegate; + EndpointId operationalStateEndpoint = 0x01; + gOperationalStateInstance = new OperationalState::Instance(gOperationalStateDelegate, operationalStateEndpoint); + + gOperationalStateInstance->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kStopped)); + + gOperationalStateInstance->Init(); +} diff --git a/examples/lock-app/nxp/k32w/k32w0/.gn b/examples/laundry-washer-app/nxp/rt/rw61x/.gn similarity index 85% rename from examples/lock-app/nxp/k32w/k32w0/.gn rename to examples/laundry-washer-app/nxp/rt/rw61x/.gn index 3d48789e30ab3d..c0a26c2dc77832 100644 --- a/examples/lock-app/nxp/k32w/k32w0/.gn +++ b/examples/laundry-washer-app/nxp/rt/rw61x/.gn @@ -1,4 +1,5 @@ # Copyright (c) 2020 Project CHIP Authors +# Copyright 2023 NXP # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,6 +14,7 @@ # limitations under the License. import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") # The location of the build configuration file. buildconfig = "${build_root}/config/BUILDCONFIG.gn" @@ -25,4 +27,7 @@ default_args = { target_os = "freertos" import("//args.gni") + + # Import default platform configs + import("${chip_root}/src/platform/nxp/rt/rw61x/args.gni") } diff --git a/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn b/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn new file mode 100644 index 00000000000000..1a0e8f39d9c9a3 --- /dev/null +++ b/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn @@ -0,0 +1,288 @@ +# Copyright (c) 2021 Project CHIP Authors +# Copyright 2023 NXP +# +# 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_overrides/nxp_sdk.gni") +import("//build_overrides/openthread.gni") +import("${chip_root}/src/platform/device.gni") + +#allows to get common NXP SDK gn options +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +# Allows to get various RT gn options +import("${nxp_sdk_build_root}/${nxp_sdk_name}/rt_sdk.gni") + +import("${chip_root}/src/platform/nxp/${nxp_platform}/args.gni") +import( + "${nxp_sdk_build_root}/${nxp_sdk_name}/${rt_platform}/${rt_platform}.gni") +import("${nxp_sdk_build_root}/${nxp_sdk_name}/nxp_executable.gni") + +assert(current_os == "freertos") +assert(target_os == "freertos") +assert(nxp_platform == "rt/rw61x") + +declare_args() { + # Allows to start the tcp download test app + tcp_download = false + + # Allows to start the wifi connect test app + wifi_connect = false + + # The 2 params below are used only if tcp_download or wifi_connect are true, otherwise they're unused. + wifi_ssid = "" + wifi_password = "" + + # Setup discriminator as argument + setup_discriminator = 3840 +} + +example_platform_dir = "${chip_root}/examples/platform/nxp/${nxp_platform}" +common_example_dir = "${chip_root}/examples/platform/nxp/common" + +if (tcp_download == true && wifi_connect == true) { + assert("Cannot enable tcp_download and wifi_connect at the same time!") +} + +# Use NXP custom zap files for laundry-washer device-type +app_common_folder = "laundry-washer-app/nxp/zap" + +# Create here the SDK instance. +# Particular sources/defines/includes could be added/changed depending on the target application. +rt_sdk("sdk") { + defines = [] + + # To be moved, temporary mbedtls config fix to build app with factory data + if (chip_enable_secure_dac_private_key_storage == 1) { + defines += [ + "MBEDTLS_NIST_KW_C", + "MBEDTLS_PSA_CRYPTO_CLIENT", + ] + } + + cflags = [] + public_deps = [] + public_configs = [] + sources = [] + include_dirs = [] + + # Indicate paths to default board files + include_dirs += [ "${example_platform_dir}/board/" ] + sources += [ "${example_platform_dir}/board/pin_mux.c" ] + sources += [ "${example_platform_dir}/board/hardware_init.c" ] + sources += [ "${example_platform_dir}/board/clock_config.c" ] + sources += [ "${example_platform_dir}/board/board.c" ] + sources += [ "${example_platform_dir}/board/peripherals.c" ] + + # Indicate the path to CHIPProjectConfig.h + include_dirs += [ "include/config" ] + + # Indicate the default path to FreeRTOSConfig.h + include_dirs += [ "${example_platform_dir}/app/project_include/freeRTOS" ] + + # Indicate the default path to OpenThreadConfig.h + include_dirs += [ "${example_platform_dir}/app/project_include/openthread" ] + + # For matter with BR feature, increase FreeRTOS heap size + if (chip_enable_wifi && chip_enable_openthread) { + defines += [ "configTOTAL_HEAP_SIZE=(size_t)(160 * 1024)" ] + } + + defines += [ + "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setup_discriminator}", + ] +} + +# Create the SDK driver instance. +# Particular sources/defines/includes could be added to add other drivers not available in the default sdk driver template +rw61x_sdk_drivers("sdk_driver") { +} + +rt_executable("laundry-washer") { + output_name = "chip-rw61x-laundry-washer-example" + + defines = [ + "CONFIG_RENDEZVOUS_MODE=7", + "CONFIG_APP_FREERTOS_OS=1", + ] + + if (chip_enable_openthread) { + defines += [ "CONFIG_NET_L2_OPENTHREAD=1" ] + } + + include_dirs = [ + "../../common/main/include", + "../../common/main", + "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/providers/", + ] + + sources = [ + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp", + "${chip_root}/examples/providers/DeviceInfoProviderImpl.cpp", + "../../common/main/AppTask.cpp", + "../../common/main/DeviceCallbacks.cpp", + "../../common/main/ZclCallbacks.cpp", + "../../common/main/include/AppEvent.h", + "../../common/main/include/AppTask.h", + "../../common/main/include/DeviceCallbacks.h", + "../../common/main/main.cpp", + ] + + if (chip_enable_secure_dac_private_key_storage == 1) { + sources += [ + "${example_platform_dir}/factory_data/source/AppFactoryDataExample.cpp", + ] + } else { + sources += [ + "${common_example_dir}/factory_data/source/AppFactoryDataDefaultImpl.cpp", + ] + } + + # App common files + include_dirs += [ + "${common_example_dir}/icd/include", + "${common_example_dir}/matter_button/include", + "${common_example_dir}/matter_cli/include", + "${common_example_dir}/device_manager/include", + "${common_example_dir}/device_callbacks/include", + "${common_example_dir}/app_task/include", + "${common_example_dir}/factory_data/include", + ] + + sources += [ + "${common_example_dir}/app_task/source/AppTaskBase.cpp", + "${common_example_dir}/app_task/source/AppTaskFreeRTOS.cpp", + "${common_example_dir}/device_callbacks/source/CommonDeviceCallbacks.cpp", + "${common_example_dir}/device_manager/source/CHIPDeviceManager.cpp", + "${common_example_dir}/icd/source/ICDUtil.cpp", + "${common_example_dir}/matter_button/source/AppMatterButtonEmpty.cpp", + "${common_example_dir}/matter_cli/source/AppMatterCli.cpp", + ] + + deps = [ "${chip_root}/examples/${app_common_folder}" ] + + sources += [ + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/laundry-washer-controls-delegate-impl.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/laundry-washer-mode.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "../../common/main/operational-state-delegate-impl.cpp", + ] + + if (chip_enable_matter_cli) { + defines += [ "ENABLE_CHIP_SHELL" ] + deps += [ + "${chip_root}/examples/shell/shell_common:shell_common", + "${chip_root}/src/lib/shell:shell", + ] + } + + if (chip_enable_ota_requestor) { + include_dirs += [ "${common_example_dir}/ota_requestor/include" ] + sources += [ + "${common_example_dir}/ota_requestor/source/OTARequestorInitiator.cpp", + "${common_example_dir}/ota_requestor/source/OTARequestorInitiatorCommon.cpp", + ] + } + + if (wifi_connect) { + defines += [ + "WIFI_CONNECT_TASK=1", + "WIFI_CONNECT=1", + ] + + if (!chip_enable_matter_cli) { + assert(wifi_ssid != "" && wifi_password != "", + "WiFi SSID and password must be specified at build time!") + } + + if (wifi_ssid != "") { + defines += [ "WIFI_SSID=\"${wifi_ssid}\"" ] + } + + if (wifi_password != "") { + defines += [ "WIFI_PASSWORD=\"${wifi_password}\"" ] + } + + include_dirs += [ "${common_example_dir}/wifi_connect/include" ] + sources += [ "${common_example_dir}/wifi_connect/source/WifiConnect.cpp" ] + } + + if (tcp_download) { + defines += [ "CONFIG_CHIP_TCP_DOWNLOAD=1" ] + defines += [ + "WIFI_CONNECT=1", + "WIFI_SSID=\"${wifi_ssid}\"", + "WIFI_PASSWORD=\"${wifi_password}\"", + ] + + include_dirs += [ "${common_example_dir}/tcp_download_test/include" ] + sources += + [ "${common_example_dir}/tcp_download_test/source/TcpDownload.cpp" ] + } + + # In case a dedicated assert function needs to be supported the flag sdk_fsl_assert_support should be set to false + # The would add to the build a dedicated application assert implementation. + if (!sdk_fsl_assert_support) { + sources += [ "${common_example_dir}/app_assert/source/AppAssert.cpp" ] + } + + cflags = [ "-Wconversion" ] + + ldscript = "${example_platform_dir}/app/ldscripts/RW610_flash.ld" + + inputs = [ ldscript ] + + ldflags = [ + "-T" + rebase_path(ldscript, root_build_dir), + "-fno-common", + "-Wl,--defsym=__stack_size__=2048", + "-ffreestanding", + "-fno-builtin", + "-mapcs", + "-u qspiflash_config", + "-u image_vector_table", + "-u boot_data", + "-u dcd_data", + "-Wl,-print-memory-usage", + "-Wl,--no-warn-rwx-segments", + ] + + if (chip_enable_ota_requestor) { + if (no_mcuboot) { + # If "no_mcuboot" is set to true, the application will be linked at the base of the flash. + print( + "Warning : The OTA Requestor is enabled without MCUBoot. This will prevent the application from applying software updates.") + } else { + # we need to reserve enough space for the bootloader (MCUBoot) + # MCUBoot requires 0x20000 Bytes to be reserved at the base of the flash + # Consequently, some sections will need to be shifted + ldflags += [ "-Wl,--defsym=__m_mcuboot_size__=0x20000" ] + } + } + + output_dir = root_out_dir +} + +group("rw61x") { + deps = [ ":laundry-washer" ] +} + +group("default") { + deps = [ ":rw61x" ] +} diff --git a/examples/laundry-washer-app/nxp/rt/rw61x/README.md b/examples/laundry-washer-app/nxp/rt/rw61x/README.md new file mode 100644 index 00000000000000..e6165a33292b1e --- /dev/null +++ b/examples/laundry-washer-app/nxp/rt/rw61x/README.md @@ -0,0 +1,5 @@ +# CHIP RW61x Laundry washer Application + +All instructions describing how to use a Matter application on NXP RW61x can be +found in [README.md](../../../../all-clusters-app/nxp/rt/rw61x/README.md) root +readme diff --git a/examples/build_overrides/k32w0_sdk.gni b/examples/laundry-washer-app/nxp/rt/rw61x/args.gni similarity index 69% rename from examples/build_overrides/k32w0_sdk.gni rename to examples/laundry-washer-app/nxp/rt/rw61x/args.gni index e77b63d1e02fa9..c2d91a5db7bae7 100644 --- a/examples/build_overrides/k32w0_sdk.gni +++ b/examples/laundry-washer-app/nxp/rt/rw61x/args.gni @@ -1,4 +1,4 @@ -# Copyright (c) 2020 Project CHIP Authors +# 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. @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -declare_args() { - # Root directory for k32w SDK. - k32w0_sdk_build_root = - "//third_party/connectedhomeip/third_party/nxp/k32w0_sdk" -} +import("//build_overrides/chip.gni") + +# SDK target definitions +nxp_sdk_target = get_label_info(":sdk", "label_no_toolchain") +nxp_sdk_driver_target = get_label_info(":sdk_driver", "label_no_toolchain") diff --git a/examples/laundry-washer-app/nxp/rt/rw61x/build_overrides b/examples/laundry-washer-app/nxp/rt/rw61x/build_overrides new file mode 120000 index 00000000000000..f10867042f4d19 --- /dev/null +++ b/examples/laundry-washer-app/nxp/rt/rw61x/build_overrides @@ -0,0 +1 @@ +../../../../build_overrides \ No newline at end of file diff --git a/examples/laundry-washer-app/nxp/rt/rw61x/include/config/CHIPProjectConfig.h b/examples/laundry-washer-app/nxp/rt/rw61x/include/config/CHIPProjectConfig.h new file mode 100644 index 00000000000000..2653e97705fe39 --- /dev/null +++ b/examples/laundry-washer-app/nxp/rt/rw61x/include/config/CHIPProjectConfig.h @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * Copyright 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 + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +/* + * Tells to the platform Factory Data Provider whether to use the example configuration or real/provisioned data. + */ +#ifndef CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA +#define CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA 0 +#endif + +/** + * 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 0x8005 + +#if !CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA +// Use a default pairing code if one hasn't been provisioned in flash. +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#endif + +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 +#endif + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_PAIRING_CODE "CHIPUS" + +/** + * CHIP_DEVICE_CONFIG_USE_TEST_SERIAL_NUMBER + * + * Enables the use of a hard-coded default serial number if none + * is found in CHIP NV storage. + */ +#define CHIP_DEVICE_CONFIG_USE_TEST_SERIAL_NUMBER "DUMMY_SN" + +#endif /* !CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA */ + +/** + * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION + * + * The hardware version number assigned to device or product by the device vendor. This + * number is scoped to the device product id, and typically corresponds to a revision of the + * physical device, a change to its packaging, and/or a change to its marketing presentation. + * This value is generally *not* incremented for device software versions. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 100 + +#ifndef CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING "v0.1.0" +#endif + +/** + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING + * + * A string identifying the software version running on the device. + * CHIP currently expects the software version to be in the format + * {MAJOR_VERSION}.0d{MINOR_VERSION} + */ +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING NXP_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION NXP_CONFIG_DEVICE_SOFTWARE_VERSION +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME "NXP Semiconductors" +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME "NXP Demo App" +#endif + +#ifndef CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION +//-> format_version = 1 +//-> vendor_id = 0xFFF1 +//-> product_id_array = [ 0x8000, 0x8001, 0x8002, 0x8003, 0x8004, 0x8005, 0x8006, 0x8007, 0x8008, 0x8009, 0x800A, 0x800B, +// 0x800C, 0x800D, 0x800E, 0x800F, 0x8010, 0x8011, 0x8012, 0x8013, 0x8014, 0x8015, 0x8016, 0x8017, 0x8018, 0x8019, 0x801A, +// 0x801B, 0x801C, 0x801D, 0x801E, 0x801F, 0x8020, 0x8021, 0x8022, 0x8023, 0x8024, 0x8025, 0x8026, 0x8027, 0x8028, 0x8029, +// 0x802A, 0x802B, 0x802C, 0x802D, 0x802E, 0x802F, 0x8030, 0x8031, 0x8032, 0x8033, 0x8034, 0x8035, 0x8036, 0x8037, 0x8038, +// 0x8039, 0x803A, 0x803B, 0x803C, 0x803D, 0x803E, 0x803F, 0x8040, 0x8041, 0x8042, 0x8043, 0x8044, 0x8045, 0x8046, 0x8047, +// 0x8048, 0x8049, 0x804A, 0x804B, 0x804C, 0x804D, 0x804E, 0x804F, 0x8050, 0x8051, 0x8052, 0x8053, 0x8054, 0x8055, 0x8056, +// 0x8057, 0x8058, 0x8059, 0x805A, 0x805B, 0x805C, 0x805D, 0x805E, 0x805F, 0x8060, 0x8061, 0x8062, 0x8063 ] +//-> device_type_id = 0x0016 +//-> certificate_id = "ZIG20142ZB330003-24" +//-> security_level = 0 +//-> security_information = 0 +//-> version_number = 0x2694 +//-> certification_type = 0 +//-> dac_origin_vendor_id is not present +//-> dac_origin_product_id is not present +#define CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION \ + { \ + 0x30, 0x82, 0x02, 0x19, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0x0a, 0x30, \ + 0x82, 0x02, 0x06, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, \ + 0x02, 0x01, 0x30, 0x82, 0x01, 0x71, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, \ + 0x01, 0x62, 0x04, 0x82, 0x01, 0x5e, 0x15, 0x24, 0x00, 0x01, 0x25, 0x01, 0xf1, 0xff, 0x36, 0x02, 0x05, 0x00, 0x80, \ + 0x05, 0x01, 0x80, 0x05, 0x02, 0x80, 0x05, 0x03, 0x80, 0x05, 0x04, 0x80, 0x05, 0x05, 0x80, 0x05, 0x06, 0x80, 0x05, \ + 0x07, 0x80, 0x05, 0x08, 0x80, 0x05, 0x09, 0x80, 0x05, 0x0a, 0x80, 0x05, 0x0b, 0x80, 0x05, 0x0c, 0x80, 0x05, 0x0d, \ + 0x80, 0x05, 0x0e, 0x80, 0x05, 0x0f, 0x80, 0x05, 0x10, 0x80, 0x05, 0x11, 0x80, 0x05, 0x12, 0x80, 0x05, 0x13, 0x80, \ + 0x05, 0x14, 0x80, 0x05, 0x15, 0x80, 0x05, 0x16, 0x80, 0x05, 0x17, 0x80, 0x05, 0x18, 0x80, 0x05, 0x19, 0x80, 0x05, \ + 0x1a, 0x80, 0x05, 0x1b, 0x80, 0x05, 0x1c, 0x80, 0x05, 0x1d, 0x80, 0x05, 0x1e, 0x80, 0x05, 0x1f, 0x80, 0x05, 0x20, \ + 0x80, 0x05, 0x21, 0x80, 0x05, 0x22, 0x80, 0x05, 0x23, 0x80, 0x05, 0x24, 0x80, 0x05, 0x25, 0x80, 0x05, 0x26, 0x80, \ + 0x05, 0x27, 0x80, 0x05, 0x28, 0x80, 0x05, 0x29, 0x80, 0x05, 0x2a, 0x80, 0x05, 0x2b, 0x80, 0x05, 0x2c, 0x80, 0x05, \ + 0x2d, 0x80, 0x05, 0x2e, 0x80, 0x05, 0x2f, 0x80, 0x05, 0x30, 0x80, 0x05, 0x31, 0x80, 0x05, 0x32, 0x80, 0x05, 0x33, \ + 0x80, 0x05, 0x34, 0x80, 0x05, 0x35, 0x80, 0x05, 0x36, 0x80, 0x05, 0x37, 0x80, 0x05, 0x38, 0x80, 0x05, 0x39, 0x80, \ + 0x05, 0x3a, 0x80, 0x05, 0x3b, 0x80, 0x05, 0x3c, 0x80, 0x05, 0x3d, 0x80, 0x05, 0x3e, 0x80, 0x05, 0x3f, 0x80, 0x05, \ + 0x40, 0x80, 0x05, 0x41, 0x80, 0x05, 0x42, 0x80, 0x05, 0x43, 0x80, 0x05, 0x44, 0x80, 0x05, 0x45, 0x80, 0x05, 0x46, \ + 0x80, 0x05, 0x47, 0x80, 0x05, 0x48, 0x80, 0x05, 0x49, 0x80, 0x05, 0x4a, 0x80, 0x05, 0x4b, 0x80, 0x05, 0x4c, 0x80, \ + 0x05, 0x4d, 0x80, 0x05, 0x4e, 0x80, 0x05, 0x4f, 0x80, 0x05, 0x50, 0x80, 0x05, 0x51, 0x80, 0x05, 0x52, 0x80, 0x05, \ + 0x53, 0x80, 0x05, 0x54, 0x80, 0x05, 0x55, 0x80, 0x05, 0x56, 0x80, 0x05, 0x57, 0x80, 0x05, 0x58, 0x80, 0x05, 0x59, \ + 0x80, 0x05, 0x5a, 0x80, 0x05, 0x5b, 0x80, 0x05, 0x5c, 0x80, 0x05, 0x5d, 0x80, 0x05, 0x5e, 0x80, 0x05, 0x5f, 0x80, \ + 0x05, 0x60, 0x80, 0x05, 0x61, 0x80, 0x05, 0x62, 0x80, 0x05, 0x63, 0x80, 0x18, 0x24, 0x03, 0x16, 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, 0x94, 0x26, 0x24, 0x08, 0x00, 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, 0x20, 0x24, 0xe5, \ + 0xd1, 0xf4, 0x7a, 0x7d, 0x7b, 0x0d, 0x20, 0x6a, 0x26, 0xef, 0x69, 0x9b, 0x7c, 0x97, 0x57, 0xb7, 0x2d, 0x46, 0x90, \ + 0x89, 0xde, 0x31, 0x92, 0xe6, 0x78, 0xc7, 0x45, 0xe7, 0xf6, 0x0c, 0x02, 0x21, 0x00, 0xf8, 0xaa, 0x2f, 0xa7, 0x11, \ + 0xfc, 0xb7, 0x9b, 0x97, 0xe3, 0x97, 0xce, 0xda, 0x66, 0x7b, 0xae, 0x46, 0x4e, 0x2b, 0xd3, 0xff, 0xdf, 0xc3, 0xcc, \ + 0xed, 0x7a, 0xa8, 0xca, 0x5f, 0x4c, 0x1a, 0x7c \ + } +#endif + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC + * + * Enables synchronizing the device's real time clock with a remote CHIP Time service + * using the CHIP Time Sync protocol. + */ +// #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 + +/** + * CHIP_CONFIG_MAX_BINDINGS + * + * Maximum number of simultaneously active bindings per ChipExchangeManager + * 1 (Time Sync) + 2 (Two 1-way subscriptions) + 1 (Software Update) = 4 + * in the worst case. Keeping another 4 as buffer. + */ +#define CHIP_CONFIG_MAX_BINDINGS 6 + +/** + * CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD + * + * Select the ability to offload event logs to any interested subscribers using WDM. + */ +#define CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD 1 + +/** + * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS + * + * Enable recording UTC timestamps. + */ +#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 + +/** + * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE + * + * A size, in bytes, of the individual debug event logging buffer. + */ +#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512) + +/** + * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE + * + * For a development build, set the default importance of events to be logged as Debug. + * Since debug is the lowest importance level, this means all standard, critical, info and + * debug importance level vi events get logged. + */ +#if BUILD_RELEASE +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Production +#else +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Debug +#endif // BUILD_RELEASE + +/* Increasing the retransmission interval of the MRP messages after subsequent failures */ +#ifndef CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL +#define CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL (2000_ms32) +#endif diff --git a/examples/lock-app/nxp/k32w/k32w0/third_party/connectedhomeip b/examples/laundry-washer-app/nxp/rt/rw61x/third_party/connectedhomeip similarity index 100% rename from examples/lock-app/nxp/k32w/k32w0/third_party/connectedhomeip rename to examples/laundry-washer-app/nxp/rt/rw61x/third_party/connectedhomeip diff --git a/build_overrides/k32w0_sdk.gni b/examples/laundry-washer-app/nxp/zap/BUILD.gn similarity index 70% rename from build_overrides/k32w0_sdk.gni rename to examples/laundry-washer-app/nxp/zap/BUILD.gn index fa487e9e7fb254..d0a891b637617a 100644 --- a/build_overrides/k32w0_sdk.gni +++ b/examples/laundry-washer-app/nxp/zap/BUILD.gn @@ -1,4 +1,5 @@ # Copyright (c) 2020 Project CHIP Authors +# Copyright 2023 NXP # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,7 +13,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -declare_args() { - # Root directory for K32W SDK build files. - k32w0_sdk_build_root = "//third_party/nxp/k32w0_sdk" +import("//build_overrides/chip.gni") + +import("${chip_root}/src/app/chip_data_model.gni") + +import("${chip_root}/src/platform/device.gni") + +chip_data_model("zap") { + zap_file = "laundry-washer-app.zap" + is_server = true } diff --git a/examples/laundry-washer-app/nxp/zap/laundry-washer-app.matter b/examples/laundry-washer-app/nxp/zap/laundry-washer-app.matter new file mode 100644 index 00000000000000..da2c45a674c038 --- /dev/null +++ b/examples/laundry-washer-app/nxp/zap/laundry-washer-app.matter @@ -0,0 +1,2342 @@ +// 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; +} + +/** Attributes and commands for group configuration and manipulation. */ +cluster Groups = 4 { + revision 4; + + bitmap Feature : bitmap32 { + kGroupNames = 0x1; + } + + bitmap NameSupportBitmap : bitmap8 { + kGroupNames = 0x80; + } + + readonly attribute NameSupportBitmap nameSupport = 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; + + request struct AddGroupRequest { + group_id groupID = 0; + char_string<16> groupName = 1; + } + + response struct AddGroupResponse = 0 { + enum8 status = 0; + group_id groupID = 1; + } + + request struct ViewGroupRequest { + group_id groupID = 0; + } + + response struct ViewGroupResponse = 1 { + enum8 status = 0; + group_id groupID = 1; + char_string<16> groupName = 2; + } + + request struct GetGroupMembershipRequest { + group_id groupList[] = 0; + } + + response struct GetGroupMembershipResponse = 2 { + nullable int8u capacity = 0; + group_id groupList[] = 1; + } + + request struct RemoveGroupRequest { + group_id groupID = 0; + } + + response struct RemoveGroupResponse = 3 { + enum8 status = 0; + group_id groupID = 1; + } + + request struct AddGroupIfIdentifyingRequest { + group_id groupID = 0; + char_string<16> groupName = 1; + } + + /** Command description for AddGroup */ + fabric command access(invoke: manage) AddGroup(AddGroupRequest): AddGroupResponse = 0; + /** Command description for ViewGroup */ + fabric command ViewGroup(ViewGroupRequest): ViewGroupResponse = 1; + /** Command description for GetGroupMembership */ + fabric command GetGroupMembership(GetGroupMembershipRequest): GetGroupMembershipResponse = 2; + /** Command description for RemoveGroup */ + fabric command access(invoke: manage) RemoveGroup(RemoveGroupRequest): RemoveGroupResponse = 3; + /** Command description for RemoveAllGroups */ + fabric command access(invoke: manage) RemoveAllGroups(): DefaultSuccess = 4; + /** Command description for AddGroupIfIdentifying */ + fabric command access(invoke: manage) AddGroupIfIdentifying(AddGroupIfIdentifyingRequest): DefaultSuccess = 5; +} + +/** Attributes and commands for switching devices between 'On' and 'Off' states. */ +cluster OnOff = 6 { + revision 6; + + enum DelayedAllOffEffectVariantEnum : enum8 { + kDelayedOffFastFade = 0; + kNoFade = 1; + kDelayedOffSlowFade = 2; + } + + enum DyingLightEffectVariantEnum : enum8 { + kDyingLightFadeOff = 0; + } + + enum EffectIdentifierEnum : enum8 { + kDelayedAllOff = 0; + kDyingLight = 1; + } + + enum StartUpOnOffEnum : enum8 { + kOff = 0; + kOn = 1; + kToggle = 2; + } + + bitmap Feature : bitmap32 { + kLighting = 0x1; + kDeadFrontBehavior = 0x2; + kOffOnly = 0x4; + } + + bitmap OnOffControlBitmap : bitmap8 { + kAcceptOnlyWhenOn = 0x1; + } + + readonly attribute boolean onOff = 0; + readonly attribute optional boolean globalSceneControl = 16384; + attribute optional int16u onTime = 16385; + attribute optional int16u offWaitTime = 16386; + attribute access(write: manage) optional nullable StartUpOnOffEnum startUpOnOff = 16387; + 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 OffWithEffectRequest { + EffectIdentifierEnum effectIdentifier = 0; + enum8 effectVariant = 1; + } + + request struct OnWithTimedOffRequest { + OnOffControlBitmap onOffControl = 0; + int16u onTime = 1; + int16u offWaitTime = 2; + } + + /** On receipt of this command, a device SHALL enter its ‘Off’ state. This state is device dependent, but it is recommended that it is used for power off or similar functions. On receipt of the Off command, the OnTime attribute SHALL be set to 0. */ + command Off(): DefaultSuccess = 0; + /** On receipt of this command, a device SHALL enter its ‘On’ state. This state is device dependent, but it is recommended that it is used for power on or similar functions. On receipt of the On command, if the value of the OnTime attribute is equal to 0, the device SHALL set the OffWaitTime attribute to 0. */ + command On(): DefaultSuccess = 1; + /** On receipt of this command, if a device is in its ‘Off’ state it SHALL enter its ‘On’ state. Otherwise, if it is in its ‘On’ state it SHALL enter its ‘Off’ state. On receipt of the Toggle command, if the value of the OnOff attribute is equal to FALSE and if the value of the OnTime attribute is equal to 0, the device SHALL set the OffWaitTime attribute to 0. If the value of the OnOff attribute is equal to TRUE, the OnTime attribute SHALL be set to 0. */ + command Toggle(): DefaultSuccess = 2; + /** The OffWithEffect command allows devices to be turned off using enhanced ways of fading. */ + command OffWithEffect(OffWithEffectRequest): DefaultSuccess = 64; + /** The OnWithRecallGlobalScene command allows the recall of the settings when the device was turned off. */ + command OnWithRecallGlobalScene(): DefaultSuccess = 65; + /** The OnWithTimedOff command allows devices to be turned on for a specific duration with a guarded off duration so that SHOULD the device be subsequently switched off, further OnWithTimedOff commands, received during this time, are prevented from turning the devices back on. */ + command OnWithTimedOff(OnWithTimedOffRequest): DefaultSuccess = 66; +} + +/** 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 Binding Cluster is meant to replace the support from the Zigbee Device Object (ZDO) for supporting the binding table. */ +cluster Binding = 30 { + revision 1; // NOTE: Default/not specifically set + + fabric_scoped struct TargetStruct { + optional node_id node = 1; + optional group_id group = 2; + optional endpoint_no endpoint = 3; + optional cluster_id cluster = 4; + fabric_idx fabricIndex = 254; + } + + attribute access(write: manage) TargetStruct binding[] = 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; +} + +/** 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; +} + +/** Nodes should be expected to be deployed to any and all regions of the world. These global regions + may have differing common languages, units of measurements, and numerical formatting + standards. As such, Nodes that visually or audibly convey information need a mechanism by which + they can be configured to use a user’s preferred language, units, etc */ +cluster LocalizationConfiguration = 43 { + revision 1; // NOTE: Default/not specifically set + + attribute access(write: manage) char_string<35> activeLocale = 0; + readonly attribute char_string supportedLocales[] = 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; +} + +/** Nodes should be expected to be deployed to any and all regions of the world. These global regions + may have differing preferences for how dates and times are conveyed. As such, Nodes that visually + or audibly convey time information need a mechanism by which they can be configured to use a + user’s preferred format. */ +cluster TimeFormatLocalization = 44 { + revision 1; // NOTE: Default/not specifically set + + enum CalendarTypeEnum : enum8 { + kBuddhist = 0; + kChinese = 1; + kCoptic = 2; + kEthiopian = 3; + kGregorian = 4; + kHebrew = 5; + kIndian = 6; + kIslamic = 7; + kJapanese = 8; + kKorean = 9; + kPersian = 10; + kTaiwanese = 11; + kUseActiveLocale = 255; + } + + enum HourFormatEnum : enum8 { + k12hr = 0; + k24hr = 1; + kUseActiveLocale = 255; + } + + bitmap Feature : bitmap32 { + kCalendarFormat = 0x1; + } + + attribute access(write: manage) HourFormatEnum hourFormat = 0; + attribute access(write: manage) optional CalendarTypeEnum activeCalendarType = 1; + readonly attribute optional CalendarTypeEnum supportedCalendarTypes[] = 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; +} + +/** Nodes should be expected to be deployed to any and all regions of the world. These global regions + may have differing preferences for the units in which values are conveyed in communication to a + user. As such, Nodes that visually or audibly convey measurable values to the user need a + mechanism by which they can be configured to use a user’s preferred unit. */ +cluster UnitLocalization = 45 { + revision 1; + + enum TempUnitEnum : enum8 { + kFahrenheit = 0; + kCelsius = 1; + kKelvin = 2; + } + + bitmap Feature : bitmap32 { + kTemperatureUnit = 0x1; + } + + attribute access(write: manage) optional TempUnitEnum temperatureUnit = 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; +} + +/** This cluster is used to describe the configuration and capabilities of a physical power source that provides power to the Node. */ +cluster PowerSource = 47 { + revision 1; // NOTE: Default/not specifically set + + enum BatApprovedChemistryEnum : enum16 { + kUnspecified = 0; + kAlkaline = 1; + kLithiumCarbonFluoride = 2; + kLithiumChromiumOxide = 3; + kLithiumCopperOxide = 4; + kLithiumIronDisulfide = 5; + kLithiumManganeseDioxide = 6; + kLithiumThionylChloride = 7; + kMagnesium = 8; + kMercuryOxide = 9; + kNickelOxyhydride = 10; + kSilverOxide = 11; + kZincAir = 12; + kZincCarbon = 13; + kZincChloride = 14; + kZincManganeseDioxide = 15; + kLeadAcid = 16; + kLithiumCobaltOxide = 17; + kLithiumIon = 18; + kLithiumIonPolymer = 19; + kLithiumIronPhosphate = 20; + kLithiumSulfur = 21; + kLithiumTitanate = 22; + kNickelCadmium = 23; + kNickelHydrogen = 24; + kNickelIron = 25; + kNickelMetalHydride = 26; + kNickelZinc = 27; + kSilverZinc = 28; + kSodiumIon = 29; + kSodiumSulfur = 30; + kZincBromide = 31; + kZincCerium = 32; + } + + enum BatChargeFaultEnum : enum8 { + kUnspecified = 0; + kAmbientTooHot = 1; + kAmbientTooCold = 2; + kBatteryTooHot = 3; + kBatteryTooCold = 4; + kBatteryAbsent = 5; + kBatteryOverVoltage = 6; + kBatteryUnderVoltage = 7; + kChargerOverVoltage = 8; + kChargerUnderVoltage = 9; + kSafetyTimeout = 10; + } + + enum BatChargeLevelEnum : enum8 { + kOK = 0; + kWarning = 1; + kCritical = 2; + } + + enum BatChargeStateEnum : enum8 { + kUnknown = 0; + kIsCharging = 1; + kIsAtFullCharge = 2; + kIsNotCharging = 3; + } + + enum BatCommonDesignationEnum : enum16 { + kUnspecified = 0; + kAAA = 1; + kAA = 2; + kC = 3; + kD = 4; + k4v5 = 5; + k6v0 = 6; + k9v0 = 7; + k12AA = 8; + kAAAA = 9; + kA = 10; + kB = 11; + kF = 12; + kN = 13; + kNo6 = 14; + kSubC = 15; + kA23 = 16; + kA27 = 17; + kBA5800 = 18; + kDuplex = 19; + k4SR44 = 20; + k523 = 21; + k531 = 22; + k15v0 = 23; + k22v5 = 24; + k30v0 = 25; + k45v0 = 26; + k67v5 = 27; + kJ = 28; + kCR123A = 29; + kCR2 = 30; + k2CR5 = 31; + kCRP2 = 32; + kCRV3 = 33; + kSR41 = 34; + kSR43 = 35; + kSR44 = 36; + kSR45 = 37; + kSR48 = 38; + kSR54 = 39; + kSR55 = 40; + kSR57 = 41; + kSR58 = 42; + kSR59 = 43; + kSR60 = 44; + kSR63 = 45; + kSR64 = 46; + kSR65 = 47; + kSR66 = 48; + kSR67 = 49; + kSR68 = 50; + kSR69 = 51; + kSR516 = 52; + kSR731 = 53; + kSR712 = 54; + kLR932 = 55; + kA5 = 56; + kA10 = 57; + kA13 = 58; + kA312 = 59; + kA675 = 60; + kAC41E = 61; + k10180 = 62; + k10280 = 63; + k10440 = 64; + k14250 = 65; + k14430 = 66; + k14500 = 67; + k14650 = 68; + k15270 = 69; + k16340 = 70; + kRCR123A = 71; + k17500 = 72; + k17670 = 73; + k18350 = 74; + k18500 = 75; + k18650 = 76; + k19670 = 77; + k25500 = 78; + k26650 = 79; + k32600 = 80; + } + + enum BatFaultEnum : enum8 { + kUnspecified = 0; + kOverTemp = 1; + kUnderTemp = 2; + } + + enum BatReplaceabilityEnum : enum8 { + kUnspecified = 0; + kNotReplaceable = 1; + kUserReplaceable = 2; + kFactoryReplaceable = 3; + } + + enum PowerSourceStatusEnum : enum8 { + kUnspecified = 0; + kActive = 1; + kStandby = 2; + kUnavailable = 3; + } + + enum WiredCurrentTypeEnum : enum8 { + kAC = 0; + kDC = 1; + } + + enum WiredFaultEnum : enum8 { + kUnspecified = 0; + kOverVoltage = 1; + kUnderVoltage = 2; + } + + bitmap Feature : bitmap32 { + kWired = 0x1; + kBattery = 0x2; + kRechargeable = 0x4; + kReplaceable = 0x8; + } + + struct BatChargeFaultChangeType { + BatChargeFaultEnum current[] = 0; + BatChargeFaultEnum previous[] = 1; + } + + struct BatFaultChangeType { + BatFaultEnum current[] = 0; + BatFaultEnum previous[] = 1; + } + + struct WiredFaultChangeType { + WiredFaultEnum current[] = 0; + WiredFaultEnum previous[] = 1; + } + + info event WiredFaultChange = 0 { + WiredFaultEnum current[] = 0; + WiredFaultEnum previous[] = 1; + } + + info event BatFaultChange = 1 { + BatFaultEnum current[] = 0; + BatFaultEnum previous[] = 1; + } + + info event BatChargeFaultChange = 2 { + BatChargeFaultEnum current[] = 0; + BatChargeFaultEnum previous[] = 1; + } + + readonly attribute PowerSourceStatusEnum status = 0; + readonly attribute int8u order = 1; + readonly attribute char_string<60> description = 2; + readonly attribute optional nullable int32u wiredAssessedInputVoltage = 3; + readonly attribute optional nullable int16u wiredAssessedInputFrequency = 4; + readonly attribute optional WiredCurrentTypeEnum wiredCurrentType = 5; + readonly attribute optional nullable int32u wiredAssessedCurrent = 6; + readonly attribute optional int32u wiredNominalVoltage = 7; + readonly attribute optional int32u wiredMaximumCurrent = 8; + readonly attribute optional boolean wiredPresent = 9; + readonly attribute optional WiredFaultEnum activeWiredFaults[] = 10; + readonly attribute optional nullable int32u batVoltage = 11; + readonly attribute optional nullable int8u batPercentRemaining = 12; + readonly attribute optional nullable int32u batTimeRemaining = 13; + readonly attribute optional BatChargeLevelEnum batChargeLevel = 14; + readonly attribute optional boolean batReplacementNeeded = 15; + readonly attribute optional BatReplaceabilityEnum batReplaceability = 16; + readonly attribute optional boolean batPresent = 17; + readonly attribute optional BatFaultEnum activeBatFaults[] = 18; + readonly attribute optional char_string<60> batReplacementDescription = 19; + readonly attribute optional BatCommonDesignationEnum batCommonDesignation = 20; + readonly attribute optional char_string<20> batANSIDesignation = 21; + readonly attribute optional char_string<20> batIECDesignation = 22; + readonly attribute optional BatApprovedChemistryEnum batApprovedChemistry = 23; + readonly attribute optional int32u batCapacity = 24; + readonly attribute optional int8u batQuantity = 25; + readonly attribute optional BatChargeStateEnum batChargeState = 26; + readonly attribute optional nullable int32u batTimeToFullCharge = 27; + readonly attribute optional boolean batFunctionalWhileCharging = 28; + readonly attribute optional nullable int32u batChargingCurrent = 29; + readonly attribute optional BatChargeFaultEnum activeBatChargeFaults[] = 30; + readonly attribute endpoint_no endpointList[] = 31; + 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 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 Wi-Fi 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 WiFiNetworkDiagnostics = 54 { + revision 1; // NOTE: Default/not specifically set + + enum AssociationFailureCauseEnum : enum8 { + kUnknown = 0; + kAssociationFailed = 1; + kAuthenticationFailed = 2; + kSsidNotFound = 3; + } + + enum ConnectionStatusEnum : enum8 { + kConnected = 0; + kNotConnected = 1; + } + + enum SecurityTypeEnum : enum8 { + kUnspecified = 0; + kNone = 1; + kWEP = 2; + kWPA = 3; + kWPA2 = 4; + kWPA3 = 5; + } + + enum WiFiVersionEnum : enum8 { + kA = 0; + kB = 1; + kG = 2; + kN = 3; + kAc = 4; + kAx = 5; + kAh = 6; + } + + bitmap Feature : bitmap32 { + kPacketCounts = 0x1; + kErrorCounts = 0x2; + } + + info event Disconnection = 0 { + int16u reasonCode = 0; + } + + info event AssociationFailure = 1 { + AssociationFailureCauseEnum associationFailureCause = 0; + int16u status = 1; + } + + info event ConnectionStatus = 2 { + ConnectionStatusEnum connectionStatus = 0; + } + + readonly attribute nullable octet_string<6> bssid = 0; + readonly attribute nullable SecurityTypeEnum securityType = 1; + readonly attribute nullable WiFiVersionEnum wiFiVersion = 2; + readonly attribute nullable int16u channelNumber = 3; + readonly attribute nullable int8s rssi = 4; + readonly attribute optional nullable int32u beaconLostCount = 5; + readonly attribute optional nullable int32u beaconRxCount = 6; + readonly attribute optional nullable int32u packetMulticastRxCount = 7; + readonly attribute optional nullable int32u packetMulticastTxCount = 8; + readonly attribute optional nullable int32u packetUnicastRxCount = 9; + readonly attribute optional nullable int32u packetUnicastTxCount = 10; + readonly attribute optional nullable int64u currentMaxRate = 11; + readonly attribute optional nullable int64u overrunCount = 12; + 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 Breacon and Packet related count attributes to 0 */ + command 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; +} + +/** The Fixed Label Cluster provides a feature for the device to tag an endpoint with zero or more read only +labels. */ +cluster FixedLabel = 64 { + revision 1; // NOTE: Default/not specifically set + + struct LabelStruct { + char_string<16> label = 0; + char_string<16> value = 1; + } + + readonly attribute LabelStruct labelList[] = 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; +} + +/** The User Label Cluster provides a feature to tag an endpoint with zero or more labels. */ +cluster UserLabel = 65 { + revision 1; // NOTE: Default/not specifically set + + struct LabelStruct { + char_string<16> label = 0; + char_string<16> value = 1; + } + + attribute access(write: manage) LabelStruct labelList[] = 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; +} + +/** Attributes and commands for selecting a mode from a list of supported options. */ +cluster ModeSelect = 80 { + revision 2; + + bitmap Feature : bitmap32 { + kOnOff = 0x1; + } + + struct SemanticTagStruct { + vendor_id mfgCode = 0; + enum16 value = 1; + } + + struct ModeOptionStruct { + char_string<64> label = 0; + int8u mode = 1; + SemanticTagStruct semanticTags[] = 2; + } + + readonly attribute char_string<64> description = 0; + readonly attribute nullable enum16 standardNamespace = 1; + readonly attribute ModeOptionStruct supportedModes[] = 2; + readonly attribute int8u currentMode = 3; + attribute optional nullable int8u startUpMode = 4; + attribute optional nullable int8u onMode = 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 ChangeToModeRequest { + int8u newMode = 0; + } + + /** On receipt of this command, if the NewMode field matches the Mode field in an entry of the SupportedModes list, the server SHALL set the CurrentMode attribute to the NewMode value, otherwise, the server SHALL respond with an INVALID_COMMAND status response. */ + command ChangeToMode(ChangeToModeRequest): DefaultSuccess = 0; +} + +/** Attributes and commands for selecting a mode from a list of supported options. */ +cluster LaundryWasherMode = 81 { + revision 2; + + enum ModeTag : enum16 { + kNormal = 16384; + kDelicate = 16385; + kHeavy = 16386; + kWhites = 16387; + } + + bitmap Feature : bitmap32 { + kOnOff = 0x1; + } + + struct ModeTagStruct { + optional vendor_id mfgCode = 0; + enum16 value = 1; + } + + struct ModeOptionStruct { + char_string<64> label = 0; + int8u mode = 1; + ModeTagStruct modeTags[] = 2; + } + + readonly attribute ModeOptionStruct supportedModes[] = 0; + readonly attribute int8u currentMode = 1; + attribute optional nullable int8u startUpMode = 2; + attribute optional nullable int8u onMode = 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 ChangeToModeRequest { + int8u newMode = 0; + } + + response struct ChangeToModeResponse = 1 { + enum8 status = 0; + optional char_string statusText = 1; + } + + /** This command is used to change device modes. + On receipt of this command the device SHALL respond with a ChangeToModeResponse command. */ + command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; +} + +/** This cluster supports remotely monitoring and controlling the different types of functionality available to a washing device, such as a washing machine. */ +cluster LaundryWasherControls = 83 { + revision 1; + + enum NumberOfRinsesEnum : enum8 { + kNone = 0; + kNormal = 1; + kExtra = 2; + kMax = 3; + } + + bitmap Feature : bitmap32 { + kSpin = 0x1; + kRinse = 0x2; + } + + readonly attribute optional char_string spinSpeeds[] = 0; + attribute optional nullable int8u spinSpeedCurrent = 1; + attribute optional NumberOfRinsesEnum numberOfRinses = 2; + readonly attribute optional NumberOfRinsesEnum supportedRinses[] = 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; +} + +/** Attributes and commands for configuring the temperature control, and reporting temperature. */ +cluster TemperatureControl = 86 { + revision 1; // NOTE: Default/not specifically set + + bitmap Feature : bitmap32 { + kTemperatureNumber = 0x1; + kTemperatureLevel = 0x2; + kTemperatureStep = 0x4; + } + + readonly attribute optional temperature temperatureSetpoint = 0; + readonly attribute optional temperature minTemperature = 1; + readonly attribute optional temperature maxTemperature = 2; + readonly attribute optional temperature step = 3; + readonly attribute optional int8u selectedTemperatureLevel = 4; + readonly attribute optional char_string supportedTemperatureLevels[] = 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 SetTemperatureRequest { + optional temperature targetTemperature = 0; + optional int8u targetTemperatureLevel = 1; + } + + /** Set Temperature */ + command SetTemperature(SetTemperatureRequest): DefaultSuccess = 0; +} + +/** This cluster supports remotely monitoring and, where supported, changing the operational state of any device where a state machine is a part of the operation. */ +cluster OperationalState = 96 { + revision 1; + + enum ErrorStateEnum : enum8 { + kNoError = 0; + kUnableToStartOrResume = 1; + kUnableToCompleteOperation = 2; + kCommandInvalidInState = 3; + } + + enum OperationalStateEnum : enum8 { + kStopped = 0; + kRunning = 1; + kPaused = 2; + kError = 3; + } + + struct ErrorStateStruct { + enum8 errorStateID = 0; + optional char_string<64> errorStateLabel = 1; + optional char_string<64> errorStateDetails = 2; + } + + struct OperationalStateStruct { + enum8 operationalStateID = 0; + optional char_string<64> operationalStateLabel = 1; + } + + critical event OperationalError = 0 { + ErrorStateStruct errorState = 0; + } + + info event OperationCompletion = 1 { + enum8 completionErrorCode = 0; + optional nullable elapsed_s totalOperationalTime = 1; + optional nullable elapsed_s pausedTime = 2; + } + + readonly attribute nullable char_string phaseList[] = 0; + readonly attribute nullable int8u currentPhase = 1; + readonly attribute optional nullable elapsed_s countdownTime = 2; + readonly attribute OperationalStateStruct operationalStateList[] = 3; + readonly attribute OperationalStateEnum operationalState = 4; + readonly attribute ErrorStateStruct operationalError = 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; + + response struct OperationalCommandResponse = 4 { + ErrorStateStruct commandResponseState = 0; + } + + /** Upon receipt, the device SHALL pause its operation if it is possible based on the current function of the server. */ + command Pause(): OperationalCommandResponse = 0; + /** Upon receipt, the device SHALL stop its operation if it is at a position where it is safe to do so and/or permitted. */ + command Stop(): OperationalCommandResponse = 1; + /** Upon receipt, the device SHALL start its operation if it is safe to do so and the device is in an operational state from which it can be started. */ + command Start(): OperationalCommandResponse = 2; + /** Upon receipt, the device SHALL resume its operation from the point it was at when it received the Pause command, or from the point when it was paused by means outside of this cluster (for example by manual button press). */ + command Resume(): OperationalCommandResponse = 3; +} + +endpoint 0 { + device type ma_rootdevice = 22, version 1; + + binding cluster OtaSoftwareUpdateProvider; + + server cluster Identify { + ram attribute identifyTime default = 0x0000; + ram attribute identifyType default = 0x00; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 4; + + handle command Identify; + } + + 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 extension; + 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 manufacturingDate; + callback attribute partNumber; + callback attribute productURL; + callback attribute productLabel; + callback attribute serialNumber; + persist attribute localConfigDisabled default = 0; + callback attribute uniqueID; + callback attribute capabilityMinima; + callback attribute productAppearance; + callback attribute specificationVersion; + callback attribute maxPathsPerInvoke; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + 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; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command AnnounceOTAProvider; + } + + server cluster LocalizationConfiguration { + persist attribute activeLocale default = "en-US"; + callback attribute supportedLocales; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster TimeFormatLocalization { + ram attribute hourFormat; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster UnitLocalization { + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + 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; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 2; + ram attribute clusterRevision default = 1; + + handle command ScanNetworks; + handle command ScanNetworksResponse; + handle command AddOrUpdateWiFiNetwork; + 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 upTime; + callback attribute totalOperationalHours; + callback attribute bootReason; + callback attribute testEventTriggersEnabled default = false; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command TestEventTrigger; + handle command TimeSnapshot; + handle command TimeSnapshotResponse; + } + + server cluster WiFiNetworkDiagnostics { + callback attribute bssid; + callback attribute securityType; + callback attribute wiFiVersion; + callback attribute channelNumber; + callback attribute rssi; + callback attribute currentMaxRate; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + 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; + } +} +endpoint 1 { + device type ma_laundry_washer = 115, version 1; + + + server cluster Identify { + ram attribute identifyTime default = 0x0; + ram attribute identifyType default = 0x00; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 4; + + handle command Identify; + handle command TriggerEffect; + } + + server cluster Groups { + ram attribute nameSupport; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 4; + + handle command AddGroup; + handle command AddGroupResponse; + handle command ViewGroup; + handle command ViewGroupResponse; + handle command GetGroupMembership; + handle command GetGroupMembershipResponse; + handle command RemoveGroup; + handle command RemoveGroupResponse; + handle command RemoveAllGroups; + handle command AddGroupIfIdentifying; + } + + server cluster OnOff { + persist attribute onOff default = 0; + ram attribute globalSceneControl default = 1; + ram attribute onTime default = 0; + ram attribute offWaitTime default = 0; + persist attribute startUpOnOff default = 0xFF; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 1; + ram attribute clusterRevision default = 5; + + handle command Off; + handle command On; + handle command Toggle; + handle command OffWithEffect; + handle command OnWithRecallGlobalScene; + handle command OnWithTimedOff; + } + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster Binding { + callback attribute binding; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster PowerSource { + ram attribute status; + ram attribute order; + ram attribute description; + ram attribute wiredCurrentType; + callback attribute endpointList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 1; + ram attribute clusterRevision default = 2; + } + + server cluster FixedLabel { + callback attribute labelList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster UserLabel { + callback attribute labelList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster ModeSelect { + ram attribute description; + ram attribute standardNamespace; + callback attribute supportedModes; + ram attribute currentMode; + ram attribute startUpMode; + ram attribute onMode; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command ChangeToMode; + } + + server cluster LaundryWasherMode { + callback attribute supportedModes; + callback attribute currentMode; + callback attribute startUpMode; + callback attribute onMode; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + callback attribute featureMap; + ram attribute clusterRevision default = 1; + + handle command ChangeToMode; + handle command ChangeToModeResponse; + } + + server cluster LaundryWasherControls { + callback attribute spinSpeeds; + ram attribute spinSpeedCurrent; + ram attribute numberOfRinses; + callback attribute supportedRinses; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 3; + ram attribute clusterRevision default = 1; + } + + server cluster TemperatureControl { + ram attribute selectedTemperatureLevel; + callback attribute supportedTemperatureLevels; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 2; + ram attribute clusterRevision default = 1; + + handle command SetTemperature; + } + + server cluster OperationalState { + emits event OperationalError; + emits event OperationCompletion; + callback attribute phaseList; + callback attribute currentPhase; + callback attribute countdownTime; + callback attribute operationalStateList; + callback attribute operationalState; + callback attribute operationalError; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command Pause; + handle command Stop; + handle command Start; + handle command Resume; + handle command OperationalCommandResponse; + } +} + + diff --git a/examples/laundry-washer-app/nxp/zap/laundry-washer-app.zap b/examples/laundry-washer-app/nxp/zap/laundry-washer-app.zap new file mode 100644 index 00000000000000..d5c7ee215e1976 --- /dev/null +++ b/examples/laundry-washer-app/nxp/zap/laundry-washer-app.zap @@ -0,0 +1,5288 @@ +{ + "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": [ + 1 + ], + "deviceIdentifiers": [ + 22 + ], + "deviceTypeName": "MA-rootdevice", + "deviceTypeCode": 22, + "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 + } + ], + "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": "0x00", + "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": 0, + "maxInterval": 65344, + "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": 0, + "maxInterval": 65344, + "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": 0, + "maxInterval": 65344, + "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": 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": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "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": "Extension", + "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": "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": "ManufacturingDate", + "code": 11, + "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": "PartNumber", + "code": 12, + "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": "ProductURL", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "long_char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductLabel", + "code": 14, + "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": "SerialNumber", + "code": 15, + "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": "LocalConfigDisabled", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "NVM", + "singleton": 1, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UniqueID", + "code": 18, + "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": "ProductAppearance", + "code": 20, + "mfgCode": null, + "side": "server", + "type": "ProductAppearanceStruct", + "included": 1, + "storageOption": "External", + "singleton": 1, + "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": null, + "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": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "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": 1, + "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": 1, + "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": 1, + "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": 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": 1, + "maxInterval": 65534, + "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": 1, + "maxInterval": 65534, + "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": "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": "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": "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": "Localization Configuration", + "code": 43, + "mfgCode": null, + "define": "LOCALIZATION_CONFIGURATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "ActiveLocale", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "en-US", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportedLocales", + "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": "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": "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 + } + ] + }, + { + "name": "Time Format Localization", + "code": 44, + "mfgCode": null, + "define": "TIME_FORMAT_LOCALIZATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "HourFormat", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "HourFormatEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "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": "", + "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": "", + "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": "", + "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": "", + "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 + } + ] + }, + { + "name": "Unit Localization", + "code": 45, + "mfgCode": null, + "define": "UNIT_LOCALIZATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "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": "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 + } + ] + }, + { + "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": "AddOrUpdateWiFiNetwork", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "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": "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": "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 + }, + { + "name": "TimeSnapshot", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TimeSnapshotResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "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": "UpTime", + "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": "TotalOperationalHours", + "code": 3, + "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": "BootReason", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "BootReasonEnum", + "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": "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": "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": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "BootReason", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "WiFi Network Diagnostics", + "code": 54, + "mfgCode": null, + "define": "WIFI_NETWORK_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "BSSID", + "code": 0, + "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": "SecurityType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "SecurityTypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "WiFiVersion", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "WiFiVersionEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ChannelNumber", + "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": "RSSI", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int8s", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CurrentMaxRate", + "code": 11, + "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": "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": "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": "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": 0, + "maxInterval": 65344, + "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": 0, + "maxInterval": 65344, + "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": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + } + ] + }, + { + "id": 2, + "name": "Anonymous Endpoint Type", + "deviceTypeRef": { + "code": 115, + "profileId": 259, + "label": "MA-laundry-washer", + "name": "MA-laundry-washer" + }, + "deviceTypes": [ + { + "code": 115, + "profileId": 259, + "label": "MA-laundry-washer", + "name": "MA-laundry-washer" + } + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 115 + ], + "deviceTypeName": "MA-laundry-washer", + "deviceTypeCode": 115, + "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": "0x0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "IdentifyType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "IdentifyTypeEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "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": "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": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Groups", + "code": 4, + "mfgCode": null, + "define": "GROUPS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "AddGroup", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddGroupResponse", + "code": 0, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ViewGroup", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ViewGroupResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "GetGroupMembership", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetGroupMembershipResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "RemoveGroup", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveGroupResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "RemoveAllGroups", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddGroupIfIdentifying", + "code": 5, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "NameSupport", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "NameSupportBitmap", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "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": "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": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "On/Off", + "code": 6, + "mfgCode": null, + "define": "ON_OFF_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "Off", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "On", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Toggle", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "OffWithEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "OnWithRecallGlobalScene", + "code": 65, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "OnWithTimedOff", + "code": 66, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "OnOff", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GlobalSceneControl", + "code": 16384, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OnTime", + "code": 16385, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OffWaitTime", + "code": 16386, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "StartUpOnOff", + "code": 16387, + "mfgCode": null, + "side": "server", + "type": "StartUpOnOffEnum", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0xFF", + "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": "1", + "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": "5", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "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": "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": "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": "Binding", + "code": 30, + "mfgCode": null, + "define": "BINDING_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "Binding", + "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": "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": "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 + } + ] + }, + { + "name": "Power Source", + "code": 47, + "mfgCode": null, + "define": "POWER_SOURCE_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "Status", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "PowerSourceStatusEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Order", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Description", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "WiredCurrentType", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "WiredCurrentTypeEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EndpointList", + "code": 31, + "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": "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": "1", + "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": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Fixed Label", + "code": 64, + "mfgCode": null, + "define": "FIXED_LABEL_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "LabelList", + "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": "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": "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 + } + ] + }, + { + "name": "User Label", + "code": 65, + "mfgCode": null, + "define": "USER_LABEL_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "LabelList", + "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": "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": "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 + } + ] + }, + { + "name": "Mode Select", + "code": 80, + "mfgCode": null, + "define": "MODE_SELECT_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ChangeToMode", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "Description", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "StandardNamespace", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "enum16", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportedModes", + "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": "CurrentMode", + "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": "StartUpMode", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OnMode", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "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": "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 + } + ] + }, + { + "name": "Laundry Washer Mode", + "code": 81, + "mfgCode": null, + "define": "LAUNDRY_WASHER_MODE_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ChangeToMode", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ChangeToModeResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "SupportedModes", + "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": "CurrentMode", + "code": 1, + "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": "StartUpMode", + "code": 2, + "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": "OnMode", + "code": 3, + "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": "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": "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": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Laundry Washer Controls", + "code": 83, + "mfgCode": null, + "define": "LAUNDRY_WASHER_CONTROLS_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "SpinSpeeds", + "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": "SpinSpeedCurrent", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "NumberOfRinses", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "NumberOfRinsesEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportedRinses", + "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": "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": "3", + "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 + } + ] + }, + { + "name": "Temperature Control", + "code": 86, + "mfgCode": null, + "define": "TEMPERATURE_CONTROL_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "SetTemperature", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "SelectedTemperatureLevel", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportedTemperatureLevels", + "code": 5, + "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": "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": "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": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Operational State", + "code": 96, + "mfgCode": null, + "define": "OPERATIONAL_STATE_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "Pause", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Stop", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Start", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Resume", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "OperationalCommandResponse", + "code": 4, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "PhaseList", + "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": "CurrentPhase", + "code": 1, + "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": "CountdownTime", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "elapsed_s", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OperationalStateList", + "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": "OperationalState", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "OperationalStateEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OperationalError", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "ErrorStateStruct", + "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": "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": "OperationalError", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "OperationCompletion", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + } + ] + } + ], + "endpoints": [ + { + "endpointTypeName": "MA-rootdevice", + "endpointTypeIndex": 0, + "profileId": 259, + "endpointId": 0, + "networkId": 0 + }, + { + "endpointTypeName": "Anonymous Endpoint Type", + "endpointTypeIndex": 1, + "profileId": 259, + "endpointId": 1, + "networkId": 0 + } + ] +} \ No newline at end of file diff --git a/examples/lighting-app/nxp/k32w/k32w0/.gn b/examples/lighting-app/nxp/k32w/k32w0/.gn index 3d48789e30ab3d..363727423ce903 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/.gn +++ b/examples/lighting-app/nxp/k32w/k32w0/.gn @@ -25,4 +25,7 @@ default_args = { target_os = "freertos" import("//args.gni") + + # Import default platform configs + import("${chip_root}/src/platform/nxp/k32w/k32w0/args.gni") } diff --git a/examples/lighting-app/nxp/k32w/k32w0/BUILD.gn b/examples/lighting-app/nxp/k32w/k32w0/BUILD.gn index 93bf1dc363f9dd..43a9860b5da48a 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/BUILD.gn +++ b/examples/lighting-app/nxp/k32w/k32w0/BUILD.gn @@ -13,11 +13,13 @@ # limitations under the License. import("//build_overrides/chip.gni") -import("//build_overrides/k32w0_sdk.gni") +import("//build_overrides/nxp_sdk.gni") import("//build_overrides/openthread.gni") -import("${k32w0_sdk_build_root}/k32w0_executable.gni") -import("${k32w0_sdk_build_root}/k32w0_sdk.gni") +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") +import("${nxp_sdk_build_root}/${nxp_sdk_name}/nxp_executable.gni") import("${chip_root}/src/crypto/crypto.gni") import("${chip_root}/src/lib/core/core.gni") @@ -26,6 +28,9 @@ import("${chip_root}/src/platform/device.gni") declare_args() { chip_software_version = 0 chip_simple_hash_verification = 0 + + # Setup discriminator as argument + setup_discriminator = 3840 } if (chip_pw_tokenizer_logging) { @@ -70,6 +75,10 @@ k32w0_sdk("sdk") { "CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION=${chip_software_version}", ] } + + defines += [ + "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setup_discriminator}", + ] } k32w0_executable("light_app") { diff --git a/examples/lighting-app/nxp/k32w/k32w0/README.md b/examples/lighting-app/nxp/k32w/k32w0/README.md index 3194d71b39b889..af43002f21c65a 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/README.md +++ b/examples/lighting-app/nxp/k32w/k32w0/README.md @@ -231,7 +231,7 @@ Start building the application: ```bash user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/lighting-app/nxp/k32w/k32w0 -user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w/k32w0$ gn gen out/debug --args="chip_with_OM15082=1 chip_with_ot_cli=0 is_debug=false chip_crypto=\"platform\" chip_with_se05x=0 chip_pw_tokenizer_logging=true" +user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w/k32w0$ gn gen out/debug user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w/k32w0$ ninja -C out/debug ``` @@ -257,6 +257,16 @@ In case the board doesn't have 32KHz crystal fitted, one can use the 32KHz free running oscillator as a clock source. In this case one must set the use_fro_32k argument to 1. +K32W0x1 supports antenna diversity feature, which is a technique that maximizes +the performance of an antenna system, allowing the radio signal to be switched +between two antennas that have very low correlation between their received +signals. Typically, this is achieved by spacing two antennas around 0.25 +wavelengths apart or by using 2 orthogonal types of polarization. This is +controlled by software. K32W0x1 provides an output (`ADO`) on one of `DIO7`, +`DIO9` or `DIO19` and optionally its complement (`ADE`) on `DIO6` that can be +used to control an antenna switch. In order to use this feature, user must set +`use_antenna_diversity` to 1. + In case signing errors are encountered when running the "sign_images.sh" script (run automatically) install the recommanded packages (python version > 3, pip3, pycrypto, pycryptodome): @@ -624,14 +634,14 @@ The concept for OTA is the next one: informed of the node id of the OTA Provider Application. _Computer #1_ can be any system running an Ubuntu distribution. We recommand -using TE 7.5 instructions from -[here](https://groups.csa-iot.org/wg/matter-csg/document/24839), where RPi 4 are -proposed. Also, TE 7.5 instructions document point to the OS/Docker images that -should be used on the RPis. For compatibility reasons, we recommand compiling -chip-tool and OTA Provider applications with the same commit id that was used -for compiling the Lighting Application. Also, please note that there is a single -controller (chip-tool) running on Computer #1 which is used for commissioning -both the device and the OTA Provider Application. If needed, +using CSA official instructions from +[here](https://groups.csa-iot.org/wg/matter-csg/document/28566), where RPi 4 are +proposed. Also, CSA official instructions document point to the OS/Docker images +that should be used on the RPis. For compatibility reasons, we recommand +compiling chip-tool and OTA Provider applications with the same commit id that +was used for compiling the Lighting Application. Also, please note that there is +a single controller (chip-tool) running on Computer #1 which is used for +commissioning both the device and the OTA Provider Application. If needed, [these instructions](https://itsfoss.com/connect-wifi-terminal-ubuntu/) could be used for connecting the RPis to WiFi. diff --git a/examples/lighting-app/nxp/k32w/k32w0/args.gni b/examples/lighting-app/nxp/k32w/k32w0/args.gni index 4f4bba4b47cf07..f5fd7a83cd9005 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/args.gni +++ b/examples/lighting-app/nxp/k32w/k32w0/args.gni @@ -13,8 +13,6 @@ # limitations under the License. import("//build_overrides/chip.gni") -import("${chip_root}/config/standalone/args.gni") -import("${chip_root}/examples/platform/nxp/k32w/k32w0/args.gni") # SDK target. This is overridden to add our SDK app_config.h & defines. k32w0_sdk_target = get_label_info(":sdk", "label_no_toolchain") @@ -22,3 +20,11 @@ k32w0_sdk_target = get_label_info(":sdk", "label_no_toolchain") chip_enable_ota_requestor = true chip_stack_lock_tracking = "fatal" chip_enable_ble = true + +is_debug = false + +chip_crypto = "platform" +chip_crypto_flavor = "NXP-Ultrafast-P256" +chip_with_ot_cli = 0 +chip_with_OM15082 = 1 +chip_pw_tokenizer_logging = true diff --git a/examples/lighting-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h b/examples/lighting-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h index 946d457622e467..e32575e55ff5c4 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h +++ b/examples/lighting-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h @@ -106,8 +106,13 @@ #define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8005 // Use a default setup PIN code if one hasn't been provisioned in flash. +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE #define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#endif + +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR #define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 +#endif /** * CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER diff --git a/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp b/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp index 39c9584c883480..7b9ecccdec3068 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp +++ b/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp @@ -52,6 +52,9 @@ #include "LEDWidget.h" #include "app_config.h" +#if CHIP_CRYPTO_HSM +#include +#endif #ifdef ENABLE_HSM_DEVICE_ATTESTATION #include "DeviceAttestationSe05xCredsExample.h" #endif @@ -643,7 +646,6 @@ void AppTask::BleStartAdvertising(intptr_t arg) else { ConnectivityMgr().SetBLEAdvertisingEnabled(true); - if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() == CHIP_NO_ERROR) { K32W_LOG("Started BLE Advertising!"); diff --git a/examples/lighting-app/nxp/k32w/k32w0/main/include/AppTask.h b/examples/lighting-app/nxp/k32w/k32w0/main/include/AppTask.h index 9590734521d5e1..0c455f431a8cf4 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/main/include/AppTask.h +++ b/examples/lighting-app/nxp/k32w/k32w0/main/include/AppTask.h @@ -112,7 +112,6 @@ class AppTask kFunctionTurnOnTurnOff, kFunction_Identify, kFunction_TriggerEffect, - kFunction_Invalid } Function; diff --git a/examples/lighting-app/nxp/k32w/k32w1/BUILD.gn b/examples/lighting-app/nxp/k32w/k32w1/BUILD.gn index 2f327213533e94..7785720c28c3ec 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/BUILD.gn +++ b/examples/lighting-app/nxp/k32w/k32w1/BUILD.gn @@ -36,6 +36,9 @@ if (chip_enable_pw_rpc) { declare_args() { chip_software_version = 0 + + # Setup discriminator as argument + setup_discriminator = 3840 } assert(current_os == "freertos") @@ -85,6 +88,10 @@ k32w1_sdk("sdk") { "BOARD_APP_UART_CLK_FREQ=96000000", ] } + + defines += [ + "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setup_discriminator}", + ] } k32w1_executable("light_app") { @@ -92,6 +99,13 @@ k32w1_executable("light_app") { sources = [] deps = [] + defines = [] + + if (chip_config_dimmable_led) { + defines += [ "CHIP_CONFIG_ENABLE_DIMMABLE_LED = 1" ] + } else { + defines += [ "CHIP_CONFIG_ENABLE_DIMMABLE_LED = 0" ] + } if (chip_enable_pw_rpc) { forward_variables_from(pw_rpc_server, "*") @@ -111,12 +125,19 @@ k32w1_executable("light_app") { "main/main.cpp", ] - public = [ "${chip_root}/src/platform/nxp/k32w/k32w1/DefaultTestEventTriggerDelegate.h" ] + if (chip_config_dimmable_led) { + sources += [ + "${k32w1_platform_dir}/util/LED_Dimmer.cpp", + "${k32w1_platform_dir}/util/include/LED_Dimmer.h", + ] + deps += [ "${chip_root}/examples/lighting-app/lighting-common/" ] + } else { + deps += [ "${chip_root}/examples/lighting-app/nxp/zap/" ] + } deps += [ ":sdk", "${chip_root}/examples/common/QRCode", - "${chip_root}/examples/lighting-app/nxp/zap/", "${chip_root}/examples/providers:device_info_provider", "${chip_root}/src/lib", "${chip_root}/src/platform:syscalls_stub", @@ -126,13 +147,13 @@ k32w1_executable("light_app") { if (chip_openthread_ftd) { deps += [ - "${chip_root}/third_party/openthread/repo:libopenthread-cli-ftd", - "${chip_root}/third_party/openthread/repo:libopenthread-ftd", + "${openthread_root}:libopenthread-cli-ftd", + "${openthread_root}:libopenthread-ftd", ] } else { deps += [ - "${chip_root}/third_party/openthread/repo:libopenthread-cli-mtd", - "${chip_root}/third_party/openthread/repo:libopenthread-mtd", + "${openthread_root}:libopenthread-cli-mtd", + "${openthread_root}:libopenthread-mtd", ] } diff --git a/examples/lighting-app/nxp/k32w/k32w1/README.md b/examples/lighting-app/nxp/k32w/k32w1/README.md index 253c21e04eafbb..c44c73a1ecc946 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/README.md +++ b/examples/lighting-app/nxp/k32w/k32w1/README.md @@ -22,18 +22,17 @@ into an existing Matter network and can be controlled by this network. - [Device UI](#device-ui) - [Building](#building) - [SMU2](#smu2-memory) + - [LED PWM](#led-pwm) - [Manufacturing data](#manufacturing-data) - [Flashing](#flashing) - [Flashing the NBU image](#flashing-the-nbu-image) - [Flashing the host image](#flashing-the-host-image) - [Debugging](#debugging) - [OTA](#ota) - - [Convert srec into sb3 file](#convert-srec-into-sb3-file) - [Convert sb3 into ota file](#convert-sb3-into-ota-file) - [Running OTA](#running-ota) - [Known issues](#known-issues) - - [Running RPC console](#running-rpc-console) @@ -136,8 +135,9 @@ In order to build the Matter example, we recommend using a Linux distribution ``` user@ubuntu:~/Desktop/git/connectedhomeip$ export NXP_K32W1_SDK_ROOT=/home/user/Desktop/SDK_K32W1/ user@ubuntu:~/Desktop/git/connectedhomeip$ source ./scripts/activate.sh +user@ubuntu:~/Desktop/git/connectedhomeip$ scripts/checkout_submodules.py --shallow --platform nxp --recursive user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/lighting-app/nxp/k32w/k32w1 -user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w/k32w1$ gn gen out/debug --args="chip_with_ot_cli=0 is_debug=false chip_openthread_ftd=true chip_crypto=\"platform\"" +user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w/k32w1$ gn gen out/debug user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w/k32w1$ ninja -C out/debug ``` @@ -154,10 +154,10 @@ memory. When compiling with OpenThread FTD support (`chip_openthread_ftd=true`) and with `use_smu2_static=true`, the following components are placed in `SMU2` memory: -- `gImageProcessor` from `OTAImageProcessorImpl.cpp`. -- `gApplicationProcessor` from `OTAHooks.cpp`. -- `Server::sServer` from `Server.cpp`. -- `ThreadStackManagerImpl::sInstance` from `ThreadStackManagerImpl.cpp`. +- `gImageProcessor` from OTAImageProcessorImpl.cpp. +- `gApplicationProcessor` from OTAHooks.cpp. +- `Server::sServer` from Server.cpp. +- `ThreadStackManagerImpl::sInstance` from ThreadStackManagerImpl.cpp. These instances and global variables are placed in `SMU2` memory through name matching in the application linker script. They should not be changed or, if @@ -171,6 +171,17 @@ 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`. +### LED PWM + +In the default configuration, the onboard RGB LED pins are configured as GPIO +pins. In order to enable the dimming feature, the pins need to be configured in +PWM mode and synced with channels of the `TPM` (Timer PWM Module). To enable +this feature, compile the application with: `chip_config_dimmable_led=true` + +If the feature is enabled, the LED brightness can be controlled using **Level +control** cluster +[commands](../../../../../docs/guides/chip_tool_guide.md#step-7-control-application-data-model-clusters). + ## Manufacturing data Use `chip_with_factory_data=1` in the gn build command to enable factory data. @@ -195,7 +206,7 @@ path - [K32W148 board quick start guide](https://www.nxp.com/document/guide/getting-started-with-the-k32w148-development-platform:GS-K32W148EVK) can be used for updating the `NBU/radio` core: -- Section 2.4 – Get Software – install `SPSDK` (Secure Provisioning Command +- Section 2.5 – Get Software – install `SPSDK` (Secure Provisioning Command Line Tool) - Section 3.3 – Updating `NBU` for Wireless examples - use the corresponding .sb3 file found in the SDK package at path @@ -298,7 +309,7 @@ In `OTAP` application the image only for the CM33 core - keep other settings at default values -### Convert sb3 into ota file +### Convert `sb3` into `ota` file In order to build an OTA image, use NXP wrapper over the standard tool `src/app/ota_image_tool.py`: diff --git a/examples/lighting-app/nxp/k32w/k32w1/args.gni b/examples/lighting-app/nxp/k32w/k32w1/args.gni index a06e5828acdc45..d0c28a1e048545 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/args.gni +++ b/examples/lighting-app/nxp/k32w/k32w1/args.gni @@ -17,6 +17,13 @@ import("//build_overrides/chip.gni") # SDK target. This is overridden to add our SDK app_config.h & defines. k32w1_sdk_target = get_label_info(":sdk", "label_no_toolchain") +chip_config_dimmable_led = false chip_enable_ota_requestor = true chip_stack_lock_tracking = "fatal" chip_enable_ble = true + +is_debug = false + +chip_crypto = "platform" +chip_openthread_ftd = true +chip_with_ot_cli = 0 diff --git a/examples/lighting-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h b/examples/lighting-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h index 05f8042ed28138..ad5d876dc650ab 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h +++ b/examples/lighting-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h @@ -101,8 +101,13 @@ #define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8005 // Use a default setup PIN code if one hasn't been provisioned in flash. +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE #define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#endif + +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR #define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 +#endif // Use a default pairing code if one hasn't been provisioned in flash. #define CHIP_DEVICE_CONFIG_USE_TEST_PAIRING_CODE "CHIPUS" diff --git a/examples/lighting-app/nxp/k32w/k32w1/main/AppTask.cpp b/examples/lighting-app/nxp/k32w/k32w1/main/AppTask.cpp index 2eb2f8e095b8b1..96f5a5b96b3248 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/main/AppTask.cpp +++ b/examples/lighting-app/nxp/k32w/k32w1/main/AppTask.cpp @@ -57,6 +57,10 @@ #include "fsl_component_button.h" #include "fwk_platform.h" +#if CHIP_CONFIG_ENABLE_DIMMABLE_LED +#include "LED_Dimmer.h" +#endif + #define FACTORY_RESET_TRIGGER_TIMEOUT 6000 #define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 3000 #define APP_TASK_PRIORITY 2 @@ -165,7 +169,13 @@ CHIP_ERROR AppTask::Init() #ifndef CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR sStatusLED.Init(SYSTEM_STATE_LED, false); #endif + +#if CHIP_CONFIG_ENABLE_DIMMABLE_LED + init_dimmable(); +#else sLightLED.Init(LIGHT_STATE_LED, false); +#endif + UpdateDeviceState(); /* intialize the Keyboard and button press callback */ @@ -487,7 +497,12 @@ void AppTask::ResetActionEventHandler(AppEvent * aEvent) #ifndef CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR sStatusLED.Set(false); #endif + +#if CHIP_CONFIG_ENABLE_DIMMABLE_LED + sLightLED.SetLevel(0); +#else sLightLED.Set(false); +#endif #ifndef CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR sStatusLED.Blink(500); @@ -537,7 +552,7 @@ void AppTask::LightActionEventHandler(AppEvent * aEvent) if (err == CHIP_NO_ERROR) { - initiated = LightingMgr().InitiateAction(actor, action); + initiated = LightingMgr().InitiateAction(actor, action, LightingMgr().IsTurnedOff() ? 0 : 1); if (!initiated) { @@ -644,6 +659,10 @@ void AppTask::ActionInitiated(LightingManager::Action_t aAction, int32_t aActor) { K32W_LOG("Turn off Action has been initiated") } + else if (aAction == LightingManager::DIM_ACTION) + { + K32W_LOG("Dim Action has been initiated"); + } if (aActor == AppEvent::kEventType_Button) { @@ -653,20 +672,33 @@ void AppTask::ActionInitiated(LightingManager::Action_t aAction, int32_t aActor) sAppTask.mFunction = kFunctionTurnOnTurnOff; } -void AppTask::ActionCompleted(LightingManager::Action_t aAction) +void AppTask::ActionCompleted(LightingManager::Action_t aAction, uint8_t level) { // Turn on the light LED if in a TURNON state OR // Turn off the light LED if in a TURNOFF state. if (aAction == LightingManager::TURNON_ACTION) { K32W_LOG("Turn on action has been completed") +#if CHIP_CONFIG_ENABLE_DIMMABLE_LED +#else sLightLED.Set(true); +#endif } else if (aAction == LightingManager::TURNOFF_ACTION) { K32W_LOG("Turn off action has been completed") +#if CHIP_CONFIG_ENABLE_DIMMABLE_LED +#else sLightLED.Set(false); +#endif + } + else if (aAction == LightingManager::DIM_ACTION) + { + K32W_LOG("Move to level %d completed", level); } +#if CHIP_CONFIG_ENABLE_DIMMABLE_LED + sLightLED.SetLevel(LightingMgr().IsTurnedOff() ? 1 : LightingMgr().GetDimLevel()); +#endif if (sAppTask.mSyncClusterToButtonAction) { @@ -679,6 +711,9 @@ void AppTask::ActionCompleted(LightingManager::Action_t aAction) void AppTask::RestoreLightingState(void) { +#if CHIP_CONFIG_ENABLE_DIMMABLE_LED + LightingMgr().SetState(!LightingMgr().IsTurnedOff()); +#else /* restore initial state for the LED indicating Lighting state */ if (LightingMgr().IsTurnedOff()) { @@ -688,6 +723,7 @@ void AppTask::RestoreLightingState(void) { sLightLED.Set(true); } +#endif } void AppTask::OnIdentifyStart(Identify * identify) @@ -706,7 +742,11 @@ void AppTask::OnIdentifyStart(Identify * identify) ChipLogProgress(Zcl, "Identify process has started. Status LED should blink with a period of 0.5 seconds."); sAppTask.mFunction = kFunction_Identify; +#if CHIP_CONFIG_ENABLE_DIMMABLE_LED + sLightLED.SetLevel(0); +#else sLightLED.Set(false); +#endif sLightLED.Blink(250); } @@ -790,7 +830,11 @@ void AppTask::OnTriggerEffect(Identify * identify) if (timerDelay) { +#if CHIP_CONFIG_ENABLE_DIMMABLE_LED + sLightLED.SetLevel(0); +#else sLightLED.Set(false); +#endif sLightLED.Blink(500); chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds16(timerDelay), OnTriggerEffectComplete, identify); @@ -873,7 +917,10 @@ void AppTask::UpdateDeviceStateInternal(intptr_t arg) (void) app::Clusters::OnOff::Attributes::OnOff::Get(1, &onoffAttrValue); /* set the device state */ +#if CHIP_CONFIG_ENABLE_DIMMABLE_LED +#else sLightLED.Set(onoffAttrValue); +#endif LightingMgr().SetState(onoffAttrValue); } diff --git a/examples/lighting-app/nxp/k32w/k32w1/main/LightingManager.cpp b/examples/lighting-app/nxp/k32w/k32w1/main/LightingManager.cpp index 7a5cefc9b668fc..2627138043bbe4 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/main/LightingManager.cpp +++ b/examples/lighting-app/nxp/k32w/k32w1/main/LightingManager.cpp @@ -19,6 +19,10 @@ #include "LightingManager.h" +#if CHIP_CONFIG_ENABLE_DIMMABLE_LED +#include "LED_Dimmer.h" +#endif + #include "AppTask.h" #include "FreeRTOS.h" @@ -30,6 +34,8 @@ int LightingManager::Init() { mState = kState_On; + mLevel = kLevel_Max; + return 0; } @@ -44,24 +50,48 @@ void LightingManager::SetState(bool state) mState = state ? kState_On : kState_Off; } +void LightingManager::SetDimLevel(uint8_t level) +{ + mLevel = level; +} + bool LightingManager::IsTurnedOff() { return (mState == kState_Off) ? true : false; } -bool LightingManager::InitiateAction(int32_t aActor, Action_t aAction) +uint8_t LightingManager::GetDimLevel() +{ + return mLevel; +} + +bool LightingManager::InitiateAction(int32_t aActor, Action_t aAction, uint8_t kValue) { bool action_initiated = false; + State_t current_state; if (mState == kState_On && aAction == TURNOFF_ACTION) { action_initiated = true; - mState = kState_Off; + current_state = kState_Off; } else if (mState == kState_Off && aAction == TURNON_ACTION) { action_initiated = true; - mState = kState_On; + current_state = kState_On; + } + + else if (aAction == DIM_ACTION && kValue != mLevel) + { + action_initiated = true; + if (kValue == 1) + { + current_state = kState_Off; + } + else + { + current_state = kState_On; + } } if (action_initiated) @@ -70,9 +100,20 @@ bool LightingManager::InitiateAction(int32_t aActor, Action_t aAction) { mActionInitiated_CB(aAction, aActor); } + + if (aAction == TURNON_ACTION || aAction == TURNOFF_ACTION) + { + SetState(current_state == kState_On); + } + else if (aAction == DIM_ACTION) + { + mState = current_state; + SetDimLevel(kValue); + } + if (mActionCompleted_CB) { - mActionCompleted_CB(aAction); + mActionCompleted_CB(aAction, kValue); } } diff --git a/examples/lighting-app/nxp/k32w/k32w1/main/ZclCallbacks.cpp b/examples/lighting-app/nxp/k32w/k32w1/main/ZclCallbacks.cpp index 5a4eee6e2c09e4..a9c6aee8798c49 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/main/ZclCallbacks.cpp +++ b/examples/lighting-app/nxp/k32w/k32w1/main/ZclCallbacks.cpp @@ -40,14 +40,21 @@ void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & return; } - LightingMgr().InitiateAction(0, *value ? LightingManager::TURNON_ACTION : LightingManager::TURNOFF_ACTION); + LightingMgr().InitiateAction(0, *value ? LightingManager::TURNON_ACTION : LightingManager::TURNOFF_ACTION, *value); } else if (path.mClusterId == LevelControl::Id) { - ChipLogProgress(Zcl, "Level Control attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u", - ChipLogValueMEI(path.mAttributeId), type, *value, size); + if (path.mAttributeId != LevelControl::Attributes::CurrentLevel::Id) + { + ChipLogProgress(Zcl, "Unknown attribute ID: " ChipLogFormatMEI, ChipLogValueMEI(path.mAttributeId)); + return; + } - // WIP Apply attribute change to Light + if (*value > 1 && *value < 254) + { + ChipLogProgress(Zcl, "Setting value: %d", *value); + LightingMgr().InitiateAction(0, LightingManager::DIM_ACTION, *value); + } } else if (path.mClusterId == ColorControl::Id) { 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 b5201da2477862..096690c680b1d2 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/main/include/AppTask.h +++ b/examples/lighting-app/nxp/k32w/k32w1/main/include/AppTask.h @@ -71,7 +71,7 @@ class AppTask CHIP_ERROR Init(); static void ActionInitiated(LightingManager::Action_t aAction, int32_t aActor); - static void ActionCompleted(LightingManager::Action_t aAction); + static void ActionCompleted(LightingManager::Action_t aAction, uint8_t level); void CancelTimer(void); diff --git a/examples/lighting-app/nxp/k32w/k32w1/main/include/LightingManager.h b/examples/lighting-app/nxp/k32w/k32w1/main/include/LightingManager.h index 327bf3bdf02763..f96d6c7ecae40c 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/main/include/LightingManager.h +++ b/examples/lighting-app/nxp/k32w/k32w1/main/include/LightingManager.h @@ -33,7 +33,7 @@ class LightingManager { TURNON_ACTION = 0, TURNOFF_ACTION, - + DIM_ACTION, INVALID_ACTION } Action; @@ -43,18 +43,24 @@ class LightingManager kState_Off, } State; + static const uint8_t kLevel_Max = 254; + static const uint8_t kLevel_Min = 0; + int Init(); bool IsTurnedOff(); - bool InitiateAction(int32_t aActor, Action_t aAction); + uint8_t GetDimLevel(); + bool InitiateAction(int32_t aActor, Action_t aAction, uint8_t kValue); typedef void (*Callback_fn_initiated)(Action_t, int32_t aActor); - typedef void (*Callback_fn_completed)(Action_t); + typedef void (*Callback_fn_completed)(Action_t, uint8_t level); void SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB); void SetState(bool state); + void SetDimLevel(uint8_t level); private: friend LightingManager & LightingMgr(void); State_t mState; + uint8_t mLevel; Callback_fn_initiated mActionInitiated_CB; Callback_fn_completed mActionCompleted_CB; diff --git a/examples/lock-app/nxp/k32w/k32w0/BUILD.gn b/examples/lock-app/nxp/k32w/k32w0/BUILD.gn deleted file mode 100644 index c755514d66a175..00000000000000 --- a/examples/lock-app/nxp/k32w/k32w0/BUILD.gn +++ /dev/null @@ -1,163 +0,0 @@ -# Copyright (c) 2020 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import("//build_overrides/chip.gni") -import("//build_overrides/k32w0_sdk.gni") -import("//build_overrides/openthread.gni") -import("${chip_root}/src/platform/device.gni") -import("${chip_root}/third_party/simw-top-mini/simw_config.gni") - -import("${k32w0_sdk_build_root}/k32w0_executable.gni") -import("${k32w0_sdk_build_root}/k32w0_sdk.gni") - -import("${chip_root}/src/crypto/crypto.gni") -import("${chip_root}/src/lib/core/core.gni") - -declare_args() { - chip_software_version = 0 -} - -if (chip_pw_tokenizer_logging) { - import("//build_overrides/pigweed.gni") - import("$dir_pw_tokenizer/database.gni") -} - -assert(current_os == "freertos") - -k32w0_platform_dir = "${chip_root}/examples/platform/nxp/k32w/k32w0" - -k32w0_sdk("sdk") { - sources = [ - "${k32w0_platform_dir}/app/project_include/OpenThreadConfig.h", - "include/CHIPProjectConfig.h", - "include/FreeRTOSConfig.h", - "main/include/app_config.h", - ] - - public_deps = - [ "${chip_root}/third_party/openthread/platforms:libopenthread-platform" ] - - include_dirs = [ - "main/include", - "main", - "include", - "${k32w0_platform_dir}/app/support", - "${k32w0_platform_dir}/util/include", - "${k32w0_platform_dir}/common", - ] - - defines = [] - if (is_debug) { - defines += [ "BUILD_RELEASE=0" ] - } else { - defines += [ "BUILD_RELEASE=1" ] - } - - if (chip_software_version != 0) { - defines += [ - "CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION=${chip_software_version}", - ] - } -} - -k32w0_executable("lock_app") { - output_name = "chip-k32w0x-lock-example" - - sources = [ - "${k32w0_platform_dir}/util/LEDWidget.cpp", - "${k32w0_platform_dir}/util/include/LEDWidget.h", - "main/AppTask.cpp", - "main/BoltLockManager.cpp", - "main/ZclCallbacks.cpp", - "main/include/AppEvent.h", - "main/include/AppTask.h", - "main/include/BoltLockManager.h", - "main/main.cpp", - ] - - if (chip_with_factory_data == 1 && use_custom_factory_provider == 1) { - sources += [ - "${k32w0_platform_dir}/common/CustomFactoryDataProvider.cpp", - "${k32w0_platform_dir}/common/CustomFactoryDataProvider.h", - ] - - defines = [ "CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER=1" ] - } - - deps = [ - ":sdk", - "${chip_root}/examples/common/QRCode", - "${chip_root}/examples/lock-app/nxp/zap/", - "${chip_root}/examples/providers:device_info_provider", - "${chip_root}/src/crypto", - "${chip_root}/src/lib", - "${chip_root}/src/platform:syscalls_stub", - "${chip_root}/third_party/mbedtls:mbedtls", - "${k32w0_platform_dir}/app/support:freertos_mbedtls_utils", - ] - - if (chip_openthread_ftd) { - deps += [ - "${chip_root}/third_party/openthread/repo:libopenthread-cli-ftd", - "${chip_root}/third_party/openthread/repo:libopenthread-ftd", - ] - } else { - deps += [ - "${chip_root}/third_party/openthread/repo:libopenthread-cli-mtd", - "${chip_root}/third_party/openthread/repo:libopenthread-mtd", - ] - } - - cflags = [ "-Wconversion" ] - - output_dir = root_out_dir - - ldscript = "${k32w0_platform_dir}/app/ldscripts/chip-k32w0x-linker.ld" - - inputs = [ ldscript ] - - ldflags = [ - "-T" + rebase_path(ldscript, root_build_dir), - "-Wl,-print-memory-usage", - ] -} - -if (chip_pw_tokenizer_logging) { - pw_tokenizer_database("lock_app.database") { - database = "$root_build_dir/chip-k32w0x-lock-example-database.bin" - create = "binary" - deps = [ ":lock_app" ] - optional_paths = [ "$root_build_dir/chip-k32w0x-lock-example" ] - } -} -group("k32w0") { - deps = [ - ":binsign", - ":lock_app", - ] - if (chip_pw_tokenizer_logging) { - deps += [ ":lock_app.database" ] - } -} - -action("binsign") { - deps = [ ":lock_app" ] - script = "${k32w0_platform_dir}/scripts/sign-outdir.py" - output_name = "bignsign.log" - outputs = [ "${root_build_dir}/${output_name}" ] -} - -group("default") { - deps = [ ":k32w0" ] -} diff --git a/examples/lock-app/nxp/k32w/k32w0/README.md b/examples/lock-app/nxp/k32w/k32w0/README.md deleted file mode 100644 index 49920906819b0f..00000000000000 --- a/examples/lock-app/nxp/k32w/k32w0/README.md +++ /dev/null @@ -1,452 +0,0 @@ -# CHIP K32W061 Lock Example Application - -The Project CHIP K32W061 Lock Example demonstrates how to remotely control a -door lock device with one basic bolt. It uses buttons to test changing the lock -and device states and LEDs to show the state of these changes. You can use this -example as a reference for creating your own application. - -The example is based on -[Project CHIP](https://github.com/project-chip/connectedhomeip) and the NXP K32W -SDK, and supports remote access and control of a simulated door lock over a -low-power, 802.15.4 Thread network. - -The example behaves as a Project CHIP accessory, that is a device that can be -paired into an existing Project CHIP network and can be controlled by this -network. - -
- -- [CHIP K32W0 Lock Example Application](#chip-k32w061-lock-example-application) -- [Introduction](#introduction) - - [Bluetooth LE Advertising](#bluetooth-le-advertising) - - [Bluetooth LE Rendezvous](#bluetooth-le-rendezvous) -- [Device UI](#device-ui) -- [Building](#building) - - [Overwrite board config files](#overwrite-board-config-files) - - [Known issues building](#known-issues-building) -- [Manufacturing data](#manufacturing-data) -- [Flashing and debugging](#flashing-and-debugging) -- [Pigweed Tokenizer](#pigweed-tokenizer) - - [Detokenizer script](#detokenizer-script) - - [Notes](#notes) - - [Known issues](#known-issues-tokenizer) -- [NXP Ultrafast P256 ECC Library](#nxp-ultrafast-p256-ecc-library) - - [Building steps](#building-steps) -- [Tinycrypt ECC library](#tinycrypt-ecc-library) - - [Building steps](#building-steps-1) -- [Low power](#low-power) - - - [Known issues low power](#known-issues-low-power) - - - -## Introduction - -![K32W061 DK6](../../../../platform/nxp/k32w/k32w0/doc/images/k32w-dk6.jpg) - -The K32W061 lock example application provides a working demonstration of a -connected door lock device, built using the Project CHIP codebase and the NXP -K32W061 SDK. The example supports remote access (e.g.: using CHIP Tool from a -mobile phone) and control of a simulated door lock over a low-power, 802.15.4 -Thread network. It is capable of being paired into an existing Project CHIP -network along with other Project CHIP-enabled devices. - -The example targets the -[NXP K32W061 DK6](https://www.nxp.com/products/wireless/thread/k32w061-41-high-performance-secure-and-ultra-low-power-mcu-for-zigbeethread-and-bluetooth-le-5-0-with-built-in-nfc-option:K32W061_41) -development kit, but is readily adaptable to other K32W-based hardware. - -The CHIP device that runs the lock application is controlled by the CHIP -controller device over the Thread protocol. By default, the CHIP device has -Thread disabled, and it should be paired over Bluetooth LE with the CHIP -controller and obtain configuration from it. The actions required before -establishing full communication are described below. - -The example also comes with a test mode, which allows to start Thread with the -default settings by pressing a button. However, this mode does not guarantee -that the device will be able to communicate with the CHIP controller and other -devices. - -### SE051H Secure Element - -Deployment of this firmware configuration requires the K32W061 board setups -using the K32W061 module board, SE051 Expansion board and Generic Expansion -board as shown below: - -![SE051H + K32W061 DK6](../../../../platform/nxp/k32w/k32w0/doc/images/k32w-se.jpg) - -The SE051H Secure Element extension may be used for best in class security and -offloading some of the Project CHIP cryptographic operations. Depending on your -hardware configuration, choose one of the options below (building with or -without Secure Element). NOTE: the SE051H is a derivative of the SE051 product -family (see http://www.nxp.com/SE051) including dedicated CHIP support in -addition to the SE051 feature set. See the material provided separately by NXP -for more details on SE051H. - -### Bluetooth LE Advertising - -In this example, to commission the device onto a Project CHIP network, it must -be discoverable over Bluetooth LE. For security reasons, you must start -Bluetooth LE advertising manually after powering up the device by pressing -Button USERINTERFACE. - -### Bluetooth LE Rendezvous - -In this example, the commissioning procedure (called rendezvous) is done over -Bluetooth LE between a CHIP device and the CHIP controller, where the controller -has the commissioner role. - -To start the rendezvous, the controller must get the commissioning information -from the CHIP device. The data payload is encoded within a QR code, printed to -the UART console and shared using an NFC tag. For security reasons, you must -start NFC tag emulation manually after powering up the device by pressing -Button 4. - -### Thread Provisioning - -Last part of the rendezvous procedure, the provisioning operation involves -sending the Thread network credentials from the CHIP controller to the CHIP -device. As a result, device is able to join the Thread network and communicate -with other Thread devices in the network. - -## Device UI - -The example application provides a simple UI that depicts the state of the -device and offers basic user control. This UI is implemented via the -general-purpose LEDs and buttons built in to the OM15082 Expansion board -attached to the DK6 board. - -**LED D2** shows the overall state of the device and its connectivity. Four -states are depicted: - -- _Short Flash On (50ms on/950ms off)_ — The device is in an - unprovisioned (unpaired) state and is waiting for a commissioning - application to connect. - -* _Rapid Even Flashing (100ms on/100ms off)_ — The device is in an - unprovisioned state and a commissioning application is connected via BLE. - -- _Short Flash Off (950ms on/50ms off)_ — The device is full - provisioned, but does not yet have full network (Thread) or service - connectivity. - -* _Solid On_ — The device is fully provisioned and has full network and - service connectivity. - -**LED D3** shows the state of the simulated lock bolt. When the LED is lit the -bolt is extended (i.e. door locked); when not lit, the bolt is retracted (door -unlocked). The LED will flash whenever the simulated bolt is in motion from one -position to another. - -**Button SW2** can be used to reset the device to a default state. A short Press -Button SW2 initiates a factory reset. After an initial period of 3 seconds, LED2 -D2 and D3 will flash in unison to signal the pending reset. After 6 seconds will -cause the device to reset its persistent configuration and 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 bolt. This can -be used to mimic a user manually operating the lock. The button behaves as a -toggle, swapping the state every time it is pressed. - -**Button SW4** can be used for joining a predefined Thread network advertised by -a Border Router. Default parameters for a Thread network are hard-coded and are -being used if this button is pressed. - -The remaining two LEDs (D1/D4) and button (SW1) are unused. - -Directly on the development board, **Button USERINTERFACE** can be used for -enabling Bluetooth LE advertising for a predefined period of time. Also, pushing -this button starts the NFC emulation by writing the onboarding information in -the NTAG. - -### No expansion board - -In case the **OM15082** Expansion board is not attached to the DK6 board, the -functionality of LED D2 and LED D3 is taken over by LED DS2, respectively LED -DS3, which can be found on the DK6 board. - -Also, by long pressing the **USERINTERFACE** button, the factory reset action -will be initiated. - -## Building - -In order to build the Project CHIP example, we recommend using a Linux -distribution (the demo-application was compiled on Ubuntu 20.04). - -Activate the Matter environment: - -```bash -user@ubuntu:~/Desktop/git/connectedhomeip$ source ./scripts/activate.sh -``` - -To bring the SDK in the environment, the user can: - -- download it with west tool, in which case it will be handled automatically - by gn: - - ```bash - user@ubuntu:~/Desktop/git/connectedhomeip$ cd third_party/nxp/k32w0_sdk/repo - user@ubuntu:~/Desktop/git/connectedhomeip/third_party/nxp/k32w0_sdk/repo$ west init -l manifest --mf west.yml - user@ubuntu:~/Desktop/git/connectedhomeip/third_party/nxp/k32w0_sdk/repo$ west update - ``` - - In case there are local modification to the already installed github NXP - SDK, use the below `west forall` command instead of the `west init` command - to reset the west workspace. Warning: all local changes will be lost after - running this command. - - ```bash - user@ubuntu:~/Desktop/git/connectedhomeip$ cd third_party/nxp/k32w0_sdk/repo - user@ubuntu:~/Desktop/git/connectedhomeip/third_party/nxp/k32w0_sdk/repo$ west forall -c "git reset --hard && git clean -xdf" -a - ``` - -- set up a custom path to the SDK, in which case - `k32w0_sdk_root=\"${NXP_K32W0_SDK_ROOT}\"` must be added to the `gn gen` - command: - - ``` - user@ubuntu:~/Desktop/git/connectedhomeip$ export NXP_K32W0_SDK_ROOT=/custom/path/to/SDK - ``` - -Start building the application: - -```bash -user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/lock-app/nxp/k32w/k32w0 -user@ubuntu:~/Desktop/git/connectedhomeip/examples/lock-app/nxp/k32w/k32w0$ gn gen out/debug --args="chip_with_OM15082=1 chip_with_ot_cli=0 is_debug=false chip_crypto=\"platform\" chip_with_se05x=0 chip_pw_tokenizer_logging=true" -user@ubuntu:~/Desktop/git/connectedhomeip/examples/lock-app/nxp/k32w/k32w0$ ninja -C out/debug -``` - -To build with Secure Element, follow the same steps as above but set -`chip_with_se05x=1` in the `gn gen` command. - -- K32W041AM flavor - - Exactly the same steps as above but set argument `build_for_k32w041am=1` in - the gn command. - -Also, in case the OM15082 Expansion Board is not attached to the DK6 board, the -build argument (`chip_with_OM15082`) inside the gn build instruction should be -set to zero. The argument `chip_with_OM15082` is set to zero by default. - -In case that Openthread CLI is needed, `chip_with_ot_cli` build argument must be -set to 1. - -In case the board doesn't have 32KHz crystal fitted, one can use the 32KHz free -running oscillator as a clock source. In this case one must set the -`use_fro_32k` argument to 1. - -In case signing errors are encountered when running the "sign_images.sh" script -(run automatically) install the recommanded packages (python version > 3, pip3, -pycrypto, pycryptodome): - -``` -user@ubuntu:~$ python3 --version -Python 3.8.2 -user@ubuntu:~$ pip3 --version -pip 20.0.2 from /usr/lib/python3/dist-packages/pip (python 3.8) -user@ubuntu:~$ pip3 list | grep -i pycrypto -pycrypto 2.6.1 -pycryptodome 3.9.8 -``` - -The resulting output file can be found in out/debug/chip-k32w0x-lock-example. - -### Overwrite board config files - -The example uses template/reference board configuration files. - -To overwrite the board configuration files, set `override_is_DK6=false` in the -`k32w0_sdk` target from the app `BUILD.gn`: - -``` -k32w0_sdk("sdk") { - override_is_DK6 = false - ... -} -``` - -This variable will be used by `k32w0_sdk.gni` to overwrite `chip_with_DK6` -option, thus the reference board configuration files will no longer be used. - -## Known issues building - -- When using Secure element and cross-compiling on Linux, log messages from - the Plug&Trust middleware stack may not echo to the console. - -## Rotating device id - -This is an optional feature and can be used in multiple ways (please see section -5.4.2.4.5 from Matter specification). One use case is Amazon Frustration Free -Setup, which leverages the C3 Characteristic (Additional commissioning-related -data) to offer an easier way to set up the device. The rotating device id will -be encoded in this additional data and is programmed to rotate at pre-defined -moments. The algorithm uses a unique per-device identifier that must be -programmed during factory provisioning. - -Please use the following build args: - -- `chip_enable_rotating_device_id=1` - to enable rotating device id. -- `chip_enable_additional_data_advertising=1` - to enable C3 characteristic. - -## Manufacturing data - -See -[Guide for writing manufacturing data on NXP devices](../../../../../docs/guides/nxp_manufacturing_flow.md). - -There are factory data generated binaries available in -examples/platform/nxp/k32w/k32w0/scripts/demo_generated_factory_data folder. -These are based on the DAC, PAI and PAA certificates found in -scripts/tools/nxp/demo_generated_certs folder. The demo_factory_data_dut1.bin -uses the DAC certificate and private key found in -examples/platform/nxp/k32w/k32w0/scripts/demo_generated_factory_data/dac/dut1 -folder. The demo_factory_data_dut2.bin uses the DAC certificate and private key -found in -examples/platform/nxp/k32w/k32w0/scripts/demo_generated_factory_data/dac/dut2 -folder. These two factory data binaries can be used for testing topologies with -2 DUTS. They contain the corresponding DACs/PAIs generated using -generate_nxp_chip_factory_bin.py script. The discriminator is 14014 and the -passcode is 1000. These demo certificates are working with the CDs installed in -CHIPProjectConfig.h. - -Regarding factory data provider, there are two options: - -- use the default factory data provider: `FactoryDataProviderImpl` by setting - `chip_with_factory_data=1` in the gn build command. -- use a custom factory data provider: please see - [Guide for implementing a custom factory data provider](../../../../platform/nxp/k32w/k32w0/common/README.md). - This can be enabled when `chip_with_factory_data=1` by setting - `use_custom_factory_provider=1` in the gn build command. - -## Flashing and debugging - -Program the firmware using the official -[OpenThread Flash Instructions](https://github.com/openthread/ot-nxp/tree/main/src/k32w0/k32w061#flash-binaries). - -All you have to do is to replace the Openthread binaries from the above -documentation with _out/debug/chip-k32w0x-lock-example.bin_ if DK6Programmer is -used or with _out/debug/chip-k32w0x-lock-example_ if MCUXpresso is used. - -## Pigweed tokenizer - -The tokenizer is a pigweed module that allows hashing the strings. This greatly -reduces the flash needed for logs. The module can be enabled by building with -the gn argument _chip_pw_tokenizer_logging=true_. The detokenizer script is -needed for parsing the hashed scripts. - -### Detokenizer script - -The python3 script detokenizer.py is a script that decodes the tokenized logs -either from a file or from a serial port. It is located in the following path -`examples/platform/nxp/k32w/k32w0/scripts/detokenizer.py`. - -The script can be used in the following ways: - -``` -usage: detokenizer.py serial [-h] -i INPUT -d DATABASE [-o OUTPUT] -usage: detokenizer.py file [-h] -i INPUT -d DATABASE -o OUTPUT -``` - -The first parameter is either _serial_ or _file_ and it selects between decoding -from a file or from a serial port. - -The second parameter is _-i INPUT_ and it must se set to the path of the file or -the serial to decode from. - -The third parameter is _-d DATABASE_ and represents the path to the token -database to be used for decoding. The default path is -_out/debug/chip-k32w0x-lock-example-database.bin_ after a successful build. - -The forth parameter is _-o OUTPUT_ and it represents the path to the output file -where the decoded logs will be stored. This parameter is required for file usage -and optional for serial usage. If not provided when used with serial port, it -will show the decoded log only at the stdout and not save it to file. - -### Notes - -The token database is created automatically after building the binary if the -argument _chip_pw_tokenizer_logging=true_ was used. - -The detokenizer script must be run inside the example's folder after a -successful run of the _scripts/activate.sh_ script. The pw_tokenizer module used -by the script is loaded by the environment. An example of running the -detokenizer script to see logs of a lock app: - -``` -python3 ../../../../../examples/platform/nxp/k32w/k32w0/scripts/detokenizer.py serial -i /dev/ttyACM0 -d out/debug/chip-k32w0x-lock-example-database.bin -o device.txt -``` - -### Known issues tokenizer - -The building process will not update the token database if it already exists. In -case that new strings are added and the database already exists in the output -folder, it must be deleted so that it will be recreated at the next build. - -Not all tokens will be decoded. This is due to a gcc/pw_tokenizer issue. The -pw_tokenizer creates special elf sections using attributes where the tokens and -strings will be stored. This sections will be used by the database creation -script. For template C++ functions, gcc ignores these attributes and places all -the strings by default in the .rodata section. As a result the database creation -script won't find them in the special-created sections. - -If run, closed and rerun with the serial option on the same serial port, the -detokenization script will get stuck and not show any logs. The solution is to -unplug and plug the board and then rerun the script. - -## NXP Ultrafast P256 ECC Library - -### Building steps - -By default, the application builds with NXP Ultrafast P256 ECC Library. To build -with this library, use the following arguments: - -- Build without Secure element (_chip_with_se05x=0_) and with crypto platform - (_chip_crypto=\"platform\"_). - -To stop using Ultrafast P256 ECC Library, simply build with -_chip_crypto=\"mbedtls\"_ or with Tinycrypt. - -## Tinycrypt ECC library - -### Building steps - -In order to use the Tinycrypt ECC library, use the following build arguments: - -- Build without Secure element (_chip_with_se05x=0_), with crypto platform - (_chip_crypto=\"platform\"_) and with tinycrypt selected - (_chip_crypto_flavor=\"tinycrypt\"_). - -## Low power - -The example also offers the possibility to run in low power mode. This means -that the board will go in a deep power down mode most of the time and the power -consumption will be very low. - -In order to build with low power support, the _chip_with_low_power=1_ must be -provided to the build system. In this case, please note that the GN build -arguments _chip_with_OM15082_ and _chip_with_ot_cli_ must be set to 0 and -_chip_logging_ must be set to false to disable logging. - -In order to maintain a low power consumption, the LEDs showing the state of the -elock and the internal state are disabled. Console logs can be used instead. -Also, please note that once the board is flashed with MCUXpresso the debugger -disconnects because the board enters low power. - -Power Measurement Tool can be used inside MCUXpresso for checking the power -consumption pattern: Window -> Show View -> Other -> Power Measurement Tool. The -configuration for this tool is the next one: - -![POWER_CONF](../../../../platform/nxp/k32w/k32w0/doc/images/power_conf.JPG) - -Also, please make sure that the J14 jumper is set to the _ENABLED_ position and -no expansion board is attached to the DK6. A view from this tool is illustrated -below: - -![POWER_VIEW](../../../../platform/nxp/k32w/k32w0/doc/images/power_view.JPG) - -Please note that that the Power Measurement Tool is not very accurate and -professional tools must be used if exact power consumption needs to be known. - -## Known issues low power - -- Power Measurement Tool may not work correctly in MCUXpresso versions greater - that 11.0.1. diff --git a/examples/lock-app/nxp/k32w/k32w0/args.gni b/examples/lock-app/nxp/k32w/k32w0/args.gni deleted file mode 100644 index a733921b547e38..00000000000000 --- a/examples/lock-app/nxp/k32w/k32w0/args.gni +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (c) 2020 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import("//build_overrides/chip.gni") -import("${chip_root}/config/standalone/args.gni") -import("${chip_root}/examples/platform/nxp/k32w/k32w0/args.gni") - -# SDK target. This is overridden to add our SDK app_config.h & defines. -k32w0_sdk_target = get_label_info(":sdk", "label_no_toolchain") - -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/lock-app/nxp/k32w/k32w0/build_overrides b/examples/lock-app/nxp/k32w/k32w0/build_overrides deleted file mode 120000 index ad07557834803a..00000000000000 --- a/examples/lock-app/nxp/k32w/k32w0/build_overrides +++ /dev/null @@ -1 +0,0 @@ -../../../../build_overrides/ \ No newline at end of file diff --git a/examples/lock-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h b/examples/lock-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h deleted file mode 100644 index 43598870fb7533..00000000000000 --- a/examples/lock-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (c) 2020 Project CHIP Authors - * Copyright (c) 2020 Google LLC. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * Example project configuration file for CHIP. - * - * This is a place to put application or project-specific overrides - * to the default configuration values for general CHIP features. - * - */ - -#pragma once - -// Security and Authentication disabled for development build. -// For convenience, enable CHIP Security Test Mode and disable the requirement for -// authentication in various protocols. -// WARNING: These options make it possible to circumvent basic CHIP security functionality, -// 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 - -// Enable usage of custom factory data provider -#ifndef CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER -#define CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER 0 -#endif - -// 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 0xA220 - -// 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 = [ 0xA220 ] -//-> device_type_id = 0x0015 -//-> certificate_id = "ZIG20142ZB330003-24" -//-> security_level = 0 -//-> security_information = 0 -//-> version_number = 0x2694 -//-> certification_type = 0 -//-> dac_origin_vendor_id is not present -//-> dac_origin_product_id is not present -#define CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION \ - { \ - 0x30, 0x81, 0xe8, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x81, 0xda, 0x30, 0x81, 0xd7, \ - 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, 0x20, 0xa2, 0x18, 0x24, 0x03, 0x15, 0x2c, 0x04, 0x13, 0x5a, 0x49, \ - 0x47, 0x32, 0x30, 0x31, 0x34, 0x31, 0x5a, 0x42, 0x33, 0x33, 0x30, 0x30, 0x30, 0x31, 0x2d, 0x32, 0x34, 0x24, 0x05, \ - 0x00, 0x24, 0x06, 0x00, 0x25, 0x07, 0x76, 0x98, 0x24, 0x08, 0x00, 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, 0x20, 0x29, 0x7f, 0xf6, 0x0e, \ - 0x4c, 0x72, 0x38, 0x77, 0x19, 0xfc, 0xb9, 0x7c, 0x08, 0x71, 0x8a, 0x88, 0x61, 0xf7, 0x0a, 0xf7, 0xf0, 0x63, 0x43, \ - 0x09, 0x69, 0xb0, 0x40, 0xf2, 0xce, 0xfd, 0x69, 0x15, 0x02, 0x21, 0x00, 0xa8, 0xd1, 0x6e, 0xae, 0xd5, 0x7f, 0x28, \ - 0x34, 0x0d, 0x21, 0x65, 0xa3, 0x3f, 0xc4, 0x4c, 0x8b, 0x26, 0x26, 0x3f, 0xb2, 0xac, 0x8f, 0x22, 0xe4, 0xff, 0xbd, \ - 0x9b, 0x48, 0x2d, 0x7e, 0xc9, 0x17, \ - } - -// All remaining data will be pulled from the provisioning region of flash. -#endif - -#else - -// Use a default setup PIN code if one hasn't been provisioned in flash. -#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 -#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 - -/** - * CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER - * - * Enables the use of a hard-coded default serial number if none - * is found in CHIP NV storage. - */ -#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 - * - * 0x8006: example lock-app - */ -#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8006 - -#endif - -/** - * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION - * - * The hardware version number assigned to device or product by the device vendor. This - * number is scoped to the device product id, and typically corresponds to a revision of the - * physical device, a change to its packaging, and/or a change to its marketing presentation. - * This value is generally *not* incremented for device software versions. - */ -#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 100 - -#ifndef CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING -#define CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING "v0.1.0" -#endif - -/** - * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING - * - * A string identifying the software version running on the device. - * CHIP currently expects the software version to be in the format - * {MAJOR_VERSION}.0d{MINOR_VERSION} - */ -#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "03-2022-te8" -#endif - -#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 42020 -#endif - -#ifndef CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME -#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME "NXP Semiconductors" -#endif - -#ifndef CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME -#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME "NXP Demo App" -#endif - -/** - * CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_TIMEOUT - * - * The amount of time in miliseconds after which BLE should change his advertisements - * from fast interval to slow interval. - * - * 30000 (30 secondes). - */ -#define CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_TIMEOUT (30 * 1000) - -/** - * @def CHIP_CONFIG_MAX_FABRICS - * - * @brief - * Maximum number of fabrics the device can participate in. Each fabric can - * provision the device with its unique operational credentials and manage - * its own access control lists. - */ -#define CHIP_CONFIG_MAX_FABRICS 5 // 5 is the minimum number of supported fabrics - -#define CHIP_DEVICE_CONFIG_ENABLE_SED 1 - -/** - * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE - * - * For a development build, set the default importance of events to be logged as Debug. - * Since debug is the lowest importance level, this means all standard, critical, info and - * debug importance level vi events get logged. - */ -#if BUILD_RELEASE -#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Production -#else -#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Debug -#endif // BUILD_RELEASE - -#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 - -/** - * CHIP_DEVICE_CONFIG_BLE_SET_PHY_2M_REQ - * - * This define enables/disables the Gap_LeSetPhy request to switch to 2M. - * It is disabled here for interoperability reasons just to be extra cautious. - * Both devices may send a Link Layer control procedure in parallel resulting in a - * LPM Error Transaction Collision. - * If the peer device doesn't accept our reject command, this can result in a BLE - * connection timeout. - */ -#define CHIP_DEVICE_CONFIG_BLE_SET_PHY_2M_REQ 0 - -/** - * @def CHIP_IM_MAX_NUM_COMMAND_HANDLER - * - * @brief Defines the maximum number of CommandHandler, limits the number of active commands transactions on server. - */ -#define CHIP_IM_MAX_NUM_COMMAND_HANDLER 1 - -/** - * @def CHIP_IM_MAX_NUM_WRITE_HANDLER - * - * @brief Defines the maximum number of WriteHandler, limits the number of active write transactions on server. - */ -#define CHIP_IM_MAX_NUM_WRITE_HANDLER 2 diff --git a/examples/lock-app/nxp/k32w/k32w0/include/FreeRTOSConfig.h b/examples/lock-app/nxp/k32w/k32w0/include/FreeRTOSConfig.h deleted file mode 100644 index c0e0a81a8fbf42..00000000000000 --- a/examples/lock-app/nxp/k32w/k32w0/include/FreeRTOSConfig.h +++ /dev/null @@ -1,184 +0,0 @@ -/* - * FreeRTOS Kernel V10.2.0 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://www.FreeRTOS.org - * http://aws.amazon.com/freertos - * - * 1 tab == 4 spaces! - */ - -#pragma once - -/*----------------------------------------------------------- - * Application specific definitions. - * - * These definitions should be adjusted for your particular hardware and - * application requirements. - * - * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE - * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. - * - * See http://www.freertos.org/a00110.html. - *----------------------------------------------------------*/ - -#define configUSE_PREEMPTION 1 - -#if defined(chip_with_low_power) && (chip_with_low_power == 1) -#define configUSE_TICKLESS_IDLE 1 -#else -#define configUSE_TICKLESS_IDLE 0 -#endif - -#define configCPU_CLOCK_HZ (SystemCoreClock) -#define configTICK_RATE_HZ ((TickType_t) 100) -#define configMAX_PRIORITIES (8) - -#if defined(configUSE_TICKLESS_IDLE) && (configUSE_TICKLESS_IDLE == 1) -#define configMINIMAL_STACK_SIZE ((unsigned short) 250) -#else -#define configMINIMAL_STACK_SIZE ((unsigned short) 450) -#endif - -#define configMAX_TASK_NAME_LEN 20 -#define configUSE_16_BIT_TICKS 0 -#define configIDLE_SHOULD_YIELD 1 -#define configUSE_TASK_NOTIFICATIONS 1 -#define configUSE_MUTEXES 1 -#define configUSE_RECURSIVE_MUTEXES 1 -#define configUSE_COUNTING_SEMAPHORES 1 -#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */ -#define configQUEUE_REGISTRY_SIZE 8 -#define configUSE_QUEUE_SETS 0 -/* make sure that Thread task can interrupt lengthy Matter - * processing in case priority inversion occurs - */ -#define configUSE_TIME_SLICING 1 -#define configUSE_NEWLIB_REENTRANT 0 -#define configENABLE_BACKWARD_COMPATIBILITY 1 -#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 - -/* Tasks.c additions (e.g. Thread Aware Debug capability) */ -#define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 1 - -/* Used memory allocation (heap_x.c) */ -#define configFRTOS_MEMORY_SCHEME 4 - -/* Memory allocation related definitions. */ -#define configSUPPORT_STATIC_ALLOCATION 0 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 -#define configTOTAL_HEAP_SIZE ((size_t) (gTotalHeapSize_c)) -#define configAPPLICATION_ALLOCATED_HEAP 1 - -#define configUSE_IDLE_HOOK 1 -#define configUSE_TICK_HOOK 0 -#define configCHECK_FOR_STACK_OVERFLOW 0 -#ifndef configUSE_MALLOC_FAILED_HOOK -#define configUSE_MALLOC_FAILED_HOOK 0 -#endif -#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 - -/* Run time and task stats gathering related definitions. */ -#define configGENERATE_RUN_TIME_STATS 0 -#define configUSE_TRACE_FACILITY 1 -#define configUSE_STATS_FORMATTING_FUNCTIONS 0 - -/* Task aware debugging. */ -#define configRECORD_STACK_HIGH_ADDRESS 1 - -/* Co-routine related definitions. */ -#define configUSE_CO_ROUTINES 0 -#define configMAX_CO_ROUTINE_PRIORITIES 2 - -/* Software timer related definitions. */ -#define configUSE_TIMERS 1 -#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1) -#define configTIMER_QUEUE_LENGTH 10 -#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 4) - -/* Define to trap errors during development. */ -#if defined gLoggingActive_d && (gLoggingActive_d != 0) -#include "dbg_logging.h" -#define configASSERT(x) \ - if ((x) == 0) \ - { \ - taskDISABLE_INTERRUPTS(); \ - DbgLogDump(1); \ - } -#else -#define configASSERT(x) \ - if ((x) == 0) \ - { \ - taskDISABLE_INTERRUPTS(); \ - for (;;) \ - ; \ - } -#endif - -/* Optional functions - most linkers will remove unused functions anyway. */ -#define INCLUDE_vTaskPrioritySet 1 -#define INCLUDE_uxTaskPriorityGet 1 -#define INCLUDE_vTaskDelete 1 -#define INCLUDE_vTaskSuspend 1 -#define INCLUDE_xResumeFromISR 1 -#define INCLUDE_vTaskDelayUntil 1 -#define INCLUDE_vTaskDelay 1 -#define INCLUDE_xTaskGetSchedulerState 1 -#define INCLUDE_xTaskGetCurrentTaskHandle 1 -#define INCLUDE_uxTaskGetStackHighWaterMark 1 -#define INCLUDE_xTaskGetIdleTaskHandle 0 -#define INCLUDE_eTaskGetState 0 -#define INCLUDE_xEventGroupSetBitFromISR 1 -#define INCLUDE_xTimerPendFunctionCall 1 -#define INCLUDE_xTaskAbortDelay 0 -#define INCLUDE_xTaskGetHandle 0 -#define INCLUDE_xTaskResumeFromISR 1 -#define INCLUDE_xQueueGetMutexHolder 1 - -/* Interrupt nesting behaviour configuration. Cortex-M specific. */ -#ifdef __NVIC_PRIO_BITS -/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ -#define configPRIO_BITS __NVIC_PRIO_BITS -#else -#define configPRIO_BITS 3 -#endif - -/* The lowest interrupt priority that can be used in a call to a "set priority" -function. */ -#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x7 - -/* The highest interrupt priority that can be used by any interrupt service -routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL -INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER -PRIORITY THAN THIS! (higher priorities are lower numeric values. */ -#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 1 - -/* Interrupt priorities used by the kernel port layer itself. These are generic -to all Cortex-M ports, and do not rely on any particular library functions. */ -#define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) -/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! -See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ -#define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) - -/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS -standard names. */ -#define vPortSVCHandler SVC_Handler -#define xPortPendSVHandler PendSV_Handler -#define xPortSysTickHandler SysTick_Handler diff --git a/examples/lock-app/nxp/k32w/k32w0/main/AppTask.cpp b/examples/lock-app/nxp/k32w/k32w0/main/AppTask.cpp index 7c6cffaf968c02..5880a6e07c784b 100644 --- a/examples/lock-app/nxp/k32w/k32w0/main/AppTask.cpp +++ b/examples/lock-app/nxp/k32w/k32w0/main/AppTask.cpp @@ -33,6 +33,7 @@ #include #include +#include #include #include "Keyboard.h" @@ -41,6 +42,9 @@ #include "PWR_Interface.h" #include "app_config.h" +#if CHIP_CRYPTO_HSM +#include +#endif #ifdef ENABLE_HSM_DEVICE_ATTESTATION #include "DeviceAttestationSe05xCredsExample.h" #endif diff --git a/examples/lock-app/nxp/k32w/k32w0/main/BoltLockManager.cpp b/examples/lock-app/nxp/k32w/k32w0/main/BoltLockManager.cpp deleted file mode 100644 index 6a18ef8214e727..00000000000000 --- a/examples/lock-app/nxp/k32w/k32w0/main/BoltLockManager.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * Copyright (c) 2019 Google LLC. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "BoltLockManager.h" - -#include "AppTask.h" -#include "FreeRTOS.h" - -#include "app_config.h" - -BoltLockManager BoltLockManager::sLock; - -TimerHandle_t sLockTimer; // FreeRTOS app sw timer. - -int BoltLockManager::Init() -{ - int err = 0; - - // Create FreeRTOS sw timer for Lock timer. - - sLockTimer = xTimerCreate("LockTmr", // Just a text name, not used by the RTOS kernel - 1, // == default timer period (mS) - false, // no timer reload (==one-shot) - (void *) this, // init timer id = lock obj context - TimerEventHandler // timer callback handler - ); - - if (sLockTimer == NULL) - { - K32W_LOG("lock timer create failed"); - assert(0); - } - - mState = kState_LockingCompleted; - mAutoLockTimerArmed = false; - mAutoRelock = false; - mAutoLockDuration = 0; - - return err; -} - -void BoltLockManager::SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB) -{ - mActionInitiated_CB = aActionInitiated_CB; - mActionCompleted_CB = aActionCompleted_CB; -} - -bool BoltLockManager::IsActionInProgress() -{ - return (mState == kState_LockingInitiated || mState == kState_UnlockingInitiated) ? true : false; -} - -bool BoltLockManager::IsUnlocked() -{ - return (mState == kState_UnlockingCompleted) ? true : false; -} - -void BoltLockManager::EnableAutoRelock(bool aOn) -{ - mAutoRelock = aOn; -} - -void BoltLockManager::SetAutoLockDuration(uint32_t aDurationInSecs) -{ - mAutoLockDuration = aDurationInSecs; -} - -bool BoltLockManager::InitiateAction(int32_t aActor, Action_t aAction) -{ - bool action_initiated = false; - State_t new_state; - - // Initiate Lock/Unlock Action only when the previous one is complete. - if (mState == kState_LockingCompleted && aAction == UNLOCK_ACTION) - { - action_initiated = true; - - new_state = kState_UnlockingInitiated; - } - else if (mState == kState_UnlockingCompleted && aAction == LOCK_ACTION) - { - action_initiated = true; - - new_state = kState_LockingInitiated; - } - - if (action_initiated) - { - if (mAutoLockTimerArmed && new_state == kState_LockingInitiated) - { - // If auto lock timer has been armed and someone initiates locking, - // cancel the timer and continue as normal. - mAutoLockTimerArmed = false; - - CancelTimer(); - } - - StartTimer(ACTUATOR_MOVEMENT_PERIOS_MS); - - // Since the timer started successfully, update the state and trigger callback - mState = new_state; - - if (mActionInitiated_CB) - { - mActionInitiated_CB(aAction, aActor); - } - } - - return action_initiated; -} - -void BoltLockManager::StartTimer(uint32_t aTimeoutMs) -{ - if (xTimerIsTimerActive(sLockTimer)) - { - K32W_LOG("lock timer already started!"); - // appError(err); - CancelTimer(); - } - - // timer is not active, change its period to required value. - // This also causes the timer to start. FreeRTOS- Block for a maximum of - // 100 ticks if the change period command cannot immediately be sent to the - // timer command queue. - if (xTimerChangePeriod(sLockTimer, aTimeoutMs / portTICK_PERIOD_MS, 100) != pdPASS) - { - K32W_LOG("lock timer start() failed"); - // appError(err); - } -} - -void BoltLockManager::CancelTimer(void) -{ - if (xTimerStop(sLockTimer, 0) == pdFAIL) - { - K32W_LOG("lock timer stop() failed"); - // appError(err); - } -} - -void BoltLockManager::TimerEventHandler(TimerHandle_t xTimer) -{ - // Get lock obj context from timer id. - BoltLockManager * lock = static_cast(pvTimerGetTimerID(xTimer)); - - // The timer event handler will be called in the context of the timer task - // once sLockTimer expires. Post an event to apptask queue with the actual handler - // so that the event can be handled in the context of the apptask. - AppEvent event; - event.Type = AppEvent::kEventType_Timer; - event.TimerEvent.Context = lock; - - if (lock->mAutoLockTimerArmed) - { - event.Handler = AutoReLockTimerEventHandler; - GetAppTask().PostEvent(&event); - } - else - { - event.Handler = ActuatorMovementTimerEventHandler; - GetAppTask().PostEvent(&event); - } -} - -void BoltLockManager::AutoReLockTimerEventHandler(void * aGenericEvent) -{ - AppEvent * aEvent = (AppEvent *) aGenericEvent; - BoltLockManager * lock = static_cast(aEvent->TimerEvent.Context); - int32_t actor = 0; - - // Make sure auto lock timer is still armed. - if (!lock->mAutoLockTimerArmed) - { - return; - } - - lock->mAutoLockTimerArmed = false; - - K32W_LOG("Auto Re-Lock has been triggered!"); - - lock->InitiateAction(actor, LOCK_ACTION); -} - -void BoltLockManager::ActuatorMovementTimerEventHandler(void * aGenericEvent) -{ - AppEvent * aEvent = (AppEvent *) aGenericEvent; - Action_t actionCompleted = INVALID_ACTION; - - BoltLockManager * lock = static_cast(aEvent->TimerEvent.Context); - - if (lock->mState == kState_LockingInitiated) - { - lock->mState = kState_LockingCompleted; - actionCompleted = LOCK_ACTION; - } - else if (lock->mState == kState_UnlockingInitiated) - { - lock->mState = kState_UnlockingCompleted; - actionCompleted = UNLOCK_ACTION; - } - - if (actionCompleted != INVALID_ACTION) - { - if (lock->mActionCompleted_CB) - { - lock->mActionCompleted_CB(actionCompleted); - } - - if (lock->mAutoRelock && actionCompleted == UNLOCK_ACTION) - { - // Start the timer for auto relock - lock->StartTimer(lock->mAutoLockDuration * 1000); - - lock->mAutoLockTimerArmed = true; - - K32W_LOG("Auto Re-lock enabled. Will be triggered in %u seconds", lock->mAutoLockDuration); - } - } -} diff --git a/examples/lock-app/nxp/k32w/k32w0/main/ZclCallbacks.cpp b/examples/lock-app/nxp/k32w/k32w0/main/ZclCallbacks.cpp deleted file mode 100644 index b888db03861c7f..00000000000000 --- a/examples/lock-app/nxp/k32w/k32w0/main/ZclCallbacks.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Copyright (c) 2020 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 - -#include "AppTask.h" -#include "BoltLockManager.h" -#include - -#include -#include -#include -#include -#include -#include -#include - -using namespace ::chip; -using namespace ::chip::app::Clusters; -using namespace ::chip::app::Clusters::DoorLock; -using ::chip::app::DataModel::Nullable; - -bool emberAfPluginDoorLockOnDoorLockCommand(chip::EndpointId endpointId, const Nullable & fabricIdx, - const Nullable & nodeId, const Optional & pinCode, - OperationErrorEnum & err) -{ - return BoltLockMgr().InitiateAction(0, BoltLockManager::LOCK_ACTION); -} - -bool emberAfPluginDoorLockOnDoorUnlockCommand(chip::EndpointId endpointId, const Nullable & fabricIdx, - const Nullable & nodeId, const Optional & pinCode, - OperationErrorEnum & err) -{ - return BoltLockMgr().InitiateAction(0, BoltLockManager::UNLOCK_ACTION); -} diff --git a/examples/lock-app/nxp/k32w/k32w0/main/include/AppTask.h b/examples/lock-app/nxp/k32w/k32w0/main/include/AppTask.h deleted file mode 100644 index 1addd9236c4bcf..00000000000000 --- a/examples/lock-app/nxp/k32w/k32w0/main/include/AppTask.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * - * Copyright (c) 2020 Google LLC. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include - -#include "AppEvent.h" -#include "BoltLockManager.h" - -#include "CHIPProjectConfig.h" - -#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA -#include -#if CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER -#include "CustomFactoryDataProvider.h" -#endif -#endif - -#include - -#include "FreeRTOS.h" -#include "timers.h" - -class AppTask -{ -public: - CHIP_ERROR StartAppTask(); - static void AppTaskMain(void * pvParameter); - - void PostLockActionRequest(int32_t aActor, BoltLockManager::Action_t aAction); - void PostEvent(const AppEvent * event); - - void UpdateClusterState(void); - -private: - friend AppTask & GetAppTask(void); - - CHIP_ERROR Init(); - - static void ActionInitiated(BoltLockManager::Action_t aAction, int32_t aActor); - static void ActionCompleted(BoltLockManager::Action_t aAction); - - void CancelTimer(void); - - void DispatchEvent(AppEvent * event); - - static void FunctionTimerEventHandler(void * aGenericEvent); - static void KBD_Callback(uint8_t events); - static void HandleKeyboard(void); - static void JoinHandler(void * aGenericEvent); - static void BleHandler(void * aGenericEvent); - static void BleStartAdvertising(intptr_t arg); - static void LockActionEventHandler(void * aGenericEvent); - static void ResetActionEventHandler(void * aGenericEvent); - static void InstallEventHandler(void * aGenericEvent); - - 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); - static void UpdateClusterStateInternal(intptr_t arg); - static void ThreadStart(); - static void InitServer(intptr_t arg); - static void PrintOnboardingInfo(); - void StartTimer(uint32_t aTimeoutInMs); - - enum Function_t - { - kFunction_NoneSelected = 0, - kFunction_SoftwareUpdate = 0, - kFunction_FactoryReset, - kFunctionLockUnlock, - - kFunction_Invalid - } Function; - - Function_t mFunction = kFunction_NoneSelected; - bool mResetTimerActive = false; - bool mSyncClusterToButtonAction = false; - - static AppTask sAppTask; -}; - -inline AppTask & GetAppTask(void) -{ - return AppTask::sAppTask; -} diff --git a/examples/lock-app/nxp/k32w/k32w0/main/include/BoltLockManager.h b/examples/lock-app/nxp/k32w/k32w0/main/include/BoltLockManager.h deleted file mode 100644 index cd33fada37b4fb..00000000000000 --- a/examples/lock-app/nxp/k32w/k32w0/main/include/BoltLockManager.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * - * Copyright (c) 2020 Google LLC. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include - -#include "AppEvent.h" - -#include "FreeRTOS.h" -#include "timers.h" // provides FreeRTOS timer support - -class BoltLockManager -{ -public: - enum Action_t - { - LOCK_ACTION = 0, - UNLOCK_ACTION, - - INVALID_ACTION - } Action; - - enum State_t - { - kState_LockingInitiated = 0, - kState_LockingCompleted, - kState_UnlockingInitiated, - kState_UnlockingCompleted, - } State; - - int Init(); - bool IsUnlocked(); - void EnableAutoRelock(bool aOn); - void SetAutoLockDuration(uint32_t aDurationInSecs); - bool IsActionInProgress(); - bool InitiateAction(int32_t aActor, Action_t aAction); - - typedef void (*Callback_fn_initiated)(Action_t, int32_t aActor); - typedef void (*Callback_fn_completed)(Action_t); - void SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB); - -private: - friend BoltLockManager & BoltLockMgr(void); - State_t mState; - - Callback_fn_initiated mActionInitiated_CB; - Callback_fn_completed mActionCompleted_CB; - - bool mAutoRelock; - uint32_t mAutoLockDuration; - bool mAutoLockTimerArmed; - - void CancelTimer(void); - void StartTimer(uint32_t aTimeoutMs); - - static void TimerEventHandler(TimerHandle_t xTimer); - static void AutoReLockTimerEventHandler(void * aGenericEvent); - static void ActuatorMovementTimerEventHandler(void * aGenericEvent); - - static BoltLockManager sLock; -}; - -inline BoltLockManager & BoltLockMgr(void) -{ - return BoltLockManager::sLock; -} diff --git a/examples/lock-app/nxp/k32w/k32w0/main/include/app_config.h b/examples/lock-app/nxp/k32w/k32w0/main/include/app_config.h deleted file mode 100644 index cfed43e850c4bc..00000000000000 --- a/examples/lock-app/nxp/k32w/k32w0/main/include/app_config.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * - * Copyright (c) 2020 Google LLC. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "LED.h" - -#pragma once - -// ---- Lock Example App Config ---- - -#define RESET_BUTTON 1 -#define LOCK_BUTTON 2 -#define JOIN_BUTTON 3 -#define BLE_BUTTON 4 - -#define RESET_BUTTON_PUSH 1 -#define LOCK_BUTTON_PUSH 2 -#define JOIN_BUTTON_PUSH 3 -#define BLE_BUTTON_PUSH 4 - -#define APP_BUTTON_PUSH 1 - -#define LOCK_STATE_LED LED2 -#define SYSTEM_STATE_LED LED1 - -// Time it takes in ms for the simulated actuator to move from one -// state to another. -#define ACTUATOR_MOVEMENT_PERIOS_MS 2000 - -// ---- Lock Example SWU Config ---- -#define SWU_INTERVAl_WINDOW_MIN_MS (23 * 60 * 60 * 1000) // 23 hours -#define SWU_INTERVAl_WINDOW_MAX_MS (24 * 60 * 60 * 1000) // 24 hours - -// ---- Thread Polling Config ---- -#define THREAD_ACTIVE_POLLING_INTERVAL_MS 100 -#define THREAD_INACTIVE_POLLING_INTERVAL_MS 1000 - -#if K32W_LOG_ENABLED -#define K32W_LOG(...) otPlatLog(OT_LOG_LEVEL_NONE, OT_LOG_REGION_API, ##__VA_ARGS__); -#else -#define K32W_LOG(...) -#endif diff --git a/examples/lock-app/nxp/k32w/k32w0/main/main.cpp b/examples/lock-app/nxp/k32w/k32w0/main/main.cpp deleted file mode 100644 index 7cb5057175b37b..00000000000000 --- a/examples/lock-app/nxp/k32w/k32w0/main/main.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/* - * - * Copyright (c) 2020 Google LLC. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// ================================================================================ -// Main Code -// ================================================================================ - -#include - -#include -#include -#include -#include -#include - -#include "FreeRtosHooks.h" -#include "app_config.h" - -#if PDM_SAVE_IDLE -#include -#endif - -#if defined(chip_with_low_power) && (chip_with_low_power == 1) -#include "fsl_gpio.h" -#include "fsl_iocon.h" -#include "gpio_pins.h" -#endif - -using namespace ::chip; -using namespace ::chip::Inet; -using namespace ::chip::DeviceLayer; -using namespace ::chip::Logging; - -#if defined(chip_with_low_power) && (chip_with_low_power == 1) -#include "Keyboard.h" -#include "OtaSupport.h" -#include "PWR_Configuration.h" -#include "PWR_Interface.h" -#include "RNG_Interface.h" -#include "app_dual_mode_low_power.h" -#include "app_dual_mode_switch.h" -#include "radio.h" -#endif - -#include "MacSched.h" - -typedef void (*InitFunc)(void); - -extern InitFunc __init_array_start; -extern InitFunc __init_array_end; - -extern "C" void sched_enable(); - -/* low power requirements */ -#if defined(chip_with_low_power) && (chip_with_low_power == 1) -extern "C" void setThreadInitialized(bool isInitialized); -extern "C" bool isThreadInitialized(); -#endif - -/* needed for FreeRtos Heap 4 */ -uint8_t __attribute__((section(".heap"))) ucHeap[HEAP_SIZE]; - -extern "C" void main_task(void const * argument) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - /* Call C++ constructors */ - InitFunc * pFunc = &__init_array_start; - for (; pFunc < &__init_array_end; ++pFunc) - { - (*pFunc)(); - } - - mbedtls_platform_set_calloc_free(CHIPPlatformMemoryCalloc, CHIPPlatformMemoryFree); - err = PlatformMgrImpl().InitBoardFwk(); - if (err != CHIP_NO_ERROR) - { - return; - } - - K32W_LOG("Welcome to NXP ELock Demo App"); - - /* Mbedtls Threading support is needed because both - * Thread and Matter tasks are using it */ - freertos_mbedtls_mutex_init(); - - // Init Chip memory management before the stack - chip::Platform::MemoryInit(); - -#if PDM_SAVE_IDLE - /* OT Settings needs to be initialized - * early as XCVR is making use of it */ - otPlatSettingsInit(NULL, NULL, 0); -#endif - - CHIP_ERROR ret = PlatformMgr().InitChipStack(); - if (ret != CHIP_NO_ERROR) - { - K32W_LOG("Error during PlatformMgr().InitMatterStack()"); - goto exit; - } - - ret = ThreadStackMgr().InitThreadStack(); - if (ret != CHIP_NO_ERROR) - { - K32W_LOG("Error during ThreadStackMgr().InitThreadStack()"); - goto exit; - } - - /* Enable the MAC scheduler after BLEManagerImpl::_Init() and V2MMAC_Enable(). - * This is needed to register properly the active protocols. - */ - sched_enable(); - - ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); - if (ret != CHIP_NO_ERROR) - { - goto exit; - } - -#if defined(chip_with_low_power) && (chip_with_low_power == 1) - setThreadInitialized(TRUE); -#endif - - // Start OpenThread task - ret = ThreadStackMgrImpl().StartThreadTask(); - if (ret != CHIP_NO_ERROR) - { - K32W_LOG("Error during ThreadStackMgrImpl().StartThreadTask()"); - goto exit; - } - - ret = GetAppTask().StartAppTask(); - if (ret != CHIP_NO_ERROR) - { - K32W_LOG("Error during GetAppTask().StartAppTask()"); - goto exit; - } - - ret = PlatformMgr().StartEventLoopTask(); - if (ret != CHIP_NO_ERROR) - { - K32W_LOG("Error during PlatformMgr().StartEventLoopTask();"); - goto exit; - } - - GetAppTask().AppTaskMain(NULL); - -exit: - return; -} - -/** - * Glue function called directly by the OpenThread stack - * when system event processing work is pending. - */ -extern "C" void otSysEventSignalPending(void) -{ - -#if defined(chip_with_low_power) && (chip_with_low_power == 1) - /* make sure that 15.4 radio is initialized before waking up the Thread task */ - if (isThreadInitialized()) -#endif - { - BaseType_t yieldRequired = ThreadStackMgrImpl().SignalThreadActivityPendingFromISR(); - portYIELD_FROM_ISR(yieldRequired); - } -} - -#if defined(chip_with_low_power) && (chip_with_low_power == 1) -extern "C" void vOptimizeConsumption(void) -{ - /* BUTTON2 change contact, BUTTON4 start adv/factoryreset */ - uint32_t u32SkipIO = (1 << IOCON_USER_BUTTON1_PIN) | (1 << IOCON_USER_BUTTON2_PIN); - - /* Pins are set to GPIO mode (IOCON FUNC0), pulldown and analog mode */ - uint32_t u32PIOvalue = (IOCON_FUNC0 | IOCON_MODE_PULLDOWN | IOCON_ANALOG_EN); - - const gpio_pin_config_t pin_config = { .pinDirection = kGPIO_DigitalInput, .outputLogic = 1U }; - - if (u32PIOvalue != 0) - { - for (int i = 0; i < 22; i++) - { - if (((u32SkipIO >> i) & 0x1) != 1) - { - /* configure GPIOs to Input mode */ - GPIO_PinInit(GPIO, 0, i, &pin_config); - IOCON_PinMuxSet(IOCON, 0, i, u32PIOvalue); - } - } - } -} -#endif diff --git a/examples/lock-app/nxp/zap/lock-app.zap b/examples/lock-app/nxp/zap/lock-app.zap index aeb737f5ac6bb6..de2ffe615ee4e5 100644 --- a/examples/lock-app/nxp/zap/lock-app.zap +++ b/examples/lock-app/nxp/zap/lock-app.zap @@ -3460,4 +3460,4 @@ "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} diff --git a/examples/all-clusters-app/nxp/common/main/AppAssert.cpp b/examples/platform/nxp/common/app_assert/source/AppAssert.cpp similarity index 100% rename from examples/all-clusters-app/nxp/common/main/AppAssert.cpp rename to examples/platform/nxp/common/app_assert/source/AppAssert.cpp diff --git a/examples/platform/nxp/common/app_task/include/AppTaskBase.h b/examples/platform/nxp/common/app_task/include/AppTaskBase.h new file mode 100644 index 00000000000000..02fdf513eb6679 --- /dev/null +++ b/examples/platform/nxp/common/app_task/include/AppTaskBase.h @@ -0,0 +1,151 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2021 Google LLC. + * Copyright 2024 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. + */ + +#pragma once + +#include +#include + +#include "AppEvent.h" +#include +#include + +namespace chip { +namespace NXP { +namespace App { +class AppTaskBase +{ +public: + virtual ~AppTaskBase() = default; + + /** + * \brief Entry point of AppTaskBase. This function should be overridden. + * + * This function should be called by the main function in order to initialize the matter stack and all other components + * required. + * Should be overriden depending on the OS, for example FreeRTOS start the AppTaskMain task, but Zephyr didn't need to start any + * task. + * + */ + virtual CHIP_ERROR Start() = 0; + + /** + * \brief This function could be overridden in order to execute code at the beginning of the InitServer function. + * + * This function is called at the begging of the InitServer function. + * + */ + virtual void PreInitMatterServerInstance(void){}; + + /** + * \brief This function could be overridden in order to execute code at the end of the InitServer function. + * + * Example of usage: all-cluster-apps example disable last fixed endpoint after InitServer function execution. + * + */ + virtual void PostInitMatterServerInstance(void){}; + + /** + * \brief This function could be overridden in order to execute code before matter stack init function. + * + * Example of usage: if some initialization has to be done before the matter stack initialization. + * + */ + virtual void PreInitMatterStack(void){}; + + /** + * \brief This function could be overridden in order to execute code after matter stack init function. + * + * Example of usage: The laundry whasher example requires the TemperatureControl cluster initialization, this initialization is + * done after matter stack init. Developper can override this function to add cluster initialization/customization. + * + */ + virtual void PostInitMatterStack(void){}; + + /** + * \brief This function could be overridden in order to register features. + * + * Example of usage: Could be overridden in order to register matter CLI or button features. + * + * \return CHIP_ERROR + * + */ + virtual CHIP_ERROR AppMatter_Register(void) { return CHIP_NO_ERROR; }; + + /** + * \brief This function could be overridden in order to register custom CLI commands. + * + * Example of usage: Laundry washer application used additionnal CLI commands. + * + */ + virtual void AppMatter_RegisterCustomCliCommands(void){}; + + /** + * \brief This function could be overridden in order to dispatch event. + * + * Example of usage: FreeRtos dispatch event using the event handler. + * + */ + virtual void DispatchEvent(const AppEvent & event){}; + + /** + * \brief Return a pointer to the NXP Wifi Driver instance. + * + * \return NXP Wifi Driver instance pointeur + */ +#if CONFIG_CHIP_WIFI || CHIP_DEVICE_CONFIG_ENABLE_WPA + virtual chip::DeviceLayer::NetworkCommissioning::WiFiDriver * GetWifiDriverInstance(void) = 0; +#endif + + /** + * \brief Stack initializations. + * + * Init matter stack and all other components (openthread, wifi, cli ...). + * + */ + CHIP_ERROR Init(); + + /** + * \brief Initialize the ZCL Data Model and start server. + * + * Call by Init function to initialize the ZCL Data Model and start server. + * + */ + static void InitServer(intptr_t arg); + + /* Commissioning handlers */ + virtual void StartCommissioningHandler(void){}; + virtual void StopCommissioningHandler(void){}; + virtual void SwitchCommissioningStateHandler(void){}; + virtual void FactoryResetHandler(void){}; + +private: + inline static chip::CommonCaseDeviceServerInitParams initParams; +}; + +/** + * Returns the application-specific implementation of the AppTaskBase object. + * + * Applications can use this to gain access to features of the AppTaskBase. + */ +extern AppTaskBase & GetAppTask(); +} // namespace App +} // namespace NXP +} // namespace chip diff --git a/examples/platform/nxp/common/app_task/include/AppTaskFreeRTOS.h b/examples/platform/nxp/common/app_task/include/AppTaskFreeRTOS.h new file mode 100644 index 00000000000000..9fbaf8063df8b7 --- /dev/null +++ b/examples/platform/nxp/common/app_task/include/AppTaskFreeRTOS.h @@ -0,0 +1,93 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright 2024 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. + */ + +#pragma once + +#include "AppTaskBase.h" + +namespace chip { +namespace NXP { +namespace App { +class AppTaskFreeRTOS : public AppTaskBase +{ +public: + virtual ~AppTaskFreeRTOS() = default; + + /** + * \brief Entry point of AppTaskBase. + * + * This function: + * - Create application message queue + * - Create the dedicated application task + * + */ + virtual CHIP_ERROR Start() override; + + /** + * \brief Application task. + * + * This function: + * - Init matter stack and other needed components + * - Dispatch event comming from the app event queue + * + */ + static void AppTaskMain(void * pvParameter); + + /** + * \brief Send event to the event queue. + * + */ + void PostEvent(const AppEvent & event); + + /** + * \brief Return a pointer to the NXP Wifi Driver instance. + * + * \return NXP Wifi Driver instance pointeur + */ +#if CHIP_DEVICE_CONFIG_ENABLE_WPA + virtual chip::DeviceLayer::NetworkCommissioning::WiFiDriver * GetWifiDriverInstance(void) override; +#endif + + /** + * \brief This function register matter CLI and button features. + * + * \return CHIP_ERROR + * + */ + virtual CHIP_ERROR AppMatter_Register(void) override; + + /* Functions that would be called in the Matter task context */ + static void StartCommissioning(intptr_t arg); + static void StopCommissioning(intptr_t arg); + static void SwitchCommissioningState(intptr_t arg); + + /* Commissioning handlers */ + virtual void StartCommissioningHandler(void) override; + virtual void StopCommissioningHandler(void) override; + virtual void SwitchCommissioningStateHandler(void) override; + + /* FactoryResetHandler */ + virtual void FactoryResetHandler(void) override; + +private: + void DispatchEvent(const AppEvent & event); +}; +} // namespace App +} // namespace NXP +} // namespace chip diff --git a/examples/platform/nxp/common/app_task/include/AppTaskZephyr.h b/examples/platform/nxp/common/app_task/include/AppTaskZephyr.h new file mode 100644 index 00000000000000..163e3e76a9d87c --- /dev/null +++ b/examples/platform/nxp/common/app_task/include/AppTaskZephyr.h @@ -0,0 +1,62 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright 2024 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. + */ + +#pragma once + +#include "AppTaskBase.h" + +namespace chip { +namespace NXP { +namespace App { +class AppTaskZephyr : public AppTaskBase +{ +public: + virtual ~AppTaskZephyr() = default; + + /** + * \brief Entry point of AppTaskBase. + * + * This function: + * - Init matter stack and other needed components + * - Dispatch event comming from the app event queue + * + */ + virtual CHIP_ERROR Start() override; + + /** + * \brief Send event to the event queue. + * + */ + void PostEvent(const AppEvent & event); + + /** + * \brief Return a pointer to the NXP Wifi Driver instance. + * + * \return NXP Wifi Driver instance pointeur + */ +#if defined(CONFIG_CHIP_WIFI) + virtual chip::DeviceLayer::NetworkCommissioning::WiFiDriver * GetWifiDriverInstance(void) override; +#endif + +private: + void DispatchEvent(const AppEvent & event); +}; +} // namespace App +} // namespace NXP +} // namespace chip diff --git a/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp b/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp new file mode 100644 index 00000000000000..e03634e9807aa5 --- /dev/null +++ b/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp @@ -0,0 +1,252 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2021 Google LLC. + * Copyright 2024 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. + */ +#include "AppTaskBase.h" +#include "AppEvent.h" +#include "AppFactoryData.h" +#include "CHIPDeviceManager.h" +#include "CommonDeviceCallbacks.h" + +#include +#include + +#include +#include +#include + +#include +#include + +#include "lib/core/ErrorStr.h" + +#include + +#ifdef EMBER_AF_PLUGIN_BINDING +#include "binding-handler.h" +#endif + +#if CONFIG_NET_L2_OPENTHREAD +#include +#include +#endif + +#if CONFIG_CHIP_TCP_DOWNLOAD +#include "TcpDownload.h" +#endif + +#if CONFIG_CHIP_OTA_PROVIDER +#include +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR +#include "OTARequestorInitiator.h" +#endif + +#if CONFIG_CHIP_TEST_EVENT && CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR +#include +#endif + +using namespace chip; +using namespace chip::TLV; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; +using namespace ::chip::DeviceManager; +using namespace ::chip::app::Clusters; + +chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; + +#if CONFIG_CHIP_WIFI || CHIP_DEVICE_CONFIG_ENABLE_WPA +app::Clusters::NetworkCommissioning::Instance sNetworkCommissioningInstance(0, + chip::NXP::App::GetAppTask().GetWifiDriverInstance()); +#endif + +#if CONFIG_CHIP_TEST_EVENT && CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR +static uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, + 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, + 0xcc, 0xdd, 0xee, 0xff }; +#endif + +#if CONFIG_NET_L2_OPENTHREAD +void LockOpenThreadTask(void) +{ + chip::DeviceLayer::ThreadStackMgr().LockThreadStack(); +} + +void UnlockOpenThreadTask(void) +{ + chip::DeviceLayer::ThreadStackMgr().UnlockThreadStack(); +} +#endif + +void chip::NXP::App::AppTaskBase::InitServer(intptr_t arg) +{ + GetAppTask().PreInitMatterServerInstance(); + +#if CONFIG_CHIP_TEST_EVENT && CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; + initParams.testEventTriggerDelegate = &testEventTriggerDelegate; +#endif + (void) initParams.InitializeStaticResourcesBeforeServerInit(); +#if CONFIG_NET_L2_OPENTHREAD + // Init ZCL Data Model and start server + chip::Inet::EndPointStateOpenThread::OpenThreadEndpointInitParam nativeParams; + nativeParams.lockCb = LockOpenThreadTask; + nativeParams.unlockCb = UnlockOpenThreadTask; + nativeParams.openThreadInstancePtr = chip::DeviceLayer::ThreadStackMgrImpl().OTInstance(); + initParams.endpointNativeParams = static_cast(&nativeParams); +#endif + + VerifyOrDie((chip::Server::GetInstance().Init(initParams)) == CHIP_NO_ERROR); + + gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); + chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); + + GetAppTask().PostInitMatterServerInstance(); + +#if CONFIG_CHIP_OTA_PROVIDER + InitOTAServer(); +#endif +} + +CHIP_ERROR chip::NXP::App::AppTaskBase::Init() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + /* Init Chip memory management before the stack */ + chip::Platform::MemoryInit(); + + /* Initialize Matter factory data before initializing the Matter stack */ + err = AppFactoryData_PreMatterStackInit(); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Pre Factory Data Provider init failed"); + goto exit; + } + + /* + * Initialize the CHIP stack. + * Would also initialize all required platform modules + */ + err = PlatformMgr().InitChipStack(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "PlatformMgr().InitChipStack() failed: %s", ErrorStr(err)); + goto exit; + } + + /* Initialize Matter factory data after initializing the Matter stack */ + err = AppFactoryData_PostMatterStackInit(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Post Factory Data Provider init failed"); + goto exit; + } + + /* + * Register all application callbacks allowing to be informed of stack events + */ + err = CHIPDeviceManager::GetInstance().Init(&GetDeviceCallbacks()); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "CHIPDeviceManager.Init() failed: %s", ErrorStr(err)); + goto exit; + } + +#if CONFIG_NET_L2_OPENTHREAD + err = ThreadStackMgr().InitThreadStack(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Error during ThreadStackMgr().InitThreadStack()"); + return err; + } + + err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); + if (err != CHIP_NO_ERROR) + { + return err; + } +#endif + + /* + * Schedule an event to the Matter stack to initialize + * the ZCL Data Model and start server + */ + PlatformMgr().ScheduleWork(InitServer, 0); + +#ifdef EMBER_AF_PLUGIN_BINDING + /* Init binding handlers */ + err = InitBindingHandlers(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "InitBindingHandlers failed: %s", ErrorStr(err)); + goto exit; + } +#endif + +#if CONFIG_CHIP_WIFI || CHIP_DEVICE_CONFIG_ENABLE_WPA + sNetworkCommissioningInstance.Init(); +#endif +#if CONFIG_CHIP_OTA_REQUESTOR + if (err == CHIP_NO_ERROR) + { + /* If an update is under test make it permanent */ + OTARequestorInitiator::Instance().HandleSelfTest(); + } +#endif + + err = AppMatter_Register(); + if (err != CHIP_NO_ERROR) + { + goto exit; + } + + ConfigurationMgr().LogDeviceConfig(); + + // QR code will be used with CHIP Tool +#if CONFIG_NETWORK_LAYER_BLE + PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kBLE)); +#else + PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kOnNetwork)); +#endif /* CONFIG_NETWORK_LAYER_BLE */ + + /* Start a task to run the CHIP Device event loop. */ + err = PlatformMgr().StartEventLoopTask(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Error during PlatformMgr().StartEventLoopTask()"); + goto exit; + } + +#if CONFIG_NET_L2_OPENTHREAD + // Start OpenThread task + err = ThreadStackMgrImpl().StartThreadTask(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Error during ThreadStackMgrImpl().StartThreadTask()"); + } +#endif + +#if CONFIG_CHIP_TCP_DOWNLOAD + EnableTcpDownloadComponent(); +#endif + +exit: + return err; +} diff --git a/examples/platform/nxp/common/app_task/source/AppTaskFreeRTOS.cpp b/examples/platform/nxp/common/app_task/source/AppTaskFreeRTOS.cpp new file mode 100644 index 00000000000000..8508884b672b23 --- /dev/null +++ b/examples/platform/nxp/common/app_task/source/AppTaskFreeRTOS.cpp @@ -0,0 +1,240 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2021 Google LLC. + * Copyright 2024 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. + */ +#include "AppTaskFreeRTOS.h" +#include +#include + +#include "AppMatterButton.h" +#include "AppMatterCli.h" + +#include "CHIPDeviceManager.h" +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_WPA +#include +#endif // CHIP_DEVICE_CONFIG_ENABLE_WPA + +#include + +#include + +#if WIFI_CONNECT_TASK +#include "WifiConnect.h" +#endif + +#ifndef APP_TASK_STACK_SIZE +#define APP_TASK_STACK_SIZE ((configSTACK_DEPTH_TYPE) 6144 / sizeof(portSTACK_TYPE)) +#endif +#ifndef APP_TASK_PRIORITY +#define APP_TASK_PRIORITY 2 +#endif +#define APP_EVENT_QUEUE_SIZE 10 + +static QueueHandle_t sAppEventQueue; + +using namespace chip; +using namespace chip::TLV; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; +using namespace ::chip::DeviceManager; +using namespace ::chip::app::Clusters; + +#if CHIP_DEVICE_CONFIG_ENABLE_WPA + +chip::DeviceLayer::NetworkCommissioning::WiFiDriver * chip::NXP::App::AppTaskFreeRTOS::GetWifiDriverInstance() +{ + return static_cast( + &(::chip::DeviceLayer::NetworkCommissioning::NXPWiFiDriver::GetInstance())); +} +#endif // CHIP_DEVICE_CONFIG_ENABLE_WPA + +CHIP_ERROR chip::NXP::App::AppTaskFreeRTOS::AppMatter_Register() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + /* Register Matter CLI cmds */ + err = AppMatterCli_RegisterCommands(); + AppMatter_RegisterCustomCliCommands(); + AppMatterCli_StartTask(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Error during AppMatterCli_RegisterCommands"); + return err; + } + /* Register Matter buttons */ + err = AppMatterButton_registerButtons(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Error during AppMatterButton_registerButtons"); + return err; + } + return err; +} + +CHIP_ERROR chip::NXP::App::AppTaskFreeRTOS::Start() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + TaskHandle_t taskHandle; + + sAppEventQueue = xQueueCreate(APP_EVENT_QUEUE_SIZE, sizeof(AppEvent)); + if (sAppEventQueue == NULL) + { + err = CHIP_ERROR_NO_MEMORY; + ChipLogError(DeviceLayer, "Failed to allocate app event queue"); + assert(err == CHIP_NO_ERROR); + } + + /* AppTaskMain function will loss actual object instance, give it as parameter */ + if (xTaskCreate(&AppTaskFreeRTOS::AppTaskMain, "AppTaskMain", APP_TASK_STACK_SIZE, this, APP_TASK_PRIORITY, &taskHandle) != + pdPASS) + { + err = CHIP_ERROR_NO_MEMORY; + ChipLogError(DeviceLayer, "Failed to start app task"); + assert(err == CHIP_NO_ERROR); + } + + return err; +} + +void chip::NXP::App::AppTaskFreeRTOS::AppTaskMain(void * pvParameter) +{ + CHIP_ERROR err; + AppEvent event; + + /* AppTaskMain function will loss AppTask object instance (FreeRTOS task context), AppTask instance is given as parameter */ + AppTaskFreeRTOS * sAppTask = static_cast(pvParameter); + + sAppTask->PreInitMatterStack(); + err = sAppTask->Init(); + sAppTask->PostInitMatterStack(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "AppTask.Init() failed"); + assert(err == CHIP_NO_ERROR); + } + + while (true) + { + BaseType_t eventReceived = xQueueReceive(sAppEventQueue, &event, portMAX_DELAY); + while (eventReceived == pdTRUE) + { + sAppTask->DispatchEvent(event); + eventReceived = xQueueReceive(sAppEventQueue, &event, 0); + } + } +} + +void chip::NXP::App::AppTaskFreeRTOS::PostEvent(const AppEvent & event) +{ + if (sAppEventQueue != NULL) + { + if (!xQueueSend(sAppEventQueue, &event, 0)) + { + ChipLogError(DeviceLayer, "Failed to post event to app task event queue"); + } + } +} + +void chip::NXP::App::AppTaskFreeRTOS::DispatchEvent(const AppEvent & event) +{ + if (event.Handler) + { + event.Handler(event); + } + else + { + ChipLogProgress(DeviceLayer, "Event received with no handler. Dropping event."); + } +} + +void chip::NXP::App::AppTaskFreeRTOS::StartCommissioning(intptr_t arg) +{ + /* Check the status of the commissioning */ + if (ConfigurationMgr().IsFullyProvisioned()) + { + ChipLogProgress(DeviceLayer, "Device already commissioned"); + } + else if (chip::Server::GetInstance().GetCommissioningWindowManager().IsCommissioningWindowOpen()) + { + ChipLogProgress(DeviceLayer, "Commissioning window already opened"); + } + else + { + chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow(); + } +} + +void chip::NXP::App::AppTaskFreeRTOS::StopCommissioning(intptr_t arg) +{ + /* Check the status of the commissioning */ + if (ConfigurationMgr().IsFullyProvisioned()) + { + ChipLogProgress(DeviceLayer, "Device already commissioned"); + } + else if (!chip::Server::GetInstance().GetCommissioningWindowManager().IsCommissioningWindowOpen()) + { + ChipLogProgress(DeviceLayer, "Commissioning window not opened"); + } + else + { + chip::Server::GetInstance().GetCommissioningWindowManager().CloseCommissioningWindow(); + } +} + +void chip::NXP::App::AppTaskFreeRTOS::SwitchCommissioningState(intptr_t arg) +{ + /* Check the status of the commissioning */ + if (ConfigurationMgr().IsFullyProvisioned()) + { + ChipLogProgress(DeviceLayer, "Device already commissioned"); + } + else if (!chip::Server::GetInstance().GetCommissioningWindowManager().IsCommissioningWindowOpen()) + { + chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow(); + } + else + { + chip::Server::GetInstance().GetCommissioningWindowManager().CloseCommissioningWindow(); + } +} + +void chip::NXP::App::AppTaskFreeRTOS::StartCommissioningHandler(void) +{ + /* Publish an event to the Matter task to always set the commissioning state in the Matter task context */ + PlatformMgr().ScheduleWork(StartCommissioning, 0); +} + +void chip::NXP::App::AppTaskFreeRTOS::StopCommissioningHandler(void) +{ + /* Publish an event to the Matter task to always set the commissioning state in the Matter task context */ + PlatformMgr().ScheduleWork(StopCommissioning, 0); +} + +void chip::NXP::App::AppTaskFreeRTOS::SwitchCommissioningStateHandler(void) +{ + /* Publish an event to the Matter task to always set the commissioning state in the Matter task context */ + PlatformMgr().ScheduleWork(SwitchCommissioningState, 0); +} + +void chip::NXP::App::AppTaskFreeRTOS::FactoryResetHandler(void) +{ + /* Emit the ShutDown event before factory reset */ + chip::Server::GetInstance().GenerateShutDownEvent(); + chip::Server::GetInstance().ScheduleFactoryReset(); +} diff --git a/examples/platform/nxp/common/app_task/source/AppTaskZephyr.cpp b/examples/platform/nxp/common/app_task/source/AppTaskZephyr.cpp new file mode 100644 index 00000000000000..03a86a572a82c2 --- /dev/null +++ b/examples/platform/nxp/common/app_task/source/AppTaskZephyr.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * Copyright 2024 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. + */ + +/* -------------------------------------------------------------------------- */ +/* Includes */ +/* -------------------------------------------------------------------------- */ +#include "AppTaskZephyr.h" + +#include "CHIPDeviceManager.h" +#include +#include +#include +#include +#include + +#ifdef CONFIG_CHIP_WIFI +#include +#endif + +#if CONFIG_CHIP_FACTORY_DATA +#include +#else +#include +#endif + +#include "AppFactoryData.h" + +LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); + +using namespace ::chip; +using namespace ::chip::app; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; +using namespace ::chip::DeviceManager; + +/* -------------------------------------------------------------------------- */ +/* Private memory */ +/* -------------------------------------------------------------------------- */ + +constexpr size_t kAppEventQueueSize = 10; +K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); + +/* -------------------------------------------------------------------------- */ +/* Class implementation */ +/* -------------------------------------------------------------------------- */ + +#if defined(CONFIG_CHIP_WIFI) +chip::DeviceLayer::NetworkCommissioning::WiFiDriver * chip::NXP::App::AppTaskZephyr::GetWifiDriverInstance() +{ + return static_cast(&(NetworkCommissioning::NxpWifiDriver::Instance())); +} +#endif // CONFIG_CHIP_WIFI + +CHIP_ERROR chip::NXP::App::AppTaskZephyr::Start() +{ + + ReturnErrorOnFailure(Init()); + + AppEvent event{}; + + while (true) + { + k_msgq_get(&sAppEventQueue, &event, K_FOREVER); + DispatchEvent(event); + } + + return CHIP_NO_ERROR; +} + +void chip::NXP::App::AppTaskZephyr::PostEvent(const AppEvent & event) +{ + if (k_msgq_put(&sAppEventQueue, &event, K_NO_WAIT) != 0) + { + LOG_INF("Failed to post event to app task event queue"); + } +} + +void chip::NXP::App::AppTaskZephyr::DispatchEvent(const AppEvent & event) +{ + if (event.Handler) + { + event.Handler(event); + } + else + { + LOG_INF("Event received with no handler. Dropping event."); + } +} diff --git a/examples/platform/nxp/common/device_callbacks/include/CommonDeviceCallbacks.h b/examples/platform/nxp/common/device_callbacks/include/CommonDeviceCallbacks.h new file mode 100644 index 00000000000000..4cbd5028ce58b3 --- /dev/null +++ b/examples/platform/nxp/common/device_callbacks/include/CommonDeviceCallbacks.h @@ -0,0 +1,69 @@ +/* + * + * Copyright (c) 2020-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 CommonDeviceCallbacks.h + * + * Common Implementations for the DeviceManager callbacks for all applications + * + **/ + +#pragma once + +#include "CHIPDeviceManager.h" +#include +#include + +namespace chip { +namespace NXP { +namespace App { +class CommonDeviceCallbacks : public chip::DeviceManager::CHIPDeviceManagerCallbacks +{ +public: + virtual void DeviceEventCallback(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + virtual void OnWiFiConnectivityChange(const chip::DeviceLayer::ChipDeviceEvent * event); + virtual void OnInternetConnectivityChange(const chip::DeviceLayer::ChipDeviceEvent * event); + virtual void OnSessionEstablished(const chip::DeviceLayer::ChipDeviceEvent * event); + virtual void OnInterfaceIpAddressChanged(const chip::DeviceLayer::ChipDeviceEvent * event); +#if CHIP_ENABLE_OPENTHREAD && CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED + virtual void OnComissioningComplete(const chip::DeviceLayer::ChipDeviceEvent * event); +#endif +}; + +class DeviceCallbacksDelegate +{ +public: + static DeviceCallbacksDelegate & Instance() + { + static DeviceCallbacksDelegate instance; + return instance; + } + DeviceCallbacksDelegate * mDelegate = nullptr; + void SetAppDelegate(DeviceCallbacksDelegate * delegate) { mDelegate = delegate; } + DeviceCallbacksDelegate * GetAppDelegate() { return mDelegate; } +}; + +/** + * Returns the application-specific implementation of the CommonDeviceCallbacks object. + * + * Applications can use this to gain access to features of the CommonDeviceCallbacks. + */ +extern chip::DeviceManager::CHIPDeviceManagerCallbacks & GetDeviceCallbacks(); +} // namespace App +} // namespace NXP +} // namespace chip diff --git a/examples/platform/nxp/common/device_callbacks/source/CommonDeviceCallbacks.cpp b/examples/platform/nxp/common/device_callbacks/source/CommonDeviceCallbacks.cpp new file mode 100644 index 00000000000000..d38d6f59f8c572 --- /dev/null +++ b/examples/platform/nxp/common/device_callbacks/source/CommonDeviceCallbacks.cpp @@ -0,0 +1,177 @@ +/* + * + * Copyright (c) 2020-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 CommonDeviceCallbacks.cpp + * + * Implements all the callbacks to the application from the CHIP Stack + * + **/ +#include "CommonDeviceCallbacks.h" + +#include +#include +#include +#include +#include + +#include +#if CHIP_ENABLE_OPENTHREAD && CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED +#include "openthread-system.h" +#include "ot_platform_common.h" +#endif /* CHIP_ENABLE_OPENTHREAD && CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED */ + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR +#include "OTARequestorInitiator.h" +#endif + +using namespace chip::app; +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::System; +using namespace ::chip::DeviceLayer; + +void chip::NXP::App::CommonDeviceCallbacks::DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) +{ + ChipLogDetail(DeviceLayer, "DeviceEventCallback: 0x%04x", event->Type); + switch (event->Type) + { + case DeviceEventType::kWiFiConnectivityChange: + OnWiFiConnectivityChange(event); + break; + + case DeviceEventType::kInternetConnectivityChange: + OnInternetConnectivityChange(event); + break; + + case DeviceEventType::kInterfaceIpAddressChanged: +#if !CHIP_ENABLE_OPENTHREAD // No need to do this for OT mDNS server + if ((event->InterfaceIpAddressChanged.Type == InterfaceIpChangeType::kIpV4_Assigned) || + (event->InterfaceIpAddressChanged.Type == InterfaceIpChangeType::kIpV6_Assigned)) + { + // MDNS server restart on any ip assignment: if link local ipv6 is configured, that + // will not trigger a 'internet connectivity change' as there is no internet + // connectivity. MDNS still wants to refresh its listening interfaces to include the + // newly selected address. + chip::app::DnssdServer::Instance().StartServer(); + } +#endif + OnInterfaceIpAddressChanged(event); + break; + +#if CHIP_ENABLE_OPENTHREAD && CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED + case DeviceEventType::kCommissioningComplete: + CommonDeviceCallbacks::OnComissioningComplete(event); + break; +#endif + case DeviceLayer::DeviceEventType::kDnssdInitialized: + ChipLogProgress(DeviceLayer, "kDnssdInitialized"); +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + /* Initialize OTA Requestor */ + OTARequestorInitiator::Instance().InitOTA(reinterpret_cast(&OTARequestorInitiator::Instance())); +#endif + break; + } +} + +void chip::NXP::App::CommonDeviceCallbacks::OnWiFiConnectivityChange(const ChipDeviceEvent * event) +{ + if (event->WiFiConnectivityChange.Result == kConnectivity_Established) + { + ChipLogProgress(DeviceLayer, "WiFi connection established"); + } + else if (event->WiFiConnectivityChange.Result == kConnectivity_Lost) + { + ChipLogProgress(DeviceLayer, "WiFi connection lost"); + } +} + +void chip::NXP::App::CommonDeviceCallbacks::OnInternetConnectivityChange(const ChipDeviceEvent * event) +{ + if (event->InternetConnectivityChange.IPv4 == kConnectivity_Established) + { + char ip_addr[Inet::IPAddress::kMaxStringLength]; + event->InternetConnectivityChange.ipAddress.ToString(ip_addr); + ChipLogProgress(DeviceLayer, "Server ready at: %s:%d", ip_addr, CHIP_PORT); +#if !CHIP_ENABLE_OPENTHREAD // No need to do this for OT mDNS server + chip::app::DnssdServer::Instance().StartServer(); +#endif + } + else if (event->InternetConnectivityChange.IPv4 == kConnectivity_Lost) + { + ChipLogProgress(DeviceLayer, "Lost IPv4 connectivity..."); + } + if (event->InternetConnectivityChange.IPv6 == kConnectivity_Established) + { + char ip_addr[Inet::IPAddress::kMaxStringLength]; + event->InternetConnectivityChange.ipAddress.ToString(ip_addr); + ChipLogProgress(DeviceLayer, "IPv6 Server ready at: [%s]:%d", ip_addr, CHIP_PORT); +#if !CHIP_ENABLE_OPENTHREAD // No need to do this for OT mDNS server + chip::app::DnssdServer::Instance().StartServer(); +#endif + } + else if (event->InternetConnectivityChange.IPv6 == kConnectivity_Lost) + { + ChipLogProgress(DeviceLayer, "Lost IPv6 connectivity..."); + } +} + +void chip::NXP::App::CommonDeviceCallbacks::OnInterfaceIpAddressChanged(const ChipDeviceEvent * event) +{ + switch (event->InterfaceIpAddressChanged.Type) + { + case InterfaceIpChangeType::kIpV4_Assigned: + ChipLogProgress(DeviceLayer, "Interface IPv4 address assigned"); + break; + case InterfaceIpChangeType::kIpV4_Lost: + ChipLogProgress(DeviceLayer, "Interface IPv4 address lost"); + break; + case InterfaceIpChangeType::kIpV6_Assigned: + ChipLogProgress(DeviceLayer, "Interface IPv6 address assigned"); + break; + case InterfaceIpChangeType::kIpV6_Lost: + ChipLogProgress(DeviceLayer, "Interface IPv6 address lost"); + break; + } +} + +void chip::NXP::App::CommonDeviceCallbacks::OnSessionEstablished(chip::DeviceLayer::ChipDeviceEvent const *) +{ + /* Empty */ +} + +#if CHIP_ENABLE_OPENTHREAD && CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED +void chip::NXP::App::CommonDeviceCallbacks::OnComissioningComplete(const chip::DeviceLayer::ChipDeviceEvent * event) +{ + /* + * If a transceiver supporting a multiprotocol scenario is used, a check of the provisioning state is required, + * so that we can inform the transceiver to stop BLE to give the priority to another protocol. + * For example it is the case when a K32W0 transceiver supporting OT+BLE+Zigbee is used. When the device is already provisioned, + * BLE is no more required and the transceiver needs to be informed so that Zigbee can be switched on and BLE switched off. + * + * If a transceiver does not support such vendor property the cmd would be ignored. + */ + if (ConfigurationMgr().IsFullyProvisioned()) + { + ChipLogDetail(DeviceLayer, "Provisioning complete, stopping BLE\n"); + ThreadStackMgrImpl().LockThreadStack(); + PlatformMgrImpl().StopBLEConnectivity(); + ThreadStackMgrImpl().UnlockThreadStack(); + } +} +#endif diff --git a/examples/all-clusters-app/nxp/common/main/include/CHIPDeviceManager.h b/examples/platform/nxp/common/device_manager/include/CHIPDeviceManager.h similarity index 100% rename from examples/all-clusters-app/nxp/common/main/include/CHIPDeviceManager.h rename to examples/platform/nxp/common/device_manager/include/CHIPDeviceManager.h diff --git a/examples/all-clusters-app/nxp/common/main/CHIPDeviceManager.cpp b/examples/platform/nxp/common/device_manager/source/CHIPDeviceManager.cpp similarity index 100% rename from examples/all-clusters-app/nxp/common/main/CHIPDeviceManager.cpp rename to examples/platform/nxp/common/device_manager/source/CHIPDeviceManager.cpp diff --git a/examples/shell/nxp/k32w/k32w0/args.gni b/examples/platform/nxp/common/diagnostic_logs/BUILD.gn similarity index 62% rename from examples/shell/nxp/k32w/k32w0/args.gni rename to examples/platform/nxp/common/diagnostic_logs/BUILD.gn index e9f2a25ea6f722..04d864753a6633 100644 --- a/examples/shell/nxp/k32w/k32w0/args.gni +++ b/examples/platform/nxp/common/diagnostic_logs/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Project CHIP Authors +# Copyright (c) 2024 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,11 +13,12 @@ # limitations under the License. import("//build_overrides/chip.gni") -import("//build_overrides/pigweed.gni") -import("${chip_root}/config/standalone/args.gni") -import("${chip_root}/examples/platform/nxp/k32w/k32w0/args.gni") -import("${chip_root}/src/platform/nxp/k32w/k32w0/args.gni") -k32w0_sdk_target = get_label_info(":sdk", "label_no_toolchain") +source_set("nxp_diagnostic_logs") { + sources = [ + "DiagnosticLogsProviderDelegateImpl.cpp", + "DiagnosticLogsProviderDelegateImpl.h", + ] -chip_enable_ble = false + include_dirs = [ "${chip_root}/src" ] +} diff --git a/examples/platform/nxp/common/diagnostic_logs/DiagnosticLogsProviderDelegateImpl.cpp b/examples/platform/nxp/common/diagnostic_logs/DiagnosticLogsProviderDelegateImpl.cpp new file mode 100644 index 00000000000000..359edc3dedc9a6 --- /dev/null +++ b/examples/platform/nxp/common/diagnostic_logs/DiagnosticLogsProviderDelegateImpl.cpp @@ -0,0 +1,168 @@ +/* + * + * Copyright (c) 2024 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 "DiagnosticLogsProviderDelegateImpl.h" + +#include +#include + +using namespace chip; +using namespace chip::app::Clusters::DiagnosticLogs; + +namespace { +bool IsValidIntent(IntentEnum intent) +{ + return intent != IntentEnum::kUnknownEnumValue; +} +} // namespace + +LogProvider LogProvider::sInstance; + +LogProvider::~LogProvider() {} + +CHIP_ERROR LogProvider::GetLogForIntent(IntentEnum intent, MutableByteSpan & outBuffer, Optional & outTimeStamp, + Optional & outTimeSinceBoot) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + LogSessionHandle sessionHandle = kInvalidLogSessionHandle; + + err = StartLogCollection(intent, sessionHandle, outTimeStamp, outTimeSinceBoot); + VerifyOrReturnError(CHIP_NO_ERROR == err, err, outBuffer.reduce_size(0)); + + bool unusedOutIsEndOfLog; + err = CollectLog(sessionHandle, outBuffer, unusedOutIsEndOfLog); + VerifyOrReturnError(CHIP_NO_ERROR == err, err, outBuffer.reduce_size(0)); + + err = EndLogCollection(sessionHandle); + VerifyOrReturnError(CHIP_NO_ERROR == err, err, outBuffer.reduce_size(0)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR LogProvider::StartLogCollection(IntentEnum intent, LogSessionHandle & outHandle, Optional & outTimeStamp, + Optional & outTimeSinceBoot) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrReturnValue(IsValidIntent(intent), CHIP_ERROR_INVALID_ARGUMENT); + + auto key = GetKeyForIntent(intent); + VerifyOrReturnValue(key.IsInitialized(), CHIP_ERROR_NOT_FOUND); + + uint16_t diagSize = GetSizeForIntent(intent); + VerifyOrReturnError(diagSize, CHIP_ERROR_NOT_FOUND); + + uint8_t * diagData = (uint8_t *) calloc(1, diagSize); + VerifyOrReturnError(diagData, CHIP_ERROR_NO_MEMORY); + + err = chip::Server::GetInstance().GetPersistentStorage().SyncGetKeyValue(key.KeyName(), diagData, diagSize); + VerifyOrReturnValue(err == CHIP_NO_ERROR, err); + + MutableByteSpan * mutableSpan = reinterpret_cast(calloc(1, sizeof(MutableByteSpan))); + VerifyOrReturnValue(mutableSpan, CHIP_ERROR_NO_MEMORY, free(diagData)); + + *mutableSpan = MutableByteSpan(diagData, diagSize); + + mLogSessionHandle++; + // If the session handle rolls over to UINT16_MAX which is invalid, reset to 0. + VerifyOrDo(mLogSessionHandle != kInvalidLogSessionHandle, mLogSessionHandle = 0); + + outHandle = mLogSessionHandle; + mSessionSpanMap[mLogSessionHandle] = mutableSpan; + mSessionDiagMap[mLogSessionHandle] = diagData; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR LogProvider::EndLogCollection(LogSessionHandle sessionHandle) +{ + VerifyOrReturnValue(sessionHandle != kInvalidLogSessionHandle, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnValue(mSessionSpanMap.count(sessionHandle), CHIP_ERROR_INVALID_ARGUMENT); + + free(mSessionDiagMap[sessionHandle]); + free(mSessionSpanMap[sessionHandle]); + + mSessionSpanMap.erase(sessionHandle); + mSessionDiagMap.erase(sessionHandle); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR LogProvider::CollectLog(LogSessionHandle sessionHandle, MutableByteSpan & outBuffer, bool & outIsEndOfLog) +{ + VerifyOrReturnValue(sessionHandle != kInvalidLogSessionHandle, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnValue(mSessionSpanMap.count(sessionHandle), CHIP_ERROR_INVALID_ARGUMENT); + + MutableByteSpan * mutableSpan = mSessionSpanMap[sessionHandle]; + auto diagSize = mutableSpan->size(); + auto count = std::min(diagSize, outBuffer.size()); + + VerifyOrReturnError(CanCastTo(count), CHIP_ERROR_INVALID_ARGUMENT, outBuffer.reduce_size(0)); + + ReturnErrorOnFailure(CopySpanToMutableSpan(ByteSpan(mutableSpan->data(), count), outBuffer)); + + outIsEndOfLog = diagSize == count; + + if (!outIsEndOfLog) + { + // reduce the span after reading count bytes + *mutableSpan = mutableSpan->SubSpan(count); + } + + return CHIP_NO_ERROR; +} + +size_t LogProvider::GetSizeForIntent(IntentEnum intent) +{ + uint16_t sizeForIntent = 0; + CHIP_ERROR err = CHIP_NO_ERROR; + + auto key = GetKeyForIntent(intent); + VerifyOrReturnValue(key.IsInitialized(), 0); + + uint16_t bufferLen = CHIP_DEVICE_CONFIG_MAX_DIAG_LOG_SIZE; + Platform::ScopedMemoryBuffer buffer; + + buffer.Calloc(bufferLen); + VerifyOrReturnValue(buffer.Get() != nullptr, 0); + + err = Server::GetInstance().GetPersistentStorage().SyncGetKeyValue(key.KeyName(), buffer.Get(), sizeForIntent); + VerifyOrReturnValue(err == CHIP_NO_ERROR, 0); + + return sizeForIntent; +} + +StorageKeyName LogProvider::GetKeyForIntent(IntentEnum intent) const +{ + StorageKeyName key = StorageKeyName::Uninitialized(); + + switch (intent) + { + case IntentEnum::kEndUserSupport: + return GetKeyDiagUserSupport(); + case IntentEnum::kNetworkDiag: + return GetKeyDiagNetwork(); + case IntentEnum::kCrashLogs: + return GetKeyDiagCrashLog(); + case IntentEnum::kUnknownEnumValue: + // It should never happen. + chipDie(); + } + + return key; +} diff --git a/examples/platform/nxp/common/diagnostic_logs/DiagnosticLogsProviderDelegateImpl.h b/examples/platform/nxp/common/diagnostic_logs/DiagnosticLogsProviderDelegateImpl.h new file mode 100644 index 00000000000000..73d60f542aacdc --- /dev/null +++ b/examples/platform/nxp/common/diagnostic_logs/DiagnosticLogsProviderDelegateImpl.h @@ -0,0 +1,75 @@ +/* + * + * Copyright (c) 2024 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 +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace DiagnosticLogs { + +/** + * The LogProvider class serves as the sole instance delegate for handling diagnostic logs. + * + * It implements the DiagnosticLogsProviderDelegate interface + */ + +class LogProvider : public DiagnosticLogsProviderDelegate +{ +public: + static inline LogProvider & GetInstance() { return sInstance; } + + /////////// DiagnosticLogsProviderDelegate Interface ///////// + CHIP_ERROR StartLogCollection(IntentEnum intent, LogSessionHandle & outHandle, Optional & outTimeStamp, + Optional & outTimeSinceBoot) override; + CHIP_ERROR EndLogCollection(LogSessionHandle sessionHandle) override; + CHIP_ERROR CollectLog(LogSessionHandle sessionHandle, MutableByteSpan & outBuffer, bool & outIsEndOfLog) override; + size_t GetSizeForIntent(IntentEnum intent) override; + CHIP_ERROR GetLogForIntent(IntentEnum intent, MutableByteSpan & outBuffer, Optional & outTimeStamp, + Optional & outTimeSinceBoot) override; + + static inline StorageKeyName GetKeyDiagUserSupport() { return StorageKeyName::FromConst("nxp/diag/usr"); } + + static inline StorageKeyName GetKeyDiagNetwork() { return StorageKeyName::FromConst("nxp/diag/nwk"); } + + static inline StorageKeyName GetKeyDiagCrashLog() { return StorageKeyName::FromConst("nxp/diag/crash"); } + +private: + static LogProvider sInstance; + LogProvider() = default; + ~LogProvider(); + + LogProvider(const LogProvider &) = delete; + LogProvider & operator=(const LogProvider &) = delete; + + // This tracks the ByteSpan for each session + std::map mSessionSpanMap; + std::map mSessionDiagMap; + LogSessionHandle mLogSessionHandle = kInvalidLogSessionHandle; + + StorageKeyName GetKeyForIntent(IntentEnum intent) const; +}; + +} // namespace DiagnosticLogs +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/all-clusters-app/nxp/common/main/include/AppFactoryData.h b/examples/platform/nxp/common/factory_data/include/AppFactoryData.h similarity index 89% rename from examples/all-clusters-app/nxp/common/main/include/AppFactoryData.h rename to examples/platform/nxp/common/factory_data/include/AppFactoryData.h index 9c84a89b0f4bc2..35d7ba9ac0745f 100644 --- a/examples/all-clusters-app/nxp/common/main/include/AppFactoryData.h +++ b/examples/platform/nxp/common/factory_data/include/AppFactoryData.h @@ -1,7 +1,7 @@ /* * * Copyright (c) 2023 Project CHIP Authors - * Copyright 2023 NXP + * Copyright 2023-2024 NXP * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,6 +26,9 @@ extern "C" { #endif +namespace chip { +namespace NXP { +namespace App { /** * Allows to register Matter factory data before initializing the Matter stack */ @@ -35,6 +38,9 @@ CHIP_ERROR AppFactoryData_PreMatterStackInit(void); * Allows to register Matter factory data after initializing the Matter stack */ CHIP_ERROR AppFactoryData_PostMatterStackInit(void); +} // namespace App +} // namespace NXP +} // namespace chip #ifdef __cplusplus } diff --git a/examples/all-clusters-app/nxp/common/main/AppFactoryDataDefaultImpl.cpp b/examples/platform/nxp/common/factory_data/source/AppFactoryDataDefaultImpl.cpp similarity index 75% rename from examples/all-clusters-app/nxp/common/main/AppFactoryDataDefaultImpl.cpp rename to examples/platform/nxp/common/factory_data/source/AppFactoryDataDefaultImpl.cpp index 0c28e5029eac99..4fd176075f00d2 100644 --- a/examples/all-clusters-app/nxp/common/main/AppFactoryDataDefaultImpl.cpp +++ b/examples/platform/nxp/common/factory_data/source/AppFactoryDataDefaultImpl.cpp @@ -1,7 +1,7 @@ /* * * Copyright (c) 2023 Project CHIP Authors - * Copyright 2023 NXP + * Copyright 2023-2024 NXP * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,14 +25,16 @@ #if CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA #include "FactoryDataProvider.h" +#if CONFIG_CHIP_ENCRYPTED_FACTORY_DATA /* * Test key used to encrypt factory data before storing it to the flash. */ static const uint8_t aes128TestKey[] __attribute__((aligned)) = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; +#endif /* CONFIG_CHIP_ENCRYPTED_FACTORY_DATA */ #else #include -#endif +#endif /* CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA */ using namespace chip; using namespace ::chip::Credentials; @@ -42,7 +44,7 @@ using namespace ::chip::DeviceLayer; * Allows to register Matter factory data before initializing the Matter stack * Empty content here nothing particular to do. */ -CHIP_ERROR AppFactoryData_PreMatterStackInit(void) +CHIP_ERROR chip::NXP::App::AppFactoryData_PreMatterStackInit(void) { return CHIP_NO_ERROR; } @@ -54,23 +56,22 @@ CHIP_ERROR AppFactoryData_PreMatterStackInit(void) * In this example we assume that the matter factory dataset is encrypted. * This example demonstrates the usage of AES ecb with a software key. */ -CHIP_ERROR AppFactoryData_PostMatterStackInit(void) +CHIP_ERROR chip::NXP::App::AppFactoryData_PostMatterStackInit(void) { - CHIP_ERROR err = CHIP_NO_ERROR; #if CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA +#if CONFIG_CHIP_ENCRYPTED_FACTORY_DATA FactoryDataPrvdImpl().SetEncryptionMode(FactoryDataProvider::encrypt_ecb); FactoryDataPrvdImpl().SetAes128Key(&aes128TestKey[0]); +#endif /* CONFIG_CHIP_ENCRYPTED_FACTORY_DATA */ - err = FactoryDataPrvdImpl().Init(); - if (err == CHIP_NO_ERROR) - { - SetDeviceInstanceInfoProvider(&FactoryDataPrvd()); - SetDeviceAttestationCredentialsProvider(&FactoryDataPrvd()); - SetCommissionableDataProvider(&FactoryDataPrvd()); - } + ReturnErrorOnFailure(FactoryDataPrvdImpl().Init()); + + SetDeviceInstanceInfoProvider(&FactoryDataPrvd()); + SetDeviceAttestationCredentialsProvider(&FactoryDataPrvd()); + SetCommissionableDataProvider(&FactoryDataPrvd()); #else // Initialize device attestation with example one (only for debug purpose) SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); -#endif - return err; +#endif /* CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA */ + return CHIP_NO_ERROR; } diff --git a/examples/platform/nxp/common/icd/include/ICDUtil.h b/examples/platform/nxp/common/icd/include/ICDUtil.h new file mode 100644 index 00000000000000..de3a5bcc273194 --- /dev/null +++ b/examples/platform/nxp/common/icd/include/ICDUtil.h @@ -0,0 +1,39 @@ +/* + * + * 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 + +namespace chip { +namespace NXP { +namespace App { +class ICDUtil : public chip::app::ReadHandler::ApplicationCallback +{ + CHIP_ERROR OnSubscriptionRequested(chip::app::ReadHandler & aReadHandler, + chip::Transport::SecureSession & aSecureSession) override; + friend ICDUtil & GetICDUtil(); + static ICDUtil sICDUtil; +}; + +inline ICDUtil & GetICDUtil() +{ + return ICDUtil::sICDUtil; +} +} // namespace App +} // namespace NXP +} // namespace chip diff --git a/examples/platform/nxp/common/icd/source/ICDUtil.cpp b/examples/platform/nxp/common/icd/source/ICDUtil.cpp new file mode 100644 index 00000000000000..648bb6fe202629 --- /dev/null +++ b/examples/platform/nxp/common/icd/source/ICDUtil.cpp @@ -0,0 +1,36 @@ +/* + * + * 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 "ICDUtil.h" + +chip::NXP::App::ICDUtil chip::NXP::App::ICDUtil::sICDUtil; + +CHIP_ERROR chip::NXP::App::ICDUtil::OnSubscriptionRequested(chip::app::ReadHandler & aReadHandler, + chip::Transport::SecureSession & aSecureSession) +{ + uint16_t agreedMaxInterval = kSubscriptionMaxIntervalPublisherLimit; + uint16_t requestedMinInterval = 0; + uint16_t requestedMaxInterval = 0; + aReadHandler.GetReportingIntervals(requestedMinInterval, requestedMaxInterval); + + if (requestedMaxInterval < agreedMaxInterval) + { + agreedMaxInterval = requestedMaxInterval; + } + return aReadHandler.SetMaxReportingInterval(agreedMaxInterval); +} diff --git a/examples/all-clusters-app/nxp/common/main/include/AppMatterButton.h b/examples/platform/nxp/common/matter_button/include/AppMatterButton.h similarity index 87% rename from examples/all-clusters-app/nxp/common/main/include/AppMatterButton.h rename to examples/platform/nxp/common/matter_button/include/AppMatterButton.h index 0c107269be620a..dd00a5c80d719f 100644 --- a/examples/all-clusters-app/nxp/common/main/include/AppMatterButton.h +++ b/examples/platform/nxp/common/matter_button/include/AppMatterButton.h @@ -1,7 +1,7 @@ /* * * Copyright (c) 2022 Project CHIP Authors - * Copyright 2023 NXP + * Copyright 2023-2024 NXP * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,11 +26,18 @@ extern "C" { #endif +namespace chip { +namespace NXP { +namespace App { /** * API allowing to register matter buttons */ CHIP_ERROR AppMatterButton_registerButtons(void); +} // namespace App +} // namespace NXP +} // namespace chip + #ifdef __cplusplus } #endif diff --git a/examples/platform/nxp/common/matter_button/source/AppMatterButton.cpp b/examples/platform/nxp/common/matter_button/source/AppMatterButton.cpp new file mode 100644 index 00000000000000..be5adc975c2f79 --- /dev/null +++ b/examples/platform/nxp/common/matter_button/source/AppMatterButton.cpp @@ -0,0 +1,81 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppMatterButton.h" +#include "AppTaskBase.h" +#include "board_comp.h" +#include "fsl_component_timer_manager.h" +#include "fwk_platform.h" +#include + +static BUTTON_HANDLE_DEFINE(sdkButtonHandle); + +static button_status_t AppMatterButton_ButtonCallback(void * buttonHandle, button_callback_message_t * message, + void * callbackParam) +{ + switch (message->event) + { + case kBUTTON_EventShortPress: + case kBUTTON_EventOneClick: + chip::NXP::App::GetAppTask().SwitchCommissioningStateHandler(); + break; + case kBUTTON_EventLongPress: + chip::NXP::App::GetAppTask().FactoryResetHandler(); + break; + default: + break; + } + return kStatus_BUTTON_Success; +} + +CHIP_ERROR chip::NXP::App::AppMatterButton_registerButtons(void) +{ + button_config_t buttonConfig; + button_status_t bStatus; + CHIP_ERROR err = CHIP_NO_ERROR; + + do + { + /* Init the Platform Timer Manager */ + if (PLATFORM_InitTimerManager() != 0) + { + err = CHIP_ERROR_UNEXPECTED_EVENT; + ChipLogError(DeviceLayer, "tmr init error"); + break; + } + + /* Init board buttons */ + bStatus = BOARD_InitButton((button_handle_t) sdkButtonHandle); + if (bStatus != kStatus_BUTTON_Success) + { + err = CHIP_ERROR_UNEXPECTED_EVENT; + ChipLogError(DeviceLayer, "button init error"); + break; + } + bStatus = BUTTON_InstallCallback((button_handle_t) sdkButtonHandle, AppMatterButton_ButtonCallback, NULL); + + if (bStatus != kStatus_BUTTON_Success) + { + err = CHIP_ERROR_UNEXPECTED_EVENT; + ChipLogError(DeviceLayer, "button init error"); + break; + } + } while (0); + + return err; +} diff --git a/examples/all-clusters-app/nxp/common/main/AppMatterButtonEmpty.cpp b/examples/platform/nxp/common/matter_button/source/AppMatterButtonEmpty.cpp similarity index 89% rename from examples/all-clusters-app/nxp/common/main/AppMatterButtonEmpty.cpp rename to examples/platform/nxp/common/matter_button/source/AppMatterButtonEmpty.cpp index dfd3eca9eeb105..c9f602cbd8d97d 100644 --- a/examples/all-clusters-app/nxp/common/main/AppMatterButtonEmpty.cpp +++ b/examples/platform/nxp/common/matter_button/source/AppMatterButtonEmpty.cpp @@ -1,7 +1,7 @@ /* * * Copyright (c) 2022 Project CHIP Authors - * Copyright 2023 NXP + * Copyright 2023-2024 NXP * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,7 +19,7 @@ #include "AppMatterButton.h" -CHIP_ERROR AppMatterButton_registerButtons(void) +CHIP_ERROR chip::NXP::App::AppMatterButton_registerButtons(void) { /* Empty content could be re-defined in a dedicated platform AppMatterButton_registerButtons function */ return CHIP_NO_ERROR; diff --git a/examples/all-clusters-app/nxp/common/main/include/AppMatterCli.h b/examples/platform/nxp/common/matter_cli/include/AppMatterCli.h similarity index 61% rename from examples/all-clusters-app/nxp/common/main/include/AppMatterCli.h rename to examples/platform/nxp/common/matter_cli/include/AppMatterCli.h index ee043e52320782..68f24fc8fcbfdc 100644 --- a/examples/all-clusters-app/nxp/common/main/include/AppMatterCli.h +++ b/examples/platform/nxp/common/matter_cli/include/AppMatterCli.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 NXP + * Copyright 2022-2024 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -14,10 +14,21 @@ extern "C" { #endif +namespace chip { +namespace NXP { +namespace App { /** * API allowing to register matter cli command */ CHIP_ERROR AppMatterCli_RegisterCommands(void); +/** + * API allowing to start matter cli task + */ +CHIP_ERROR AppMatterCli_StartTask(void); + +} // namespace App +} // namespace NXP +} // namespace chip #ifdef __cplusplus } diff --git a/examples/all-clusters-app/nxp/common/main/AppMatterCli.cpp b/examples/platform/nxp/common/matter_cli/source/AppMatterCli.cpp similarity index 80% rename from examples/all-clusters-app/nxp/common/main/AppMatterCli.cpp rename to examples/platform/nxp/common/matter_cli/source/AppMatterCli.cpp index 663bc85920ddb4..e206ad0a2d4127 100644 --- a/examples/all-clusters-app/nxp/common/main/AppMatterCli.cpp +++ b/examples/platform/nxp/common/matter_cli/source/AppMatterCli.cpp @@ -1,7 +1,7 @@ /* * * Copyright (c) 2022 Project CHIP Authors - * Copyright 2023 NXP + * Copyright 2023-2024 NXP * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,11 +18,15 @@ */ #include "AppMatterCli.h" -#include "AppTask.h" +#include "AppTaskBase.h" #include #include #include +#ifdef CONFIG_CHIP_APP_DEVICE_TYPE_LAUNDRY_WASHER +#include +#endif /* CONFIG_CHIP_APP_DEVICE_TYPE_LAUNDRY_WASHER */ + #ifdef ENABLE_CHIP_SHELL #include "task.h" #include @@ -38,6 +42,9 @@ static bool isShellInitialized = false; #define MATTER_CLI_LOG(...) #endif /* ENABLE_CHIP_SHELL */ +using namespace chip; +using namespace chip::app::Clusters; + void AppMatterCliTask(void * args) { #ifdef ENABLE_CHIP_SHELL @@ -52,11 +59,11 @@ CHIP_ERROR commissioningManager(int argc, char * argv[]) CHIP_ERROR error = CHIP_NO_ERROR; if (strncmp(argv[0], "on", 2) == 0) { - GetAppTask().StartCommissioningHandler(); + chip::NXP::App::GetAppTask().StartCommissioningHandler(); } else if (strncmp(argv[0], "off", 3) == 0) { - GetAppTask().StopCommissioningHandler(); + chip::NXP::App::GetAppTask().StopCommissioningHandler(); } else { @@ -68,7 +75,7 @@ CHIP_ERROR commissioningManager(int argc, char * argv[]) CHIP_ERROR cliFactoryReset(int argc, char * argv[]) { - GetAppTask().FactoryResetHandler(); + chip::NXP::App::GetAppTask().FactoryResetHandler(); return CHIP_NO_ERROR; } @@ -84,7 +91,7 @@ CHIP_ERROR cliReset(int argc, char * argv[]) return CHIP_NO_ERROR; } -CHIP_ERROR AppMatterCli_RegisterCommands(void) +CHIP_ERROR chip::NXP::App::AppMatterCli_RegisterCommands(void) { #ifdef ENABLE_CHIP_SHELL if (!isShellInitialized) @@ -123,15 +130,21 @@ CHIP_ERROR AppMatterCli_RegisterCommands(void) }; Engine::Root().RegisterCommands(kCommands, sizeof(kCommands) / sizeof(kCommands[0])); - - if (xTaskCreate(&AppMatterCliTask, "AppMatterCli_task", MATTER_CLI_TASK_SIZE, NULL, 1, &AppMatterCliTaskHandle) != pdPASS) - { - ChipLogError(Shell, "Failed to start Matter CLI task"); - return CHIP_ERROR_INTERNAL; - } isShellInitialized = true; } #endif /* ENABLE_CHIP_SHELL */ return CHIP_NO_ERROR; } + +CHIP_ERROR chip::NXP::App::AppMatterCli_StartTask() +{ +#ifdef ENABLE_CHIP_SHELL + if (xTaskCreate(&AppMatterCliTask, "AppMatterCli_task", MATTER_CLI_TASK_SIZE, NULL, 1, &AppMatterCliTaskHandle) != pdPASS) + { + ChipLogError(Shell, "Failed to start Matter CLI task"); + return CHIP_ERROR_INTERNAL; + } +#endif /* ENABLE_CHIP_SHELL */ + return CHIP_NO_ERROR; +} diff --git a/examples/platform/nxp/common/OTARequestorInitiator.h b/examples/platform/nxp/common/ota_requestor/include/OTARequestorInitiator.h similarity index 78% rename from examples/platform/nxp/common/OTARequestorInitiator.h rename to examples/platform/nxp/common/ota_requestor/include/OTARequestorInitiator.h index 808a58d03dfe91..4054bb4a2a473f 100644 --- a/examples/platform/nxp/common/OTARequestorInitiator.h +++ b/examples/platform/nxp/common/ota_requestor/include/OTARequestorInitiator.h @@ -1,7 +1,7 @@ /* * * Copyright (c) 2022 Project CHIP Authors - * Copyright 2023 NXP + * Copyright 2023-2024 NXP * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,11 +23,25 @@ #include "app/clusters/ota-requestor/DefaultOTARequestor.h" #include "app/clusters/ota-requestor/DefaultOTARequestorDriver.h" #include "app/clusters/ota-requestor/DefaultOTARequestorStorage.h" + +#ifdef CONFIG_CHIP_OTA_IMAGE_PROCESSOR_HEADER +#include CONFIG_CHIP_OTA_IMAGE_PROCESSOR_HEADER +#else +#ifdef CONFIG_CHIP +#include +#else #include "platform/nxp/common/OTAImageProcessorImpl.h" +#endif /* CONFIG_CHIP */ +#endif /* CONFIG_CHIP_OTA_IMAGE_PROCESSOR_HEADER */ + #include using namespace chip; +using namespace chip::DeviceLayer; +namespace chip { +namespace NXP { +namespace App { class OTARequestorInitiator { public: @@ -48,3 +62,6 @@ class OTARequestorInitiator BDXDownloader gDownloader; OTAImageProcessorImpl gImageProcessor; }; +} // namespace App +} // namespace NXP +} // namespace chip diff --git a/examples/platform/nxp/common/ota_requestor/source/OTARequestorInitiator.cpp b/examples/platform/nxp/common/ota_requestor/source/OTARequestorInitiator.cpp new file mode 100644 index 00000000000000..3f71a8268cc1bf --- /dev/null +++ b/examples/platform/nxp/common/ota_requestor/source/OTARequestorInitiator.cpp @@ -0,0 +1,54 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * Copyright 2023-2024 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. + */ + +#include "OTARequestorInitiator.h" + +extern "C" { +#include "mflash_drv.h" +} +using namespace chip; + +void chip::NXP::App::OTARequestorInitiator::HandleSelfTest() +{ + /* If application is in test mode after an OTA update + mark image as "ok" to switch the update state to permanent + (if we have arrived this far, the bootloader had validated the image) */ + + mflash_drv_init(); + + OtaImgState_t update_state; + + /* Retrieve current update state */ + update_state = OTA_GetImgState(); + + if (update_state == OtaImgState_RunCandidate) + { + if (OTA_UpdateImgState(OtaImgState_Permanent) != gOtaSuccess_c) + { + ChipLogError(SoftwareUpdate, "Self-testing : Failed to switch update state to permanent"); + return; + } + + ChipLogProgress(SoftwareUpdate, "Successful software update... applied permanently"); + } + + OTA_Initialize(); + + /* If the image is not marked ok, the bootloader will automatically revert back to primary application at next reboot */ +} diff --git a/examples/platform/nxp/common/OTARequestorInitiator.cpp b/examples/platform/nxp/common/ota_requestor/source/OTARequestorInitiatorCommon.cpp similarity index 61% rename from examples/platform/nxp/common/OTARequestorInitiator.cpp rename to examples/platform/nxp/common/ota_requestor/source/OTARequestorInitiatorCommon.cpp index a7a898bb3718d1..cbf4b0ef01ce2d 100644 --- a/examples/platform/nxp/common/OTARequestorInitiator.cpp +++ b/examples/platform/nxp/common/ota_requestor/source/OTARequestorInitiatorCommon.cpp @@ -1,7 +1,7 @@ /* * * Copyright (c) 2022 Project CHIP Authors - * Copyright 2023 NXP + * Copyright 2023-2024 NXP * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,13 +19,9 @@ #include "OTARequestorInitiator.h" -extern "C" { -#include "mflash_drv.h" -} - using namespace chip; -void OTARequestorInitiator::InitOTA(intptr_t context) +void chip::NXP::App::OTARequestorInitiator::InitOTA(intptr_t context) { auto * otaRequestorInit = reinterpret_cast(context); // Set the global instance of the OTA requestor core component @@ -40,32 +36,3 @@ void OTARequestorInitiator::InitOTA(intptr_t context) // Set the image processor instance used for handling image being downloaded otaRequestorInit->gDownloader.SetImageProcessorDelegate(&otaRequestorInit->gImageProcessor); } - -void OTARequestorInitiator::HandleSelfTest() -{ - /* If application is in test mode after an OTA update - mark image as "ok" to switch the update state to permanent - (if we have arrived this far, the bootloader had validated the image) */ - - mflash_drv_init(); - - OtaImgState_t update_state; - - /* Retrieve current update state */ - update_state = OTA_GetImgState(); - - if (update_state == OtaImgState_RunCandidate) - { - if (OTA_UpdateImgState(OtaImgState_Permanent) != gOtaSuccess_c) - { - ChipLogError(SoftwareUpdate, "Self-testing : Failed to switch update state to permanent"); - return; - } - - ChipLogProgress(SoftwareUpdate, "Successful software update... applied permanently"); - } - - OTA_Initialize(); - - /* If the image is not marked ok, the bootloader will automatically revert back to primary application at next reboot */ -} diff --git a/examples/platform/nxp/common/ota_requestor/source/OTARequestorInitiatorZephyr.cpp b/examples/platform/nxp/common/ota_requestor/source/OTARequestorInitiatorZephyr.cpp new file mode 100644 index 00000000000000..f176c3e67804f7 --- /dev/null +++ b/examples/platform/nxp/common/ota_requestor/source/OTARequestorInitiatorZephyr.cpp @@ -0,0 +1,41 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * Copyright 2023-2024 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. + */ + +#include "OTARequestorInitiator.h" + +#include +#include + +using namespace chip; + +void chip::NXP::App::OTARequestorInitiator::HandleSelfTest() +{ + if (mcuboot_swap_type() == BOOT_SWAP_TYPE_REVERT) + { + int img_confirmation = boot_write_img_confirmed(); + if (img_confirmation) + { + ChipLogError(SoftwareUpdate, "Self-testing : Failed to switch update state to permanent"); + } + else + { + ChipLogProgress(SoftwareUpdate, "Successful software update... applied permanently"); + } + } +} diff --git a/examples/platform/nxp/k32w/k32w0/BUILD.gn b/examples/platform/nxp/k32w/k32w0/BUILD.gn index 8abd38f2a250eb..eb0c79742f3b99 100644 --- a/examples/platform/nxp/k32w/k32w0/BUILD.gn +++ b/examples/platform/nxp/k32w/k32w0/BUILD.gn @@ -13,9 +13,11 @@ # limitations under the License. import("//build_overrides/chip.gni") -import("//build_overrides/k32w0_sdk.gni") +import("//build_overrides/nxp_sdk.gni") -import("${k32w0_sdk_build_root}/k32w0_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/k32w0/app/args.gni b/examples/platform/nxp/k32w/k32w0/app/args.gni index 13a35134496eb4..44a96b88a65b1b 100644 --- a/examples/platform/nxp/k32w/k32w0/app/args.gni +++ b/examples/platform/nxp/k32w/k32w0/app/args.gni @@ -16,9 +16,6 @@ import("//build_overrides/chip.gni") import("${chip_root}/src/platform/nxp/k32w/k32w0/args.gni") -arm_float_abi = "soft" -arm_cpu = "cortex-m4" - openthread_project_core_config_file = "OpenThreadConfig.h" chip_ble_project_config_include = "" diff --git a/examples/platform/nxp/k32w/k32w0/app/ldscripts/chip-k32w0x-linker.ld b/examples/platform/nxp/k32w/k32w0/app/ldscripts/chip-k32w0x-linker.ld index d3ea6ac41daf78..c51182b104ec53 100644 --- a/examples/platform/nxp/k32w/k32w0/app/ldscripts/chip-k32w0x-linker.ld +++ b/examples/platform/nxp/k32w/k32w0/app/ldscripts/chip-k32w0x-linker.ld @@ -94,7 +94,7 @@ OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") */ BOOT_RESUME_STACK_SIZE = 1024; -STACK_SIZE = (4096); +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x01000; MEM_RAM0_BASE = 0x4000400; MEM_RAM0_SIZE = 0x0015c00; @@ -130,9 +130,10 @@ MEMORY { Flash640 (rx) : ORIGIN = m_app_start, LENGTH = m_app_size - SCRATCH_RAM(rwx) : ORIGIN = 0x4000000, LENGTH = 0x400 /* 1K bytes (alias SCRATCH_RAM) */ - RAM0 (rwx) : ORIGIN = 0x4000400, LENGTH = 0x0015c00 /* 87K bytes (alias RAM) */ - RAM1 (rwx) : ORIGIN = 0x4020000, LENGTH = 0x10000 /* 64K bytes (alias RAM2) */ + SCRATCH_RAM(rwx) : ORIGIN = 0x4000000, LENGTH = 0x400 /* 1K bytes (alias SCRATCH_RAM) */ + RAM0 (rwx) : ORIGIN = 0x4000400, LENGTH = 0x0015BE0 /* [87K - 32] bytes (alias RAM) */ + reserved (rwx) : ORIGIN = 0x4015FE0, LENGTH = 0x20 /* 32 bytes (reserved for ROM code) */ + RAM1 (rwx) : ORIGIN = 0x4020000, LENGTH = 0x10000 /* 64K bytes (alias RAM2) */ } /* Define a symbol for the top of each memory region */ @@ -431,6 +432,7 @@ SECTIONS PROVIDE(_scratch_buf_end = __scratch_area_top__); __StackLimit = _vStackTop - STACK_SIZE; + ASSERT(__StackLimit >= _end_heap, "Stack and heap spaces are overlapping!") __MATTER_FACTORY_DATA_START = FACTORY_DATA_START_ADDRESS; __MATTER_FACTORY_DATA_SIZE = m_factory_data_size; diff --git a/examples/platform/nxp/k32w/k32w0/app/support/BUILD.gn b/examples/platform/nxp/k32w/k32w0/app/support/BUILD.gn index 014199c60a7619..7b10c468a02fe6 100644 --- a/examples/platform/nxp/k32w/k32w0/app/support/BUILD.gn +++ b/examples/platform/nxp/k32w/k32w0/app/support/BUILD.gn @@ -13,7 +13,7 @@ # limitations under the License. import("//build_overrides/chip.gni") -import("//build_overrides/k32w0_sdk.gni") +import("//build_overrides/nxp_sdk.gni") config("support_config") { include_dirs = [ "../../../../.." ] diff --git a/examples/platform/nxp/k32w/k32w0/args.gni b/examples/platform/nxp/k32w/k32w0/args.gni index 954fad9a2faee2..5af5e1d18b3123 100644 --- a/examples/platform/nxp/k32w/k32w0/args.gni +++ b/examples/platform/nxp/k32w/k32w0/args.gni @@ -16,11 +16,6 @@ import("//build_overrides/chip.gni") import("${chip_root}/src/platform/nxp/k32w/k32w0/args.gni") -arm_float_abi = "soft" -arm_cpu = "cortex-m4" -arm_arch = "armv7e-m" - -chip_openthread_ftd = false openthread_core_config_deps = [] openthread_core_config_deps = [ "${chip_root}/examples/platform/nxp/k32w/k32w0:openthread_core_config_k32w0_chip_examples" ] diff --git a/examples/platform/nxp/k32w/k32w0/scripts/sign-outdir.py b/examples/platform/nxp/k32w/k32w0/scripts/sign-outdir.py index ea4a888c9e3555..8660b4bc5f4b06 100644 --- a/examples/platform/nxp/k32w/k32w0/scripts/sign-outdir.py +++ b/examples/platform/nxp/k32w/k32w0/scripts/sign-outdir.py @@ -7,7 +7,8 @@ def main(args): if "NXP_K32W0_SDK_ROOT" in os.environ and os.environ["NXP_K32W0_SDK_ROOT"] != "": sign_images_path = os.environ["NXP_K32W0_SDK_ROOT"] + "/tools/imagetool/sign_images.sh" else: - sign_images_path = os.getcwd() + "/../../../../../../../third_party/nxp/k32w0_sdk/repo/core/tools/imagetool/sign_images.sh" + sign_images_path = os.path.abspath( + __file__ + "/../../../../../../../third_party/nxp/k32w0_sdk/repo/core/tools/imagetool/sign_images.sh") # Give execute permission if needed if os.access(sign_images_path, os.X_OK) is False: diff --git a/examples/platform/nxp/k32w/k32w1/util/LEDWidget.cpp b/examples/platform/nxp/k32w/k32w1/util/LEDWidget.cpp index b7a01ae6c7545f..695da50e3dae32 100644 --- a/examples/platform/nxp/k32w/k32w1/util/LEDWidget.cpp +++ b/examples/platform/nxp/k32w/k32w1/util/LEDWidget.cpp @@ -23,6 +23,10 @@ #include "app.h" +#if CHIP_CONFIG_ENABLE_DIMMABLE_LED +#include "LED_Dimmer.h" +#endif + #if (defined(gAppLedCnt_c) && (gAppLedCnt_c > 0)) void LEDWidget::Init(uint8_t led, bool inverted) @@ -48,6 +52,13 @@ void LEDWidget::Set(bool state) DoSet(state); } +void LEDWidget::SetLevel(uint8_t level) +{ +#if CHIP_CONFIG_ENABLE_DIMMABLE_LED + move_to_level(level); +#endif +} + void LEDWidget::Blink(uint32_t changeRateMS) { Blink(changeRateMS, changeRateMS); @@ -70,7 +81,12 @@ void LEDWidget::Animate() if (nextChangeTimeMS < nowMS) { +#if CHIP_CONFIG_ENABLE_DIMMABLE_LED + SetLevel(!mState * 254); + mState = !mState; +#else DoSet(!mState); +#endif mLastChangeTimeMS = nowMS; } } diff --git a/examples/platform/nxp/k32w/k32w1/util/LED_Dimmer.cpp b/examples/platform/nxp/k32w/k32w1/util/LED_Dimmer.cpp new file mode 100644 index 00000000000000..02a62724716e53 --- /dev/null +++ b/examples/platform/nxp/k32w/k32w1/util/LED_Dimmer.cpp @@ -0,0 +1,193 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "LED_Dimmer.h" +#include "fsl_common.h" +#include "fsl_port.h" +#include "fsl_tpm.h" + +#include + +#define BOARD_TPM_BASEADDR TPM0 +#define TPM_SOURCE_CLOCK CLOCK_GetIpFreq(kCLOCK_Tpm0) +#define BOARD_FIRST_TPM_CHANNEL kTPM_Chnl_0 +#define BOARD_SECOND_TPM_CHANNEL kTPM_Chnl_1 +#define BOARD_THIRD_TPM_CHANNEL kTPM_Chnl_2 +#ifndef TPM_LED_ON_LEVEL +#define TPM_LED_ON_LEVEL kTPM_HighTrue +#endif +#ifndef DEMO_PWM_FREQUENCY +#define DEMO_PWM_FREQUENCY (24000U) +#endif + +volatile uint8_t updatedDutycycle = 0U; + +void init_dimmable() +{ + const port_pin_config_t porta20_pin17_config = { /* Internal pull-up/down resistor is disabled */ + (uint16_t) kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + (uint16_t) kPORT_LowPullResistor, + /* Fast slew rate is configured */ + (uint16_t) kPORT_FastSlewRate, + /* Passive input filter is disabled */ + (uint16_t) kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + (uint16_t) kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + (uint16_t) kPORT_LowDriveStrength, + /* Normal drive strength is configured */ + (uint16_t) kPORT_NormalDriveStrength, + /* Pin is configured as TPM0_CH0 */ + (uint16_t) kPORT_MuxAlt5, + /* Pin Control Register fields [15:0] are not locked */ + (uint16_t) kPORT_UnlockRegister + }; + /* PORTA20 (pin 17) is configured as TPM0_CH0 */ + PORT_SetPinConfig(PORTA, 20U, &porta20_pin17_config); + + const port_pin_config_t porta21_pin18_config = { /* Internal pull-up/down resistor is disabled */ + (uint16_t) kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + (uint16_t) kPORT_LowPullResistor, + /* Fast slew rate is configured */ + (uint16_t) kPORT_FastSlewRate, + /* Passive input filter is disabled */ + (uint16_t) kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + (uint16_t) kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + (uint16_t) kPORT_LowDriveStrength, + /* Normal drive strength is configured */ + (uint16_t) kPORT_NormalDriveStrength, + /* Pin is configured as TPM0_CH0 */ + (uint16_t) kPORT_MuxAlt5, + /* Pin Control Register fields [15:0] are not locked */ + (uint16_t) kPORT_UnlockRegister + }; + /* PORTA21 (pin 18) is configured as TPM0_CH0 */ + PORT_SetPinConfig(PORTA, 21U, &porta21_pin18_config); + + const port_pin_config_t porta19_pin14_config = { /* Internal pull-up/down resistor is disabled */ + (uint16_t) kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + (uint16_t) kPORT_LowPullResistor, + /* Fast slew rate is configured */ + (uint16_t) kPORT_FastSlewRate, + /* Passive input filter is disabled */ + (uint16_t) kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + (uint16_t) kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + (uint16_t) kPORT_LowDriveStrength, + /* Normal drive strength is configured */ + (uint16_t) kPORT_NormalDriveStrength, + /* Pin is configured as TPM0_CH0 */ + (uint16_t) kPORT_MuxAlt5, + /* Pin Control Register fields [15:0] are not locked */ + (uint16_t) kPORT_UnlockRegister + }; + /* PORTA19 (pin 14) is configured as TPM0_CH0 */ + PORT_SetPinConfig(PORTA, 19U, &porta19_pin14_config); + + init_tpm(); +} + +void init_tpm() +{ + tpm_config_t tpmInfo; + tpm_chnl_pwm_signal_param_t tpmParam[3]; + + /* TPM 0 Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_Tpm0); + /* Set the source for the LPIT module */ + CLOCK_SetIpSrc(kCLOCK_Tpm0, kCLOCK_IpSrcFro6M); + + /* Fill in the TPM config struct with the default settings */ + TPM_GetDefaultConfig(&tpmInfo); + /* Calculate the clock division based on the PWM frequency to be obtained */ + tpmInfo.prescale = TPM_CalculateCounterClkDiv(BOARD_TPM_BASEADDR, DEMO_PWM_FREQUENCY, TPM_SOURCE_CLOCK); + /* Initialize TPM module */ + TPM_Init(BOARD_TPM_BASEADDR, &tpmInfo); + + /* Configure tpm params with frequency 24kHZ */ + tpmParam[0].chnlNumber = (tpm_chnl_t) BOARD_FIRST_TPM_CHANNEL; +#if (defined(FSL_FEATURE_TPM_HAS_PAUSE_LEVEL_SELECT) && FSL_FEATURE_TPM_HAS_PAUSE_LEVEL_SELECT) + tpmParam[0].pauseLevel = kTPM_ClearOnPause; +#endif + tpmParam[0].level = TPM_LED_ON_LEVEL; + tpmParam[0].dutyCyclePercent = updatedDutycycle; + + tpmParam[1].chnlNumber = (tpm_chnl_t) BOARD_SECOND_TPM_CHANNEL; +#if (defined(FSL_FEATURE_TPM_HAS_PAUSE_LEVEL_SELECT) && FSL_FEATURE_TPM_HAS_PAUSE_LEVEL_SELECT) + tpmParam[1].pauseLevel = kTPM_ClearOnPause; +#endif + tpmParam[1].level = TPM_LED_ON_LEVEL; + tpmParam[1].dutyCyclePercent = updatedDutycycle; + + tpmParam[2].chnlNumber = (tpm_chnl_t) BOARD_THIRD_TPM_CHANNEL; +#if (defined(FSL_FEATURE_TPM_HAS_PAUSE_LEVEL_SELECT) && FSL_FEATURE_TPM_HAS_PAUSE_LEVEL_SELECT) + tpmParam[2].pauseLevel = kTPM_ClearOnPause; +#endif + tpmParam[2].level = TPM_LED_ON_LEVEL; + tpmParam[2].dutyCyclePercent = updatedDutycycle; + + if (kStatus_Success != + TPM_SetupPwm(BOARD_TPM_BASEADDR, tpmParam, 2U, kTPM_EdgeAlignedPwm, DEMO_PWM_FREQUENCY, TPM_SOURCE_CLOCK)) + { + return; + } + + TPM_StartTimer(BOARD_TPM_BASEADDR, kTPM_SystemClock); +} + +void move_to_level(uint8_t level) +{ + uint8_t control; + + updatedDutycycle = static_cast(level * 90) / 255; + + control = TPM_GetChannelContorlBits(BOARD_TPM_BASEADDR, (tpm_chnl_t) BOARD_FIRST_TPM_CHANNEL); + + /* Disable output on each channel of the pair before updating the dutycycle */ + TPM_DisableChannel(BOARD_TPM_BASEADDR, (tpm_chnl_t) BOARD_FIRST_TPM_CHANNEL); + TPM_DisableChannel(BOARD_TPM_BASEADDR, (tpm_chnl_t) BOARD_SECOND_TPM_CHANNEL); + TPM_DisableChannel(BOARD_TPM_BASEADDR, (tpm_chnl_t) BOARD_THIRD_TPM_CHANNEL); + + /* Update PWM duty cycle */ + if ((kStatus_Success == + TPM_UpdatePwmDutycycle(BOARD_TPM_BASEADDR, (tpm_chnl_t) BOARD_FIRST_TPM_CHANNEL, kTPM_EdgeAlignedPwm, updatedDutycycle)) && + (kStatus_Success == + TPM_UpdatePwmDutycycle(BOARD_TPM_BASEADDR, (tpm_chnl_t) BOARD_SECOND_TPM_CHANNEL, kTPM_EdgeAlignedPwm, + updatedDutycycle)) && + (kStatus_Success == + TPM_UpdatePwmDutycycle(BOARD_TPM_BASEADDR, (tpm_chnl_t) BOARD_THIRD_TPM_CHANNEL, kTPM_EdgeAlignedPwm, updatedDutycycle))) + { + ChipLogError(NotSpecified, "TPM: Duty cycle updated successfully"); + } + else + { + ChipLogError(NotSpecified, "ERR: Duty cycle failed to updated"); + } + + /* Start output on each channel of the pair with updated dutycycle */ + TPM_EnableChannel(BOARD_TPM_BASEADDR, (tpm_chnl_t) BOARD_FIRST_TPM_CHANNEL, control); + TPM_EnableChannel(BOARD_TPM_BASEADDR, (tpm_chnl_t) BOARD_SECOND_TPM_CHANNEL, control); + TPM_EnableChannel(BOARD_TPM_BASEADDR, (tpm_chnl_t) BOARD_THIRD_TPM_CHANNEL, control); +} diff --git a/examples/platform/nxp/k32w/k32w1/util/include/LEDWidget.h b/examples/platform/nxp/k32w/k32w1/util/include/LEDWidget.h index 4d55f246d49e05..a73ab8a904018b 100644 --- a/examples/platform/nxp/k32w/k32w1/util/include/LEDWidget.h +++ b/examples/platform/nxp/k32w/k32w1/util/include/LEDWidget.h @@ -25,6 +25,7 @@ class LEDWidget public: void Init(uint8_t gpioNum, bool inverted); void Set(bool state); + void SetLevel(uint8_t level); void Invert(void); void Blink(uint32_t changeRateMS); void Blink(uint32_t onTimeMS, uint32_t offTimeMS); diff --git a/examples/platform/nxp/k32w/k32w1/util/include/LED_Dimmer.h b/examples/platform/nxp/k32w/k32w1/util/include/LED_Dimmer.h new file mode 100644 index 00000000000000..424ffa20c97bbd --- /dev/null +++ b/examples/platform/nxp/k32w/k32w1/util/include/LED_Dimmer.h @@ -0,0 +1,21 @@ +/* + * + * Copyright (c) 2020 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +void init_dimmable(); +void init_tpm(); +void move_to_level(uint8_t level); diff --git a/examples/platform/nxp/rt/rw61x/app/ldscripts/RW610_flash.ld b/examples/platform/nxp/rt/rw61x/app/ldscripts/RW610_flash.ld index e3b51876eca963..eec10d6fddafde 100644 --- a/examples/platform/nxp/rt/rw61x/app/ldscripts/RW610_flash.ld +++ b/examples/platform/nxp/rt/rw61x/app/ldscripts/RW610_flash.ld @@ -78,12 +78,12 @@ _stated_ | m_text | ' fw_storage ' ACTIVE_APP (slot - - - +---------------+ - - - - - - - - - - - - - - - - - - - - + + + + - - - - +---------------+ - - - - - - - - - - - - - - - - - - - - - 4k | FactoryData | - - - +---------------+ - - - - - - - - - - - - - - - - - - - - | | NV_STORAGE_START_ADDRESS | NVM_region | | | NV_STORAGE_END_ADDRESS + - - - +---------------+ - - - - - - - - - - - - - - - - - - - - + 4k | FactoryData | - - - +---------------+ - - - - - - - - - - - - - - - - - - - - 0x0C00_0000 FLASH_END @@ -174,20 +174,20 @@ FW_UPDATE_STORAGE_END = FW_UPDATE_STORAGE_START + FW_UPDATE_STORAG fw_top = FW_UPDATE_STORAGE_END + 1; +/*** FactoryData space 1 sector is reserved ***/ +__FACTORY_DATA_SIZE = m_sector_size; +__FACTORY_DATA_END = m_flash_end; +__FACTORY_DATA_START = __FACTORY_DATA_END - __FACTORY_DATA_SIZE + 1; +__FACTORY_DATA_START_OFFSET = __FACTORY_DATA_START - m_flash_start; + /* FileSystem Configuration */ -NV_STORAGE_END_ADDRESS = m_flash_end; +NV_STORAGE_END_ADDRESS = __FACTORY_DATA_START - 1; NV_STORAGE_MAX_SECTORS = DEFINED(gNVMSectorCountLink_d) ? gNVMSectorCountLink_d : 16; NV_STORAGE_SECTOR_SIZE = m_sector_size; NV_STORAGE_SIZE = NV_STORAGE_SECTOR_SIZE * NV_STORAGE_MAX_SECTORS; NV_STORAGE_START_ADDRESS = NV_STORAGE_END_ADDRESS - NV_STORAGE_SIZE + 1; NV_STORAGE_START_ADDRESS_OFFSET = NV_STORAGE_START_ADDRESS - m_flash_start; -/*** FactoryData space 1 sector is reserved ***/ -__FACTORY_DATA_SIZE = m_sector_size; -__FACTORY_DATA_END = NV_STORAGE_START_ADDRESS -1; -__FACTORY_DATA_START = __FACTORY_DATA_END - __FACTORY_DATA_SIZE + 1; -__FACTORY_DATA_START_OFFSET = __FACTORY_DATA_START - m_flash_start; - /* -------------------------------------------------------------------------- */ /* RAM */ /* -------------------------------------------------------------------------- */ @@ -491,6 +491,21 @@ SECTIONS } > m_data __DATA_END = __DATA_ROM + (__data_end__ - __data_start__); + + /* Place holder for RAM function. + * By default CodeQuickAccess is placed in .data section, but if there's dedicated mem region + * allocated on code bus (SRAM address starts from 0x0), CodeQuickAccess can be inserted in + * .ram_function and the .ram_function can be located in the code bus region instead of m_data + * to get better performance. Remember to define __STARTUP_INITIALIZE_RAMFUNCTION macro to + * build startup_xx.S to ensure the RAM function copy from flash to RAM. */ + .ram_function : AT(__DATA_END) + { + . = ALIGN(4); + __ram_function_start__ = .; + /* RAM function sections */ + . = ALIGN(4); + __ram_function_end__ = .; + } > m_data text_end = ORIGIN(m_text) + LENGTH(m_text); diff --git a/examples/platform/nxp/rt/rw61x/app/project_include/freeRTOS/FreeRTOSConfig.h b/examples/platform/nxp/rt/rw61x/app/project_include/freeRTOS/FreeRTOSConfig.h index cb7d563f756f8c..b61ed92c03d286 100644 --- a/examples/platform/nxp/rt/rw61x/app/project_include/freeRTOS/FreeRTOSConfig.h +++ b/examples/platform/nxp/rt/rw61x/app/project_include/freeRTOS/FreeRTOSConfig.h @@ -51,7 +51,7 @@ /* stack size increased for NVM/LITTLE_FS save in idle task */ #define configMINIMAL_STACK_SIZE ((uint16_t) 2048) #ifndef configTOTAL_HEAP_SIZE -#define configTOTAL_HEAP_SIZE ((size_t) (122 * 1024)) +#define configTOTAL_HEAP_SIZE ((size_t) (126 * 1024)) #endif #define configAPPLICATION_ALLOCATED_HEAP 1 #define configSUPPORT_STATIC_ALLOCATION 0 diff --git a/examples/platform/nxp/rt/rw61x/app/project_include/openthread/OpenThreadConfig.h b/examples/platform/nxp/rt/rw61x/app/project_include/openthread/OpenThreadConfig.h index 166222d1295311..a5bc2999e80cfb 100644 --- a/examples/platform/nxp/rt/rw61x/app/project_include/openthread/OpenThreadConfig.h +++ b/examples/platform/nxp/rt/rw61x/app/project_include/openthread/OpenThreadConfig.h @@ -43,13 +43,18 @@ // disable unused features #define OPENTHREAD_CONFIG_COAP_API_ENABLE 0 #define OPENTHREAD_CONFIG_JOINER_ENABLE 0 -#define OPENTHREAD_CONFIG_COMMISSIONER_ENABLE 0 #define OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE 0 -#define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE 0 #define OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE 0 #define OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE 0 #define OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE 0 +#ifndef OPENTHREAD_CONFIG_COMMISSIONER_ENABLE +#define OPENTHREAD_CONFIG_COMMISSIONER_ENABLE 0 +#endif +#ifndef OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE +#define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE 0 +#endif + // Enable usage of external heap allocator for ot #define OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE 1 diff --git a/examples/platform/nxp/rt/rw61x/doc/images/mcuboot_demo.PNG b/examples/platform/nxp/rt/rw61x/doc/images/mcuboot_demo.PNG index c22b1c772b7c41..6584f2d53b5301 100644 Binary files a/examples/platform/nxp/rt/rw61x/doc/images/mcuboot_demo.PNG and b/examples/platform/nxp/rt/rw61x/doc/images/mcuboot_demo.PNG differ diff --git a/examples/platform/nxp/rt/rw61x/doc/images/mcux-sdk-download.PNG b/examples/platform/nxp/rt/rw61x/doc/images/mcux-sdk-download.PNG index c6afd18b6beb0b..f1e236a896e05c 100644 Binary files a/examples/platform/nxp/rt/rw61x/doc/images/mcux-sdk-download.PNG and b/examples/platform/nxp/rt/rw61x/doc/images/mcux-sdk-download.PNG differ diff --git a/examples/platform/nxp/rt/rw61x/factory_data/source/AppFactoryDataExample.cpp b/examples/platform/nxp/rt/rw61x/factory_data/source/AppFactoryDataExample.cpp new file mode 100644 index 00000000000000..50992a049f01a5 --- /dev/null +++ b/examples/platform/nxp/rt/rw61x/factory_data/source/AppFactoryDataExample.cpp @@ -0,0 +1,59 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * Copyright 2023-2024 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. + */ + +#include "AppFactoryData.h" + +#include +#include +#include + +#if CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA +#include "FactoryDataProvider.h" +#else +#include +#endif + +using namespace chip; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; + +/** + * Allows to register Matter factory data before initializing the Matter stack + */ +CHIP_ERROR NXP::App::AppFactoryData_PreMatterStackInit(void) +{ + return CHIP_NO_ERROR; +} + +/** + * Allows to register Matter factory data after initializing the Matter stack + */ +CHIP_ERROR NXP::App::AppFactoryData_PostMatterStackInit(void) +{ +#if CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA + FactoryDataPrvdImpl().Init(); + SetDeviceInstanceInfoProvider(&FactoryDataPrvd()); + SetDeviceAttestationCredentialsProvider(&FactoryDataPrvd()); + SetCommissionableDataProvider(&FactoryDataPrvd()); +#else + // Initialize device attestation with example one (only for debug purpose) + SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif + return CHIP_NO_ERROR; +} diff --git a/examples/shell/nxp/k32w/k32w0/BUILD.gn b/examples/shell/nxp/k32w/k32w0/BUILD.gn deleted file mode 100644 index b19d08fe44e325..00000000000000 --- a/examples/shell/nxp/k32w/k32w0/BUILD.gn +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright (c) 2021 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/k32w0_sdk.gni") -import("//build_overrides/openthread.gni") -import("${chip_root}/src/platform/device.gni") -import("${chip_root}/third_party/simw-top-mini/simw_config.gni") - -import("${k32w0_sdk_build_root}/k32w0_executable.gni") -import("${k32w0_sdk_build_root}/k32w0_sdk.gni") - -assert(current_os == "freertos") - -k32w0_platform_dir = "${chip_root}/examples/platform/nxp/k32w/k32w0" - -k32w0_sdk("sdk") { - sources = [ - "${k32w0_platform_dir}/app/project_include/OpenThreadConfig.h", - "include/CHIPProjectConfig.h", - "include/FreeRTOSConfig.h", - "main/include/app_config.h", - ] - - public_deps = - [ "${chip_root}/third_party/openthread/platforms:libopenthread-platform" ] - - include_dirs = [ - "main/include", - "main", - "include", - "${k32w0_platform_dir}/app/support", - "${k32w0_platform_dir}/util/include", - ] - - defines = [] - if (is_debug) { - defines += [ "BUILD_RELEASE=0" ] - } else { - defines += [ "BUILD_RELEASE=1" ] - } -} - -k32w0_executable("shell_app") { - output_name = "chip-k32w0x-shell-example" - - sources = [ - "${k32w0_platform_dir}/util/LEDWidget.cpp", - "${k32w0_platform_dir}/util/include/LEDWidget.h", - "main/AppTask.cpp", - "main/main.cpp", - ] - - deps = [ - ":sdk", - "${chip_root}/examples/common/QRCode", - "${chip_root}/examples/lock-app/lock-common", - "${chip_root}/examples/shell/shell_common:shell_common", - "${chip_root}/src/platform:syscalls_stub", - "${chip_root}/third_party/mbedtls:mbedtls", - "${k32w0_platform_dir}/app/support:freertos_mbedtls_utils", - ] - - cflags = [ "-Wconversion" ] - - output_dir = root_out_dir - - ldscript = "${k32w0_platform_dir}/app/ldscripts/chip-k32w0x-linker.ld" - - inputs = [ ldscript ] - - ldflags = [ "-T" + rebase_path(ldscript, root_build_dir) ] -} - -group("k32w0") { - deps = [ ":shell_app" ] -} - -group("default") { - deps = [ ":k32w0" ] -} diff --git a/examples/shell/nxp/k32w/k32w0/README.md b/examples/shell/nxp/k32w/k32w0/README.md deleted file mode 100644 index 8d87de3f08b983..00000000000000 --- a/examples/shell/nxp/k32w/k32w0/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# CHIP NXP K32W Shell Application - -A [chip-shell](../../../README.md) project for NXP K32W family. - -## Building - -The steps to build the NXP K32W Shell Application are exactly the same as in -case of the Lock Example. Please refer to -[this](../../../../lock-app/nxp/k32w/k32w0/README.md) guide to learn how to -build, flash and debug the application. diff --git a/examples/shell/nxp/k32w/k32w0/build_overrides b/examples/shell/nxp/k32w/k32w0/build_overrides deleted file mode 120000 index ad07557834803a..00000000000000 --- a/examples/shell/nxp/k32w/k32w0/build_overrides +++ /dev/null @@ -1 +0,0 @@ -../../../../build_overrides/ \ No newline at end of file diff --git a/examples/shell/nxp/k32w/k32w0/include/AppTask.h b/examples/shell/nxp/k32w/k32w0/include/AppTask.h deleted file mode 100644 index 28480735fef81d..00000000000000 --- a/examples/shell/nxp/k32w/k32w0/include/AppTask.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * - * Copyright (c) 2021 Google LLC. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include - -#include "AppEvent.h" - -#include - -#include "FreeRTOS.h" -#include "timers.h" - -// Application-defined error codes in the CHIP_ERROR space. -#define APP_ERROR_EVENT_QUEUE_FAILED CHIP_APPLICATION_ERROR(0x01) -#define APP_ERROR_CREATE_TASK_FAILED CHIP_APPLICATION_ERROR(0x02) -#define APP_ERROR_UNHANDLED_EVENT CHIP_APPLICATION_ERROR(0x03) -#define APP_ERROR_CREATE_TIMER_FAILED CHIP_APPLICATION_ERROR(0x04) -#define APP_ERROR_START_TIMER_FAILED CHIP_APPLICATION_ERROR(0x05) -#define APP_ERROR_STOP_TIMER_FAILED CHIP_APPLICATION_ERROR(0x06) - -class AppTask -{ -public: - CHIP_ERROR StartAppTask(); - static void AppTaskMain(void * pvParameter); - void PostEvent(const AppEvent * event); - -private: - friend AppTask & GetAppTask(void); - - CHIP_ERROR Init(); - - void CancelTimer(void); - - void DispatchEvent(AppEvent * event); - - static void FunctionTimerEventHandler(AppEvent * aEvent); - static void KBD_Callback(uint8_t events); - static void HandleKeyboard(void); - static void BleHandler(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 ThreadProvisioningHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); - - static void ThreadStart(); - void StartTimer(uint32_t aTimeoutInMs); - static void InitServer(intptr_t arg); - - enum Function_t - { - kFunction_NoneSelected = 0, - kFunction_SoftwareUpdate = 0, - kFunction_FactoryReset, - - kFunction_Invalid - } Function; - - Function_t mFunction = kFunction_NoneSelected; - bool mResetTimerActive = false; - - static AppTask sAppTask; -}; - -inline AppTask & GetAppTask(void) -{ - return AppTask::sAppTask; -} diff --git a/examples/shell/nxp/k32w/k32w0/include/CHIPProjectConfig.h b/examples/shell/nxp/k32w/k32w0/include/CHIPProjectConfig.h deleted file mode 100644 index f7ef2f6c352cce..00000000000000 --- a/examples/shell/nxp/k32w/k32w0/include/CHIPProjectConfig.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2020 Project CHIP Authors - * Copyright (c) 2020 Google LLC. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * Example project configuration file for CHIP. - * - * This is a place to put application or project-specific overrides - * to the default configuration values for general CHIP features. - * - */ - -#pragma once - -// Security and Authentication disabled for development build. -// For convenience, enable CHIP Security Test Mode and disable the requirement for -// authentication in various protocols. -// WARNING: These options make it possible to circumvent basic CHIP security functionality, -// including message encryption. Because of this they MUST NEVER BE ENABLED IN PRODUCTION BUILDS. -#define CHIP_CONFIG_SECURITY_TEST_MODE 0 - -// Use a default setup PIN code if one hasn't been provisioned in flash. -#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 -#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 - -/** - * CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER - * - * Enables the use of a hard-coded default serial number if none - * is found in CHIP NV storage. - */ -#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 - * - * 0x8009: example shell - */ -#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8012 - -/** - * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION - * - * The hardware version number assigned to device or product by the device vendor. This - * number is scoped to the device product id, and typically corresponds to a revision of the - * physical device, a change to its packaging, and/or a change to its marketing presentation. - * This value is generally *not* incremented for device software versions. - */ -#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 100 - -#ifndef CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING -#define CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING "v0.1.0" -#endif - -/** - * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING - * - * A string identifying the software version running on the device. - * CHIP currently expects the software version to be in the format - * {MAJOR_VERSION}.0d{MINOR_VERSION} - */ -#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "04-2020-te2" -#endif - -#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 42020 -#endif - -#ifndef CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME -#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME "NXP Semiconductors" -#endif - -#ifndef CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME -#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME "NXP Demo App" -#endif - -/** - * @def CHIP_CONFIG_ENABLE_SERVER_IM_EVENT - * - * @brief Enable Interaction model Event support in server - */ -#define CHIP_CONFIG_ENABLE_SERVER_IM_EVENT 0 - -/** - * CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_TIMEOUT - * - * The amount of time in miliseconds after which BLE should change his advertisements - * from fast interval to slow interval. - * - * 30000 (30 secondes). - */ -#define CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_TIMEOUT (30 * 1000) - -/** - * @def CHIP_CONFIG_MAX_FABRICS - * - * @brief - * Maximum number of fabrics the device can participate in. Each fabric can - * provision the device with its unique operational credentials and manage - * its own access control lists. - */ -#define CHIP_CONFIG_MAX_FABRICS 2 // 1 fabrics + 1 for rotation slack - -/** - * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE - * - * For a development build, set the default importance of events to be logged as Debug. - * Since debug is the lowest importance level, this means all standard, critical, info and - * debug importance level vi events get logged. - */ -#if BUILD_RELEASE -#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Production -#else -#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Debug -#endif // BUILD_RELEASE - -/** - * @def CHIP_IM_MAX_NUM_COMMAND_HANDLER - * - * @brief Defines the maximum number of CommandHandler, limits the number of active commands transactions on server. - */ -#define CHIP_IM_MAX_NUM_COMMAND_HANDLER 2 - -/** - * @def CHIP_IM_MAX_NUM_WRITE_HANDLER - * - * @brief Defines the maximum number of WriteHandler, limits the number of active write transactions on server. - */ -#define CHIP_IM_MAX_NUM_WRITE_HANDLER 2 diff --git a/examples/shell/nxp/k32w/k32w0/include/FreeRTOSConfig.h b/examples/shell/nxp/k32w/k32w0/include/FreeRTOSConfig.h deleted file mode 100644 index e9e79054721218..00000000000000 --- a/examples/shell/nxp/k32w/k32w0/include/FreeRTOSConfig.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * FreeRTOS Kernel V10.2.0 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://www.FreeRTOS.org - * http://aws.amazon.com/freertos - * - * 1 tab == 4 spaces! - */ - -#pragma once - -/*----------------------------------------------------------- - * Application specific definitions. - * - * These definitions should be adjusted for your particular hardware and - * application requirements. - * - * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE - * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. - * - * See http://www.freertos.org/a00110.html. - *----------------------------------------------------------*/ - -#define configUSE_PREEMPTION 1 -#define configUSE_TICKLESS_IDLE 0 -#define configCPU_CLOCK_HZ (SystemCoreClock) -#define configTICK_RATE_HZ ((TickType_t) 100) -#define configMAX_PRIORITIES (8) -#define configMINIMAL_STACK_SIZE ((unsigned short) 90) -#define configMAX_TASK_NAME_LEN 20 -#define configUSE_16_BIT_TICKS 0 -#define configIDLE_SHOULD_YIELD 1 -#define configUSE_TASK_NOTIFICATIONS 1 -#define configUSE_MUTEXES 1 -#define configUSE_RECURSIVE_MUTEXES 1 -#define configUSE_COUNTING_SEMAPHORES 1 -#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */ -#define configQUEUE_REGISTRY_SIZE 8 -#define configUSE_QUEUE_SETS 0 -/* make sure that Thread task can interrupt lengthy Matter - * processing in case priority inversion occurs - */ -#define configUSE_TIME_SLICING 1 -#define configUSE_NEWLIB_REENTRANT 0 -#define configENABLE_BACKWARD_COMPATIBILITY 1 -#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 - -/* Tasks.c additions (e.g. Thread Aware Debug capability) */ -#define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 1 - -/* Used memory allocation (heap_x.c) */ -#define configFRTOS_MEMORY_SCHEME 4 - -/* Memory allocation related definitions. */ -#define configSUPPORT_STATIC_ALLOCATION 0 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 -#define configTOTAL_HEAP_SIZE ((size_t) (gTotalHeapSize_c)) -#define configAPPLICATION_ALLOCATED_HEAP 1 - -/* Hook function related definitions. */ -#ifndef configUSE_IDLE_HOOK -#define configUSE_IDLE_HOOK 0 -#endif -#define configUSE_TICK_HOOK 0 -#define configCHECK_FOR_STACK_OVERFLOW 0 -#ifndef configUSE_MALLOC_FAILED_HOOK -#define configUSE_MALLOC_FAILED_HOOK 0 -#endif -#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 - -/* Run time and task stats gathering related definitions. */ -#define configGENERATE_RUN_TIME_STATS 0 -#define configUSE_TRACE_FACILITY 1 -#define configUSE_STATS_FORMATTING_FUNCTIONS 0 - -/* Task aware debugging. */ -#define configRECORD_STACK_HIGH_ADDRESS 1 - -/* Co-routine related definitions. */ -#define configUSE_CO_ROUTINES 0 -#define configMAX_CO_ROUTINE_PRIORITIES 2 - -/* Software timer related definitions. */ -#define configUSE_TIMERS 1 -#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1) -#define configTIMER_QUEUE_LENGTH 10 -#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 4) - -/* Define to trap errors during development. */ -#define configASSERT(x) \ - if ((x) == 0) \ - { \ - taskDISABLE_INTERRUPTS(); \ - for (;;) \ - ; \ - } - -/* Optional functions - most linkers will remove unused functions anyway. */ -#define INCLUDE_vTaskPrioritySet 1 -#define INCLUDE_uxTaskPriorityGet 1 -#define INCLUDE_vTaskDelete 1 -#define INCLUDE_vTaskSuspend 1 -#define INCLUDE_xResumeFromISR 1 -#define INCLUDE_vTaskDelayUntil 1 -#define INCLUDE_vTaskDelay 1 -#define INCLUDE_xTaskGetSchedulerState 1 -#define INCLUDE_xTaskGetCurrentTaskHandle 1 -#define INCLUDE_uxTaskGetStackHighWaterMark 1 -#define INCLUDE_xTaskGetIdleTaskHandle 0 -#define INCLUDE_eTaskGetState 0 -#define INCLUDE_xEventGroupSetBitFromISR 1 -#define INCLUDE_xTimerPendFunctionCall 1 -#define INCLUDE_xTaskAbortDelay 0 -#define INCLUDE_xTaskGetHandle 0 -#define INCLUDE_xTaskResumeFromISR 1 -#define INCLUDE_xQueueGetMutexHolder 1 - -/* Interrupt nesting behaviour configuration. Cortex-M specific. */ -#ifdef __NVIC_PRIO_BITS -/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ -#define configPRIO_BITS __NVIC_PRIO_BITS -#else -#define configPRIO_BITS 3 -#endif - -/* The lowest interrupt priority that can be used in a call to a "set priority" -function. */ -#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x7 - -/* The highest interrupt priority that can be used by any interrupt service -routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL -INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER -PRIORITY THAN THIS! (higher priorities are lower numeric values. */ -#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 1 - -/* Interrupt priorities used by the kernel port layer itself. These are generic -to all Cortex-M ports, and do not rely on any particular library functions. */ -#define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) -/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! -See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ -#define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) - -/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS -standard names. */ -#define vPortSVCHandler SVC_Handler -#define xPortPendSVHandler PendSV_Handler -#define xPortSysTickHandler SysTick_Handler diff --git a/examples/shell/nxp/k32w/k32w0/main/AppTask.cpp b/examples/shell/nxp/k32w/k32w0/main/AppTask.cpp deleted file mode 100644 index 23f1417ed8aeb1..00000000000000 --- a/examples/shell/nxp/k32w/k32w0/main/AppTask.cpp +++ /dev/null @@ -1,486 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * Copyright (c) 2021 Google LLC. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "AppTask.h" -#include "AppEvent.h" -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "Keyboard.h" -#include "LED.h" -#include "LEDWidget.h" -#include "app_config.h" - -constexpr uint32_t kFactoryResetTriggerTimeout = 6000; -constexpr uint8_t kAppEventQueueSize = 10; - -TimerHandle_t sFunctionTimer; // FreeRTOS app sw timer. - -static QueueHandle_t sAppEventQueue; - -static LEDWidget sStatusLED; - -static bool sIsThreadProvisioned = false; -static bool sHaveBLEConnections = false; - -static uint32_t eventMask = 0; - -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; - -AppTask AppTask::sAppTask; - -CHIP_ERROR AppTask::StartAppTask() -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - sAppEventQueue = xQueueCreate(kAppEventQueueSize, sizeof(AppEvent)); - if (sAppEventQueue == NULL) - { - err = APP_ERROR_EVENT_QUEUE_FAILED; - K32W_LOG("Failed to allocate app event queue"); - assert(false); - } - - return err; -} - -CHIP_ERROR AppTask::Init() -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - // Init ZCL Data Model and start server - PlatformMgr().ScheduleWork(InitServer, 0); - - // Initialize device attestation config - SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); - - // QR code will be used with CHIP Tool - PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); - - /* HW init leds */ - LED_Init(); - - /* start with all LEDS turnedd off */ - sStatusLED.Init(SYSTEM_STATE_LED); - - /* intialize the Keyboard and button press calback */ - KBD_Init(KBD_Callback); - - // Create FreeRTOS sw timer for Function Selection. - sFunctionTimer = xTimerCreate("FnTmr", // Just a text name, not used by the RTOS kernel - 1, // == default timer period (mS) - false, // no timer reload (==one-shot) - (void *) this, // init timer id = app task obj context - TimerEventHandler // timer callback handler - ); - - if (sFunctionTimer == NULL) - { - err = APP_ERROR_CREATE_TIMER_FAILED; - K32W_LOG("app_timer_create() failed"); - assert(err == CHIP_NO_ERROR); - } - - // Print the current software version - char currentSoftwareVer[ConfigurationManager::kMaxSoftwareVersionStringLength + 1] = { 0 }; - err = ConfigurationMgr().GetSoftwareVersionString(currentSoftwareVer, sizeof(currentSoftwareVer)); - if (err != CHIP_NO_ERROR) - { - K32W_LOG("Get version error"); - assert(err == CHIP_NO_ERROR); - } - - K32W_LOG("Current Software Version: %s", currentSoftwareVer); - -#if CONFIG_CHIP_NFC_COMMISSIONING - PlatformMgr().AddEventHandler(ThreadProvisioningHandler, 0); -#endif - - return err; -} - -void LockOpenThreadTask(void) -{ - chip::DeviceLayer::ThreadStackMgr().LockThreadStack(); -} - -void UnlockOpenThreadTask(void) -{ - chip::DeviceLayer::ThreadStackMgr().UnlockThreadStack(); -} - -void AppTask::InitServer(intptr_t arg) -{ - static chip::CommonCaseDeviceServerInitParams initParams; - (void) initParams.InitializeStaticResourcesBeforeServerInit(); - - // Init ZCL Data Model and start server - chip::Inet::EndPointStateOpenThread::OpenThreadEndpointInitParam nativeParams; - nativeParams.lockCb = LockOpenThreadTask; - nativeParams.unlockCb = UnlockOpenThreadTask; - nativeParams.openThreadInstancePtr = chip::DeviceLayer::ThreadStackMgrImpl().OTInstance(); - initParams.endpointNativeParams = static_cast(&nativeParams); - VerifyOrDie((chip::Server::GetInstance().Init(initParams)) == CHIP_NO_ERROR); -} - -void AppTask::AppTaskMain(void * pvParameter) -{ - AppEvent event; - - CHIP_ERROR err = sAppTask.Init(); - if (err != CHIP_NO_ERROR) - { - K32W_LOG("AppTask.Init() failed"); - assert(err == CHIP_NO_ERROR); - } - - while (true) - { - TickType_t xTicksToWait = pdMS_TO_TICKS(10); - BaseType_t eventReceived = xQueueReceive(sAppEventQueue, &event, xTicksToWait); - while (eventReceived == pdTRUE) - { - sAppTask.DispatchEvent(&event); - eventReceived = xQueueReceive(sAppEventQueue, &event, 0); - } - - // Collect connectivity and configuration state from the CHIP stack. Because the - // CHIP event loop is being run in a separate task, the stack must be locked - // while these values are queried. However we use a non-blocking lock request - // (TryLockChipStack()) to avoid blocking other UI activities when the CHIP - // task is busy (e.g. with a long crypto operation). - if (PlatformMgr().TryLockChipStack()) - { - sHaveBLEConnections = (ConnectivityMgr().NumBLEConnections() != 0); - PlatformMgr().UnlockChipStack(); - } - - // Update the status LED if factory reset has not been initiated. - // - // If system has "full connectivity", keep the LED On constantly. - // - // If thread and service provisioned, but not attached to the thread network yet OR no - // connectivity to the service OR subscriptions are not fully established - // THEN blink the LED Off for a short period of time. - // - // If the system has ble connection(s) uptill the stage above, THEN blink the LEDs at an even - // rate of 100ms. - // - // Otherwise, blink the LED ON for a very short time. - if (sAppTask.mFunction != kFunction_FactoryReset) - { - if (sIsThreadProvisioned) - { - sStatusLED.Blink(950, 50); - } - else if (sHaveBLEConnections) - { - sStatusLED.Blink(100, 100); - } - else - { - sStatusLED.Blink(50, 950); - } - } - - sStatusLED.Animate(); - } -} - -void AppTask::ButtonEventHandler(uint8_t pin_no, uint8_t button_action) -{ - if ((pin_no != RESET_BUTTON) && (pin_no != BLE_BUTTON)) - { - return; - } - - AppEvent button_event; - button_event.Type = AppEvent::kEventType_Button; - button_event.ButtonEvent.PinNo = pin_no; - button_event.ButtonEvent.Action = button_action; - - if (pin_no == RESET_BUTTON) - { - button_event.Handler = ResetActionEventHandler; - } - else if (pin_no == BLE_BUTTON) - { - button_event.Handler = BleHandler; -#if !(defined OM15082) - if (button_action == RESET_BUTTON_PUSH) - { - button_event.Handler = ResetActionEventHandler; - } -#endif - } - - sAppTask.PostEvent(&button_event); -} - -void AppTask::KBD_Callback(uint8_t events) -{ - eventMask = eventMask | (uint32_t) (1 << events); - - HandleKeyboard(); -} - -void AppTask::HandleKeyboard(void) -{ - uint8_t keyEvent = 0xFF; - uint8_t pos = 0; - - while (eventMask) - { - for (pos = 0; pos < (8 * sizeof(eventMask)); pos++) - { - if (eventMask & (1 << pos)) - { - keyEvent = pos; - eventMask = eventMask & ~(1 << pos); - break; - } - } - - switch (keyEvent) - { - case gKBD_EventPB1_c: -#if (defined OM15082) - ButtonEventHandler(RESET_BUTTON, RESET_BUTTON_PUSH); - break; -#else - ButtonEventHandler(BLE_BUTTON, BLE_BUTTON_PUSH); - break; -#endif - case gKBD_EventPB4_c: - ButtonEventHandler(BLE_BUTTON, BLE_BUTTON_PUSH); - break; -#if !(defined OM15082) - case gKBD_EventLongPB1_c: - ButtonEventHandler(BLE_BUTTON, RESET_BUTTON_PUSH); - break; -#endif - default: - break; - } - } -} - -void AppTask::TimerEventHandler(TimerHandle_t xTimer) -{ - AppEvent event; - event.Type = AppEvent::kEventType_Timer; - event.TimerEvent.Context = (void *) xTimer; - event.Handler = FunctionTimerEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FunctionTimerEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type != AppEvent::kEventType_Timer) - return; - - K32W_LOG("Device will factory reset..."); - - // Actually trigger Factory Reset - chip::Server::GetInstance().ScheduleFactoryReset(); -} - -void AppTask::ResetActionEventHandler(AppEvent * aEvent) -{ - if (aEvent->ButtonEvent.PinNo != RESET_BUTTON && aEvent->ButtonEvent.PinNo != BLE_BUTTON) - return; - - if (sAppTask.mResetTimerActive) - { - sAppTask.CancelTimer(); - sAppTask.mFunction = kFunction_NoneSelected; - - K32W_LOG("Factory Reset was cancelled!"); - } - else - { - uint32_t resetTimeout = kFactoryResetTriggerTimeout; - - if (sAppTask.mFunction != kFunction_NoneSelected) - { - K32W_LOG("Another function is scheduled. Could not initiate Factory Reset!"); - return; - } - - K32W_LOG("Factory Reset Triggered. Push the RESET button within %u ms to cancel!", resetTimeout); - sAppTask.mFunction = kFunction_FactoryReset; - - /* LEDs will start blinking to signal that a Factory Reset was scheduled */ - sStatusLED.Set(false); - sStatusLED.Blink(500); - - sAppTask.StartTimer(kFactoryResetTriggerTimeout); - } -} - -void AppTask::BleHandler(AppEvent * aEvent) -{ - if (aEvent->ButtonEvent.PinNo != BLE_BUTTON) - return; - - if (sAppTask.mFunction != kFunction_NoneSelected) - { - K32W_LOG("Another function is scheduled. Could not toggle BLE state!"); - return; - } - - if (ConnectivityMgr().IsBLEAdvertisingEnabled()) - { - ConnectivityMgr().SetBLEAdvertisingEnabled(false); - K32W_LOG("Stopped BLE Advertising!"); - } - else - { - ConnectivityMgr().SetBLEAdvertisingEnabled(true); - - if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() == CHIP_NO_ERROR) - { - K32W_LOG("Started BLE Advertising!"); - } - else - { - K32W_LOG("OpenBasicCommissioningWindow() failed"); - } - } -} - -void AppTask::ThreadProvisioningHandler(const ChipDeviceEvent * event, intptr_t) -{ - if (event->Type == DeviceEventType::kServiceProvisioningChange && event->ServiceProvisioningChange.IsServiceProvisioned) - { - if (event->ServiceProvisioningChange.IsServiceProvisioned) - { - sIsThreadProvisioned = TRUE; - } - else - { - sIsThreadProvisioned = FALSE; - } - } - -#if CONFIG_CHIP_NFC_COMMISSIONING - if (event->Type == DeviceEventType::kCHIPoBLEAdvertisingChange && event->CHIPoBLEAdvertisingChange.Result == kActivity_Stopped) - { - if (!NFCMgr().IsTagEmulationStarted()) - { - K32W_LOG("NFC Tag emulation is already stopped!"); - } - else - { - NFCMgr().StopTagEmulation(); - K32W_LOG("Stopped NFC Tag Emulation!"); - } - } - else if (event->Type == DeviceEventType::kCHIPoBLEAdvertisingChange && - event->CHIPoBLEAdvertisingChange.Result == kActivity_Started) - { - if (NFCMgr().IsTagEmulationStarted()) - { - K32W_LOG("NFC Tag emulation is already started!"); - } - else - { - ShareQRCodeOverNFC(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); - K32W_LOG("Started NFC Tag Emulation!"); - } - } -#endif -} - -void AppTask::CancelTimer() -{ - if (xTimerStop(sFunctionTimer, 0) == pdFAIL) - { - K32W_LOG("app timer stop() failed"); - } - - mResetTimerActive = false; -} - -void AppTask::StartTimer(uint32_t aTimeoutInMs) -{ - if (xTimerIsTimerActive(sFunctionTimer)) - { - K32W_LOG("app timer already started!"); - CancelTimer(); - } - - // timer is not active, change its period to required value (== restart). - // FreeRTOS- Block for a maximum of 100 ticks if the change period command - // cannot immediately be sent to the timer command queue. - if (xTimerChangePeriod(sFunctionTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) != pdPASS) - { - K32W_LOG("app timer start() failed"); - } - - mResetTimerActive = true; -} - -void AppTask::PostEvent(const AppEvent * aEvent) -{ - portBASE_TYPE taskToWake = pdFALSE; - if (sAppEventQueue != NULL) - { - if (__get_IPSR()) - { - if (!xQueueSendToFrontFromISR(sAppEventQueue, aEvent, &taskToWake)) - { - K32W_LOG("Failed to post event to app task event queue"); - } - if (taskToWake) - { - portYIELD_FROM_ISR(taskToWake); - } - } - else if (!xQueueSend(sAppEventQueue, aEvent, 0)) - { - K32W_LOG("Failed to post event to app task event queue"); - } - } -} - -void AppTask::DispatchEvent(AppEvent * aEvent) -{ - if (aEvent->Handler) - { - aEvent->Handler(aEvent); - } - else - { - K32W_LOG("Event received with no handler. Dropping event."); - } -} - -extern "C" void OTAIdleActivities(void) {} diff --git a/examples/shell/nxp/k32w/k32w0/main/include/app_config.h b/examples/shell/nxp/k32w/k32w0/main/include/app_config.h deleted file mode 100644 index 08edfc477c2623..00000000000000 --- a/examples/shell/nxp/k32w/k32w0/main/include/app_config.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * Copyright (c) 2020 Google LLC. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "LED.h" - -#pragma once - -// ---- Lock Example App Config ---- - -#define RESET_BUTTON 1 -#define LOCK_BUTTON 2 -#define JOIN_BUTTON 3 -#define BLE_BUTTON 4 - -#define RESET_BUTTON_PUSH 1 -#define LOCK_BUTTON_PUSH 2 -#define JOIN_BUTTON_PUSH 3 -#define BLE_BUTTON_PUSH 4 - -#define APP_BUTTON_PUSH 1 - -#define SYSTEM_STATE_LED LED1 -#define LOCK_STATE_LED LED2 - -// Time it takes in ms for the simulated actuator to move from one -// state to another. -#define ACTUATOR_MOVEMENT_PERIOS_MS 2000 - -// ---- Lock Example SWU Config ---- -#define SWU_INTERVAl_WINDOW_MIN_MS (23 * 60 * 60 * 1000) // 23 hours -#define SWU_INTERVAl_WINDOW_MAX_MS (24 * 60 * 60 * 1000) // 24 hours - -#if K32W_LOG_ENABLED -#define K32W_LOG(...) otPlatLog(OT_LOG_LEVEL_NONE, OT_LOG_REGION_API, ##__VA_ARGS__); -#else -#define K32W_LOG(...) -#endif diff --git a/examples/shell/nxp/k32w/k32w0/main/main.cpp b/examples/shell/nxp/k32w/k32w0/main/main.cpp deleted file mode 100644 index 59b4ddcd063ea1..00000000000000 --- a/examples/shell/nxp/k32w/k32w0/main/main.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/* - * - * Copyright (c) 2021 Google LLC. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// ================================================================================ -// Main Code -// ================================================================================ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "FreeRtosHooks.h" -#include "app_config.h" - -#if PDM_SAVE_IDLE -#include -#endif - -const uint16_t shell_task_size = 3096; -const uint8_t shell_task_priority = 0; - -using namespace ::chip; -using namespace ::chip::Inet; -using namespace ::chip::DeviceLayer; -using namespace ::chip::Logging; -using chip::Shell::Engine; -#include "MacSched.h" - -typedef void (*InitFunc)(void); -extern InitFunc __init_array_start; -extern InitFunc __init_array_end; - -/* needed for FreeRtos Heap 4 */ -uint8_t __attribute__((section(".heap"))) ucHeap[HEAP_SIZE]; - -extern "C" unsigned int sleep(unsigned int seconds) -{ - const TickType_t xDelay = 1000 * seconds / portTICK_PERIOD_MS; - vTaskDelay(xDelay); - return 0; -} - -static void shell_task(void * args) -{ - Engine::Root().Init(); - Engine::Root().RunMainLoop(); -} - -extern "C" void main_task(void const * argument) -{ - int status = 0; - char * argv[1] = { 0 }; - BaseType_t shellTaskHandle; - CHIP_ERROR err = CHIP_NO_ERROR; - - /* Call C++ constructors */ - InitFunc * pFunc = &__init_array_start; - for (; pFunc < &__init_array_end; ++pFunc) - { - (*pFunc)(); - } - - err = PlatformMgrImpl().InitBoardFwk(); - if (err != CHIP_NO_ERROR) - { - return; - } - - mbedtls_platform_set_calloc_free(CHIPPlatformMemoryCalloc, CHIPPlatformMemoryFree); - - K32W_LOG("Welcome to NXP Shell Demo App"); - - /* Mbedtls Threading support is needed because both - * Thread and Matter tasks are using it */ - freertos_mbedtls_mutex_init(); - - // Init Chip memory management before the stack - chip::Platform::MemoryInit(); - -#if PDM_SAVE_IDLE - /* OT Settings needs to be initialized - * early as XCVR is making use of it */ - otPlatSettingsInit(NULL, NULL, 0); -#endif - - CHIP_ERROR ret = PlatformMgr().InitChipStack(); - if (ret != CHIP_NO_ERROR) - { - K32W_LOG("Error during PlatformMgr().InitMatterStack()"); - goto exit; - } - - ret = ThreadStackMgr().InitThreadStack(); - if (ret != CHIP_NO_ERROR) - { - K32W_LOG("Error during ThreadStackMgr().InitThreadStack()"); - goto exit; - } - - /* Enable the MAC scheduler after BLEManagerImpl::_Init() and V2MMAC_Enable(). - * This is needed to register properly the active protocols. - */ - sched_enable(); - - ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); - if (ret != CHIP_NO_ERROR) - { - goto exit; - } - - ret = PlatformMgr().StartEventLoopTask(); - if (ret != CHIP_NO_ERROR) - { - K32W_LOG("Error during PlatformMgr().StartEventLoopTask();"); - goto exit; - } - - // Start OpenThread task - ret = ThreadStackMgrImpl().StartThreadTask(); - if (ret != CHIP_NO_ERROR) - { - K32W_LOG("Error during ThreadStackMgrImpl().StartThreadTask()"); - goto exit; - } - - shellTaskHandle = xTaskCreate(shell_task, "shell_task", shell_task_size / sizeof(StackType_t), NULL, shell_task_priority, NULL); - if (!shellTaskHandle) - { - K32W_LOG("Error while creating the shell task!"); - goto exit; - } - - ret = GetAppTask().StartAppTask(); - if (ret != CHIP_NO_ERROR) - { - K32W_LOG("Error during GetAppTask().StartAppTask()"); - goto exit; - } - GetAppTask().AppTaskMain(NULL); - -exit: - return; -} - -extern "C" void otSysEventSignalPending(void) -{ - { - BaseType_t yieldRequired = ThreadStackMgrImpl().SignalThreadActivityPendingFromISR(); - portYIELD_FROM_ISR(yieldRequired); - } -} diff --git a/examples/shell/nxp/k32w/k32w0/third_party/connectedhomeip b/examples/shell/nxp/k32w/k32w0/third_party/connectedhomeip deleted file mode 120000 index 477cbaad6077b0..00000000000000 --- a/examples/shell/nxp/k32w/k32w0/third_party/connectedhomeip +++ /dev/null @@ -1 +0,0 @@ -../../../../../../ \ No newline at end of file diff --git a/examples/thermostat/nxp/common/main/AppTask.cpp b/examples/thermostat/nxp/common/main/AppTask.cpp new file mode 100644 index 00000000000000..8e3f8f1036a2e4 --- /dev/null +++ b/examples/thermostat/nxp/common/main/AppTask.cpp @@ -0,0 +1,49 @@ +/* + * + * Copyright (c) 2021-2023 Project CHIP Authors + * Copyright (c) 2021 Google LLC. + * Copyright 2023-2024 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. + */ + +#include "AppTask.h" +#include "CHIPDeviceManager.h" +#include "ICDUtil.h" +#include +#include + +using namespace chip; + +void ThermostatApp::AppTask::PreInitMatterStack() +{ + ChipLogProgress(DeviceLayer, "Welcome to NXP thermostat Demo App"); +} + +void ThermostatApp::AppTask::PostInitMatterStack() +{ + chip::app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(&chip::NXP::App::GetICDUtil()); +} + +// This returns an instance of this class. +ThermostatApp::AppTask & ThermostatApp::AppTask::GetDefaultInstance() +{ + static ThermostatApp::AppTask sAppTask; + return sAppTask; +} + +chip::NXP::App::AppTaskBase & chip::NXP::App::GetAppTask() +{ + return ThermostatApp::AppTask::GetDefaultInstance(); +} diff --git a/examples/thermostat/nxp/common/main/DeviceCallbacks.cpp b/examples/thermostat/nxp/common/main/DeviceCallbacks.cpp new file mode 100644 index 00000000000000..d52d933d26ef16 --- /dev/null +++ b/examples/thermostat/nxp/common/main/DeviceCallbacks.cpp @@ -0,0 +1,101 @@ +/* + * + * Copyright (c) 2020-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 DeviceCallbacks.cpp + * + * Implements all the callbacks to the application from the CHIP Stack + * + **/ +#include "DeviceCallbacks.h" + +#include +#include +#include +#include +#include +#include + +#include + +using namespace chip::app; +void OnTriggerEffect(::Identify * identify) +{ + switch (identify->mCurrentEffectIdentifier) + { + case Clusters::Identify::EffectIdentifierEnum::kBlink: + ChipLogProgress(Zcl, "Clusters::Identify::EffectIdentifierEnum::kBlink"); + break; + case Clusters::Identify::EffectIdentifierEnum::kBreathe: + ChipLogProgress(Zcl, "Clusters::Identify::EffectIdentifierEnum::kBreathe"); + break; + case Clusters::Identify::EffectIdentifierEnum::kOkay: + ChipLogProgress(Zcl, "Clusters::Identify::EffectIdentifierEnum::kOkay"); + break; + case Clusters::Identify::EffectIdentifierEnum::kChannelChange: + ChipLogProgress(Zcl, "Clusters::Identify::EffectIdentifierEnum::kChannelChange"); + break; + default: + ChipLogProgress(Zcl, "No identifier effect"); + return; + } +} + +Identify gIdentify0 = { + chip::EndpointId{ 1 }, + [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStart"); }, + [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStop"); }, + chip::app::Clusters::Identify::IdentifyTypeEnum::kNone, + OnTriggerEffect, +}; + +Identify gIdentify1 = { + chip::EndpointId{ 1 }, + [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStart"); }, + [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStop"); }, + chip::app::Clusters::Identify::IdentifyTypeEnum::kNone, + OnTriggerEffect, +}; + +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::System; +using namespace ::chip::DeviceLayer; +using namespace chip::app::Clusters; + +void ThermostatApp::DeviceCallbacks::PostAttributeChangeCallback(EndpointId endpointId, ClusterId clusterId, + AttributeId attributeId, uint8_t type, uint16_t size, + uint8_t * value) +{ + ChipLogProgress(DeviceLayer, + "endpointId " ChipLogFormatMEI " clusterId " ChipLogFormatMEI " attribute ID: " ChipLogFormatMEI + " Type: %u Value: %u, length %u", + ChipLogValueMEI(endpointId), ChipLogValueMEI(clusterId), ChipLogValueMEI(attributeId), type, *value, size); +} + +// This returns an instance of this class. +ThermostatApp::DeviceCallbacks & ThermostatApp::DeviceCallbacks::GetDefaultInstance() +{ + static DeviceCallbacks sDeviceCallbacks; + return sDeviceCallbacks; +} + +chip::DeviceManager::CHIPDeviceManagerCallbacks & chip::NXP::App::GetDeviceCallbacks() +{ + return ThermostatApp::DeviceCallbacks::GetDefaultInstance(); +} diff --git a/examples/thermostat/nxp/common/main/ZclCallbacks.cpp b/examples/thermostat/nxp/common/main/ZclCallbacks.cpp new file mode 100644 index 00000000000000..86ea10f4687558 --- /dev/null +++ b/examples/thermostat/nxp/common/main/ZclCallbacks.cpp @@ -0,0 +1,41 @@ +/* + * + * Copyright (c) 2021-2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "AppTask.h" +#include "CHIPDeviceManager.h" + +#include +#include +#include +#include +#include + +using namespace ::chip; + +void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & path, uint8_t type, uint16_t size, uint8_t * value) +{ + chip::DeviceManager::CHIPDeviceManagerCallbacks * cb = + chip::DeviceManager::CHIPDeviceManager::GetInstance().GetCHIPDeviceManagerCallbacks(); + if (cb != nullptr) + { + // propagate event to device manager + cb->PostAttributeChangeCallback(path.mEndpointId, path.mClusterId, path.mAttributeId, type, size, value); + } +} diff --git a/examples/lock-app/nxp/k32w/k32w0/main/include/AppEvent.h b/examples/thermostat/nxp/common/main/include/AppEvent.h similarity index 65% rename from examples/lock-app/nxp/k32w/k32w0/main/include/AppEvent.h rename to examples/thermostat/nxp/common/main/include/AppEvent.h index 864628869959f6..a0dad141a27055 100644 --- a/examples/lock-app/nxp/k32w/k32w0/main/include/AppEvent.h +++ b/examples/thermostat/nxp/common/main/include/AppEvent.h @@ -1,6 +1,6 @@ /* - * - * Copyright (c) 2020 Nest Labs, Inc. + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2021 Nest Labs, Inc. * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,30 +19,21 @@ #pragma once struct AppEvent; -typedef void (*EventHandler)(void *); +using EventHandler = void (*)(const AppEvent &); struct AppEvent { enum AppEventTypes { - kEventType_Button = 0, - kEventType_Timer, - kEventType_Lock, + kEventType_Timer = 0, + kEventType_TurnOn, kEventType_Install, -#if defined(chip_with_low_power) && (chip_with_low_power == 1) - kEventType_Lp, -#endif }; - AppEventTypes Type; + uint16_t Type; union { - struct - { - uint8_t PinNo; - uint8_t Action; - } ButtonEvent; struct { void * Context; @@ -51,12 +42,8 @@ struct AppEvent { uint8_t Action; int32_t Actor; - } LockEvent; + } ClusterEvent; }; EventHandler Handler; - -#if defined(chip_with_low_power) && (chip_with_low_power == 1) - void * param; -#endif }; diff --git a/examples/thermostat/nxp/common/main/include/AppTask.h b/examples/thermostat/nxp/common/main/include/AppTask.h new file mode 100644 index 00000000000000..51b1df49e023c1 --- /dev/null +++ b/examples/thermostat/nxp/common/main/include/AppTask.h @@ -0,0 +1,54 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2021-2023 Google LLC. + * Copyright 2024 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. + */ + +#pragma once + +#if CONFIG_APP_FREERTOS_OS +#include "AppTaskFreeRTOS.h" +#else +#include "AppTaskZephyr.h" +#endif + +namespace ThermostatApp { +#if CONFIG_APP_FREERTOS_OS +class AppTask : public chip::NXP::App::AppTaskFreeRTOS +#else +class AppTask : public chip::NXP::App::AppTaskZephyr +#endif +{ +public: + ~AppTask() override{}; + void PostInitMatterStack(void) override; + void PreInitMatterStack(void) override; + // This returns an instance of this class. + static AppTask & GetDefaultInstance(); + +private: + static AppTask sAppTask; +}; +} // namespace ThermostatApp + +/** + * Returns the application-specific implementation of the AppTaskBase object. + * + * Applications can use this to gain access to features of the AppTaskBase + * that are specific to the selected application. + */ +chip::NXP::App::AppTaskBase & GetAppTask(); diff --git a/examples/thermostat/nxp/common/main/include/DeviceCallbacks.h b/examples/thermostat/nxp/common/main/include/DeviceCallbacks.h new file mode 100644 index 00000000000000..0abdc20aebe38f --- /dev/null +++ b/examples/thermostat/nxp/common/main/include/DeviceCallbacks.h @@ -0,0 +1,52 @@ +/* + * + * Copyright (c) 2020-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 DeviceCallbacks.h + * + * Implementations for the DeviceManager callbacks for this application + * + **/ + +#pragma once + +#include "CHIPDeviceManager.h" +#include "CommonDeviceCallbacks.h" + +namespace ThermostatApp { +class DeviceCallbacks : public chip::NXP::App::CommonDeviceCallbacks +{ +public: + // This returns an instance of this class. + static DeviceCallbacks & GetDefaultInstance(); + + void PostAttributeChangeCallback(chip::EndpointId endpointId, chip::ClusterId clusterId, chip::AttributeId attributeId, + uint8_t type, uint16_t size, uint8_t * value); + +private: + void OnIdentifyPostAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value); +}; +} // namespace ThermostatApp + +/** + * Returns the application-specific implementation of the CommonDeviceCallbacks object. + * + * Applications can use this to gain access to features of the CommonDeviceCallbacks + * that are specific to the selected application. + */ +chip::DeviceManager::CHIPDeviceManagerCallbacks & GetDeviceCallbacks(); diff --git a/examples/thermostat/nxp/common/main/main.cpp b/examples/thermostat/nxp/common/main/main.cpp new file mode 100644 index 00000000000000..b2aadab98ceb8b --- /dev/null +++ b/examples/thermostat/nxp/common/main/main.cpp @@ -0,0 +1,49 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2021-2023 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ================================================================================ +// Main Code +// ================================================================================ + +#include "FreeRTOS.h" +#include +#include +#include + +#if configAPPLICATION_ALLOCATED_HEAP +uint8_t __attribute__((section(".heap"))) ucHeap[configTOTAL_HEAP_SIZE]; +#endif + +using namespace ::chip::DeviceLayer; + +extern "C" int main(int argc, char * argv[]) +{ + TaskHandle_t taskHandle; + + PlatformMgrImpl().HardwareInit(); + chip::NXP::App::GetAppTask().Start(); + vTaskStartScheduler(); +} + +#if (defined(configCHECK_FOR_STACK_OVERFLOW) && (configCHECK_FOR_STACK_OVERFLOW > 0)) +void vApplicationStackOverflowHook(TaskHandle_t xTask, char * pcTaskName) +{ + assert(0); +} +#endif diff --git a/examples/shell/nxp/k32w/k32w0/.gn b/examples/thermostat/nxp/rt/rw61x/.gn similarity index 80% rename from examples/shell/nxp/k32w/k32w0/.gn rename to examples/thermostat/nxp/rt/rw61x/.gn index 81cec9d11a421b..c0a26c2dc77832 100644 --- a/examples/shell/nxp/k32w/k32w0/.gn +++ b/examples/thermostat/nxp/rt/rw61x/.gn @@ -1,4 +1,5 @@ -# Copyright (c) 2021 Project CHIP Authors +# Copyright (c) 2020 Project CHIP Authors +# Copyright 2023 NXP # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,6 +14,7 @@ # limitations under the License. import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") # The location of the build configuration file. buildconfig = "${build_root}/config/BUILDCONFIG.gn" @@ -25,4 +27,7 @@ default_args = { target_os = "freertos" import("//args.gni") + + # Import default platform configs + import("${chip_root}/src/platform/nxp/rt/rw61x/args.gni") } diff --git a/examples/thermostat/nxp/rt/rw61x/BUILD.gn b/examples/thermostat/nxp/rt/rw61x/BUILD.gn new file mode 100644 index 00000000000000..76610146809bca --- /dev/null +++ b/examples/thermostat/nxp/rt/rw61x/BUILD.gn @@ -0,0 +1,278 @@ +# Copyright (c) 2021 Project CHIP Authors +# Copyright 2023 NXP +# +# 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_overrides/nxp_sdk.gni") +import("//build_overrides/openthread.gni") +import("${chip_root}/src/platform/device.gni") + +#allows to get common NXP SDK gn options +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +# Allows to get various RT gn options +import("${nxp_sdk_build_root}/${nxp_sdk_name}/rt_sdk.gni") + +import("${chip_root}/src/platform/nxp/${nxp_platform}/args.gni") +import( + "${nxp_sdk_build_root}/${nxp_sdk_name}/${rt_platform}/${rt_platform}.gni") +import("${nxp_sdk_build_root}/${nxp_sdk_name}/nxp_executable.gni") + +assert(current_os == "freertos") +assert(target_os == "freertos") +assert(nxp_platform == "rt/rw61x") + +declare_args() { + # Allows to start the tcp download test app + tcp_download = false + + # Allows to start the wifi connect test app + wifi_connect = false + + # The 2 params below are used only if tcp_download or wifi_connect are true, otherwise they're unused. + wifi_ssid = "" + wifi_password = "" + + # Setup discriminator as argument + setup_discriminator = 3840 +} + +example_platform_dir = "${chip_root}/examples/platform/nxp/${nxp_platform}" +common_example_dir = "${chip_root}/examples/platform/nxp/common" + +if (tcp_download == true && wifi_connect == true) { + assert("Cannot enable tcp_download and wifi_connect at the same time!") +} + +# Use NXP custom zap files for thermostatdevice-types +app_common_folder = "thermostat/nxp/zap" + +# Create here the SDK instance. +# Particular sources/defines/includes could be added/changed depending on the target application. +rt_sdk("sdk") { + defines = [] + + # To be moved, temporary mbedtls config fix to build app with factory data + if (chip_enable_secure_dac_private_key_storage == 1) { + defines += [ + "MBEDTLS_NIST_KW_C", + "MBEDTLS_PSA_CRYPTO_CLIENT", + ] + } + + cflags = [] + public_deps = [] + public_configs = [] + sources = [] + include_dirs = [] + + # Indicate paths to default board files + include_dirs += [ "${example_platform_dir}/board/" ] + sources += [ "${example_platform_dir}/board/pin_mux.c" ] + sources += [ "${example_platform_dir}/board/hardware_init.c" ] + sources += [ "${example_platform_dir}/board/clock_config.c" ] + sources += [ "${example_platform_dir}/board/board.c" ] + sources += [ "${example_platform_dir}/board/peripherals.c" ] + + # Indicate the path to CHIPProjectConfig.h + include_dirs += [ "include/config" ] + + # Indicate the default path to FreeRTOSConfig.h + include_dirs += [ "${example_platform_dir}/app/project_include/freeRTOS" ] + + # Indicate the default path to OpenThreadConfig.h + include_dirs += [ "${example_platform_dir}/app/project_include/openthread" ] + + # For matter with BR feature, increase FreeRTOS heap size + if (chip_enable_wifi && chip_enable_openthread) { + defines += [ "configTOTAL_HEAP_SIZE=(size_t)(160 * 1024)" ] + } +} + +# Create the SDK driver instance. +# Particular sources/defines/includes could be added to add other drivers not available in the default sdk driver template +rw61x_sdk_drivers("sdk_driver") { +} + +rt_executable("thermostat") { + output_name = "chip-rw61x-thermostat-example" + + defines = [ + "CONFIG_RENDEZVOUS_MODE=7", + "CONFIG_APP_FREERTOS_OS=1", + ] + + if (chip_enable_openthread) { + defines += [ "CONFIG_NET_L2_OPENTHREAD=1" ] + } + + include_dirs = [ + "../../common/main/include", + "../../common/main", + "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/providers/", + ] + + sources = [ + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp", + "${chip_root}/examples/providers/DeviceInfoProviderImpl.cpp", + "../../common/main/AppTask.cpp", + "../../common/main/DeviceCallbacks.cpp", + "../../common/main/ZclCallbacks.cpp", + "../../common/main/include/AppEvent.h", + "../../common/main/include/AppTask.h", + "../../common/main/include/DeviceCallbacks.h", + "../../common/main/main.cpp", + ] + + if (chip_enable_secure_dac_private_key_storage == 1) { + sources += [ + "${example_platform_dir}/factory_data/source/AppFactoryDataExample.cpp", + ] + } else { + sources += [ + "${common_example_dir}/factory_data/source/AppFactoryDataDefaultImpl.cpp", + ] + } + + # App common files + include_dirs += [ + "${common_example_dir}/icd/include", + "${common_example_dir}/matter_button/include", + "${common_example_dir}/matter_cli/include", + "${common_example_dir}/device_manager/include", + "${common_example_dir}/device_callbacks/include", + "${common_example_dir}/app_task/include", + "${common_example_dir}/factory_data/include", + ] + + sources += [ + "${common_example_dir}/app_task/source/AppTaskBase.cpp", + "${common_example_dir}/app_task/source/AppTaskFreeRTOS.cpp", + "${common_example_dir}/device_callbacks/source/CommonDeviceCallbacks.cpp", + "${common_example_dir}/device_manager/source/CHIPDeviceManager.cpp", + "${common_example_dir}/icd/source/ICDUtil.cpp", + "${common_example_dir}/matter_button/source/AppMatterButtonEmpty.cpp", + "${common_example_dir}/matter_cli/source/AppMatterCli.cpp", + ] + + deps = [ "${chip_root}/examples/${app_common_folder}" ] + + if (chip_enable_matter_cli) { + defines += [ "ENABLE_CHIP_SHELL" ] + deps += [ + "${chip_root}/examples/shell/shell_common:shell_common", + "${chip_root}/src/lib/shell:shell", + ] + } + + if (chip_enable_ota_requestor) { + include_dirs += [ "${common_example_dir}/ota_requestor/include" ] + sources += [ + "${common_example_dir}/ota_requestor/source/OTARequestorInitiator.cpp", + "${common_example_dir}/ota_requestor/source/OTARequestorInitiatorCommon.cpp", + ] + } + + if (wifi_connect) { + defines += [ + "WIFI_CONNECT_TASK=1", + "WIFI_CONNECT=1", + ] + + if (!chip_enable_matter_cli) { + assert(wifi_ssid != "" && wifi_password != "", + "WiFi SSID and password must be specified at build time!") + } + + if (wifi_ssid != "") { + defines += [ "WIFI_SSID=\"${wifi_ssid}\"" ] + } + + if (wifi_password != "") { + defines += [ "WIFI_PASSWORD=\"${wifi_password}\"" ] + } + + include_dirs += [ "${common_example_dir}/wifi_connect/include" ] + sources += [ "${common_example_dir}/wifi_connect/source/WifiConnect.cpp" ] + } + + if (tcp_download) { + defines += [ "CONFIG_CHIP_TCP_DOWNLOAD=1" ] + defines += [ + "WIFI_CONNECT=1", + "WIFI_SSID=\"${wifi_ssid}\"", + "WIFI_PASSWORD=\"${wifi_password}\"", + ] + + include_dirs += [ "${common_example_dir}/tcp_download_test/include" ] + sources += + [ "${common_example_dir}/tcp_download_test/source/TcpDownload.cpp" ] + } + + # In case a dedicated assert function needs to be supported the flag sdk_fsl_assert_support should be set to false + # The would add to the build a dedicated application assert implementation. + if (!sdk_fsl_assert_support) { + sources += [ "${common_example_dir}/app_assert/source/AppAssert.cpp" ] + } + + cflags = [ "-Wconversion" ] + + ldscript = "${example_platform_dir}/app/ldscripts/RW610_flash.ld" + + inputs = [ ldscript ] + + ldflags = [ + "-T" + rebase_path(ldscript, root_build_dir), + "-fno-common", + "-Wl,--defsym=__stack_size__=2048", + "-ffreestanding", + "-fno-builtin", + "-mapcs", + "-u qspiflash_config", + "-u image_vector_table", + "-u boot_data", + "-u dcd_data", + "-Wl,-print-memory-usage", + "-Wl,--no-warn-rwx-segments", + ] + + if (chip_enable_ota_requestor) { + if (no_mcuboot) { + # If "no_mcuboot" is set to true, the application will be linked at the base of the flash. + print( + "Warning : The OTA Requestor is enabled without MCUBoot. This will prevent the application from applying software updates.") + } else { + # we need to reserve enough space for the bootloader (MCUBoot) + # MCUBoot requires 0x20000 Bytes to be reserved at the base of the flash + # Consequently, some sections will need to be shifted + ldflags += [ "-Wl,--defsym=__m_mcuboot_size__=0x20000" ] + } + + defines += [ + "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setup_discriminator}", + ] + } + + output_dir = root_out_dir +} + +group("rw61x") { + deps = [ ":thermostat" ] +} + +group("default") { + deps = [ ":rw61x" ] +} diff --git a/examples/thermostat/nxp/rt/rw61x/README.md b/examples/thermostat/nxp/rt/rw61x/README.md new file mode 100644 index 00000000000000..6e7a90448467c4 --- /dev/null +++ b/examples/thermostat/nxp/rt/rw61x/README.md @@ -0,0 +1,5 @@ +# CHIP RW61x Thermostat Application + +All instructions describing how to use a Matter application on NXP RW61x can be +found in [README.md](../../../../all-clusters-app/nxp/rt/rw61x/README.md) root +readme diff --git a/examples/thermostat/nxp/rt/rw61x/args.gni b/examples/thermostat/nxp/rt/rw61x/args.gni new file mode 100644 index 00000000000000..c2d91a5db7bae7 --- /dev/null +++ b/examples/thermostat/nxp/rt/rw61x/args.gni @@ -0,0 +1,19 @@ +# 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") + +# SDK target definitions +nxp_sdk_target = get_label_info(":sdk", "label_no_toolchain") +nxp_sdk_driver_target = get_label_info(":sdk_driver", "label_no_toolchain") diff --git a/examples/thermostat/nxp/rt/rw61x/build_overrides b/examples/thermostat/nxp/rt/rw61x/build_overrides new file mode 120000 index 00000000000000..f10867042f4d19 --- /dev/null +++ b/examples/thermostat/nxp/rt/rw61x/build_overrides @@ -0,0 +1 @@ +../../../../build_overrides \ No newline at end of file diff --git a/examples/thermostat/nxp/rt/rw61x/include/config/CHIPProjectConfig.h b/examples/thermostat/nxp/rt/rw61x/include/config/CHIPProjectConfig.h new file mode 100644 index 00000000000000..2653e97705fe39 --- /dev/null +++ b/examples/thermostat/nxp/rt/rw61x/include/config/CHIPProjectConfig.h @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * Copyright 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 + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +/* + * Tells to the platform Factory Data Provider whether to use the example configuration or real/provisioned data. + */ +#ifndef CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA +#define CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA 0 +#endif + +/** + * 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 0x8005 + +#if !CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA +// Use a default pairing code if one hasn't been provisioned in flash. +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#endif + +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 +#endif + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_PAIRING_CODE "CHIPUS" + +/** + * CHIP_DEVICE_CONFIG_USE_TEST_SERIAL_NUMBER + * + * Enables the use of a hard-coded default serial number if none + * is found in CHIP NV storage. + */ +#define CHIP_DEVICE_CONFIG_USE_TEST_SERIAL_NUMBER "DUMMY_SN" + +#endif /* !CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA */ + +/** + * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION + * + * The hardware version number assigned to device or product by the device vendor. This + * number is scoped to the device product id, and typically corresponds to a revision of the + * physical device, a change to its packaging, and/or a change to its marketing presentation. + * This value is generally *not* incremented for device software versions. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 100 + +#ifndef CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING "v0.1.0" +#endif + +/** + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING + * + * A string identifying the software version running on the device. + * CHIP currently expects the software version to be in the format + * {MAJOR_VERSION}.0d{MINOR_VERSION} + */ +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING NXP_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION NXP_CONFIG_DEVICE_SOFTWARE_VERSION +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME "NXP Semiconductors" +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME "NXP Demo App" +#endif + +#ifndef CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION +//-> format_version = 1 +//-> vendor_id = 0xFFF1 +//-> product_id_array = [ 0x8000, 0x8001, 0x8002, 0x8003, 0x8004, 0x8005, 0x8006, 0x8007, 0x8008, 0x8009, 0x800A, 0x800B, +// 0x800C, 0x800D, 0x800E, 0x800F, 0x8010, 0x8011, 0x8012, 0x8013, 0x8014, 0x8015, 0x8016, 0x8017, 0x8018, 0x8019, 0x801A, +// 0x801B, 0x801C, 0x801D, 0x801E, 0x801F, 0x8020, 0x8021, 0x8022, 0x8023, 0x8024, 0x8025, 0x8026, 0x8027, 0x8028, 0x8029, +// 0x802A, 0x802B, 0x802C, 0x802D, 0x802E, 0x802F, 0x8030, 0x8031, 0x8032, 0x8033, 0x8034, 0x8035, 0x8036, 0x8037, 0x8038, +// 0x8039, 0x803A, 0x803B, 0x803C, 0x803D, 0x803E, 0x803F, 0x8040, 0x8041, 0x8042, 0x8043, 0x8044, 0x8045, 0x8046, 0x8047, +// 0x8048, 0x8049, 0x804A, 0x804B, 0x804C, 0x804D, 0x804E, 0x804F, 0x8050, 0x8051, 0x8052, 0x8053, 0x8054, 0x8055, 0x8056, +// 0x8057, 0x8058, 0x8059, 0x805A, 0x805B, 0x805C, 0x805D, 0x805E, 0x805F, 0x8060, 0x8061, 0x8062, 0x8063 ] +//-> device_type_id = 0x0016 +//-> certificate_id = "ZIG20142ZB330003-24" +//-> security_level = 0 +//-> security_information = 0 +//-> version_number = 0x2694 +//-> certification_type = 0 +//-> dac_origin_vendor_id is not present +//-> dac_origin_product_id is not present +#define CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION \ + { \ + 0x30, 0x82, 0x02, 0x19, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0x0a, 0x30, \ + 0x82, 0x02, 0x06, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, \ + 0x02, 0x01, 0x30, 0x82, 0x01, 0x71, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, \ + 0x01, 0x62, 0x04, 0x82, 0x01, 0x5e, 0x15, 0x24, 0x00, 0x01, 0x25, 0x01, 0xf1, 0xff, 0x36, 0x02, 0x05, 0x00, 0x80, \ + 0x05, 0x01, 0x80, 0x05, 0x02, 0x80, 0x05, 0x03, 0x80, 0x05, 0x04, 0x80, 0x05, 0x05, 0x80, 0x05, 0x06, 0x80, 0x05, \ + 0x07, 0x80, 0x05, 0x08, 0x80, 0x05, 0x09, 0x80, 0x05, 0x0a, 0x80, 0x05, 0x0b, 0x80, 0x05, 0x0c, 0x80, 0x05, 0x0d, \ + 0x80, 0x05, 0x0e, 0x80, 0x05, 0x0f, 0x80, 0x05, 0x10, 0x80, 0x05, 0x11, 0x80, 0x05, 0x12, 0x80, 0x05, 0x13, 0x80, \ + 0x05, 0x14, 0x80, 0x05, 0x15, 0x80, 0x05, 0x16, 0x80, 0x05, 0x17, 0x80, 0x05, 0x18, 0x80, 0x05, 0x19, 0x80, 0x05, \ + 0x1a, 0x80, 0x05, 0x1b, 0x80, 0x05, 0x1c, 0x80, 0x05, 0x1d, 0x80, 0x05, 0x1e, 0x80, 0x05, 0x1f, 0x80, 0x05, 0x20, \ + 0x80, 0x05, 0x21, 0x80, 0x05, 0x22, 0x80, 0x05, 0x23, 0x80, 0x05, 0x24, 0x80, 0x05, 0x25, 0x80, 0x05, 0x26, 0x80, \ + 0x05, 0x27, 0x80, 0x05, 0x28, 0x80, 0x05, 0x29, 0x80, 0x05, 0x2a, 0x80, 0x05, 0x2b, 0x80, 0x05, 0x2c, 0x80, 0x05, \ + 0x2d, 0x80, 0x05, 0x2e, 0x80, 0x05, 0x2f, 0x80, 0x05, 0x30, 0x80, 0x05, 0x31, 0x80, 0x05, 0x32, 0x80, 0x05, 0x33, \ + 0x80, 0x05, 0x34, 0x80, 0x05, 0x35, 0x80, 0x05, 0x36, 0x80, 0x05, 0x37, 0x80, 0x05, 0x38, 0x80, 0x05, 0x39, 0x80, \ + 0x05, 0x3a, 0x80, 0x05, 0x3b, 0x80, 0x05, 0x3c, 0x80, 0x05, 0x3d, 0x80, 0x05, 0x3e, 0x80, 0x05, 0x3f, 0x80, 0x05, \ + 0x40, 0x80, 0x05, 0x41, 0x80, 0x05, 0x42, 0x80, 0x05, 0x43, 0x80, 0x05, 0x44, 0x80, 0x05, 0x45, 0x80, 0x05, 0x46, \ + 0x80, 0x05, 0x47, 0x80, 0x05, 0x48, 0x80, 0x05, 0x49, 0x80, 0x05, 0x4a, 0x80, 0x05, 0x4b, 0x80, 0x05, 0x4c, 0x80, \ + 0x05, 0x4d, 0x80, 0x05, 0x4e, 0x80, 0x05, 0x4f, 0x80, 0x05, 0x50, 0x80, 0x05, 0x51, 0x80, 0x05, 0x52, 0x80, 0x05, \ + 0x53, 0x80, 0x05, 0x54, 0x80, 0x05, 0x55, 0x80, 0x05, 0x56, 0x80, 0x05, 0x57, 0x80, 0x05, 0x58, 0x80, 0x05, 0x59, \ + 0x80, 0x05, 0x5a, 0x80, 0x05, 0x5b, 0x80, 0x05, 0x5c, 0x80, 0x05, 0x5d, 0x80, 0x05, 0x5e, 0x80, 0x05, 0x5f, 0x80, \ + 0x05, 0x60, 0x80, 0x05, 0x61, 0x80, 0x05, 0x62, 0x80, 0x05, 0x63, 0x80, 0x18, 0x24, 0x03, 0x16, 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, 0x94, 0x26, 0x24, 0x08, 0x00, 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, 0x20, 0x24, 0xe5, \ + 0xd1, 0xf4, 0x7a, 0x7d, 0x7b, 0x0d, 0x20, 0x6a, 0x26, 0xef, 0x69, 0x9b, 0x7c, 0x97, 0x57, 0xb7, 0x2d, 0x46, 0x90, \ + 0x89, 0xde, 0x31, 0x92, 0xe6, 0x78, 0xc7, 0x45, 0xe7, 0xf6, 0x0c, 0x02, 0x21, 0x00, 0xf8, 0xaa, 0x2f, 0xa7, 0x11, \ + 0xfc, 0xb7, 0x9b, 0x97, 0xe3, 0x97, 0xce, 0xda, 0x66, 0x7b, 0xae, 0x46, 0x4e, 0x2b, 0xd3, 0xff, 0xdf, 0xc3, 0xcc, \ + 0xed, 0x7a, 0xa8, 0xca, 0x5f, 0x4c, 0x1a, 0x7c \ + } +#endif + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC + * + * Enables synchronizing the device's real time clock with a remote CHIP Time service + * using the CHIP Time Sync protocol. + */ +// #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 + +/** + * CHIP_CONFIG_MAX_BINDINGS + * + * Maximum number of simultaneously active bindings per ChipExchangeManager + * 1 (Time Sync) + 2 (Two 1-way subscriptions) + 1 (Software Update) = 4 + * in the worst case. Keeping another 4 as buffer. + */ +#define CHIP_CONFIG_MAX_BINDINGS 6 + +/** + * CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD + * + * Select the ability to offload event logs to any interested subscribers using WDM. + */ +#define CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD 1 + +/** + * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS + * + * Enable recording UTC timestamps. + */ +#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 + +/** + * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE + * + * A size, in bytes, of the individual debug event logging buffer. + */ +#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512) + +/** + * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE + * + * For a development build, set the default importance of events to be logged as Debug. + * Since debug is the lowest importance level, this means all standard, critical, info and + * debug importance level vi events get logged. + */ +#if BUILD_RELEASE +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Production +#else +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Debug +#endif // BUILD_RELEASE + +/* Increasing the retransmission interval of the MRP messages after subsequent failures */ +#ifndef CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL +#define CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL (2000_ms32) +#endif diff --git a/examples/thermostat/nxp/rt/rw61x/third_party/connectedhomeip b/examples/thermostat/nxp/rt/rw61x/third_party/connectedhomeip new file mode 120000 index 00000000000000..305f2077ffe860 --- /dev/null +++ b/examples/thermostat/nxp/rt/rw61x/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../../.. \ No newline at end of file diff --git a/examples/thermostat/nxp/zap/thermostat_matter_thread.matter b/examples/thermostat/nxp/zap/thermostat_matter_thread.matter index 37bcbfae360373..c2c580189efe77 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_thread.matter +++ b/examples/thermostat/nxp/zap/thermostat_matter_thread.matter @@ -2269,10 +2269,15 @@ endpoint 0 { server cluster Identify { ram attribute identifyTime default = 0x0000; ram attribute identifyType default = 0x00; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; handle command Identify; + handle command TriggerEffect; } server cluster Descriptor { @@ -2318,16 +2323,23 @@ endpoint 0 { callback attribute productLabel; callback attribute serialNumber; persist attribute localConfigDisabled default = 0; - ram attribute reachable default = 1; callback attribute uniqueID; callback attribute capabilityMinima; + callback attribute productAppearance; callback attribute specificationVersion; callback attribute maxPathsPerInvoke; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 3; + ram attribute clusterRevision default = 1; } 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; @@ -2341,20 +2353,29 @@ endpoint 0 { server cluster LocalizationConfiguration { persist attribute activeLocale default = "en-US"; callback attribute supportedLocales; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; } server cluster TimeFormatLocalization { persist attribute hourFormat default = 0; - persist attribute activeCalendarType default = 0; - callback attribute supportedCalendarTypes; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; } server cluster UnitLocalization { - persist attribute temperatureUnit default = 0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0x1; ram attribute clusterRevision default = 1; } @@ -2385,6 +2406,10 @@ endpoint 0 { ram attribute lastNetworkingStatus; ram attribute lastNetworkID; ram attribute lastConnectErrorValue; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 1; @@ -2406,10 +2431,11 @@ endpoint 0 { callback attribute upTime; callback attribute totalOperationalHours; callback attribute bootReason; - callback attribute activeHardwareFaults; - callback attribute activeRadioFaults; - callback attribute activeNetworkFaults; callback attribute testEventTriggersEnabled default = false; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2486,7 +2512,7 @@ endpoint 0 { callback attribute acceptedCommandList; callback attribute attributeList; ram attribute featureMap default = 0x000F; - ram attribute clusterRevision default = 2; + ram attribute clusterRevision default = 1; handle command ResetCounts; } @@ -2499,7 +2525,6 @@ endpoint 0 { ram attribute clusterRevision default = 1; handle command OpenCommissioningWindow; - handle command OpenBasicCommissioningWindow; handle command RevokeCommissioning; } @@ -2551,10 +2576,15 @@ endpoint 1 { server cluster Identify { ram attribute identifyTime default = 0x0000; ram attribute identifyType default = 0x0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; handle command Identify; + handle command TriggerEffect; } server cluster Groups { @@ -2601,6 +2631,7 @@ endpoint 1 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; + callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 1; @@ -2624,10 +2655,11 @@ endpoint 1 { } server cluster ScenesManagement { - ram attribute sceneTableSize; + callback attribute lastConfiguredBy default = 0x00; + ram attribute sceneTableSize default = 0x10; callback attribute fabricSceneInfo; - ram attribute featureMap default = 1; - ram attribute clusterRevision default = 1; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 4; handle command AddScene; handle command AddSceneResponse; diff --git a/examples/thermostat/nxp/zap/thermostat_matter_thread.zap b/examples/thermostat/nxp/zap/thermostat_matter_thread.zap index 6079af2bea9471..aa8b54c82574b9 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_thread.zap +++ b/examples/thermostat/nxp/zap/thermostat_matter_thread.zap @@ -1,6 +1,6 @@ { "fileFormat": 2, - "featureLevel": 100, + "featureLevel": 99, "creator": "zap", "keyValuePairs": [ { @@ -75,6 +75,14 @@ "source": "client", "isIncoming": 1, "isEnabled": 1 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 } ], "attributes": [ @@ -110,6 +118,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "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": "", + "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": "", + "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": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -685,46 +757,46 @@ "reportableChange": 0 }, { - "name": "Reachable", - "code": 17, + "name": "UniqueID", + "code": 18, "mfgCode": null, "side": "server", - "type": "boolean", + "type": "char_string", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "1", + "defaultValue": null, "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 }, { - "name": "UniqueID", - "code": 18, + "name": "CapabilityMinima", + "code": 19, "mfgCode": null, "side": "server", - "type": "char_string", + "type": "CapabilityMinimaStruct", "included": 1, "storageOption": "External", - "singleton": 1, + "singleton": 0, "bounded": 0, "defaultValue": null, "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 }, { - "name": "CapabilityMinima", - "code": 19, + "name": "ProductAppearance", + "code": 20, "mfgCode": null, "side": "server", - "type": "CapabilityMinimaStruct", + "type": "ProductAppearanceStruct", "included": 1, "storageOption": "External", - "singleton": 0, + "singleton": 1, "bounded": 0, "defaultValue": null, "reportable": 1, @@ -764,6 +836,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "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": 1, + "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": 1, + "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": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -790,7 +926,7 @@ "storageOption": "RAM", "singleton": 1, "bounded": 0, - "defaultValue": "3", + "defaultValue": "1", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -1003,6 +1139,29 @@ "maxInterval": 65534, "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 + } ] }, { @@ -1045,6 +1204,70 @@ "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, @@ -1104,24 +1327,56 @@ "reportableChange": 0 }, { - "name": "ActiveCalendarType", - "code": 1, + "name": "GeneratedCommandList", + "code": 65528, "mfgCode": null, "side": "server", - "type": "CalendarTypeEnum", + "type": "array", "included": 1, - "storageOption": "NVM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "SupportedCalendarTypes", - "code": 2, + "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", @@ -1178,16 +1433,64 @@ "enabled": 1, "attributes": [ { - "name": "TemperatureUnit", - "code": 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": "TempUnitEnum", + "type": "array", "included": 1, - "storageOption": "NVM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -1609,6 +1912,70 @@ "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, @@ -1758,8 +2125,24 @@ "reportableChange": 0 }, { - "name": "ActiveHardwareFaults", - "code": 5, + "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": "GeneratedCommandList", + "code": 65528, "mfgCode": null, "side": "server", "type": "array", @@ -1774,8 +2157,8 @@ "reportableChange": 0 }, { - "name": "ActiveRadioFaults", - "code": 6, + "name": "AcceptedCommandList", + "code": 65529, "mfgCode": null, "side": "server", "type": "array", @@ -1790,8 +2173,8 @@ "reportableChange": 0 }, { - "name": "ActiveNetworkFaults", - "code": 7, + "name": "EventList", + "code": 65530, "mfgCode": null, "side": "server", "type": "array", @@ -1806,16 +2189,16 @@ "reportableChange": 0 }, { - "name": "TestEventTriggersEnabled", - "code": 8, + "name": "AttributeList", + "code": 65531, "mfgCode": null, "side": "server", - "type": "boolean", + "type": "array", "included": 1, "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "false", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -2964,7 +3347,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "1", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -2988,14 +3371,6 @@ "isIncoming": 1, "isEnabled": 1 }, - { - "name": "OpenBasicCommissioningWindow", - "code": 1, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, { "name": "RevokeCommissioning", "code": 2, @@ -3524,9 +3899,33 @@ "source": "client", "isIncoming": 0, "isEnabled": 1 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 } ], "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "client", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "ClusterRevision", "code": 65533, @@ -3560,6 +3959,14 @@ "source": "client", "isIncoming": 1, "isEnabled": 1 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 } ], "attributes": [ @@ -3595,6 +4002,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "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": "", + "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": "", + "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": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -4117,6 +4588,22 @@ "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, @@ -4478,6 +4965,22 @@ } ], "attributes": [ + { + "name": "LastConfiguredBy", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "node_id", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, { "name": "SceneTableSize", "code": 1, @@ -4488,10 +4991,10 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": "0x10", "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, + "minInterval": 0, + "maxInterval": 65344, "reportableChange": 0 }, { @@ -4506,8 +5009,8 @@ "bounded": 0, "defaultValue": null, "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, + "minInterval": 0, + "maxInterval": 65344, "reportableChange": 0 }, { @@ -4520,7 +5023,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "0", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -4536,7 +5039,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "4", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -4893,16 +5396,14 @@ "endpointTypeIndex": 0, "profileId": 259, "endpointId": 0, - "networkId": 0, - "parentEndpointIdentifier": null + "networkId": 0 }, { "endpointTypeName": "MA-thermostat", "endpointTypeIndex": 1, "profileId": 259, "endpointId": 1, - "networkId": 0, - "parentEndpointIdentifier": null + "networkId": 0 } ] } \ No newline at end of file diff --git a/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter b/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter index ff712e71043379..e9b2cc844f67ef 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter +++ b/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter @@ -2180,10 +2180,15 @@ endpoint 0 { server cluster Identify { ram attribute identifyTime default = 0x0000; ram attribute identifyType default = 0x00; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; handle command Identify; + handle command TriggerEffect; } server cluster Descriptor { @@ -2229,16 +2234,23 @@ endpoint 0 { callback attribute productLabel; callback attribute serialNumber; persist attribute localConfigDisabled default = 0; - ram attribute reachable default = 1; callback attribute uniqueID; callback attribute capabilityMinima; + callback attribute productAppearance; callback attribute specificationVersion; callback attribute maxPathsPerInvoke; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 3; + ram attribute clusterRevision default = 1; } 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; @@ -2252,20 +2264,29 @@ endpoint 0 { server cluster LocalizationConfiguration { persist attribute activeLocale default = "en-US"; callback attribute supportedLocales; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; } server cluster TimeFormatLocalization { persist attribute hourFormat default = 0; - persist attribute activeCalendarType default = 0; - callback attribute supportedCalendarTypes; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; } server cluster UnitLocalization { - persist attribute temperatureUnit default = 0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0x1; ram attribute clusterRevision default = 1; } @@ -2296,6 +2317,10 @@ endpoint 0 { ram attribute lastNetworkingStatus; ram attribute lastNetworkID; ram attribute lastConnectErrorValue; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 1; @@ -2317,10 +2342,11 @@ endpoint 0 { callback attribute upTime; callback attribute totalOperationalHours; callback attribute bootReason; - callback attribute activeHardwareFaults; - callback attribute activeRadioFaults; - callback attribute activeNetworkFaults; callback attribute testEventTriggersEnabled default = false; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2335,14 +2361,11 @@ endpoint 0 { callback attribute wiFiVersion; callback attribute channelNumber; callback attribute rssi; - callback attribute beaconLostCount; - callback attribute beaconRxCount; - callback attribute packetMulticastRxCount; - callback attribute packetMulticastTxCount; - callback attribute packetUnicastRxCount; - callback attribute packetUnicastTxCount; callback attribute currentMaxRate; - callback attribute overrunCount; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; } @@ -2355,7 +2378,6 @@ endpoint 0 { ram attribute clusterRevision default = 1; handle command OpenCommissioningWindow; - handle command OpenBasicCommissioningWindow; handle command RevokeCommissioning; } @@ -2407,10 +2429,15 @@ endpoint 1 { server cluster Identify { ram attribute identifyTime default = 0x0000; ram attribute identifyType default = 0x0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; handle command Identify; + handle command TriggerEffect; } server cluster Groups { @@ -2457,6 +2484,7 @@ endpoint 1 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; + callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 1; @@ -2480,10 +2508,11 @@ endpoint 1 { } server cluster ScenesManagement { - ram attribute sceneTableSize; + callback attribute lastConfiguredBy default = 0x00; + ram attribute sceneTableSize default = 0x10; callback attribute fabricSceneInfo; - ram attribute featureMap default = 1; - ram attribute clusterRevision default = 1; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 4; handle command AddScene; handle command AddSceneResponse; diff --git a/examples/thermostat/nxp/zap/thermostat_matter_wifi.zap b/examples/thermostat/nxp/zap/thermostat_matter_wifi.zap index 7f667adb460ce1..9e18152bebf2bd 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_wifi.zap +++ b/examples/thermostat/nxp/zap/thermostat_matter_wifi.zap @@ -1,6 +1,6 @@ { "fileFormat": 2, - "featureLevel": 100, + "featureLevel": 99, "creator": "zap", "keyValuePairs": [ { @@ -75,6 +75,14 @@ "source": "client", "isIncoming": 1, "isEnabled": 1 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 } ], "attributes": [ @@ -110,6 +118,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "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": "", + "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": "", + "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": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -685,46 +757,46 @@ "reportableChange": 0 }, { - "name": "Reachable", - "code": 17, + "name": "UniqueID", + "code": 18, "mfgCode": null, "side": "server", - "type": "boolean", + "type": "char_string", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "1", + "defaultValue": null, "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 }, { - "name": "UniqueID", - "code": 18, + "name": "CapabilityMinima", + "code": 19, "mfgCode": null, "side": "server", - "type": "char_string", + "type": "CapabilityMinimaStruct", "included": 1, "storageOption": "External", - "singleton": 1, + "singleton": 0, "bounded": 0, "defaultValue": null, "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 }, { - "name": "CapabilityMinima", - "code": 19, + "name": "ProductAppearance", + "code": 20, "mfgCode": null, "side": "server", - "type": "CapabilityMinimaStruct", + "type": "ProductAppearanceStruct", "included": 1, "storageOption": "External", - "singleton": 0, + "singleton": 1, "bounded": 0, "defaultValue": null, "reportable": 1, @@ -764,6 +836,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "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": 1, + "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": 1, + "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": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -790,7 +926,7 @@ "storageOption": "RAM", "singleton": 1, "bounded": 0, - "defaultValue": "3", + "defaultValue": "1", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -1003,6 +1139,29 @@ "maxInterval": 65534, "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 + } ] }, { @@ -1045,6 +1204,70 @@ "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, @@ -1104,24 +1327,56 @@ "reportableChange": 0 }, { - "name": "ActiveCalendarType", - "code": 1, + "name": "GeneratedCommandList", + "code": 65528, "mfgCode": null, "side": "server", - "type": "CalendarTypeEnum", + "type": "array", "included": 1, - "storageOption": "NVM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "SupportedCalendarTypes", - "code": 2, + "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", @@ -1178,16 +1433,64 @@ "enabled": 1, "attributes": [ { - "name": "TemperatureUnit", - "code": 0, + "name": "GeneratedCommandList", + "code": 65528, "mfgCode": null, "side": "server", - "type": "TempUnitEnum", + "type": "array", "included": 1, - "storageOption": "NVM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "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, @@ -1609,6 +1912,70 @@ "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, @@ -1726,11 +2093,27 @@ "reportableChange": 0 }, { - "name": "TotalOperationalHours", - "code": 3, + "name": "TotalOperationalHours", + "code": 3, + "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": "BootReason", + "code": 4, "mfgCode": null, "side": "server", - "type": "int32u", + "type": "BootReasonEnum", "included": 1, "storageOption": "External", "singleton": 0, @@ -1742,24 +2125,24 @@ "reportableChange": 0 }, { - "name": "BootReason", - "code": 4, + "name": "TestEventTriggersEnabled", + "code": 8, "mfgCode": null, "side": "server", - "type": "BootReasonEnum", + "type": "boolean", "included": 1, "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "false", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "ActiveHardwareFaults", - "code": 5, + "name": "GeneratedCommandList", + "code": 65528, "mfgCode": null, "side": "server", "type": "array", @@ -1774,8 +2157,8 @@ "reportableChange": 0 }, { - "name": "ActiveRadioFaults", - "code": 6, + "name": "AcceptedCommandList", + "code": 65529, "mfgCode": null, "side": "server", "type": "array", @@ -1790,8 +2173,8 @@ "reportableChange": 0 }, { - "name": "ActiveNetworkFaults", - "code": 7, + "name": "EventList", + "code": 65530, "mfgCode": null, "side": "server", "type": "array", @@ -1806,16 +2189,16 @@ "reportableChange": 0 }, { - "name": "TestEventTriggersEnabled", - "code": 8, + "name": "AttributeList", + "code": 65531, "mfgCode": null, "side": "server", - "type": "boolean", + "type": "array", "included": 1, "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "false", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -1953,59 +2336,11 @@ "reportableChange": 0 }, { - "name": "BeaconLostCount", - "code": 5, - "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": "BeaconRxCount", - "code": 6, - "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": "PacketMulticastRxCount", - "code": 7, - "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": "PacketMulticastTxCount", - "code": 8, + "name": "CurrentMaxRate", + "code": 11, "mfgCode": null, "side": "server", - "type": "int32u", + "type": "int64u", "included": 1, "storageOption": "External", "singleton": 0, @@ -2017,59 +2352,59 @@ "reportableChange": 0 }, { - "name": "PacketUnicastRxCount", - "code": 9, + "name": "GeneratedCommandList", + "code": 65528, "mfgCode": null, "side": "server", - "type": "int32u", + "type": "array", "included": 1, "storageOption": "External", "singleton": 0, "bounded": 0, "defaultValue": null, "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 }, { - "name": "PacketUnicastTxCount", - "code": 10, + "name": "AcceptedCommandList", + "code": 65529, "mfgCode": null, "side": "server", - "type": "int32u", + "type": "array", "included": 1, "storageOption": "External", "singleton": 0, "bounded": 0, "defaultValue": null, "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 }, { - "name": "CurrentMaxRate", - "code": 11, + "name": "EventList", + "code": 65530, "mfgCode": null, "side": "server", - "type": "int64u", + "type": "array", "included": 1, "storageOption": "External", "singleton": 0, "bounded": 0, "defaultValue": null, "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 }, { - "name": "OverrunCount", - "code": 12, + "name": "AttributeList", + "code": 65531, "mfgCode": null, "side": "server", - "type": "int64u", + "type": "array", "included": 1, "storageOption": "External", "singleton": 0, @@ -2130,14 +2465,6 @@ "isIncoming": 1, "isEnabled": 1 }, - { - "name": "OpenBasicCommissioningWindow", - "code": 1, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, { "name": "RevokeCommissioning", "code": 2, @@ -2666,9 +2993,33 @@ "source": "client", "isIncoming": 0, "isEnabled": 1 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 } ], "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "client", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "ClusterRevision", "code": 65533, @@ -2702,6 +3053,14 @@ "source": "client", "isIncoming": 1, "isEnabled": 1 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 } ], "attributes": [ @@ -2737,6 +3096,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "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": "", + "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": "", + "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": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -3259,6 +3682,22 @@ "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, @@ -3620,6 +4059,22 @@ } ], "attributes": [ + { + "name": "LastConfiguredBy", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "node_id", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, { "name": "SceneTableSize", "code": 1, @@ -3630,10 +4085,10 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": "0x10", "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, + "minInterval": 0, + "maxInterval": 65344, "reportableChange": 0 }, { @@ -3648,8 +4103,8 @@ "bounded": 0, "defaultValue": null, "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, + "minInterval": 0, + "maxInterval": 65344, "reportableChange": 0 }, { @@ -3662,7 +4117,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "0", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -3678,7 +4133,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "4", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -4035,16 +4490,14 @@ "endpointTypeIndex": 0, "profileId": 259, "endpointId": 0, - "networkId": 0, - "parentEndpointIdentifier": null + "networkId": 0 }, { "endpointTypeName": "MA-thermostat", "endpointTypeIndex": 1, "profileId": 259, "endpointId": 1, - "networkId": 0, - "parentEndpointIdentifier": null + "networkId": 0 } ] } \ No newline at end of file diff --git a/scripts/build/BUILD.gn b/scripts/build/BUILD.gn index 0e716ae7e9b390..6b13a8c1011ebd 100644 --- a/scripts/build/BUILD.gn +++ b/scripts/build/BUILD.gn @@ -59,6 +59,7 @@ pw_python_package("build_examples") { "builders/nrf.py", "builders/openiotsdk.py", "builders/qpg.py", + "builders/rw61x.py", "builders/telink.py", "builders/tizen.py", "runner/__init__.py", diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index af1bd454b86ddb..8bc69a2fc620f4 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -30,6 +30,7 @@ from builders.nrf import NrfApp, NrfBoard, NrfConnectBuilder from builders.openiotsdk import OpenIotSdkApp, OpenIotSdkBuilder, OpenIotSdkCryptoBackend from builders.qpg import QpgApp, QpgBoard, QpgBuilder +from builders.rw61x import RW61XApp, RW61XBuilder from builders.stm32 import stm32App, stm32Board, stm32Builder from builders.telink import TelinkApp, TelinkBoard, TelinkBuilder from builders.ti import TIApp, TIBoard, TIBuilder @@ -703,6 +704,25 @@ def BuildMW320Target(): return target +def BuildRW61XTarget(): + target = BuildTarget('rw61x', RW61XBuilder) + + # apps + target.AppendFixedTargets([ + TargetPart('all-clusters-app', app=RW61XApp.ALL_CLUSTERS, release=True), + TargetPart('thermostat', app=RW61XApp.THERMOSTAT, release=True), + TargetPart('laundry-washer', app=RW61XApp.LAUNDRY_WASHER, release=True), + ]) + + target.AppendModifier(name="ota", enable_ota=True) + target.AppendModifier(name="wifi", enable_wifi=True) + target.AppendModifier(name="thread", enable_thread=True) + target.AppendModifier(name="factory-data", enable_factory_data=True) + target.AppendModifier(name="matter-shell", enable_shell=True) + + return target + + def BuildGenioTarget(): target = BuildTarget('genio', GenioBuilder) target.AppendFixedTargets([TargetPart('lighting-app', app=GenioApp.LIGHT)]) @@ -783,6 +803,7 @@ def BuildOpenIotSdkTargets(): BuildHostTestRunnerTarget(), BuildIMXTarget(), BuildInfineonTarget(), + BuildRW61XTarget(), BuildK32WTarget(), BuildMbedTarget(), BuildMW320Target(), diff --git a/scripts/build/builders/k32w.py b/scripts/build/builders/k32w.py index 1cf7862d3d8739..86ba55217c64a5 100644 --- a/scripts/build/builders/k32w.py +++ b/scripts/build/builders/k32w.py @@ -111,7 +111,9 @@ def GnBuildArgs(self): args = [] if self.low_power: - args.append('chip_with_low_power=1') + args.append('chip_with_low_power=1 chip_logging=false') + if self.board == K32WBoard.K32W0: + args.append('chip_pw_tokenizer_logging=false chip_with_OM15082=0') else: args.append('chip_with_low_power=0') diff --git a/scripts/build/builders/rw61x.py b/scripts/build/builders/rw61x.py new file mode 100644 index 00000000000000..546c6549e2aab9 --- /dev/null +++ b/scripts/build/builders/rw61x.py @@ -0,0 +1,124 @@ +# 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 os +from enum import Enum, auto + +from .gn import GnBuilder + + +class RW61XApp(Enum): + ALL_CLUSTERS = auto() + THERMOSTAT = auto() + LAUNDRY_WASHER = auto() + + def ExampleName(self): + if self == RW61XApp.ALL_CLUSTERS: + return 'all-clusters-app' + elif self == RW61XApp.THERMOSTAT: + return 'thermostat' + elif self == RW61XApp.LAUNDRY_WASHER: + return 'laundry-washer-app' + else: + raise Exception('Unknown app type: %r' % self) + + def NameSuffix(self): + if self == RW61XApp.ALL_CLUSTERS: + return '-'.join(['chip', 'rw61x', 'all-cluster-example']) + if self == RW61XApp.THERMOSTAT: + return '-'.join(['chip', 'rw61x', 'thermostat-example']) + if self == RW61XApp.LAUNDRY_WASHER: + return '-'.join(['chip', 'rw61x', 'laundry-washer-example']) + else: + raise Exception('Unknown app type: %r' % self) + + def BuildRoot(self, root): + return os.path.join(root, 'examples', self.ExampleName(), 'nxp', 'rt/rw61x') + + +class RW61XBuilder(GnBuilder): + + def __init__(self, + root, + runner, + app: RW61XApp = RW61XApp.ALL_CLUSTERS, + release: bool = False, + disable_ble: bool = False, + enable_thread: bool = False, + enable_wifi: bool = False, + disable_ipv4: bool = False, + enable_shell: bool = False, + enable_ota: bool = False, + enable_factory_data: bool = False, + is_sdk_package: bool = True, + a2_board_revision: bool = False): + super(RW61XBuilder, self).__init__( + root=app.BuildRoot(root), + runner=runner) + self.app = app + self.release = release + self.disable_ipv4 = disable_ipv4 + self.disable_ble = disable_ble + self.enable_thread = enable_thread + self.enable_wifi = enable_wifi + self.enable_ota = enable_ota + self.enable_factory_data = enable_factory_data + self.enable_shell = enable_shell + self.is_sdk_package = is_sdk_package + self.a2_board_revision = a2_board_revision + + def GnBuildArgs(self): + args = [] + + if self.release: + args.append('is_debug=false') + + if self.enable_ota: + args.append('chip_enable_ota_requestor=true no_mcuboot=false') + + if self.disable_ipv4: + args.append('chip_inet_config_enable_ipv4=false') + + if self.disable_ble: + args.append('chip_enable_ble=false') + + if self.enable_wifi: + args.append('chip_enable_wifi=true') + + if self.enable_thread: + args.append('chip_enable_openthread=true chip_inet_config_enable_ipv4=false') + + if self.enable_factory_data: + args.append('chip_with_factory_data=1') + + if self.a2_board_revision: + args.append('board_version=\"A2\"') + + if self.enable_shell: + args.append('chip_enable_matter_cli=true') + + if self.is_sdk_package: + args.append('is_sdk_package=true') + + return args + + def generate(self): + super(RW61XBuilder, self).generate() + + def build_outputs(self): + name = '%s' % self.app.NameSuffix() + return { + '%s.elf' % name: os.path.join(self.output_dir, name), + '%s.map' % name: os.path.join(self.output_dir, '%s.map' % name) + } diff --git a/scripts/build/testdata/all_targets_linux_x64.txt b/scripts/build/testdata/all_targets_linux_x64.txt index 3c6a2d3b643d6b..93ad9255c0b9d6 100644 --- a/scripts/build/testdata/all_targets_linux_x64.txt +++ b/scripts/build/testdata/all_targets_linux_x64.txt @@ -14,6 +14,7 @@ linux-{x64,arm64}-{rpc-console,all-clusters,all-clusters-minimal,chip-tool,therm linux-x64-efr32-test-runner[-clang] imx-{chip-tool,lighting-app,thermostat,all-clusters-app,all-clusters-minimal-app,ota-provider-app}[-release] infineon-psoc6-{lock,light,all-clusters,all-clusters-minimal}[-ota][-updateimage] +rw61x-{all-clusters-app,thermostat,laundry-washer}[-ota][-wifi][-thread][-factory-data][-matter-shell] k32w-{k32w0,k32w1}-{light,shell,lock,contact}[-se05x][-no-ble][-no-ota][-low-power][-nologs][-crypto-platform][-tokenizer][-openthread-ftd] mbed-cy8cproto_062_4343w-{lock,light,all-clusters,all-clusters-minimal,pigweed,ota-requestor,shell}[-release][-develop][-debug] mw320-all-clusters-app diff --git a/scripts/checkout_submodules.py b/scripts/checkout_submodules.py index 6cd87e96177570..aa220f7ff3b139 100755 --- a/scripts/checkout_submodules.py +++ b/scripts/checkout_submodules.py @@ -36,7 +36,8 @@ 'silabs', 'esp32', 'infineon', - 'k32w', + 'nxp', + 'rw61x', 'linux', 'mbed', 'nrfconnect', diff --git a/scripts/tools/nxp/factory_data_generator/custom.py b/scripts/tools/nxp/factory_data_generator/custom.py index e2f7584e2d7fa2..179f990c3052bc 100644 --- a/scripts/tools/nxp/factory_data_generator/custom.py +++ b/scripts/tools/nxp/factory_data_generator/custom.py @@ -278,3 +278,62 @@ def key(self): def max_length(self): return 64 + + +class ProductFinish(StrArgument): + + VALUES = ["Other", "Matte", "Satin", "Polished", "Rugged", "Fabric"] + + def __init__(self, arg): + super().__init__(arg) + + def key(self): + return 22 + + def length(self): + return 1 + + def encode(self): + val = "" + try: + val = ProductFinish.VALUES.index(self.val) + except Exception: + print(f"Error: {self.val} not in {ProductFinish.VALUES}") + exit() + + return val.to_bytes(self.length(), "little") + + def max_length(self): + return 64 + + +class ProductPrimaryColor(StrArgument): + + VALUES = [ + "Black", "Navy", "Green", "Teal", "Maroon", + "Purple", "Olive", "Gray", "Blue", "Lime", + "Aqua", "Red", "Fuchsia", "Yellow", "White", + "Nickel", "Chrome", "Brass", "Copper", "Silver", "Gold" + ] + + def __init__(self, arg): + super().__init__(arg) + + def key(self): + return 23 + + def length(self): + return 1 + + def encode(self): + val = "" + try: + val = ProductPrimaryColor.VALUES.index(self.val) + except Exception: + print(f"Error: {self.val} not in {ProductPrimaryColor.VALUES}") + exit() + + return val.to_bytes(self.length(), "little") + + def max_length(self): + return 64 diff --git a/scripts/tools/nxp/factory_data_generator/generate.py b/scripts/tools/nxp/factory_data_generator/generate.py index 1fb7d91edeedaf..0d905d41faae0b 100755 --- a/scripts/tools/nxp/factory_data_generator/generate.py +++ b/scripts/tools/nxp/factory_data_generator/generate.py @@ -23,17 +23,13 @@ import sys from custom import (CertDeclaration, DacCert, DacPKey, Discriminator, HardwareVersion, HardwareVersionStr, IterationCount, - ManufacturingDate, PaiCert, PartNumber, ProductId, ProductLabel, ProductName, ProductURL, Salt, SerialNum, - SetupPasscode, StrArgument, UniqueId, VendorId, VendorName, Verifier) + ManufacturingDate, PaiCert, PartNumber, ProductFinish, ProductId, ProductLabel, ProductName, + ProductPrimaryColor, ProductURL, Salt, SerialNum, SetupPasscode, StrArgument, UniqueId, VendorId, VendorName, + Verifier) from default import InputArgument -# A magic value used in the factory data integrity check. -# The value will be checked at runtime, before verifying the -# factory data integrity. Factory data header has the following format: -# | hash id (4 bytes) | size (4 bytes) | hash (4 bytes) | -# If the hash id check fails, it means the factory data is either missing -# or has become corrupted. -HASH_ID = "CE47BA5E" +# Global variable for hash ID +hash_id = "CE47BA5E" def set_logger(): @@ -131,7 +127,7 @@ def to_bin(self, klv, out, aes128_key): fullContent = size.to_bytes(4, "little") + fullContent # Add hash id - hashId = bytearray.fromhex("CE47BA5E") + hashId = bytearray.fromhex(hash_id) hashId.reverse() fullContent = hashId + fullContent @@ -163,7 +159,7 @@ def to_bin(self, klv, out, aes128_key): fullContentCipher = size.to_bytes(4, "little") + fullContentCipher # Add hash id - hashId = bytearray.fromhex(HASH_ID) + hashId = bytearray.fromhex(hash_id) hashId.reverse() fullContentCipher = hashId + fullContentCipher @@ -235,6 +231,10 @@ def main(): help="[str] Serial Number") optional.add_argument("--unique_id", type=UniqueId, help="[str] Unique identifier for the device") + optional.add_argument("--product_finish", type=ProductFinish, metavar=ProductFinish.VALUES, + help="[str] Visible finish of the product") + optional.add_argument("--product_primary_color", type=ProductPrimaryColor, metavar=ProductPrimaryColor.VALUES, + help="[str] Representative color of the visible parts of the product") args = parser.parse_args() diff --git a/scripts/tools/nxp/generate_certs.py b/scripts/tools/nxp/generate_certs.py index 7a98f7138ebe05..d6c23a92dc0f18 100644 --- a/scripts/tools/nxp/generate_certs.py +++ b/scripts/tools/nxp/generate_certs.py @@ -20,7 +20,7 @@ import os import subprocess -MATTER_ROOT = os.path.dirname(os.path.realpath(f"{__file__}/../../../")) +MATTER_ROOT = os.path.dirname(os.path.realpath(__file__))[:-len("/scripts/tools/nxp")] def gen_test_certs(chip_cert_exe: str, diff --git a/scripts/tools/nxp/ota/README.md b/scripts/tools/nxp/ota/README.md index 45766b1db8d44f..d96ab70d63c251 100644 --- a/scripts/tools/nxp/ota/README.md +++ b/scripts/tools/nxp/ota/README.md @@ -25,7 +25,7 @@ are also available here: python3 ./scripts/tools/nxp/ota/ota_image_tool.py create -v 0xDEAD -p 0xBEEF -vn 50000 -vs "1.0" -da sha256 ``` -followed by \*_custom options_- and a positional argument (should be last) that +followed by **custom options**- and a positional argument (should be last) that specifies the output file. Please see the `create_ota_images.sh` for some reference commands. diff --git a/scripts/tools/nxp/ota/examples/ota_max_entries_example.json b/scripts/tools/nxp/ota/examples/ota_max_entries_example.json index d5ba8ff8e80964..d28c2def45496c 100644 --- a/scripts/tools/nxp/ota/examples/ota_max_entries_example.json +++ b/scripts/tools/nxp/ota/examples/ota_max_entries_example.json @@ -1,7 +1,7 @@ { "inputs": [ { - "tag": 4, + "tag": 100, "descriptor": [ { "name": "ssbl_version", @@ -22,7 +22,7 @@ "path": "./binaries/ssbl_ext_flash_ota_entry_example.bin" }, { - "tag": 5, + "tag": 101, "descriptor": [ { "name": "ssbl_version", @@ -43,7 +43,7 @@ "path": "./binaries/ssbl_ext_flash_ota_entry_example.bin" }, { - "tag": 6, + "tag": 102, "descriptor": [ { "name": "ssbl_version", @@ -64,7 +64,7 @@ "path": "./binaries/ssbl_ext_flash_ota_entry_example.bin" }, { - "tag": 7, + "tag": 103, "descriptor": [ { "name": "ssbl_version", @@ -85,7 +85,7 @@ "path": "./binaries/ssbl_ext_flash_ota_entry_example.bin" }, { - "tag": 8, + "tag": 104, "descriptor": [ { "name": "ssbl_version", @@ -106,7 +106,7 @@ "path": "./binaries/ssbl_ext_flash_ota_entry_example.bin" }, { - "tag": 9, + "tag": 105, "descriptor": [ { "name": "ssbl_version", @@ -127,7 +127,7 @@ "path": "./binaries/ssbl_ext_flash_ota_entry_example.bin" }, { - "tag": 10, + "tag": 106, "descriptor": [ { "name": "ssbl_version", @@ -148,7 +148,7 @@ "path": "./binaries/ssbl_ext_flash_ota_entry_example.bin" }, { - "tag": 11, + "tag": 107, "descriptor": [ { "name": "ssbl_version", diff --git a/scripts/tools/nxp/ota/ota_image_tool.py b/scripts/tools/nxp/ota/ota_image_tool.py index 64715d784aeecd..592fb71329e7fd 100755 --- a/scripts/tools/nxp/ota/ota_image_tool.py +++ b/scripts/tools/nxp/ota/ota_image_tool.py @@ -24,9 +24,6 @@ The OTA payload can then be used to generate an OTA image file, which will be parsed by the OTA image processor. The total size of TLVs is needed as input for a TLVReader. - -Currently, this script only supports Certification Declaration update, -but it could be modified to support all factory data fields. ''' import argparse @@ -63,6 +60,9 @@ class TAG: APPLICATION = 1 BOOTLOADER = 2 FACTORY_DATA = 3 + # Reserving 99 tags (highly unlikely this number will be reached) for NXP use. + # Custom TLVs should set its tag values to a number greater than LAST_RESERVED. + LAST_RESERVED = 99 def write_to_temp(path: str, payload: bytearray): @@ -211,6 +211,12 @@ def generate_custom_tlvs(data): elif isinstance(field["value"], int): descriptor += bytearray(field["value"].to_bytes(field["length"], "little")) file_size = os.path.getsize(entry["path"]) + + if entry["tag"] <= TAG.LAST_RESERVED: + print( + f"There is a custom TLV with a reserved tag {entry['tag']}. Please ensure all tags are greater than {TAG.LAST_RESERVED}") + sys.exit(1) + payload = generate_header(entry["tag"], len(descriptor) + file_size) + descriptor temp_output = os.path.join(os.path.dirname(__file__), "ota_temp_custom_tlv_" + str(iteration) + ".bin") diff --git a/src/credentials/tests/BUILD.gn b/src/credentials/tests/BUILD.gn index 3b0458233ac757..2de5d99a7bb091 100644 --- a/src/credentials/tests/BUILD.gn +++ b/src/credentials/tests/BUILD.gn @@ -57,7 +57,7 @@ chip_test_suite_using_nltest("tests") { ] # DUTVectors test requires which is not supported on all platforms - if (chip_device_platform != "openiotsdk") { + if (chip_device_platform != "openiotsdk" && chip_device_platform != "nxp") { test_sources += [ "TestCommissionerDUTVectors.cpp" ] } diff --git a/src/lib/shell/BUILD.gn b/src/lib/shell/BUILD.gn index 0bc5ce60874e02..10dad73a268602 100644 --- a/src/lib/shell/BUILD.gn +++ b/src/lib/shell/BUILD.gn @@ -56,11 +56,6 @@ static_library("shell") { "MainLoopSilabs.cpp", "streamer_silabs.cpp", ] - } else if (chip_device_platform == "k32w0") { - sources += [ - "MainLoopDefault.cpp", - "streamer_k32w.cpp", - ] } else if (chip_device_platform == "nxp") { sources += [ "MainLoopDefault.cpp", diff --git a/src/lib/shell/streamer_k32w.cpp b/src/lib/shell/streamer_k32w.cpp deleted file mode 100644 index fadcb82f1913e1..00000000000000 --- a/src/lib/shell/streamer_k32w.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * Source implementation of an input / output stream for k32w targets. - */ - -#include -#include - -#include -#include - -#include "SerialManager.h" -extern uint8_t gShellSerMgrIf; - -namespace chip { -namespace Shell { -namespace { -extern "C" void K32WWriteBlocking(const uint8_t * aBuf, uint32_t len); -extern "C" serialStatus_t Serial_Read(uint8_t InterfaceId, uint8_t * pData, uint16_t dataSize, uint16_t * bytesRead); - -int streamer_k32w_init(streamer_t * streamer) -{ - (void) streamer; - - return 0; -} - -ssize_t streamer_k32w_read(streamer_t * streamer, char * buffer, size_t length) -{ - uint16_t bytesRead = 0; - - (void) streamer; - Serial_Read(gShellSerMgrIf, (uint8_t *) buffer, length, &bytesRead); - - return bytesRead; -} - -ssize_t streamer_k32w_write(streamer_t * streamer, const char * buffer, size_t length) -{ - (void) streamer; - K32WWriteBlocking((uint8_t *) buffer, length); - - return length; -} - -static streamer_t streamer_k32w = { - .init_cb = streamer_k32w_init, - .read_cb = streamer_k32w_read, - .write_cb = streamer_k32w_write, -}; -} // namespace - -streamer_t * streamer_get(void) -{ - return &streamer_k32w; -} - -} // namespace Shell -} // namespace chip diff --git a/src/lib/shell/streamer_nxp.cpp b/src/lib/shell/streamer_nxp.cpp index aed4796902942a..e46fce84072529 100644 --- a/src/lib/shell/streamer_nxp.cpp +++ b/src/lib/shell/streamer_nxp.cpp @@ -25,6 +25,7 @@ /* Includes */ /* -------------------------------------------------------------------------- */ +#include #include #include @@ -97,10 +98,10 @@ static void Uart_TxCallBack(void * pBuffer, serial_manager_callback_message_t * static SERIAL_MANAGER_HANDLE_DEFINE(streamerSerialHandle); static SERIAL_MANAGER_WRITE_HANDLE_DEFINE(streamerSerialWriteHandle); static SERIAL_MANAGER_READ_HANDLE_DEFINE(streamerSerialReadHandle); -static volatile int txCount = 0; -static bool readDone = true; +static volatile int txCount = 0; +volatile static bool readDone = true; -static streamer_serial_port_uart_config_t uartConfig = { .clockRate = BOARD_APP_UART_CLK_FREQ, +static streamer_serial_port_uart_config_t uartConfig = { .clockRate = 0, .baudRate = BOARD_DEBUG_UART_BAUDRATE, .parityMode = kSerialManager_UartParityDisabled, .stopBitCount = kSerialManager_UartOneStopBit, @@ -129,6 +130,8 @@ static const serial_manager_config_t s_serialManagerConfig = { .portConfig = (serial_port_uart_config_t *) &uartConfig, }; +OSA_MUTEX_HANDLE_DEFINE(streamerMutex); + /* -------------------------------------------------------------------------- */ /* Public functions */ /* -------------------------------------------------------------------------- */ @@ -146,6 +149,8 @@ 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; @@ -180,6 +185,9 @@ int streamer_nxp_init(streamer_t * streamer) OSA_InterruptEnable(); + osa_status_t status_osa = OSA_MutexCreate((osa_mutex_handle_t) streamerMutex); + assert(status_osa == KOSA_StatusSuccess); + return status; } @@ -204,10 +212,13 @@ ssize_t streamer_nxp_read(streamer_t * streamer, char * buffer, size_t length) assert(status != kStatus_SerialManager_Error); /** - * If we are at the end of the line or the buffer is empty, - * consider the reading process done + * In certain cases such as a copy-paste of multiple commands, we may encounter '\n' or '\r' caracters + * although the buffer is not empty yet, so the reading process should be considered done only when the + * bytesRead return null, + * this is to ensure that all commands are processed before blocking the CLI task + * **/ - if ((buffer[length - 1] == '\n') || (buffer[length - 1] == '\r') || (bytesRead == 0)) + if (bytesRead == 0) { readDone = true; } @@ -219,25 +230,36 @@ ssize_t streamer_nxp_read(streamer_t * streamer, char * buffer, size_t length) ssize_t streamer_nxp_write(streamer_t * streamer, const char * buffer, size_t length) { uint32_t intMask; - serial_manager_status_t status = kStatus_SerialManager_Error; + serial_manager_status_t status = kStatus_SerialManager_Success; size_t len = 0; - intMask = DisableGlobalIRQ(); - txCount++; - status = SerialManager_WriteNonBlocking((serial_write_handle_t) streamerSerialWriteHandle, - (uint8_t *) (const_cast(buffer)), (uint32_t) length); - EnableGlobalIRQ(intMask); - if (status == kStatus_SerialManager_Success) - { - len = length; - } + /* Mutex lock to ensure the streamer write is accessed by only one task at a time */ + osa_status_t status_osa = OSA_MutexLock(streamerMutex, osaWaitForever_c); - /* Wait for the serial manager task to empty the TX buffer */ - while (txCount) + // If length is 0 there will be an assert in Serial Manager. Some OT functions output 0 bytes, for example + // in SrpServer::Process -> OutputLine(hasSubType ? "" : "(null)"); + if (length > 0) { - OSA_TimeDelay(STREAMER_UART_FLUSH_DELAY_MS); + intMask = DisableGlobalIRQ(); + txCount++; + status = SerialManager_WriteNonBlocking((serial_write_handle_t) streamerSerialWriteHandle, (uint8_t *) buffer, + (uint32_t) length); + EnableGlobalIRQ(intMask); + if (status == kStatus_SerialManager_Success) + { + len = length; + } + + /* Wait for the serial manager task to empty the TX buffer */ + while (txCount) + { + OSA_TimeDelay(STREAMER_UART_FLUSH_DELAY_MS); + } } + status_osa = OSA_MutexUnlock(streamerMutex); + assert(status_osa == KOSA_StatusSuccess); + return len; } diff --git a/src/lwip/BUILD.gn b/src/lwip/BUILD.gn index 98e94def25fb84..6d7e58d8a59fff 100644 --- a/src/lwip/BUILD.gn +++ b/src/lwip/BUILD.gn @@ -30,12 +30,11 @@ 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 == "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 == "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") { @@ -54,8 +53,6 @@ if (lwip_platform == "cc13xx_26xx") { } else if (lwip_platform == "qpg") { import("//build_overrides/qpg_sdk.gni") import("${qpg_sdk_build_root}/qpg_sdk.gni") -} else if (lwip_platform == "k32w0") { - import("//build_overrides/k32w0_sdk.gni") } else if (lwip_platform == "psoc6") { import("//build_overrides/psoc6.gni") } else if (lwip_platform == "cyw30739") { @@ -230,8 +227,6 @@ if (current_os == "zephyr" || current_os == "mbed") { ] } else if (lwip_platform == "standalone") { public_deps += [ "${chip_root}/src/lib/support" ] - } else if (lwip_platform == "k32w0") { - public_deps += [ "${k32w0_sdk_build_root}:k32w0_sdk" ] } else if (lwip_platform == "cyw30739") { public_deps += [ "${cyw30739_sdk_build_root}:cyw30739_sdk" ] } else if (lwip_platform == "bl702") { diff --git a/src/lwip/k32w1/arch/cc.h b/src/lwip/k32w1/arch/cc.h new file mode 100644 index 00000000000000..0dd3a291498a93 --- /dev/null +++ b/src/lwip/k32w1/arch/cc.h @@ -0,0 +1,90 @@ +/* + * + * Copyright (c) 2020 Nest Labs, Inc. + * All rights reserved. + * + * This document is the property of Nest. It is considered + * confidential and proprietary information. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Nest. + * + * Description: + * This file defines processor-architecture- and toolchain- + * specific constants and types required for building + * LwIP against FreeRTOS. + * + */ + +#ifndef NL_LWIP_FREERTOS_ARCH_CC_H +#define NL_LWIP_FREERTOS_ARCH_CC_H + +#include +#include +#include +#include +#include +#include +#include + +#if CHIP_CONFIG_MEMORY_MGMT_MALLOC +#include +#endif + +#if __cplusplus +extern "C" { +#endif + +#ifndef LWIP_NOASSERT +#ifdef DEBUG +#define LWIP_PLATFORM_ASSERT(MSG) assert(MSG); +#else +#define LWIP_PLATFORM_ASSERT(MSG) +#endif +#else +#define LWIP_PLATFORM_ASSERT(message) +#endif + +#ifndef BYTE_ORDER +#if defined(__LITTLE_ENDIAN__) +#define BYTE_ORDER LITTLE_ENDIAN +#elif defined(__BIG_ENDIAN__) +#define BYTE_ORDER BIG_ENDIAN +#elif defined(__BYTE_ORDER__) +#define BYTE_ORDER __BYTE_ORDER__ +#endif +#endif // BYTE_ORDER + +#define PACK_STRUCT_STRUCT __attribute__((__packed__)) +#define PACK_STRUCT_FIELD(x) x + +extern void LwIPLog(const char * fmt, ...); +#define LWIP_PLATFORM_DIAG(x) \ + do \ + { \ + LwIPLog x; \ + } while (0) + +// Place LwIP pools into their own subsections of .bss to make it easier to see +// their sizes in the linker map file. +extern uint8_t __attribute__((section(".bss.lwip_ND6_QUEUE"))) memp_memory_ND6_QUEUE_base[]; +extern uint8_t __attribute__((section(".bss.lwip_IP6_REASSDATA"))) memp_memory_IP6_REASSDATA_base[]; +extern uint8_t __attribute__((section(".bss.lwip_RAW_PCB"))) memp_memory_RAW_PCB_base[]; +extern uint8_t __attribute__((section(".bss.lwip_TCP_SEG"))) memp_memory_TCP_SEG_base[]; +extern uint8_t __attribute__((section(".bss.lwip_PBUF_POOL"))) memp_memory_PBUF_POOL_base[]; +extern uint8_t __attribute__((section(".bss.lwip_FRAG_PBUF"))) memp_memory_FRAG_PBUF_base[]; +extern uint8_t __attribute__((section(".bss.lwip_PBUF"))) memp_memory_PBUF_base[]; +extern uint8_t __attribute__((section(".bss.lwip_TCP_PCB_LISTEN"))) memp_memory_TCP_PCB_LISTEN_base[]; +extern uint8_t __attribute__((section(".bss.lwip_REASSDATA"))) memp_memory_REASSDATA_base[]; +extern uint8_t __attribute__((section(".bss.lwip_UDP_PCB"))) memp_memory_UDP_PCB_base[]; +extern uint8_t __attribute__((section(".bss.lwip_MLD6_GROUP"))) memp_memory_MLD6_GROUP_base[]; +extern uint8_t __attribute__((section(".bss.lwip_IGMP_GROUP"))) memp_memory_IGMP_GROUP_base[]; +extern uint8_t __attribute__((section(".bss.lwip_TCP_PCB"))) memp_memory_TCP_PCB_base[]; +extern uint8_t __attribute__((section(".bss.lwip_SYS_TIMEOUT"))) memp_memory_SYS_TIMEOUT_base[]; + +#if __cplusplus +} +#endif + +#endif /* NL_LWIP_FREERTOS_ARCH_CC_H */ diff --git a/src/lwip/k32w1/arch/perf.h b/src/lwip/k32w1/arch/perf.h new file mode 100644 index 00000000000000..bbef2139053135 --- /dev/null +++ b/src/lwip/k32w1/arch/perf.h @@ -0,0 +1,26 @@ +/* + * + * Copyright (c) 2020 Nest Labs, Inc. + * All rights reserved. + * + * This document is the property of Nest. It is considered + * confidential and proprietary information. + * + * This document may not be reproduced or transmitted in any form, + * in whole or in part, without the express written permission of + * Nest. + * + * Description: + * This file defines processor-architecture-specific constants, + * interfaces and types required for LwIP performance + * measurement. + * + */ + +#ifndef NL_LWIP_FREERTOS_ARCH_PERF_H +#define NL_LWIP_FREERTOS_ARCH_PERF_H + +#define PERF_START +#define PERF_STOP(s) + +#endif /* NL_LWIP_FREERTOS_ARCH_PERF_H */ diff --git a/src/lwip/k32w1/lwipopts.h b/src/lwip/k32w1/lwipopts.h new file mode 100644 index 00000000000000..1ecec9f14f0a70 --- /dev/null +++ b/src/lwip/k32w1/lwipopts.h @@ -0,0 +1,172 @@ +/* + * + * Copyright (c) 2020 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Compile-time configuration for LwIP on K32W platforms using the + * NXP K32W SDK. + * + */ + +#ifndef __LWIPOPTS_H__ +#define __LWIPOPTS_H__ + +#if CHIP_HAVE_CONFIG_H +#include +#endif + +#include + +#define NO_SYS 0 +#define MEM_ALIGNMENT (4) +#define MEMP_NUM_TCP_SEG (TCP_SND_QUEUELEN + 1) +#define LWIP_TIMEVAL_PRIVATE (0) +#define MEM_LIBC_MALLOC (0) +#define LWIP_COMPAT_MUTEX (0) +#define SYS_LIGHTWEIGHT_PROT (1) +#define LWIP_AUTOIP (0) +#define LWIP_DHCP_AUTOIP_COOP (0) +#define LWIP_SOCKET_SET_ERRNO 0 +#define IP_REASS_MAX_PBUFS 0 +#define IP_REASSEMBLY 0 +#define MEMP_NUM_REASSDATA 0 +#define LWIP_SO_RCVTIMEO 0 +#define SO_REUSE (1) +#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS (1) +#define LWIP_STATS (0) +#define LWIP_TCPIP_CORE_LOCKING 1 +#define TCP_QUEUE_OOSEQ 0 +#define ARP_QUEUEING (0) + +#define LWIP_SOCKET 0 + +#define LWIP_RAW 0 +#define MEMP_NUM_RAW_PCB 0 +#if INET_CONFIG_ENABLE_TCP_ENDPOINT +#define LWIP_TCP 1 +#else +#define LWIP_TCP 0 +#define MEMP_NUM_TCP_PCB 0 +#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT + +// TODO: verify count +#define MEMP_NUM_UDP_PCB (7) + +#define LWIP_HAVE_LOOPIF (0) + +// TODO: not sure why this is disabled +#define LWIP_NETIF_LOOPBACK (0) + +#define MEMP_NUM_NETCONN (0) + +#define LWIP_IPV4 0 +#define LWIP_IPV6 1 +#define LWIP_ARP (0) +#define LWIP_DNS (0) +#define LWIP_ICMP (0) +#define LWIP_IGMP (0) +#define LWIP_DHCP (0) +#define LWIP_IPV6_REASS (0) +#define LWIP_IPV6_DHCP6 0 +#define LWIP_IPV6_AUTOCONFIG (0) +#define LWIP_IPV6_ROUTER_SUPPORT 0 +#define LWIP_ND6_LISTEN_RA 0 + +#define LWIP_ND6_NUM_NEIGHBORS (0) +#define LWIP_ND6_NUM_DESTINATIONS (0) +#define LWIP_ND6_NUM_PREFIXES (0) +#define LWIP_ND6_NUM_ROUTERS (0) +#define LWIP_ND6_MAX_MULTICAST_SOLICIT (0) +#define LWIP_ND6_MAX_UNICAST_SOLICIT (0) +#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT (0) +#define LWIP_ND6_TCP_REACHABILITY_HINTS (0) + +#define MEMP_SEPARATE_POOLS (1) +#define LWIP_PBUF_FROM_CUSTOM_POOLS (0) +#define MEMP_USE_CUSTOM_POOLS (0) +#define PBUF_POOL_SIZE (6) +#define PBUF_POOL_BUFSIZE (1280) +#define PBUF_CUSTOM_POOL_IDX_START (MEMP_PBUF_POOL_SMALL) +#define PBUF_CUSTOM_POOL_IDX_END (MEMP_PBUF_POOL_LARGE) + +#define TCP_MSS (1152) +#define TCP_SND_BUF (2 * TCP_MSS) +#define TCP_LISTEN_BACKLOG (1) + +#define ETH_PAD_SIZE (0) +#define SUB_ETHERNET_HEADER_SPACE (0) +#define PBUF_LINK_HLEN (0) + +#define TCPIP_THREAD_STACKSIZE (2048) +#define TCPIP_THREAD_PRIO (3) + +#define NETIF_MAX_HWADDR_LEN 8U + +#define LWIP_IPV6_NUM_ADDRESSES 5 + +#define LWIP_IPV6_ND 0 +#define LWIP_ND6_QUEUEING 0 + +#define LWIP_MULTICAST_PING 0 + +#define TCPIP_MBOX_SIZE 6 +#define DEFAULT_RAW_RECVMBOX_SIZE 6 +#define DEFAULT_UDP_RECVMBOX_SIZE 6 +#define DEFAULT_TCP_RECVMBOX_SIZE 6 + +// TODO: make LWIP_DEBUG conditional on build type + +#ifndef LWIP_DEBUG +#define LWIP_DEBUG 0 +#endif + +#define MEMP_OVERFLOW_CHECK (0) +#define MEMP_SANITY_CHECK (0) +#define MEM_DEBUG (LWIP_DBG_OFF) +#define MEMP_DEBUG (LWIP_DBG_OFF) +#define PBUF_DEBUG (LWIP_DBG_OFF) +#define API_LIB_DEBUG (LWIP_DBG_OFF) +#define API_MSG_DEBUG (LWIP_DBG_OFF) +#define TCPIP_DEBUG (LWIP_DBG_OFF) +#define NETIF_DEBUG (LWIP_DBG_OFF) +#define SOCKETS_DEBUG (LWIP_DBG_OFF) +#define DEMO_DEBUG (LWIP_DBG_OFF) +#define DHCP_DEBUG (LWIP_DBG_OFF) +#define AUTOIP_DEBUG (LWIP_DBG_OFF) +#define ETHARP_DEBUG (LWIP_DBG_OFF) +#define IP_DEBUG (LWIP_DBG_OFF) +#define IP_REASS_DEBUG (LWIP_DBG_OFF) +#define IP6_DEBUG (LWIP_DBG_OFF) +#define RAW_DEBUG (LWIP_DBG_OFF) +#define ICMP_DEBUG (LWIP_DBG_OFF) +#define UDP_DEBUG (LWIP_DBG_OFF) +#define TCP_DEBUG (LWIP_DBG_OFF) +#define TCP_INPUT_DEBUG (LWIP_DBG_OFF) +#define TCP_OUTPUT_DEBUG (LWIP_DBG_OFF) +#define TCP_RTO_DEBUG (LWIP_DBG_OFF) +#define TCP_CWND_DEBUG (LWIP_DBG_OFF) +#define TCP_WND_DEBUG (LWIP_DBG_OFF) +#define TCP_FR_DEBUG (LWIP_DBG_OFF) +#define TCP_QLEN_DEBUG (LWIP_DBG_OFF) +#define TCP_RST_DEBUG (LWIP_DBG_OFF) +#define PPP_DEBUG (LWIP_DBG_OFF) + +#define LWIP_DBG_TYPES_ON \ + (LWIP_DBG_ON | LWIP_DBG_TRACE) /* (LWIP_DBG_ON|LWIP_DBG_TRACE|LWIP_DBG_STATE|LWIP_DBG_FRESH|LWIP_DBG_HALT) */ + +#endif /* __LWIPOPTS_H__ */ diff --git a/src/lwip/k32w1/lwippools.h b/src/lwip/k32w1/lwippools.h new file mode 100644 index 00000000000000..8b137891791fe9 --- /dev/null +++ b/src/lwip/k32w1/lwippools.h @@ -0,0 +1 @@ + diff --git a/src/messaging/tests/BUILD.gn b/src/messaging/tests/BUILD.gn index b6f1dcb02c5ce7..699066ff0b7402 100644 --- a/src/messaging/tests/BUILD.gn +++ b/src/messaging/tests/BUILD.gn @@ -55,7 +55,7 @@ chip_test_suite_using_nltest("tests") { ] if (chip_device_platform != "esp32" && chip_device_platform != "mbed" && - chip_device_platform != "nrfconnect") { + chip_device_platform != "nrfconnect" && chip_device_platform != "nxp") { test_sources += [ "TestExchangeHolder.cpp" ] } diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn index 4a0760334fb8cb..654875cde51b49 100644 --- a/src/platform/BUILD.gn +++ b/src/platform/BUILD.gn @@ -141,9 +141,8 @@ if (chip_device_platform != "none" && chip_device_platform != "external") { if (chip_device_platform == "linux" || chip_device_platform == "darwin" || chip_device_platform == "tizen" || chip_device_platform == "android" || - chip_device_platform == "k32w0" || chip_device_platform == "webos" || - chip_device_platform == "bl602" || chip_device_platform == "bl702" || - chip_device_platform == "bl702l") { + chip_device_platform == "webos" || chip_device_platform == "bl602" || + chip_device_platform == "bl702" || chip_device_platform == "bl702l") { defines += [ "CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE=${chip_enable_ble}" ] } @@ -217,9 +216,6 @@ if (chip_device_platform != "none" && chip_device_platform != "external") { } else if (chip_device_platform == "qpg") { device_layer_target_define = "QPG" defines += [ "CHIP_DEVICE_LAYER_TARGET=qpg" ] - } else if (chip_device_platform == "k32w0") { - device_layer_target_define = "K32W" - defines += [ "CHIP_DEVICE_LAYER_TARGET=nxp/k32w/k32w0" ] } else if (chip_device_platform == "nxp") { import("//build_overrides/nxp_sdk.gni") import("${nxp_sdk_build_root}/nxp_sdk.gni") @@ -335,7 +331,6 @@ if (chip_device_platform != "none" && chip_device_platform != "external") { "TIZEN", "NRFCONNECT", "QPG", - "K32W", "NXP", "NXP_ZEPHYR", "TELINK", @@ -538,8 +533,6 @@ if (chip_device_platform != "none") { _platform_target = "silabs/SiWx917" } else if (chip_device_platform == "esp32") { _platform_target = "ESP32" - } else if (chip_device_platform == "k32w0") { - _platform_target = "nxp/k32w/k32w0" } else if (chip_device_platform == "linux") { _platform_target = "Linux" } else if (chip_device_platform == "nrfconnect") { diff --git a/src/platform/device.gni b/src/platform/device.gni index 933b730186ec85..5dc4c812c0c648 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, nxp, qpg, tizen, cyw30739, bl602, mw320, zephyr, beken, openiotsdk, none. + # Device platform layer: cc13x2_26x2, cc13x4_26x4, cc32xx, darwin, efr32, esp32, external, freertos, linux, nrfconnect, nxp, qpg, tizen, cyw30739, bl602, mw320, zephyr, beken, openiotsdk, none. chip_device_platform = "auto" chip_platform_target = "" @@ -51,8 +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 == "tizen" || - chip_device_platform == "stm32" || chip_device_platform == "webos" + chip_device_platform == "tizen" || chip_device_platform == "stm32" || + chip_device_platform == "webos" } declare_args() { @@ -149,8 +149,6 @@ if (chip_device_platform == "cc13x2_26x2") { _chip_device_layer = "nrfconnect" } else if (chip_device_platform == "qpg") { _chip_device_layer = "qpg" -} else if (chip_device_platform == "k32w0") { - _chip_device_layer = "nxp/k32w/k32w0" } else if (chip_device_platform == "nxp") { import("//build_overrides/nxp_sdk.gni") import("${nxp_sdk_build_root}/nxp_sdk.gni") @@ -252,7 +250,6 @@ 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 == "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/common/CHIPNXPPlatformDefaultConfig.h b/src/platform/nxp/common/CHIPNXPPlatformDefaultConfig.h index 6070fbc84dcdb7..9282ffb5fe868e 100644 --- a/src/platform/nxp/common/CHIPNXPPlatformDefaultConfig.h +++ b/src/platform/nxp/common/CHIPNXPPlatformDefaultConfig.h @@ -66,7 +66,7 @@ #endif // CHIP_CONFIG_ERROR_CLASS #ifndef CHIP_CONFIG_SHA256_CONTEXT_SIZE -#define CHIP_CONFIG_SHA256_CONTEXT_SIZE (sizeof(unsigned int) * 76) +#define CHIP_CONFIG_SHA256_CONTEXT_SIZE (sizeof(unsigned int) * 98) #endif // CHIP_CONFIG_SHA256_CONTEXT_SIZE // ==================== Security Adaptations ==================== diff --git a/src/platform/nxp/common/ConnectivityManagerImpl.cpp b/src/platform/nxp/common/ConnectivityManagerImpl.cpp index 36b2ae978d65c8..91311b3f53a8ca 100644 --- a/src/platform/nxp/common/ConnectivityManagerImpl.cpp +++ b/src/platform/nxp/common/ConnectivityManagerImpl.cpp @@ -2,7 +2,7 @@ * * Copyright (c) 2020-2022 Project CHIP Authors * Copyright (c) 2020 Nest Labs, Inc. - * Copyright 2023 NXP + * Copyright 2023-2024 NXP * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -51,13 +51,18 @@ extern "C" { #include -#include +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + +#include + +#include "br_rtos_manager.h" +#endif /* CHIP_DEVICE_CONFIG_ENABLE_THREAD */ #endif /* CHIP_DEVICE_CONFIG_ENABLE_WPA */ #if CHIP_DEVICE_CONFIG_ENABLE_THREAD #include -#endif +#endif /* CHIP_DEVICE_CONFIG_ENABLE_THREAD */ using namespace ::chip; using namespace ::chip::Inet; @@ -87,6 +92,10 @@ CHIP_ERROR ConnectivityManagerImpl::_Init() GenericConnectivityManagerImpl_Thread::_Init(); #endif +#if CHIP_DEVICE_CONFIG_ENABLE_WPA + StartWiFiManagement(); +#endif + SuccessOrExit(err); exit: @@ -110,11 +119,34 @@ void ConnectivityManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) } else if (event->Type == kPlatformNxpStartWlanConnectEvent) { - if (wlan_add_network(event->Platform.pNetworkDataEvent) == WM_SUCCESS) + bool is_wlan_added = false; + struct wlan_network searchedNetwork = { 0 }; + + /* If network was added before on a previous connection call or other API, do not add it again */ + if (wlan_get_network_byname(event->Platform.pNetworkDataEvent->name, &searchedNetwork) != WM_SUCCESS) + { + if (wlan_add_network(event->Platform.pNetworkDataEvent) == WM_SUCCESS) + { + ChipLogProgress(DeviceLayer, "Added WLAN \"%s\"", event->Platform.pNetworkDataEvent->name); + is_wlan_added = true; + } + } + else + { + is_wlan_added = false; + } + + /* At this point, the network details should be registered in the wlan driver */ + if (is_wlan_added == true) { _SetWiFiStationState(kWiFiStationState_Connecting); ChipLogProgress(DeviceLayer, "WLAN connecting to network.name = \"%s\"", event->Platform.pNetworkDataEvent->name); +#if WIFI_DFS_OPTIMIZATION + /* Skip DFS (Dynamic Frequency Selection) channels during scan, DFS is used to avoid interferences */ + wlan_connect_opt(event->Platform.pNetworkDataEvent->name, true); +#else wlan_connect(event->Platform.pNetworkDataEvent->name); +#endif } if (event->Platform.pNetworkDataEvent != NULL) { @@ -314,6 +346,9 @@ void ConnectivityManagerImpl::UpdateInternetConnectivityState() const ip6_addr_t * addr6; CHIP_ERROR err; ChipDeviceEvent event; +#if CHIP_ENABLE_OPENTHREAD + otIp6Address newIpAddress; +#endif // If the WiFi station is currently in the connected state... if (_IsWiFiStationConnected()) @@ -350,6 +385,11 @@ void ConnectivityManagerImpl::UpdateInternetConnectivityState() { haveIPv6Conn = true; addr6 = netif_ip6_addr(netif, i); +#if CHIP_ENABLE_OPENTHREAD + // We are using ot mDNS sever and need to add IP address to server list + memcpy(&newIpAddress.mFields.m32, addr6->addr, sizeof(Inet::IPAddress)); + otMdnsServerAddAddress(ThreadStackMgrImpl().OTInstance(), &newIpAddress); +#endif break; } } @@ -369,8 +409,6 @@ void ConnectivityManagerImpl::UpdateInternetConnectivityState() if (haveIPv4Conn) { event.InternetConnectivityChange.ipAddress = IPAddress(*addr4); - /* (Re-)start the DNSSD server */ - chip::app::DnssdServer::Instance().StartServer(); } err = PlatformMgr().PostEvent(&event); VerifyOrDie(err == CHIP_NO_ERROR); @@ -386,8 +424,11 @@ void ConnectivityManagerImpl::UpdateInternetConnectivityState() if (haveIPv6Conn) { event.InternetConnectivityChange.ipAddress = IPAddress(*addr6); - /* (Re-)start the DNSSD server */ - chip::app::DnssdServer::Instance().StartServer(); + +#if CHIP_ENABLE_OPENTHREAD + // Start the Border Router services including MDNS Server + StartBrServices(); +#endif } err = PlatformMgr().PostEvent(&event); VerifyOrDie(err == CHIP_NO_ERROR); @@ -435,6 +476,48 @@ void ConnectivityManagerImpl::StartWiFiManagement() chipDie(); } } +#if CHIP_ENABLE_OPENTHREAD +void ConnectivityManagerImpl::StartBrServices() +{ + if (mBorderRouterInit == false) + { + struct netif * extNetIfPtr = static_cast(net_get_mlan_handle()); + struct netif * thrNetIfPtr = ThreadStackMgrImpl().ThreadNetIf(); + otInstance * thrInstancePtr; + + // Initalize internal interface variables, these can be used by other modules like the DNSSD Impl to + // get the underlying IP interface + Inet::InterfaceId tmpExtIf(extNetIfPtr); + Inet::InterfaceId tmpThrIf(thrNetIfPtr); + mExternalNetIf = tmpExtIf; + mThreadNetIf = tmpThrIf; + + // Need to wait for the wifi to be connected because the mlan netif can be !=null but not initialized + // properly. If the thread netif is !=null it means that it was fully initialized + + // Lock OT task + if ((thrNetIfPtr) && (mWiFiStationState == kWiFiStationState_Connected)) + { + mBorderRouterInit = true; + // Check if OT instance is init + thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + + BrInitServices(thrInstancePtr, extNetIfPtr, thrNetIfPtr); + otMdnsServerStart(thrInstancePtr); + } + } +} + +Inet::InterfaceId ConnectivityManagerImpl::GetThreadInterface() +{ + return sInstance.mThreadNetIf; +} + +Inet::InterfaceId ConnectivityManagerImpl::GetExternalInterface() +{ + return sInstance.mExternalNetIf; +} +#endif // CHIP_ENABLE_OPENTHREAD #endif // CHIP_DEVICE_CONFIG_ENABLE_WPA CHIP_ERROR ConnectivityManagerImpl::ProvisionWiFiNetwork(const char * ssid, uint8_t ssidLen, const char * key, uint8_t keyLen) diff --git a/src/platform/nxp/common/ConnectivityManagerImpl.h b/src/platform/nxp/common/ConnectivityManagerImpl.h index 427cbbe8e61cc3..806826daf0f7d3 100644 --- a/src/platform/nxp/common/ConnectivityManagerImpl.h +++ b/src/platform/nxp/common/ConnectivityManagerImpl.h @@ -87,6 +87,11 @@ class ConnectivityManagerImpl final : public ConnectivityManager, #if CHIP_DEVICE_CONFIG_ENABLE_WPA void StartWiFiManagement(); +#if CHIP_ENABLE_OPENTHREAD + Inet::InterfaceId GetExternalInterface(); + Inet::InterfaceId GetThreadInterface(); +#endif + #endif private: @@ -124,6 +129,7 @@ class ConnectivityManagerImpl final : public ConnectivityManager, ConnectivityManager::WiFiStationState mWiFiStationState; ConnectivityManager::WiFiAPMode mWiFiAPMode; uint32_t mWiFiStationReconnectIntervalMS; + bool mBorderRouterInit = false; #if CHIP_DEVICE_CONFIG_ENABLE_WPA enum WiFiEventGroup{ @@ -133,12 +139,20 @@ class ConnectivityManagerImpl final : public ConnectivityManager, BitFlags mFlags; static netif_ext_callback_t sNetifCallback; +#if CHIP_ENABLE_OPENTHREAD + Inet::InterfaceId mThreadNetIf; + Inet::InterfaceId mExternalNetIf; +#endif + static int _WlanEventCallback(enum wlan_event_reason event, void * data); static void _NetifExtCallback(struct netif * netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t * args); void OnStationConnected(void); void OnStationDisconnected(void); void UpdateInternetConnectivityState(void); +#if CHIP_ENABLE_OPENTHREAD + void StartBrServices(void); +#endif /* CHIP_DEVICE_CONFIG_ENABLE_THREAD */ #endif /* CHIP_DEVICE_CONFIG_ENABLE_WPA */ }; @@ -177,7 +191,7 @@ inline ConnectivityManager & ConnectivityMgr(void) * Returns the platform-specific implementation of the ConnectivityManager singleton object. * * Chip applications can use this to gain access to features of the ConnectivityManager - * that are specific to the ESP32 platform. + * that are specific to the NXP platform. */ inline ConnectivityManagerImpl & ConnectivityMgrImpl(void) { diff --git a/src/platform/nxp/common/DiagnosticDataProviderImpl.cpp b/src/platform/nxp/common/DiagnosticDataProviderImpl.cpp index 10e9f8d528b12f..0dd9b52f6a0aba 100644 --- a/src/platform/nxp/common/DiagnosticDataProviderImpl.cpp +++ b/src/platform/nxp/common/DiagnosticDataProviderImpl.cpp @@ -118,7 +118,7 @@ CHIP_ERROR DiagnosticDataProviderImpl::GetNetworkInterfaces(NetworkInterface ** ifp->isOperational = true; ifp->offPremiseServicesReachableIPv4.SetNull(); ifp->offPremiseServicesReachableIPv6.SetNull(); - ifp->type = EMBER_ZCL_INTERFACE_TYPE_ENUM_THREAD; + ifp->type = app::Clusters::GeneralDiagnostics::InterfaceTypeEnum::kThread; ConfigurationMgr().GetPrimary802154MACAddress(ifp->MacAddress); ifp->hardwareAddress = ByteSpan(ifp->MacAddress, kMaxHardwareAddrSize); #elif CHIP_DEVICE_CONFIG_ENABLE_WPA @@ -129,7 +129,7 @@ CHIP_ERROR DiagnosticDataProviderImpl::GetNetworkInterfaces(NetworkInterface ** ifp->isOperational = true; ifp->offPremiseServicesReachableIPv4.SetNull(); ifp->offPremiseServicesReachableIPv6.SetNull(); - ifp->type = EMBER_ZCL_INTERFACE_TYPE_ENUM_WI_FI; + ifp->type = app::Clusters::GeneralDiagnostics::InterfaceTypeEnum::kWiFi; ifp->hardwareAddress = ByteSpan(netif->hwaddr, netif->hwaddr_len); #endif diff --git a/src/platform/nxp/common/DnssdImpl.cpp b/src/platform/nxp/common/DnssdImpl.cpp new file mode 100644 index 00000000000000..8050da137f26b8 --- /dev/null +++ b/src/platform/nxp/common/DnssdImpl.cpp @@ -0,0 +1,797 @@ +/* + * + * 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 "lib/dnssd/platform/Dnssd.h" +#include +#include +#include +#include +#include + +#include + +#include + +using namespace ::chip::DeviceLayer; +using namespace chip::DeviceLayer::Internal; + +namespace chip { +namespace Dnssd { + +#define LOCAL_DOMAIN_STRING_SIZE 7 +#define ARPA_DOMAIN_STRING_SIZE 22 +#define MATTER_DNS_TXT_SIZE 128 + +// Support both operational and commissionable discovery, so buffers sizes must be worst case. +static constexpr uint8_t kMaxMdnsServiceTxtEntriesNumber = + std::max(Dnssd::CommissionAdvertisingParameters::kTxtMaxNumber, Dnssd::OperationalAdvertisingParameters::kTxtMaxNumber); +static constexpr size_t kTotalMdnsServiceTxtValueSize = std::max(Dnssd::CommissionAdvertisingParameters::kTxtTotalValueSize, + Dnssd::OperationalAdvertisingParameters::kTxtTotalValueSize); +static constexpr size_t kTotalMdnsServiceTxtKeySize = + std::max(Dnssd::CommissionAdvertisingParameters::kTxtTotalKeySize, Dnssd::OperationalAdvertisingParameters::kTxtTotalKeySize); + +static constexpr size_t kTotalMdnsServiceTxtBufferSize = + kTotalMdnsServiceTxtKeySize + kMaxMdnsServiceTxtEntriesNumber + kTotalMdnsServiceTxtValueSize; + +static const char * GetProtocolString(DnssdServiceProtocol protocol) +{ + return protocol == DnssdServiceProtocol::kDnssdProtocolUdp ? "_udp" : "_tcp"; +} + +struct DnsServiceTxtEntries +{ + uint8_t mBuffer[kTotalMdnsServiceTxtBufferSize]; + Dnssd::TextEntry mTxtEntries[kMaxMdnsServiceTxtEntriesNumber]; +}; + +struct mDnsQueryCtx +{ + void * matterCtx; + chip::Dnssd::DnssdService mMdnsService; + DnsServiceTxtEntries mServiceTxtEntry; + char mServiceType[chip::Dnssd::kDnssdTypeAndProtocolMaxSize + LOCAL_DOMAIN_STRING_SIZE + 1]; + CHIP_ERROR error; + + mDnsQueryCtx(void * context, CHIP_ERROR aError) + { + matterCtx = context; + error = aError; + } +}; + +static const char * GetProtocolString(DnssdServiceProtocol protocol); + +static void OtBrowseCallback(otError aError, const otDnsBrowseResponse * aResponse, void * aContext); +static void OtServiceCallback(otError aError, const otDnsServiceResponse * aResponse, void * aContext); + +static void DispatchBrowseEmpty(intptr_t context); +static void DispatchBrowse(intptr_t context); +static void DispatchBrowseNoMemory(intptr_t context); + +void DispatchAddressResolve(intptr_t context); +void DispatchResolve(intptr_t context); +void DispatchResolveNoMemory(intptr_t context); + +static DnsBrowseCallback mDnsBrowseCallback; +static DnsResolveCallback mDnsResolveCallback; + +CHIP_ERROR ResolveBySrp(DnssdService * mdnsReq, otInstance * thrInstancePtr, char * instanceName, void * context); +CHIP_ERROR BrowseBySrp(otInstance * thrInstancePtr, char * serviceName, void * context); + +CHIP_ERROR FromSrpCacheToMdnsData(const otSrpServerService * service, const otSrpServerHost * host, + const DnssdService * mdnsQueryReq, chip::Dnssd::DnssdService & mdnsService, + DnsServiceTxtEntries & serviceTxtEntries); + +static bool bBrowseInProgress = false; + +CHIP_ERROR ChipDnssdInit(DnssdAsyncReturnCallback initCallback, DnssdAsyncReturnCallback errorCallback, void * context) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + + uint8_t macBuffer[ConfigurationManager::kPrimaryMACAddressLength]; + MutableByteSpan mac(macBuffer); + char hostname[kHostNameMaxLength + LOCAL_DOMAIN_STRING_SIZE + 1] = ""; + ReturnErrorOnFailure(DeviceLayer::ConfigurationMgr().GetPrimaryMACAddress(mac)); + MakeHostName(hostname, sizeof(hostname), mac); + snprintf(hostname + strlen(hostname), sizeof(hostname), ".local."); + + error = MapOpenThreadError(otMdnsServerSetHostName(thrInstancePtr, hostname)); + + initCallback(context, error); + return error; +} + +void ChipDnssdShutdown() +{ + otMdnsServerStop(ThreadStackMgrImpl().OTInstance()); +} + +CHIP_ERROR ChipDnssdRemoveServices() +{ + otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + + otMdnsServerMarkServiceForRemoval(thrInstancePtr, nullptr, "_matter._tcp.local."); + otMdnsServerMarkServiceForRemoval(thrInstancePtr, nullptr, "_matterc._udp.local."); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR ChipDnssdPublishService(const DnssdService * service, DnssdPublishCallback callback, void * context) +{ + ReturnErrorCodeIf(service == nullptr, CHIP_ERROR_INVALID_ARGUMENT); + otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + otError otErr; + otDnsTxtEntry aTxtEntry; + uint32_t txtBufferOffset = 0; + + char fullInstName[Common::kInstanceNameMaxLength + chip::Dnssd::kDnssdTypeAndProtocolMaxSize + LOCAL_DOMAIN_STRING_SIZE + 1] = + ""; + char serviceType[chip::Dnssd::kDnssdTypeAndProtocolMaxSize + LOCAL_DOMAIN_STRING_SIZE + 1] = ""; + // secure space for the raw TXT data in the worst-case scenario relevant for Matter: + // each entry consists of txt_entry_size (1B) + txt_entry_key + "=" + txt_entry_data + uint8_t txtBuffer[kMaxMdnsServiceTxtEntriesNumber + kTotalMdnsServiceTxtBufferSize] = { 0 }; + + if ((strcmp(service->mHostName, "") != 0) && (nullptr == otMdnsServerGetHostName(thrInstancePtr))) + { + char hostname[kHostNameMaxLength + LOCAL_DOMAIN_STRING_SIZE + 1] = ""; + snprintf(hostname, sizeof(hostname), "%s.local.", service->mHostName); + otMdnsServerSetHostName(thrInstancePtr, hostname); + } + + snprintf(serviceType, sizeof(serviceType), "%s.%s.local.", service->mType, GetProtocolString(service->mProtocol)); + snprintf(fullInstName, sizeof(fullInstName), "%s.%s", service->mName, serviceType); + + for (uint32_t i = 0; i < service->mTextEntrySize; i++) + { + uint32_t keySize = strlen(service->mTextEntries[i].mKey); + // add TXT entry len, + 1 is for '=' + *(txtBuffer + txtBufferOffset++) = keySize + service->mTextEntries[i].mDataSize + 1; + + // add TXT entry key + memcpy(txtBuffer + txtBufferOffset, service->mTextEntries[i].mKey, keySize); + txtBufferOffset += keySize; + + // add TXT entry value if pointer is not null, if pointer is null it means we have bool value + if (service->mTextEntries[i].mData) + { + *(txtBuffer + txtBufferOffset++) = '='; + memcpy(txtBuffer + txtBufferOffset, service->mTextEntries[i].mData, service->mTextEntries[i].mDataSize); + txtBufferOffset += service->mTextEntries[i].mDataSize; + } + } + aTxtEntry.mKey = nullptr; + aTxtEntry.mValue = txtBuffer; + aTxtEntry.mValueLength = txtBufferOffset; + + otErr = otMdnsServerAddService(thrInstancePtr, fullInstName, serviceType, service->mSubTypes, service->mSubTypeSize, + service->mPort, &aTxtEntry, 1); + // Ignore duplicate error and threat it as error none + if (otErr == OT_ERROR_DUPLICATED) + otErr = OT_ERROR_NONE; + + return MapOpenThreadError(otErr); +} + +CHIP_ERROR ChipDnssdFinalizeServiceUpdate() +{ + otMdnsServerRemoveMarkedServices(ThreadStackMgrImpl().OTInstance()); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, Inet::IPAddressType addressType, + Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context, intptr_t * browseIdentifier) +{ + *browseIdentifier = reinterpret_cast(nullptr); + CHIP_ERROR error = CHIP_NO_ERROR; + CHIP_ERROR srpBrowseError = CHIP_NO_ERROR; + char serviceType[chip::Dnssd::kDnssdTypeAndProtocolMaxSize + ARPA_DOMAIN_STRING_SIZE + 1] = ""; // +1 for null-terminator + + if (type == nullptr || callback == nullptr) + return CHIP_ERROR_INVALID_ARGUMENT; + + otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + mDnsBrowseCallback = callback; + + mDnsQueryCtx * browseContext = Platform::New(context, CHIP_NO_ERROR); + VerifyOrReturnError(browseContext != nullptr, CHIP_ERROR_NO_MEMORY); + + // First try to browse the service in the SRP cache, use default.service.arpa as domain name + snprintf(serviceType, sizeof(serviceType), "%s.%s.default.service.arpa.", type, GetProtocolString(protocol)); + // After browsing in the SRP cache we will continue with regular mDNS browse + srpBrowseError = BrowseBySrp(thrInstancePtr, serviceType, context); + + // Proceed to generate a mDNS query + snprintf(browseContext->mServiceType, sizeof(browseContext->mServiceType), "%s.%s.local.", type, GetProtocolString(protocol)); + + error = MapOpenThreadError(otMdnsServerBrowse(thrInstancePtr, browseContext->mServiceType, OtBrowseCallback, browseContext)); + + if (CHIP_NO_ERROR == error) + { + bBrowseInProgress = true; + *browseIdentifier = reinterpret_cast(browseContext); + } + else + { + if (srpBrowseError == CHIP_NO_ERROR) + { + // In this case, we need to send a final browse indication to signal the Matter App that there are no more + // browse results coming + browseContext->error = error; + DeviceLayer::PlatformMgr().ScheduleWork(DispatchBrowseEmpty, reinterpret_cast(browseContext)); + } + else + { + Platform::Delete(browseContext); + } + } + return error; +} + +CHIP_ERROR ChipDnssdStopBrowse(intptr_t browseIdentifier) +{ + mDnsQueryCtx * browseContext = reinterpret_cast(browseIdentifier); + otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + otError error = OT_ERROR_INVALID_ARGS; + + // browseContext is only valid when bBrowseInProgress is true. The Matter stack can call this function even with a browseContext + // that has been freed in DispatchBrowseEmpty before. + if ((true == bBrowseInProgress) && (browseContext)) + { + browseContext->error = MapOpenThreadError(otMdnsServerStopQuery(thrInstancePtr, browseContext->mServiceType)); + + // browse context will be freed in DispatchBrowseEmpty + DeviceLayer::PlatformMgr().ScheduleWork(DispatchBrowseEmpty, reinterpret_cast(browseContext)); + } + return MapOpenThreadError(error); +} + +CHIP_ERROR ChipDnssdResolve(DnssdService * browseResult, Inet::InterfaceId interface, DnssdResolveCallback callback, void * context) +{ + ChipError error; + if (browseResult == nullptr || callback == nullptr) + return CHIP_ERROR_INVALID_ARGUMENT; + + otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + mDnsResolveCallback = callback; + + char serviceType[chip::Dnssd::kDnssdTypeAndProtocolMaxSize + ARPA_DOMAIN_STRING_SIZE + 1] = ""; // +1 for null-terminator + char fullInstName[Common::kInstanceNameMaxLength + chip::Dnssd::kDnssdTypeAndProtocolMaxSize + ARPA_DOMAIN_STRING_SIZE + 1] = + ""; + + // First try to find the service in the SRP cache, use default.service.arpa as domain name + snprintf(serviceType, sizeof(serviceType), "%s.%s.default.service.arpa.", browseResult->mType, + GetProtocolString(browseResult->mProtocol)); + snprintf(fullInstName, sizeof(fullInstName), "%s.%s", browseResult->mName, serviceType); + + error = ResolveBySrp(browseResult, thrInstancePtr, fullInstName, context); + if (CHIP_ERROR_NOT_FOUND == error) + { + // If the SRP cache returns not found, proceed to generate a MDNS query + memset(serviceType, 0, sizeof(serviceType)); + memset(fullInstName, 0, sizeof(fullInstName)); + + snprintf(serviceType, sizeof(serviceType), "%s.%s.local.", browseResult->mType, GetProtocolString(browseResult->mProtocol)); + snprintf(fullInstName, sizeof(fullInstName), "%s.%s", browseResult->mName, serviceType); + + return MapOpenThreadError(otMdnsServerResolveService(thrInstancePtr, fullInstName, OtServiceCallback, context)); + } + else + { + return error; + } +} + +CHIP_ERROR BrowseBySrp(otInstance * thrInstancePtr, char * serviceName, void * context) +{ + const otSrpServerHost * host = nullptr; + const otSrpServerService * service = nullptr; + CHIP_ERROR error = CHIP_ERROR_NOT_FOUND; + + while ((host = otSrpServerGetNextHost(thrInstancePtr, host)) != nullptr) + { + service = otSrpServerHostFindNextService(host, service, OT_SRP_SERVER_FLAGS_ANY_TYPE_ACTIVE_SERVICE, serviceName, nullptr); + if (service != nullptr) + { + mDnsQueryCtx * serviceContext; + + serviceContext = Platform::New(context, CHIP_NO_ERROR); + if (serviceContext != nullptr) + { + if (CHIP_NO_ERROR == + FromSrpCacheToMdnsData(service, host, nullptr, serviceContext->mMdnsService, serviceContext->mServiceTxtEntry)) + { + // Set error to CHIP_NO_ERROR to signal that there was at least one service found in the cache + error = CHIP_NO_ERROR; + DeviceLayer::PlatformMgr().ScheduleWork(DispatchBrowse, reinterpret_cast(serviceContext)); + } + else + { + Platform::Delete(serviceContext); + } + } + } + } + return error; +} + +CHIP_ERROR ResolveBySrp(DnssdService * mdnsReq, otInstance * thrInstancePtr, char * instanceName, void * context) +{ + const otSrpServerHost * host = nullptr; + const otSrpServerService * service = nullptr; + CHIP_ERROR error = CHIP_ERROR_NOT_FOUND; + + while ((host = otSrpServerGetNextHost(thrInstancePtr, host)) != nullptr) + { + service = otSrpServerHostFindNextService( + host, service, (OT_SRP_SERVER_SERVICE_FLAG_BASE_TYPE | OT_SRP_SERVER_SERVICE_FLAG_ACTIVE), nullptr, instanceName); + if (service != nullptr) + { + error = CHIP_NO_ERROR; + mDnsQueryCtx * serviceContext; + + serviceContext = Platform::New(context, CHIP_NO_ERROR); + if (serviceContext != nullptr) + { + error = + FromSrpCacheToMdnsData(service, host, mdnsReq, serviceContext->mMdnsService, serviceContext->mServiceTxtEntry); + if (error == CHIP_NO_ERROR) + { + DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolve, reinterpret_cast(serviceContext)); + } + else + { + Platform::Delete(serviceContext); + } + } + else + { + error = CHIP_ERROR_NO_MEMORY; + } + break; + } + } + return error; +} + +CHIP_ERROR FromSrpCacheToMdnsData(const otSrpServerService * service, const otSrpServerHost * host, + const DnssdService * mdnsQueryReq, chip::Dnssd::DnssdService & mdnsService, + DnsServiceTxtEntries & serviceTxtEntries) +{ + const char * tmpName; + const uint8_t * txtStringPtr; + size_t substringSize; + uint8_t addrNum = 0; + uint16_t txtDataLen; + const otIp6Address * ip6AddrPtr = otSrpServerHostGetAddresses(host, &addrNum); + + if (mdnsQueryReq != nullptr) + { + Platform::CopyString(mdnsService.mName, sizeof(mdnsService.mName), mdnsQueryReq->mName); + Platform::CopyString(mdnsService.mType, sizeof(mdnsService.mType), mdnsQueryReq->mType); + mdnsService.mProtocol = mdnsQueryReq->mProtocol; + } + else + { + tmpName = otSrpServerServiceGetInstanceName(service); + // Extract from the .... the part + size_t substringSize = strchr(tmpName, '.') - tmpName; + if (substringSize >= ArraySize(mdnsService.mName)) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + Platform::CopyString(mdnsService.mName, substringSize + 1, tmpName); + + // Extract from the .... the part. + tmpName = tmpName + substringSize + 1; + substringSize = strchr(tmpName, '.') - tmpName; + if (substringSize >= ArraySize(mdnsService.mType)) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + Platform::CopyString(mdnsService.mType, substringSize + 1, tmpName); + + // Extract from the .... the part. + tmpName = tmpName + substringSize + 1; + substringSize = strchr(tmpName, '.') - tmpName; + if (substringSize >= (chip::Dnssd::kDnssdProtocolTextMaxSize + 1)) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + if (strncmp(tmpName, "_udp", substringSize) == 0) + { + mdnsService.mProtocol = chip::Dnssd::DnssdServiceProtocol::kDnssdProtocolUdp; + } + else if (strncmp(tmpName, "_tcp", substringSize) == 0) + { + mdnsService.mProtocol = chip::Dnssd::DnssdServiceProtocol::kDnssdProtocolTcp; + } + else + { + mdnsService.mProtocol = chip::Dnssd::DnssdServiceProtocol::kDnssdProtocolUnknown; + } + } + + // Extract from the .. the part. + tmpName = otSrpServerHostGetFullName(host); + substringSize = strchr(tmpName, '.') - tmpName; + if (substringSize >= ArraySize(mdnsService.mHostName)) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + Platform::CopyString(mdnsService.mHostName, substringSize + 1, tmpName); + mdnsService.mPort = otSrpServerServiceGetPort(service); + + // All SRP cache hits come from the Thread Netif + mdnsService.mInterface = ConnectivityManagerImpl().GetThreadInterface(); + + mdnsService.mAddressType = Inet::IPAddressType::kIPv6; + mdnsService.mAddress = MakeOptional(ToIPAddress(*ip6AddrPtr)); + + // Extract TXT record SRP service + txtStringPtr = otSrpServerServiceGetTxtData(service, &txtDataLen); + if (txtDataLen != 0) + { + otDnsTxtEntryIterator iterator; + otDnsInitTxtEntryIterator(&iterator, txtStringPtr, txtDataLen); + + otDnsTxtEntry txtEntry; + chip::FixedBufferAllocator alloc(serviceTxtEntries.mBuffer); + + uint8_t entryIndex = 0; + while ((otDnsGetNextTxtEntry(&iterator, &txtEntry) == OT_ERROR_NONE) && entryIndex < 64) + { + if (txtEntry.mKey == nullptr || txtEntry.mValue == nullptr) + continue; + + serviceTxtEntries.mTxtEntries[entryIndex].mKey = alloc.Clone(txtEntry.mKey); + serviceTxtEntries.mTxtEntries[entryIndex].mData = alloc.Clone(txtEntry.mValue, txtEntry.mValueLength); + serviceTxtEntries.mTxtEntries[entryIndex].mDataSize = txtEntry.mValueLength; + entryIndex++; + } + + ReturnErrorCodeIf(alloc.AnyAllocFailed(), CHIP_ERROR_BUFFER_TOO_SMALL); + + mdnsService.mTextEntries = serviceTxtEntries.mTxtEntries; + mdnsService.mTextEntrySize = entryIndex; + } + else + { + mdnsService.mTextEntrySize = 0; + } + + mdnsService.mSubTypes = nullptr; + mdnsService.mSubTypeSize = 0; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FromOtDnsResponseToMdnsData(otDnsServiceInfo & serviceInfo, const char * serviceType, + chip::Dnssd::DnssdService & mdnsService, DnsServiceTxtEntries & serviceTxtEntries, + otError error) +{ + char protocol[chip::Dnssd::kDnssdProtocolTextMaxSize + 1]; + + if (strchr(serviceType, '.') == nullptr) + return CHIP_ERROR_INVALID_ARGUMENT; + + // Extract from the ... the part. + size_t substringSize = strchr(serviceType, '.') - serviceType; + if (substringSize >= ArraySize(mdnsService.mType)) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + Platform::CopyString(mdnsService.mType, substringSize + 1, serviceType); + + // Extract from the ... the part. + const char * protocolSubstringStart = serviceType + substringSize + 1; + + if (strchr(protocolSubstringStart, '.') == nullptr) + return CHIP_ERROR_INVALID_ARGUMENT; + + substringSize = strchr(protocolSubstringStart, '.') - protocolSubstringStart; + if (substringSize >= ArraySize(protocol)) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + Platform::CopyString(protocol, substringSize + 1, protocolSubstringStart); + + if (strncmp(protocol, "_udp", chip::Dnssd::kDnssdProtocolTextMaxSize) == 0) + { + mdnsService.mProtocol = chip::Dnssd::DnssdServiceProtocol::kDnssdProtocolUdp; + } + else if (strncmp(protocol, "_tcp", chip::Dnssd::kDnssdProtocolTextMaxSize) == 0) + { + mdnsService.mProtocol = chip::Dnssd::DnssdServiceProtocol::kDnssdProtocolTcp; + } + else + { + mdnsService.mProtocol = chip::Dnssd::DnssdServiceProtocol::kDnssdProtocolUnknown; + } + + // Check if SRV record was included in DNS response. + if (error != OT_ERROR_NOT_FOUND) + { + if (strchr(serviceInfo.mHostNameBuffer, '.') == nullptr) + return CHIP_ERROR_INVALID_ARGUMENT; + + // Extract from the .. the part. + substringSize = strchr(serviceInfo.mHostNameBuffer, '.') - serviceInfo.mHostNameBuffer; + if (substringSize >= ArraySize(mdnsService.mHostName)) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + Platform::CopyString(mdnsService.mHostName, substringSize + 1, serviceInfo.mHostNameBuffer); + + mdnsService.mPort = serviceInfo.mPort; + } + + // All mDNS replies come from the External Netif + mdnsService.mInterface = ConnectivityManagerImpl().GetExternalInterface(); + + // Check if AAAA record was included in DNS response. + if (!otIp6IsAddressUnspecified(&serviceInfo.mHostAddress)) + { + mdnsService.mAddressType = Inet::IPAddressType::kIPv6; + mdnsService.mAddress = MakeOptional(ToIPAddress(serviceInfo.mHostAddress)); + } + + // Check if TXT record was included in DNS response. + if (serviceInfo.mTxtDataSize != 0) + { + otDnsTxtEntryIterator iterator; + otDnsInitTxtEntryIterator(&iterator, serviceInfo.mTxtData, serviceInfo.mTxtDataSize); + + otDnsTxtEntry txtEntry; + chip::FixedBufferAllocator alloc(serviceTxtEntries.mBuffer); + + uint8_t entryIndex = 0; + while ((otDnsGetNextTxtEntry(&iterator, &txtEntry) == OT_ERROR_NONE) && entryIndex < 64) + { + if (txtEntry.mKey == nullptr || txtEntry.mValue == nullptr) + continue; + + serviceTxtEntries.mTxtEntries[entryIndex].mKey = alloc.Clone(txtEntry.mKey); + serviceTxtEntries.mTxtEntries[entryIndex].mData = alloc.Clone(txtEntry.mValue, txtEntry.mValueLength); + serviceTxtEntries.mTxtEntries[entryIndex].mDataSize = txtEntry.mValueLength; + entryIndex++; + } + + ReturnErrorCodeIf(alloc.AnyAllocFailed(), CHIP_ERROR_BUFFER_TOO_SMALL); + + mdnsService.mTextEntries = serviceTxtEntries.mTxtEntries; + mdnsService.mTextEntrySize = entryIndex; + } + else + { + mdnsService.mTextEntrySize = 0; + } + + return CHIP_NO_ERROR; +} + +void ChipDnssdResolveNoLongerNeeded(const char * instanceName) {} + +CHIP_ERROR ChipDnssdReconfirmRecord(const char * hostname, chip::Inet::IPAddress address, chip::Inet::InterfaceId interface) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +static void OtBrowseCallback(otError aError, const otDnsBrowseResponse * aResponse, void * aContext) +{ + CHIP_ERROR error; + // type buffer size is kDnssdTypeAndProtocolMaxSize + . + kMaxDomainNameSize + . + termination character + char type[Dnssd::kDnssdTypeAndProtocolMaxSize + LOCAL_DOMAIN_STRING_SIZE + 3]; + // hostname buffer size is kHostNameMaxLength + . + kMaxDomainNameSize + . + termination character + char hostname[Dnssd::kHostNameMaxLength + LOCAL_DOMAIN_STRING_SIZE + 3]; + // secure space for the raw TXT data in the worst-case scenario relevant for Matter: + // each entry consists of txt_entry_size (1B) + txt_entry_key + "=" + txt_entry_data + uint8_t txtBuffer[kMaxMdnsServiceTxtEntriesNumber + kTotalMdnsServiceTxtBufferSize]; + + mDnsQueryCtx * browseContext = reinterpret_cast(aContext); + otDnsServiceInfo serviceInfo; + uint16_t index = 0; + + /// TODO: check this code, might be remvoed, or if not free browseContext + if (mDnsBrowseCallback == nullptr) + { + ChipLogError(DeviceLayer, "Invalid dns browse callback"); + return; + } + + VerifyOrExit(aError == OT_ERROR_NONE, error = MapOpenThreadError(aError)); + + error = MapOpenThreadError(otDnsBrowseResponseGetServiceName(aResponse, type, sizeof(type))); + + VerifyOrExit(error == CHIP_NO_ERROR, ); + + char serviceName[Dnssd::Common::kInstanceNameMaxLength + 1]; + while (otDnsBrowseResponseGetServiceInstance(aResponse, index, serviceName, sizeof(serviceName)) == OT_ERROR_NONE) + { + serviceInfo.mHostNameBuffer = hostname; + serviceInfo.mHostNameBufferSize = sizeof(hostname); + serviceInfo.mTxtData = txtBuffer; + serviceInfo.mTxtDataSize = sizeof(txtBuffer); + + otError err = otDnsBrowseResponseGetServiceInfo(aResponse, serviceName, &serviceInfo); + error = MapOpenThreadError(err); + + VerifyOrExit(err == OT_ERROR_NOT_FOUND || err == OT_ERROR_NONE, ); + + mDnsQueryCtx * tmpContext = Platform::New(browseContext->matterCtx, CHIP_NO_ERROR); + + VerifyOrExit(tmpContext != nullptr, error = CHIP_ERROR_NO_MEMORY); + + error = FromOtDnsResponseToMdnsData(serviceInfo, type, tmpContext->mMdnsService, tmpContext->mServiceTxtEntry, err); + if (CHIP_NO_ERROR == error) + { + // Invoke callback for every service one by one instead of for the whole + // list due to large memory size needed to allocate on stack. + static_assert(ArraySize(tmpContext->mMdnsService.mName) >= ArraySize(serviceName), + "The target buffer must be big enough"); + Platform::CopyString(tmpContext->mMdnsService.mName, serviceName); + DeviceLayer::PlatformMgr().ScheduleWork(DispatchBrowse, reinterpret_cast(tmpContext)); + } + else + { + Platform::Delete(tmpContext); + } + index++; + } + +exit: + // Invoke callback to notify about end-of-browse when OT_ERROR_RESPONSE_TIMEOUT is received, otherwise ignore errors + if (aError == OT_ERROR_RESPONSE_TIMEOUT) + { + DeviceLayer::PlatformMgr().ScheduleWork(DispatchBrowseEmpty, reinterpret_cast(browseContext)); + } +} +static void OtServiceCallback(otError aError, const otDnsServiceResponse * aResponse, void * aContext) +{ + CHIP_ERROR error; + otError otErr; + otDnsServiceInfo serviceInfo; + mDnsQueryCtx * serviceContext; + bool bStopQuery = false; + + // If error is timeout we don't need to inform the Matter app and we can just exit + VerifyOrReturn(aError != OT_ERROR_RESPONSE_TIMEOUT, ); + + bStopQuery = true; + serviceContext = Platform::New(aContext, MapOpenThreadError(aError)); + VerifyOrExit(serviceContext != nullptr, error = CHIP_ERROR_NO_MEMORY); + + // type buffer size is kDnssdTypeAndProtocolMaxSize + . + kMaxDomainNameSize + . + termination character + char type[Dnssd::kDnssdTypeAndProtocolMaxSize + LOCAL_DOMAIN_STRING_SIZE + 3]; + // hostname buffer size is kHostNameMaxLength + . + kMaxDomainNameSize + . + termination character + char hostname[Dnssd::kHostNameMaxLength + LOCAL_DOMAIN_STRING_SIZE + 3]; + // secure space for the raw TXT data in the worst-case scenario relevant for Matter: + // each entry consists of txt_entry_size (1B) + txt_entry_key + "=" + txt_entry_data + uint8_t txtBuffer[kMaxMdnsServiceTxtEntriesNumber + kTotalMdnsServiceTxtBufferSize]; + + if (mDnsResolveCallback == nullptr) + { + ChipLogError(DeviceLayer, "Invalid dns resolve callback"); + return; + } + + VerifyOrExit(aError == OT_ERROR_NONE, error = MapOpenThreadError(aError)); + + error = MapOpenThreadError(otDnsServiceResponseGetServiceName(aResponse, serviceContext->mMdnsService.mName, + sizeof(serviceContext->mMdnsService.mName), type, sizeof(type))); + + VerifyOrExit(error == CHIP_NO_ERROR, ); + + serviceInfo.mHostNameBuffer = hostname; + serviceInfo.mHostNameBufferSize = sizeof(hostname); + serviceInfo.mTxtData = txtBuffer; + serviceInfo.mTxtDataSize = sizeof(txtBuffer); + + otErr = otDnsServiceResponseGetServiceInfo(aResponse, &serviceInfo); + error = MapOpenThreadError(otErr); + + VerifyOrExit(error == CHIP_NO_ERROR, ); + + error = FromOtDnsResponseToMdnsData(serviceInfo, type, serviceContext->mMdnsService, serviceContext->mServiceTxtEntry, otErr); + +exit: + if (serviceContext == nullptr) + { + DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolveNoMemory, reinterpret_cast(aContext)); + return; + } + + serviceContext->error = error; + + // If IPv6 address in unspecified (AAAA record not present), send additional DNS query to obtain IPv6 address. + if (otIp6IsAddressUnspecified(&serviceInfo.mHostAddress)) + { + DeviceLayer::PlatformMgr().ScheduleWork(DispatchAddressResolve, reinterpret_cast(serviceContext)); + } + else + { + DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolve, reinterpret_cast(serviceContext)); + } + + if (bStopQuery) + { + char fullInstName[Common::kInstanceNameMaxLength + chip::Dnssd::kDnssdTypeAndProtocolMaxSize + LOCAL_DOMAIN_STRING_SIZE + + 1] = ""; + snprintf(fullInstName, sizeof(fullInstName), "%s.%s", serviceContext->mMdnsService.mName, type); + + otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); + otMdnsServerStopQuery(thrInstancePtr, fullInstName); + } +} + +void DispatchBrowseEmpty(intptr_t context) +{ + auto * browseContext = reinterpret_cast(context); + mDnsBrowseCallback(browseContext->matterCtx, nullptr, 0, true, browseContext->error); + Platform::Delete(browseContext); + bBrowseInProgress = false; +} + +void DispatchBrowse(intptr_t context) +{ + auto * browseContext = reinterpret_cast(context); + mDnsBrowseCallback(browseContext->matterCtx, &browseContext->mMdnsService, 1, false, browseContext->error); + Platform::Delete(browseContext); +} + +void DispatchBrowseNoMemory(intptr_t context) +{ + mDnsBrowseCallback(reinterpret_cast(context), nullptr, 0, true, CHIP_ERROR_NO_MEMORY); +} + +void DispatchAddressResolve(intptr_t context) +{ + CHIP_ERROR error = CHIP_ERROR_NO_MEMORY; // ResolveAddress(context, OnDnsAddressResolveResult); + + // In case of address resolve failure, fill the error code field and dispatch method to end resolve process. + if (error != CHIP_NO_ERROR) + { + mDnsQueryCtx * resolveContext = reinterpret_cast(context); + resolveContext->error = error; + + DeviceLayer::PlatformMgr().ScheduleWork(DispatchResolve, reinterpret_cast(resolveContext)); + } +} + +void DispatchResolve(intptr_t context) +{ + mDnsQueryCtx * resolveContext = reinterpret_cast(context); + Dnssd::DnssdService & service = resolveContext->mMdnsService; + Span ipAddrs; + + if (service.mAddress.HasValue()) + { + ipAddrs = Span(&service.mAddress.Value(), 1); + } + + mDnsResolveCallback(resolveContext->matterCtx, &service, ipAddrs, resolveContext->error); + Platform::Delete(resolveContext); +} + +void DispatchResolveNoMemory(intptr_t context) +{ + Span ipAddrs; + mDnsResolveCallback(reinterpret_cast(context), nullptr, ipAddrs, CHIP_ERROR_NO_MEMORY); +} + +} // namespace Dnssd +} // namespace chip diff --git a/src/platform/nxp/common/KeyValueStoreManagerImpl.cpp b/src/platform/nxp/common/KeyValueStoreManagerImpl.cpp index 8b704841374d21..af2598ca2be188 100644 --- a/src/platform/nxp/common/KeyValueStoreManagerImpl.cpp +++ b/src/platform/nxp/common/KeyValueStoreManagerImpl.cpp @@ -46,6 +46,15 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t err = chip::DeviceLayer::Internal::NXPConfig::ReadConfigValueBin(key, (uint8_t *) value, value_size, read_bytes); + if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) + { + ChipLogError(DeviceLayer, "KVS, key not found!"); + } + else if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "KVS, failed to read key!"); + } + *read_bytes_size = read_bytes; exit: @@ -63,6 +72,9 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, err = chip::DeviceLayer::Internal::NXPConfig::WriteConfigValueBin(key, (uint8_t *) value, value_size); + if (err != CHIP_NO_ERROR) + ChipLogError(DeviceLayer, "KVS, failed to save key!"); + exit: ConvertError(err); return err; @@ -78,6 +90,9 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key) err = chip::DeviceLayer::Internal::NXPConfig::ClearConfigValue(key); + if (err != CHIP_NO_ERROR) + ChipLogError(DeviceLayer, "KVS, failed to delete key!"); + exit: ConvertError(err); return err; diff --git a/src/platform/nxp/common/NXPConfig.cpp b/src/platform/nxp/common/NXPConfig.cpp index fef73e8a31a34e..cc6f8d51ec1256 100644 --- a/src/platform/nxp/common/NXPConfig.cpp +++ b/src/platform/nxp/common/NXPConfig.cpp @@ -37,13 +37,23 @@ #define CHIP_PLAT_SAVE_NVM_DATA_ON_IDLE 1 #endif -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD -#include "ot_platform_common.h" +#define BUFFER_LOG_SIZE 256 + +/* + * If the developer has specified a size for integer keys RAM buffer + * partition, use it. Othewise use the default. + */ +#ifndef CONFIG_CHIP_NVM_RAMBUFFER_SIZE_KEY_INT +#define CONFIG_CHIP_NVM_RAMBUFFER_SIZE_KEY_INT (4 * 2048) #endif -#define BUFFER_LOG_SIZE 256 -#define CHIP_CONFIG_RAM_BUFFER_KEY_INT_SIZE 4 * 2048 -#define CHIP_CONFIG_RAM_BUFFER_KEY_STRING_SIZE 4 * 5000 +/* + * If the developer has specified a size for string keys RAM buffer + * partition, use it. Othewise use the default. + */ +#ifndef CONFIG_CHIP_NVM_RAMBUFFER_SIZE_KEY_STRING +#define CONFIG_CHIP_NVM_RAMBUFFER_SIZE_KEY_STRING (4 * 5000) +#endif #ifndef NVM_ID_CHIP_CONFIG_DATA_KEY_INT #define NVM_ID_CHIP_CONFIG_DATA_KEY_INT 0xf104 @@ -74,21 +84,21 @@ typedef struct { uint16_t chipConfigRamBufferLen; uint16_t padding; - uint8_t chipConfigRamBuffer[CHIP_CONFIG_RAM_BUFFER_KEY_INT_SIZE]; + uint8_t chipConfigRamBuffer[CONFIG_CHIP_NVM_RAMBUFFER_SIZE_KEY_INT]; } ChipConfigRamStructKeyInt; typedef struct { uint16_t chipConfigRamBufferLen; uint16_t padding; - uint8_t chipConfigRamBuffer[CHIP_CONFIG_RAM_BUFFER_KEY_STRING_SIZE]; + uint8_t chipConfigRamBuffer[CONFIG_CHIP_NVM_RAMBUFFER_SIZE_KEY_STRING]; } ChipConfigRamStructKeyString; /* File system containing only integer keys */ static ChipConfigRamStructKeyInt chipConfigRamStructKeyInt; static ramBufferDescriptor ramDescrKeyInt = { .ramBufferLen = &chipConfigRamStructKeyInt.chipConfigRamBufferLen, - .ramBufferMaxLen = CHIP_CONFIG_RAM_BUFFER_KEY_INT_SIZE, + .ramBufferMaxLen = CONFIG_CHIP_NVM_RAMBUFFER_SIZE_KEY_INT, .pRamBuffer = &chipConfigRamStructKeyInt.chipConfigRamBuffer[0], }; @@ -96,7 +106,7 @@ static ramBufferDescriptor ramDescrKeyInt = { static ChipConfigRamStructKeyString chipConfigRamStructKeyString; static ramBufferDescriptor ramDescrKeyString = { .ramBufferLen = &chipConfigRamStructKeyString.chipConfigRamBufferLen, - .ramBufferMaxLen = CHIP_CONFIG_RAM_BUFFER_KEY_STRING_SIZE, + .ramBufferMaxLen = CONFIG_CHIP_NVM_RAMBUFFER_SIZE_KEY_STRING, .pRamBuffer = &chipConfigRamStructKeyString.chipConfigRamBuffer[0], }; @@ -109,8 +119,8 @@ NVM_RegisterDataSet((void *) &chipConfigRamStructKeyString, 1, sizeof(chipConfig NVM_ID_CHIP_CONFIG_DATA_KEY_STRING, gNVM_MirroredInRam_c); #elif (CHIP_PLAT_NVM_SUPPORT == CHIP_PLAT_LITTLEFS) -const char mt_key_int_file_name[] = "mt_key_int"; -const char mt_key_str_file_name[] = "mt_key_str"; +const char * mt_key_int_file_name = "mt_key_int"; +const char * mt_key_str_file_name = "mt_key_str"; #if CHIP_PLAT_SAVE_NVM_DATA_ON_IDLE static bool mt_key_int_save_in_flash = false; static bool mt_key_str_save_in_flash = false; @@ -140,7 +150,7 @@ int NXPConfig::SaveIntKeysToFS(void) err_len = ramStorageSavetoFlash(mt_key_int_file_name, &chipConfigRamStructKeyInt.chipConfigRamBuffer[0], chipConfigRamStructKeyInt.chipConfigRamBufferLen); - assert(err_len <= CHIP_CONFIG_RAM_BUFFER_KEY_INT_SIZE); + assert(err_len <= CONFIG_CHIP_NVM_RAMBUFFER_SIZE_KEY_INT); assert(err_len >= 0); #endif @@ -156,7 +166,7 @@ int NXPConfig::SaveStringKeysToFS(void) int err_len; #if (CHIP_PLAT_NVM_SUPPORT == CHIP_PLAT_NVM_FWK) err_len = -1; - NvSaveOnIdle(&chipConfigRamStructKeyInt, false); + NvSaveOnIdle(&chipConfigRamStructKeyString, false); #elif (CHIP_PLAT_NVM_SUPPORT == CHIP_PLAT_LITTLEFS) err_len = -2; @@ -168,7 +178,7 @@ int NXPConfig::SaveStringKeysToFS(void) err_len = ramStorageSavetoFlash(mt_key_str_file_name, &chipConfigRamStructKeyString.chipConfigRamBuffer[0], chipConfigRamStructKeyString.chipConfigRamBufferLen); - assert(err_len <= CHIP_CONFIG_RAM_BUFFER_KEY_STRING_SIZE); + assert(err_len <= CONFIG_CHIP_NVM_RAMBUFFER_SIZE_KEY_STRING); assert(err_len >= 0); #endif @@ -207,14 +217,14 @@ CHIP_ERROR NXPConfig::Init() #elif (CHIP_PLAT_NVM_SUPPORT == CHIP_PLAT_LITTLEFS) /* Try to load the ot dataset in RAM */ err_len = ramStorageReadFromFlash(mt_key_int_file_name, &chipConfigRamStructKeyInt.chipConfigRamBuffer[0], - CHIP_CONFIG_RAM_BUFFER_KEY_INT_SIZE); - assert(err_len <= CHIP_CONFIG_RAM_BUFFER_KEY_INT_SIZE); + CONFIG_CHIP_NVM_RAMBUFFER_SIZE_KEY_INT); + assert(err_len <= CONFIG_CHIP_NVM_RAMBUFFER_SIZE_KEY_INT); assert(err_len >= 0); chipConfigRamStructKeyInt.chipConfigRamBufferLen = (uint16_t) err_len; err_len = ramStorageReadFromFlash(mt_key_str_file_name, &chipConfigRamStructKeyString.chipConfigRamBuffer[0], - CHIP_CONFIG_RAM_BUFFER_KEY_STRING_SIZE); - assert(err_len <= CHIP_CONFIG_RAM_BUFFER_KEY_STRING_SIZE); + CONFIG_CHIP_NVM_RAMBUFFER_SIZE_KEY_STRING); + assert(err_len <= CONFIG_CHIP_NVM_RAMBUFFER_SIZE_KEY_STRING); assert(err_len >= 0); chipConfigRamStructKeyString.chipConfigRamBufferLen = (uint16_t) err_len; @@ -240,7 +250,9 @@ CHIP_ERROR NXPConfig::ReadConfigValue(Key key, bool & val) SuccessOrExit(err = MapRamStorageStatus(status)); val = tempVal; +#if (DEBUG_NVM > 0) ChipLogProgress(DeviceLayer, "ReadConfigValue bool = %u", val); +#endif exit: return err; @@ -258,7 +270,9 @@ CHIP_ERROR NXPConfig::ReadConfigValue(Key key, uint32_t & val) SuccessOrExit(err = MapRamStorageStatus(status)); val = tempVal; +#if (DEBUG_NVM > 0) ChipLogProgress(DeviceLayer, "ReadConfigValue uint32_t = %lu", val); +#endif exit: return err; @@ -276,7 +290,9 @@ CHIP_ERROR NXPConfig::ReadConfigValue(Key key, uint64_t & val) SuccessOrExit(err = MapRamStorageStatus(status)); val = tempVal; +#if (DEBUG_NVM > 0) ChipLogProgress(DeviceLayer, "ReadConfigValue uint64_t = " ChipLogFormatX64, ChipLogValueX64(val)); +#endif exit: return err; @@ -292,7 +308,9 @@ CHIP_ERROR NXPConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize, si status = ramStorageGet(&ramDescrKeyInt, (uint8_t *) &key, sizeof(Key), 0, (uint8_t *) buf, &sizeToRead); SuccessOrExit(err = MapRamStorageStatus(status)); outLen = sizeToRead; +#if (DEBUG_NVM > 0) ChipLogProgress(DeviceLayer, "ReadConfigValueStr lenRead = %u", outLen); +#endif exit: return err; @@ -313,7 +331,9 @@ CHIP_ERROR NXPConfig::ReadConfigValueBin(const char * keyString, uint8_t * buf, status = ramStorageGet(&ramDescrKeyString, (const uint8_t *) keyString, strlen(keyString), 0, (uint8_t *) buf, &sizeToRead); SuccessOrExit(err = MapRamStorageStatus(status)); outLen = sizeToRead; +#if (DEBUG_NVM > 0) ChipLogProgress(DeviceLayer, "ReadConfigValueStr lenRead = %u", outLen); +#endif exit: return err; @@ -339,7 +359,9 @@ CHIP_ERROR NXPConfig::WriteConfigValue(Key key, bool val) (void) err_len; DBG_PRINTF("WriteConfigValue: MT write %d\r\n", err_len); +#if (DEBUG_NVM > 0) ChipLogProgress(DeviceLayer, "WriteConfigValue done"); +#endif exit: return err; @@ -359,7 +381,9 @@ CHIP_ERROR NXPConfig::WriteConfigValue(Key key, uint32_t val) (void) err_len; DBG_PRINTF("WriteConfigValue: MT write %d\r\n", err_len); +#if (DEBUG_NVM > 0) ChipLogProgress(DeviceLayer, "WriteConfigValue done"); +#endif exit: return err; @@ -379,7 +403,9 @@ CHIP_ERROR NXPConfig::WriteConfigValue(Key key, uint64_t val) (void) err_len; DBG_PRINTF("WriteConfigValue64: MT write %d\r\n", err_len); +#if (DEBUG_NVM > 0) ChipLogProgress(DeviceLayer, "WriteConfigValue done"); +#endif exit: return err; @@ -404,7 +430,9 @@ CHIP_ERROR NXPConfig::WriteConfigValueStr(Key key, const char * str, size_t strL (void) err_len; DBG_PRINTF("WriteConfigValueStr: MT write %d\r\n", err_len); +#if (DEBUG_NVM > 0) ChipLogProgress(DeviceLayer, "WriteConfigValue done"); +#endif exit: return err; @@ -429,7 +457,9 @@ CHIP_ERROR NXPConfig::WriteConfigValueBin(const char * keyString, const uint8_t (void) err_len; DBG_PRINTF("WriteConfigValueBin: MT write %d\r\n", err_len); +#if (DEBUG_NVM > 0) ChipLogProgress(DeviceLayer, "WriteConfigValue done"); +#endif exit: return err; @@ -499,11 +529,26 @@ CHIP_ERROR NXPConfig::FactoryResetConfig(void) ClearConfigValue(key); } + // Clear RebootCount, TotalOperationalHours, UpTime counters during factory reset + for (Key key = kMinConfigKey_ChipCounter; key <= (kMinConfigKey_ChipCounter + 3); key++) + { + ClearConfigValue(key); + } + /* Reset the key string file system as it contains on data that needs to be erased when doing a factoryreset */ FLib_MemSet((void *) &chipConfigRamStructKeyString, 0, sizeof(chipConfigRamStructKeyString)); +#if (CHIP_PLAT_NVM_SUPPORT == CHIP_PLAT_NVM_FWK) + /* + * Save to flash now. System is restarting and there is no more time to + * wait for the idle task to save the data. + */ + NvSyncSave(&chipConfigRamStructKeyString, false); + NvSyncSave(&chipConfigRamStructKeyInt, false); +#else SaveStringKeysToFS(); SaveIntKeysToFS(); +#endif DBG_PRINTF("FactoryResetConfig done\r\n"); return CHIP_NO_ERROR; @@ -569,12 +614,14 @@ void NXPConfig::RunSystemIdleTask(void) err_len = ramStorageSavetoFlash(mt_key_int_file_name, &chipConfigRamStructKeyInt.chipConfigRamBuffer[0], chipConfigRamStructKeyInt.chipConfigRamBufferLen); - assert(err_len <= CHIP_CONFIG_RAM_BUFFER_KEY_INT_SIZE); + assert(err_len <= CONFIG_CHIP_NVM_RAMBUFFER_SIZE_KEY_INT); assert(err_len >= 0); INFO_PRINTF("int mt write %d bytes / %d \r\n", err_len, chipConfigRamStructKeyInt.chipConfigRamBufferLen); #if 0 - int len = ramStorageReadFromFlash(mt_key_int_file_name, &chipConfigRamStructKeyInt.chipConfigRamBuffer[0], CHIP_CONFIG_RAM_BUFFER_KEY_INT_SIZE); + int len = ramStorageReadFromFlash(mt_key_int_file_name, + &chipConfigRamStructKeyInt.chipConfigRamBuffer[0], + CONFIG_CHIP_NVM_RAMBUFFER_SIZE_KEY_INT); INFO_PRINTF("mt read after write %d\r\n", len); #endif } @@ -591,12 +638,14 @@ void NXPConfig::RunSystemIdleTask(void) err_len = ramStorageSavetoFlash(mt_key_str_file_name, &chipConfigRamStructKeyString.chipConfigRamBuffer[0], chipConfigRamStructKeyString.chipConfigRamBufferLen); - assert(err_len <= CHIP_CONFIG_RAM_BUFFER_KEY_STRING_SIZE); + assert(err_len <= CONFIG_CHIP_NVM_RAMBUFFER_SIZE_KEY_STRING); assert(err_len >= 0); INFO_PRINTF("str mt write %d bytes / %d \r\n", err_len, chipConfigRamStructKeyString.chipConfigRamBufferLen); #if 0 - int len = ramStorageReadFromFlash(mt_key_str_file_name, &chipConfigRamStructKeyString.chipConfigRamBuffer[0], CHIP_CONFIG_RAM_BUFFER_KEY_STRING_SIZE); + int len = ramStorageReadFromFlash(mt_key_str_file_name, + &chipConfigRamStructKeyString.chipConfigRamBuffer[0], + CONFIG_CHIP_NVM_RAMBUFFER_SIZE_KEY_STRING); INFO_PRINTF("mt read after write %d\r\n", len); #endif } diff --git a/src/platform/nxp/common/NXPConfigKS.cpp b/src/platform/nxp/common/NXPConfigKS.cpp new file mode 100644 index 00000000000000..f7dd6bdc972919 --- /dev/null +++ b/src/platform/nxp/common/NXPConfigKS.cpp @@ -0,0 +1,494 @@ +/* + * + * 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. + */ + +/** + * @file + * Utilities for accessing persisted device configuration on + * platforms based on the NXP SDK. + */ +/* this file behaves like a config.h, comes first */ +#include + +#include "NXPConfig.h" + +#include "FreeRTOS.h" +#include "FunctionLib.h" +#include "board.h" +#include +#include + +#include "fwk_file_cache.h" +#include "fwk_key_storage.h" +#include "fwk_lfs_mflash.h" + +#if defined(DEBUG_NVM) && (DEBUG_NVM == 2) +#include "fsl_debug_console.h" +#define DBG_PRINTF PRINTF +#define INFO_PRINTF PRINTF + +#elif defined(DEBUG_NVM) && (DEBUG_NVM == 1) +#include "fsl_debug_console.h" +#define DBG_PRINTF PRINTF +#define INFO_PRINTF(...) + +#else +#define DBG_PRINTF(...) +#define INFO_PRINTF(...) +#endif + +/* Temporary namespace for integer and string keys */ +#define NS_INT "_fki" +#define NS_STR "_fks" + +/* Set to 1 if you want to see the statistics about the keys and their length */ +#define ENABLE_KEYS_STATS 0 + +/* Size of the ram memory section for the KS configuration */ +/* following the study of the size of the Matter key storage files, +we defined that a buffer size equal to 2265 is necessary. We decided to add a mark-up, bringing the buffer size to 5k to be safe */ +#ifndef KS_MATTER_SCRATCH_AREA_SIZE_MAX +#define KS_MATTER_SCRATCH_AREA_SIZE_MAX 5 * 1024 +#endif + +static uint8_t mem_section[KS_MATTER_SCRATCH_AREA_SIZE_MAX]; +static ks_config_t ks_config = { + .size = KS_MATTER_SCRATCH_AREA_SIZE_MAX, .KS_name = "KSconf", .mem_p = mem_section, + //.mem_p = NULL, +}; +static void * ks_handle_p = NULL; + +static bool isInitialized = false; + +#if (ENABLE_KEYS_STATS == 1) +typedef struct +{ + uint16_t writtenKeys_str; + uint16_t deletedKeys_str; + uint16_t writtenKeys_int; + uint16_t deletedKeys_int; +} ks_keys_stats_t; +static ks_keys_stats_t keys_stats = { 0, 0, 0, 0 }; +#endif + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +CHIP_ERROR NXPConfig::Init() +{ + if (!isInitialized) + { + ks_handle_p = KS_Init(&ks_config); + isInitialized = true; + } + + DBG_PRINTF("Init"); + return CHIP_NO_ERROR; +} + +CHIP_ERROR NXPConfig::ReadConfigValue(Key key, bool & val) +{ + CHIP_ERROR err; + ks_error_t status; + int req_len; + int outLen; + bool tempVal; + + req_len = sizeof(bool); + outLen = 0; + tempVal = false; + + VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + status = KS_GetKeyInt(ks_handle_p, (int) key, (char *) NS_INT, (void *) &tempVal, req_len, &outLen); + SuccessOrExit(err = MapKeyStorageStatus(status)); + val = tempVal; +#if (DEBUG_NVM > 0) + ChipLogProgress(DeviceLayer, "ReadConfigValue bool = %u", val); +#endif + +exit: + return err; +} + +CHIP_ERROR NXPConfig::ReadConfigValue(Key key, uint32_t & val) +{ + CHIP_ERROR err; + ks_error_t status; + int req_len; + int outLen; + uint32_t tempVal; + + req_len = sizeof(uint32_t); + outLen = 0; + tempVal = 0; + + VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + status = KS_GetKeyInt(ks_handle_p, (int) key, (char *) NS_INT, (void *) &tempVal, req_len, &outLen); + SuccessOrExit(err = MapKeyStorageStatus(status)); + val = tempVal; +#if (DEBUG_NVM > 0) + ChipLogProgress(DeviceLayer, "ReadConfigValue uint32_t = %lu", val); +#endif + +exit: + return err; +} + +CHIP_ERROR NXPConfig::ReadConfigValue(Key key, uint64_t & val) +{ + CHIP_ERROR err; + ks_error_t status; + int req_len; + int outLen; + uint64_t tempVal; + + req_len = sizeof(uint64_t); + outLen = 0; + tempVal = 0; + + VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + status = KS_GetKeyInt(ks_handle_p, (int) key, (char *) NS_INT, (void *) &tempVal, req_len, &outLen); + SuccessOrExit(err = MapKeyStorageStatus(status)); + val = tempVal; +#if (DEBUG_NVM > 0) + ChipLogProgress(DeviceLayer, "ReadConfigValue uint64_t = " ChipLogFormatX64, ChipLogValueX64(val)); +#endif + +exit: + return err; +} + +CHIP_ERROR NXPConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) +{ + CHIP_ERROR err; + ks_error_t status; + uint32_t sizeToRead; + + sizeToRead = bufSize; + VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + status = KS_GetKeyInt(ks_handle_p, (int) key, (char *) NS_INT, (void *) buf, (int) bufSize, (int *) &sizeToRead); + SuccessOrExit(err = MapKeyStorageStatus(status)); + outLen = sizeToRead; +#if (DEBUG_NVM > 0) + ChipLogProgress(DeviceLayer, "ReadConfigValueStr bufSize = %u, lenRead = %u", bufSize, outLen); +#endif + +exit: + return err; +} + +CHIP_ERROR NXPConfig::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) +{ + return ReadConfigValueStr(key, (char *) buf, bufSize, outLen); +} + +CHIP_ERROR NXPConfig::ReadConfigValueBin(const char * keyString, uint8_t * buf, size_t bufSize, size_t & outLen) +{ + CHIP_ERROR err; + ks_error_t status; + uint32_t sizeToRead; + + sizeToRead = bufSize; + VerifyOrExit(keyString != NULL, err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + status = KS_GetKeyString(ks_handle_p, (char *) keyString, strlen(keyString) + 1, (char *) NS_STR, (void *) buf, (int) bufSize, + (int *) &sizeToRead); // +1 to add end \0 char + SuccessOrExit(err = MapKeyStorageStatus(status)); + outLen = sizeToRead; +#if (DEBUG_NVM > 0) + ChipLogProgress(DeviceLayer, "ReadConfigValueStr lenRead = %u", outLen); +#endif + +exit: + return err; +} + +CHIP_ERROR NXPConfig::ReadConfigValueCounter(uint8_t counterIdx, uint32_t & val) +{ + Key key = kMinConfigKey_ChipCounter + counterIdx; + return ReadConfigValue(key, val); +} + +CHIP_ERROR NXPConfig::WriteConfigValue(Key key, bool val) +{ + CHIP_ERROR err; + ks_error_t status; + int valSize; + + valSize = sizeof(bool); + VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + status = KS_SetKeyInt(ks_handle_p, (int) key, (char *) NS_INT, (void *) &val, valSize); + SuccessOrExit(err = MapKeyStorageStatus(status)); + + DBG_PRINTF("WriteConfigValue: MT write \r\n"); + +#if (DEBUG_NVM > 0) + ChipLogProgress(DeviceLayer, "WriteConfigValue done"); +#endif + +#if (ENABLE_KEYS_STATS == 1) + keys_stats.writtenKeys_int++; + ChipLogProgress(DeviceLayer, "Data len: %u. Integer keys written until now: %u.", valSize, keys_stats.writtenKeys_int); +#endif + +exit: + return err; +} + +CHIP_ERROR NXPConfig::WriteConfigValue(Key key, uint32_t val) +{ + CHIP_ERROR err; + ks_error_t status; + int valSize; + + valSize = sizeof(uint32_t); + VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + status = KS_SetKeyInt(ks_handle_p, (int) key, (char *) NS_INT, (void *) &val, valSize); + SuccessOrExit(err = MapKeyStorageStatus(status)); + + DBG_PRINTF("WriteConfigValue: MT write \r\n"); + +#if (DEBUG_NVM > 0) + ChipLogProgress(DeviceLayer, "WriteConfigValue done"); +#endif + +#if (ENABLE_KEYS_STATS == 1) + keys_stats.writtenKeys_int++; + ChipLogProgress(DeviceLayer, "Data len: %u. Integer keys written until now: %u.", valSize, keys_stats.writtenKeys_int); +#endif + +exit: + return err; +} + +CHIP_ERROR NXPConfig::WriteConfigValue(Key key, uint64_t val) +{ + CHIP_ERROR err; + ks_error_t status; + int valSize; + + valSize = sizeof(uint64_t); + VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + status = KS_SetKeyInt(ks_handle_p, (int) key, (char *) NS_INT, (void *) &val, valSize); + SuccessOrExit(err = MapKeyStorageStatus(status)); + + DBG_PRINTF("WriteConfigValue64: MT write \r\n"); + +#if (DEBUG_NVM > 0) + ChipLogProgress(DeviceLayer, "WriteConfigValue done"); +#endif + +#if (ENABLE_KEYS_STATS == 1) + keys_stats.writtenKeys_int++; + ChipLogProgress(DeviceLayer, "Data len: %u. Integer keys written until now: %u.", valSize, keys_stats.writtenKeys_int); +#endif + +exit: + return err; +} + +CHIP_ERROR NXPConfig::WriteConfigValueStr(Key key, const char * str) +{ + return WriteConfigValueStr(key, str, (str != NULL) ? strlen(str) : 0); +} + +CHIP_ERROR NXPConfig::WriteConfigValueStr(Key key, const char * str, size_t strLen) +{ + CHIP_ERROR err; + ks_error_t status; + + VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + status = KS_SetKeyInt(ks_handle_p, (int) key, (char *) NS_INT, (void *) str, strLen); + SuccessOrExit(err = MapKeyStorageStatus(status)); + + DBG_PRINTF("WriteConfigValueStr: MT write \r\n"); + +#if (DEBUG_NVM > 0) + ChipLogProgress(DeviceLayer, "WriteConfigValue done"); +#endif + +#if (ENABLE_KEYS_STATS == 1) + keys_stats.writtenKeys_int++; + ChipLogProgress(DeviceLayer, "Data len: %u. Integer keys written until now: %u.", strLen, keys_stats.writtenKeys_int); +#endif + +exit: + return err; +} + +CHIP_ERROR NXPConfig::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) +{ + return WriteConfigValueStr(key, (char *) data, dataLen); +} + +CHIP_ERROR NXPConfig::WriteConfigValueBin(const char * keyString, const uint8_t * data, size_t dataLen) +{ + CHIP_ERROR err; + ks_error_t status; + int keyLen; + + keyLen = (int) strlen(keyString) + 1; // +1 to add end \0 char + VerifyOrExit(keyString != NULL, err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + status = KS_SetKeyString(ks_handle_p, (char *) keyString, keyLen, (char *) NS_STR, (void *) data, (int) dataLen); + SuccessOrExit(err = MapKeyStorageStatus(status)); + + DBG_PRINTF("WriteConfigValueBin: MT write \r\n"); + +#if (DEBUG_NVM > 0) + ChipLogProgress(DeviceLayer, "WriteConfigValue done"); +#endif + +#if (ENABLE_KEYS_STATS == 1) + keys_stats.writtenKeys_str++; + ChipLogProgress(DeviceLayer, "Data len: %u. Key len: %u. String keys written until now: %u.", dataLen, keyLen, + keys_stats.writtenKeys_str); +#endif + +exit: + return err; +} + +CHIP_ERROR NXPConfig::WriteConfigValueCounter(uint8_t counterIdx, uint32_t val) +{ + Key key = kMinConfigKey_ChipCounter + counterIdx; + return WriteConfigValue(key, val); +} + +CHIP_ERROR NXPConfig::ClearConfigValue(Key key) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + ks_error_t status; + + VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + status = KS_DeleteKeyInt(ks_handle_p, (int) key, (char *) NS_INT); + SuccessOrExit(err = MapKeyStorageStatus(status)); + + DBG_PRINTF("ClearConfigValue: MT write \r\n"); + +#if (ENABLE_KEYS_STATS == 1) + keys_stats.deletedKeys_int++; + ChipLogProgress(DeviceLayer, "Integer keys deleted until now: %u.", keys_stats.deletedKeys_int); +#endif + +exit: + return err; +} + +CHIP_ERROR NXPConfig::ClearConfigValue(const char * keyString) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + ks_error_t status; + int keyLen; + + keyLen = strlen(keyString) + 1; // +1 to add end \0 char + VerifyOrExit(keyString != NULL, err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + status = KS_DeleteKeyString(ks_handle_p, (char *) keyString, keyLen, (char *) NS_STR); + SuccessOrExit(err = MapKeyStorageStatus(status)); + + DBG_PRINTF("WriteConfigValueBin: MT write \r\n"); + +#if (ENABLE_KEYS_STATS == 1) + keys_stats.deletedKeys_str++; + ChipLogProgress(DeviceLayer, "String keys deleted until now: %u.", keys_stats.deletedKeys_str); +#endif + +exit: + return err; +} + +bool NXPConfig::ConfigValueExists(Key key) +{ + ks_error_t status; + bool found; + void * readValue_p; + int outLen; + int bufSize; + + found = false; + readValue_p = NULL; + outLen = 0; + /* Max number of bytes read when getting a value */ + bufSize = 256; + + if (ValidConfigKey(key)) + { + /* Get the first occurence */ + status = KS_GetKeyInt(ks_handle_p, (int) key, (char *) NS_INT, readValue_p, bufSize, &outLen); + found = (status == KS_ERROR_NONE && outLen != 0); + } + return found; +} + +CHIP_ERROR NXPConfig::FactoryResetConfig(void) +{ + /*for (Key key = kMinConfigKey_ChipConfig; key <= kMaxConfigKey_ChipConfig; key++) + { + ClearConfigValue(key); + }*/ + + KS_Reset(ks_handle_p); + + DBG_PRINTF("FactoryResetConfig done\r\n"); + + return CHIP_NO_ERROR; +} + +bool NXPConfig::ValidConfigKey(Key key) +{ + // Returns true if the key is in the valid CHIP Config PDM key range. + + if ((key >= kMinConfigKey_ChipFactory) && (key <= kMaxConfigKey_KVS)) + { + return true; + } + + return false; +} + +CHIP_ERROR NXPConfig::MapKeyStorageStatus(ks_error_t ksStatus) +{ + CHIP_ERROR err; + + switch (ksStatus) + { + case KS_ERROR_NONE: + err = CHIP_NO_ERROR; + break; + case KS_ERROR_BUF_TOO_SMALL: + err = CHIP_ERROR_BUFFER_TOO_SMALL; + break; + default: /* KS_ERROR_KEY_NOT_FOUND */ + err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + break; + } + + return err; +} + +void NXPConfig::RunConfigUnitTest(void) {} + +void NXPConfig::RunSystemIdleTask(void) +{ + if (isInitialized) + { + FC_Process(); + INFO_PRINTF("str mt write \r\n"); + } +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/common/NetworkCommissioningDriver.h b/src/platform/nxp/common/NetworkCommissioningDriver.h index 4e7c9f0292e47b..5757771476e057 100644 --- a/src/platform/nxp/common/NetworkCommissioningDriver.h +++ b/src/platform/nxp/common/NetworkCommissioningDriver.h @@ -72,6 +72,10 @@ class NXPWiFiDriver final : public WiFiDriver Status ReorderNetwork(ByteSpan networkId, uint8_t index, MutableCharSpan & outDebugText) override; void ConnectNetwork(ByteSpan networkId, ConnectCallback * callback) override; + /* Can be used to disconnect from WiFi network. + */ + int DisconnectNetwork(); + /* Returns the network SSID. User needs to allocate a buffer of size >= DeviceLayer::Internal::kMaxWiFiSSIDLength. * ssid - pointer to the returned SSID */ @@ -82,6 +86,9 @@ class NXPWiFiDriver final : public WiFiDriver */ Status GetNetworkPassword(char * credentials); + /* Returns all supported WiFi bands */ + uint32_t GetSupportedWiFiBandsMask() const override; + // WiFiDriver Status AddOrUpdateNetwork(ByteSpan ssid, ByteSpan credentials, MutableCharSpan & outDebugText, uint8_t & outNetworkIndex) override; diff --git a/src/platform/nxp/common/NetworkCommissioningWiFiDriver.cpp b/src/platform/nxp/common/NetworkCommissioningWiFiDriver.cpp index 7863b511b227c2..d697c75d1042d7 100644 --- a/src/platform/nxp/common/NetworkCommissioningWiFiDriver.cpp +++ b/src/platform/nxp/common/NetworkCommissioningWiFiDriver.cpp @@ -69,7 +69,7 @@ CHIP_ERROR NXPWiFiDriver::Init(NetworkStatusChangeCallback * networkStatusChange if (err != CHIP_NO_ERROR) { ChipLogProgress(DeviceLayer, "WiFi network SSID not retrieved from persisted storage: %" CHIP_ERROR_FORMAT, err.Format()); - return CHIP_NO_ERROR; + return err; } err = PersistedStorage::KeyValueStoreMgr().Get(kWiFiCredentialsKeyName, mSavedNetwork.credentials, @@ -78,7 +78,7 @@ CHIP_ERROR NXPWiFiDriver::Init(NetworkStatusChangeCallback * networkStatusChange { ChipLogProgress(DeviceLayer, "WiFi network credentials not retrieved from persisted storage: %" CHIP_ERROR_FORMAT, err.Format()); - return CHIP_NO_ERROR; + return err; } mSavedNetwork.credentialsLen = credentialsLen; @@ -90,7 +90,7 @@ CHIP_ERROR NXPWiFiDriver::Init(NetworkStatusChangeCallback * networkStatusChange mpStatusChangeCallback = networkStatusChangeCallback; // Connect to saved network - ConnectWiFiNetwork(mSavedNetwork.ssid, ssidLen, mSavedNetwork.credentials, credentialsLen); + err = ConnectWiFiNetwork(mSavedNetwork.ssid, ssidLen, mSavedNetwork.credentials, credentialsLen); return err; } @@ -193,6 +193,8 @@ CHIP_ERROR NXPWiFiDriver::ConnectWiFiNetwork(const char * ssid, uint8_t ssidLen, void NXPWiFiDriver::OnConnectWiFiNetwork(Status commissioningError, CharSpan debugText, int32_t connectStatus) { + CommitConfiguration(); + if (mpConnectCallback != nullptr) { mpConnectCallback->OnResult(commissioningError, debugText, connectStatus); @@ -236,6 +238,29 @@ void NXPWiFiDriver::ConnectNetwork(ByteSpan networkId, ConnectCallback * callbac } } +int NXPWiFiDriver::DisconnectNetwork(void) +{ + int ret = 0; + + if (ConnectivityMgrImpl().IsWiFiStationConnected()) + { + ChipLogProgress(NetworkProvisioning, "Disconnecting from WiFi network."); + + ret = wlan_disconnect(); + + if (ret != WM_SUCCESS) + { + ChipLogError(NetworkProvisioning, "Failed to disconnect from network with error: %u", (uint8_t) ret); + } + } + else + { + ChipLogError(NetworkProvisioning, "Error: WiFi not connected!"); + } + + return ret; +} + CHIP_ERROR NXPWiFiDriver::StartScanWiFiNetworks(ByteSpan ssid) { wlan_scan_params_v2_t wlan_scan_param; @@ -385,6 +410,15 @@ void NXPWiFiDriver::ScanNetworks(ByteSpan ssid, WiFiDriver::ScanCallback * callb } } +uint32_t NXPWiFiDriver::GetSupportedWiFiBandsMask() const +{ + uint32_t bands = static_cast(1UL << chip::to_underlying(WiFiBandEnum::k2g4)); +#ifdef CONFIG_5GHz_SUPPORT + bands |= (1UL << chip::to_underlying(WiFiBandEnum::k5g)); +#endif + return bands; +} + static CHIP_ERROR GetConnectedNetwork(Network & network) { struct wlan_network wlan_network; diff --git a/src/platform/nxp/common/factory_data/FactoryDataProvider.cpp b/src/platform/nxp/common/factory_data/FactoryDataProvider.cpp index bdaaaae1d120b8..b60d7e49c0ad81 100644 --- a/src/platform/nxp/common/factory_data/FactoryDataProvider.cpp +++ b/src/platform/nxp/common/factory_data/FactoryDataProvider.cpp @@ -21,20 +21,6 @@ #include #include -#ifndef FACTORY_DATA_PROVIDER_ENABLE_TESTS -#define FACTORY_DATA_PROVIDER_RUN_TESTS 0 -#endif - -#if FACTORY_DATA_PROVIDER_RUN_TESTS -#include -#include -#include -#include -#include -#include -#include -#endif - #include "FactoryDataProvider.h" #include @@ -315,42 +301,28 @@ CHIP_ERROR FactoryDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & un return err; } -void FactoryDataProvider::FactoryDataProviderRunTests(void) +CHIP_ERROR FactoryDataProvider::GetProductFinish(app::Clusters::BasicInformation::ProductFinishEnum * finish) { -#if FACTORY_DATA_PROVIDER_RUN_TESTS - static const ByteSpan kExpectedDacPublicKey = DevelopmentCerts::kDacPublicKey; - constexpr uint8_t kExampleDigest[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, - 0x13, 0x14, 0x15, 0x16, 0x17, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, - 0x26, 0x27, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37 }; - - // Sign using the example attestation private key - P256ECDSASignature da_signature; - MutableByteSpan out_sig_span(da_signature.Bytes(), da_signature.Capacity()); - CHIP_ERROR err = SignWithDeviceAttestationKey(ByteSpan{ kExampleDigest }, out_sig_span); - assert(err == CHIP_NO_ERROR); - - assert(out_sig_span.size() == kP256_ECDSA_Signature_Length_Raw); - da_signature.SetLength(out_sig_span.size()); - - // Get DAC from the provider - uint8_t dac_cert_buf[kMaxDERCertLength]; - MutableByteSpan dac_cert_span(dac_cert_buf); - - memset(dac_cert_span.data(), 0, dac_cert_span.size()); - err = GetDeviceAttestationCert(dac_cert_span); - assert(err == CHIP_NO_ERROR); - - // Extract public key from DAC, prior to signature verification - P256PublicKey dac_public_key; - err = ExtractPubkeyFromX509Cert(dac_cert_span, dac_public_key); - assert(err == CHIP_NO_ERROR); - assert(dac_public_key.Length() == kExpectedDacPublicKey.size()); - assert(0 == memcmp(dac_public_key.ConstBytes(), kExpectedDacPublicKey.data(), kExpectedDacPublicKey.size())); - - // Verify round trip signature - err = dac_public_key.ECDSA_validate_msg_signature(&kExampleDigest[0], sizeof(kExampleDigest), da_signature); - assert(err == CHIP_NO_ERROR); -#endif + uint8_t productFinish; + uint16_t length = 0; + auto err = SearchForId(FactoryDataId::kProductFinish, &productFinish, sizeof(productFinish), length); + ReturnErrorCodeIf(err != CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); + + *finish = static_cast(productFinish); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetProductPrimaryColor(app::Clusters::BasicInformation::ColorEnum * primaryColor) +{ + uint8_t color; + uint16_t length = 0; + auto err = SearchForId(FactoryDataId::kProductPrimaryColor, &color, sizeof(color), length); + ReturnErrorCodeIf(err != CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); + + *primaryColor = static_cast(color); + + return CHIP_NO_ERROR; } } // namespace DeviceLayer diff --git a/src/platform/nxp/common/factory_data/FactoryDataProvider.h b/src/platform/nxp/common/factory_data/FactoryDataProvider.h index 47f85fa6ccc4b2..b06089270a7355 100644 --- a/src/platform/nxp/common/factory_data/FactoryDataProvider.h +++ b/src/platform/nxp/common/factory_data/FactoryDataProvider.h @@ -70,6 +70,8 @@ class FactoryDataProvider : public chip::Credentials::DeviceAttestationCredentia kPartNumber, kProductURL, kProductLabel, + kProductFinish, + kProductPrimaryColor, kMaxId }; @@ -105,8 +107,8 @@ class FactoryDataProvider : public chip::Credentials::DeviceAttestationCredentia CHIP_ERROR GetHardwareVersion(uint16_t & hardwareVersion) override; CHIP_ERROR GetHardwareVersionString(char * buf, size_t bufSize) override; CHIP_ERROR GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) override; - - void FactoryDataProviderRunTests(void); + CHIP_ERROR GetProductFinish(app::Clusters::BasicInformation::ProductFinishEnum * finish) override; + CHIP_ERROR GetProductPrimaryColor(app::Clusters::BasicInformation::ColorEnum * primaryColor) override; protected: // Methods to be implemented by impl class delegate. diff --git a/src/platform/nxp/k32w/common/BLEManagerCommon.cpp b/src/platform/nxp/k32w/common/BLEManagerCommon.cpp index 40f9bc5c7d7abf..b532ddef7f207e 100644 --- a/src/platform/nxp/k32w/common/BLEManagerCommon.cpp +++ b/src/platform/nxp/k32w/common/BLEManagerCommon.cpp @@ -135,7 +135,7 @@ const ChipBleUUID ChipUUID_CHIPoBLEChar_TX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0 static bool bleAppStopInProgress; #endif -BLEManagerCommon * sImplInstance; +BLEManagerCommon * sImplInstance = nullptr; } // namespace @@ -1085,7 +1085,7 @@ void BLEManagerCommon::blekw_generic_cb(gapGenericEvent_t * pGenericEvent) /* Call BLE Conn Manager */ BleConnManager_GenericEvent(pGenericEvent); - if (sImplInstance->callbackDelegate.gapCallback) + if (sImplInstance && sImplInstance->callbackDelegate.gapCallback) { sImplInstance->callbackDelegate.gapCallback(pGenericEvent); } @@ -1240,7 +1240,7 @@ void BLEManagerCommon::blekw_stop_connection_timeout(void) void BLEManagerCommon::blekw_gatt_server_cb(deviceId_t deviceId, gattServerEvent_t * pServerEvent) { - if (sImplInstance->callbackDelegate.gattCallback) + if (sImplInstance && sImplInstance->callbackDelegate.gattCallback) { sImplInstance->callbackDelegate.gattCallback(deviceId, pServerEvent); } diff --git a/src/platform/nxp/k32w/common/CHIPDevicePlatformRamStorageConfig.h b/src/platform/nxp/k32w/common/CHIPDevicePlatformRamStorageConfig.h index 33c68807ca7af9..bcb9ecdd82d58c 100644 --- a/src/platform/nxp/k32w/common/CHIPDevicePlatformRamStorageConfig.h +++ b/src/platform/nxp/k32w/common/CHIPDevicePlatformRamStorageConfig.h @@ -21,6 +21,8 @@ * Configuration of RAM storage metadata: key IDs and NVM IDs. */ +#pragma once + /* Base key IDs used when creating new keys for RAM storage instances. */ /** * @def kKeyId_Factory @@ -111,11 +113,35 @@ * KVS buffer can become quite big, so this PDM * id is used as base id for subsequent PDM ids * used to store data in chunks of PDM page size. + * This will use the extended search feature, so + * subsequent PDM ids should not be used. */ #ifndef kNvmId_KvsValues #define kNvmId_KvsValues (uint16_t) 0x6001 #endif +/** + * @def kNvmId_KvsSubscription + * + * PDM ID used for KVS subscription RAM storage. + * It will store both keys and values for those keys. + */ +#ifndef kNvmId_KvsSubscription +#define kNvmId_KvsSubscription (uint16_t) 0x6100 +#endif + +/** + * @def kNvmId_KvsGroups + * + * PDM ID used for KVS groups RAM storage. + * It will store both keys and values for those keys. + * This will use the extended search feature, so + * subsequent PDM ids should not be used. + */ +#ifndef kNvmId_KvsGroups +#define kNvmId_KvsGroups (uint16_t) 0x6200 +#endif + /** * @def kNvmId_OTConfigData * @@ -145,14 +171,3 @@ #define kNvmId_FactoryDataBackup (uint16_t) 0x7000 #endif #endif // CONFIG_CHIP_LOAD_REAL_FACTORY_DATA - -/** - * @def kKVS_RamBufferSize - * - * Size of KVS values RAM storage buffer. - * This value is empirical, based on some minimal resource requirements tests. - * Applications should overwrite this value if necessary. - */ -#ifndef kKVS_RamBufferSize -#define kKVS_RamBufferSize (12 * 1024) -#endif diff --git a/src/platform/nxp/k32w/common/FactoryDataProvider.cpp b/src/platform/nxp/k32w/common/FactoryDataProvider.cpp index 1770cf22c659f0..dd79b020c881ea 100644 --- a/src/platform/nxp/k32w/common/FactoryDataProvider.cpp +++ b/src/platform/nxp/k32w/common/FactoryDataProvider.cpp @@ -39,6 +39,10 @@ namespace DeviceLayer { static constexpr size_t kSpake2pSerializedVerifier_MaxBase64Len = BASE64_ENCODED_LEN(chip::Crypto::kSpake2p_VerifierSerialized_Length) + 1; static constexpr size_t kSpake2pSalt_MaxBase64Len = BASE64_ENCODED_LEN(chip::Crypto::kSpake2p_Max_PBKDF_Salt_Length) + 1; +/* Secure subsystem private key blob size is 32 + 24 = 56. + * DAC private key may be used to store an SSS exported blob instead of the private key. + */ +static constexpr size_t kDacPrivateKey_MaxLen = Crypto::kP256_PrivateKey_Length + 24; uint32_t FactoryDataProvider::kFactoryDataStart = (uint32_t) __MATTER_FACTORY_DATA_START; uint32_t FactoryDataProvider::kFactoryDataSize = (uint32_t) __MATTER_FACTORY_DATA_SIZE; diff --git a/src/platform/nxp/k32w/common/FactoryDataProvider.h b/src/platform/nxp/k32w/common/FactoryDataProvider.h index 2bad3e7934482f..03ccf370f7641c 100644 --- a/src/platform/nxp/k32w/common/FactoryDataProvider.h +++ b/src/platform/nxp/k32w/common/FactoryDataProvider.h @@ -25,6 +25,8 @@ #include "CHIPPlatformConfig.h" +#include + /* Grab symbol for the base address from the linker file. */ extern uint32_t __MATTER_FACTORY_DATA_START[]; extern uint32_t __MATTER_FACTORY_DATA_SIZE[]; diff --git a/src/platform/nxp/k32w/common/K32W_OTA_README.md b/src/platform/nxp/k32w/common/K32W_OTA_README.md index 63079e0ce3c81e..0c9715b4610ff8 100644 --- a/src/platform/nxp/k32w/common/K32W_OTA_README.md +++ b/src/platform/nxp/k32w/common/K32W_OTA_README.md @@ -48,7 +48,6 @@ public: CHIP_ERROR Process(ByteSpan & block); void RegisterDescriptorCallback(ProcessDescriptor callback); - protected: virtual CHIP_ERROR ProcessInternal(ByteSpan & block) = 0; }; diff --git a/src/platform/nxp/k32w/common/OTAImageProcessorImpl.cpp b/src/platform/nxp/k32w/common/OTAImageProcessorImpl.cpp index 591d082ea992f7..c927ce65675035 100644 --- a/src/platform/nxp/k32w/common/OTAImageProcessorImpl.cpp +++ b/src/platform/nxp/k32w/common/OTAImageProcessorImpl.cpp @@ -179,11 +179,11 @@ CHIP_ERROR OTAImageProcessorImpl::SelectProcessor(ByteSpan & block) auto pair = mProcessorMap.find(header.tag); if (pair == mProcessorMap.end()) { - ChipLogError(SoftwareUpdate, "There is no registered processor for tag: %lu", header.tag); + ChipLogError(SoftwareUpdate, "There is no registered processor for tag: %" PRIu32, header.tag); return CHIP_OTA_PROCESSOR_NOT_REGISTERED; } - ChipLogDetail(SoftwareUpdate, "Selected processor with tag: %lu", pair->first); + ChipLogDetail(SoftwareUpdate, "Selected processor with tag: %ld", pair->first); mCurrentProcessor = pair->second; mCurrentProcessor->SetLength(header.length); mCurrentProcessor->SetWasSelected(true); @@ -196,7 +196,7 @@ CHIP_ERROR OTAImageProcessorImpl::RegisterProcessor(uint32_t tag, OTATlvProcesso auto pair = mProcessorMap.find(tag); if (pair != mProcessorMap.end()) { - ChipLogError(SoftwareUpdate, "A processor for tag %lu is already registered.", tag); + ChipLogError(SoftwareUpdate, "A processor for tag %" PRIu32 " is already registered.", tag); return CHIP_OTA_PROCESSOR_ALREADY_REGISTERED; } @@ -298,8 +298,8 @@ CHIP_ERROR OTAImageProcessorImpl::ConfirmCurrentImage() ReturnErrorOnFailure(DeviceLayer::ConfigurationMgr().GetSoftwareVersion(currentVersion)); if (currentVersion != targetVersion) { - ChipLogError(SoftwareUpdate, "Current sw version %lu is different than the expected sw version = %lu", currentVersion, - targetVersion); + ChipLogError(SoftwareUpdate, "Current sw version %" PRIu32 " is different than the expected sw version = %" PRIu32, + currentVersion, targetVersion); return CHIP_ERROR_INCORRECT_STATE; } @@ -384,17 +384,14 @@ void OTAImageProcessorImpl::HandleApply(intptr_t context) imageProcessor->mAccumulator.Clear(); ConfigurationManagerImpl().StoreSoftwareUpdateCompleted(); + PlatformMgr().HandleServerShuttingDown(); // Set the necessary information to inform the SSBL that a new image is available // and trigger the actual device reboot after some time, to take into account // queued actions, e.g. sending events to a subscription SystemLayer().StartTimer( chip::System::Clock::Milliseconds32(CHIP_DEVICE_LAYER_OTA_REBOOT_DELAY), - [](chip::System::Layer *, void *) { - PlatformMgr().HandleServerShuttingDown(); - OtaHookReset(); - }, - nullptr); + [](chip::System::Layer *, void *) { OtaHookReset(); }, nullptr); } CHIP_ERROR OTAImageProcessorImpl::ReleaseBlock() diff --git a/src/platform/nxp/k32w/k32w0/BUILD.gn b/src/platform/nxp/k32w/k32w0/BUILD.gn index a58609f28ef539..9d1ef45db9fdb5 100644 --- a/src/platform/nxp/k32w/k32w0/BUILD.gn +++ b/src/platform/nxp/k32w/k32w0/BUILD.gn @@ -13,18 +13,19 @@ # limitations under the License. import("//build_overrides/chip.gni") -import("//build_overrides/k32w0_sdk.gni") +import("//build_overrides/nxp_sdk.gni") import("${chip_root}/src/platform/device.gni") -import("${k32w0_sdk_build_root}/k32w0_sdk.gni") +import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") -assert(chip_device_platform == "k32w0") +assert(chip_device_platform == "nxp") +assert(nxp_platform == "k32w/k32w0") if (chip_enable_openthread) { import("//build_overrides/openthread.gni") } -static_library("k32w0") { +static_library("nxp_platform") { sources = [ "../../../SingletonConfigurationManager.cpp", "../common/BLEManagerCommon.cpp", @@ -60,6 +61,7 @@ static_library("k32w0") { "${chip_root}/src/credentials/examples/DeviceAttestationCredsExample.h", "${chip_root}/src/credentials/examples/ExampleDACs.h", "${chip_root}/src/credentials/examples/ExamplePAI.h", + "${chip_root}/src/platform/nxp/k32w/k32w0/BLEManagerImpl.h", ] if (chip_with_factory_data == 1) { @@ -119,8 +121,8 @@ static_library("k32w0") { sources += [ "${chip_root}/src/platform/nxp/k32w/k32w0/crypto/CHIPCryptoPALNXPUltrafastP256.cpp" ] public_deps += [ - "${chip_root}/third_party/nxp/k32w0_sdk:k32w0_sdk", "${mbedtls_root}:mbedtls", + "${nxp_sdk_build_root}/${nxp_sdk_name}:nxp_sdk", ] } } diff --git a/src/platform/nxp/k32w/k32w0/CHIPDevicePlatformConfig.h b/src/platform/nxp/k32w/k32w0/CHIPDevicePlatformConfig.h index a584e0c79afbbb..faa283ffbe41dc 100644 --- a/src/platform/nxp/k32w/k32w0/CHIPDevicePlatformConfig.h +++ b/src/platform/nxp/k32w/k32w0/CHIPDevicePlatformConfig.h @@ -115,6 +115,25 @@ #define CHIP_DEVICE_LAYER_OTA_REBOOT_DELAY 3000 #endif // CHIP_DEVICE_LAYER_OTA_REBOOT_DELAY +/** + * @def CONFIG_CHIP_K32W0_KVS_MOVE_KEYS_TO_SPECIFIC_STORAGE + * + * When enabled, the application can opt to move some keys from + * current KVS storage to a dedicated storage, based on the key name. + * + * Currently, the mechanism supports moving keys and values for: + * - subscriptions + * - groups + * + * Note: the system is meant to ensure backwards compatibility. This should only + * be used once, but, if this feature is still enabled after the first conversion, + * the corresponding keys will not be found in KVS default storage. This does + * not affect the functionality, but it introduces a delay in the initialization. + */ +#ifndef CONFIG_CHIP_K32W0_KVS_MOVE_KEYS_TO_SPECIFIC_STORAGE +#define CONFIG_CHIP_K32W0_KVS_MOVE_KEYS_TO_SPECIFIC_STORAGE 0 +#endif // CONFIG_CHIP_K32W0_KVS_MOVE_KEYS_TO_SPECIFIC_STORAGE + /** * @def CONFIG_CHIP_K32W0_OTA_FACTORY_DATA_PROCESSOR * @@ -144,7 +163,7 @@ #endif // CHIP_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE // Max size of event queue -#define CHIP_DEVICE_CONFIG_MAX_EVENT_QUEUE_SIZE 75 +#define CHIP_DEVICE_CONFIG_MAX_EVENT_QUEUE_SIZE 25 #ifndef CHIP_DEVICE_CONFIG_BLE_APP_TASK_NAME #define CHIP_DEVICE_CONFIG_BLE_APP_TASK_NAME "BLE App Task" diff --git a/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.cpp b/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.cpp index 0cf81fa9bf1749..4d378cb01cbe1f 100644 --- a/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.cpp +++ b/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.cpp @@ -37,11 +37,54 @@ namespace PersistedStorage { constexpr size_t kMaxNumberOfKeys = 200; constexpr size_t kMaxKeyValueBytes = 255; -Internal::RamStorage KeyValueStoreManagerImpl::sKeysStorage = { kNvmId_KvsKeys }; -Internal::RamStorage KeyValueStoreManagerImpl::sValuesStorage = { kNvmId_KvsValues }; +Internal::RamStorage KeyValueStoreManagerImpl::sKeysStorage = { kNvmId_KvsKeys }; +Internal::RamStorage KeyValueStoreManagerImpl::sValuesStorage = { kNvmId_KvsValues }; +Internal::RamStorage KeyValueStoreManagerImpl::sSubscriptionStorage = { kNvmId_KvsSubscription }; +Internal::RamStorage KeyValueStoreManagerImpl::sGroupsStorage = { kNvmId_KvsGroups }; KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance; +#if CONFIG_CHIP_K32W0_KVS_MOVE_KEYS_TO_SPECIFIC_STORAGE +static CHIP_ERROR MoveKeysAndValues(); +#endif // CONFIG_CHIP_K32W0_KVS_MOVE_KEYS_TO_SPECIFIC_STORAGE + +static inline bool IsKeyRelatedToGroups(const char * key) +{ + std::string _key(key); + if (_key.find("f/") != 0) + return false; + + return (_key.find("/g") != std::string::npos) || (_key.find("/k/") != std::string::npos); +} + +static inline bool IsKeyRelatedToSubscriptions(const char * key) +{ + std::string _key(key); + return _key.find("g/su") == 0; +} + +static Internal::RamStorage * GetValStorage(const char * key) +{ + Internal::RamStorage * storage = nullptr; + + storage = IsKeyRelatedToSubscriptions(key) ? &KeyValueStoreManagerImpl::sSubscriptionStorage + : &KeyValueStoreManagerImpl::sValuesStorage; + storage = IsKeyRelatedToGroups(key) ? &KeyValueStoreManagerImpl::sGroupsStorage : storage; + + return storage; +} + +static Internal::RamStorage * GetKeyStorage(const char * key) +{ + Internal::RamStorage * storage = nullptr; + + storage = IsKeyRelatedToSubscriptions(key) ? &KeyValueStoreManagerImpl::sSubscriptionStorage + : &KeyValueStoreManagerImpl::sKeysStorage; + storage = IsKeyRelatedToGroups(key) ? &KeyValueStoreManagerImpl::sGroupsStorage : storage; + + return storage; +} + uint16_t GetStringKeyId(const char * key, uint16_t * freeId) { CHIP_ERROR err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; @@ -54,7 +97,7 @@ uint16_t GetStringKeyId(const char * key, uint16_t * freeId) { uint16_t keyStringSize = kMaxKeyValueBytes; pdmInternalId = Internal::RamStorageKey::GetInternalId(kKeyId_KvsKeys, keyId); - err = KeyValueStoreManagerImpl::sKeysStorage.Read(pdmInternalId, 0, (uint8_t *) keyString, &keyStringSize); + err = GetKeyStorage(key)->Read(pdmInternalId, 0, (uint8_t *) keyString, &keyStringSize); if (err == CHIP_NO_ERROR) { @@ -76,18 +119,37 @@ uint16_t GetStringKeyId(const char * key, uint16_t * freeId) CHIP_ERROR KeyValueStoreManagerImpl::Init() { CHIP_ERROR err = CHIP_NO_ERROR; - err = sKeysStorage.Init(Internal::RamStorage::kRamBufferInitialSize); + + err = sKeysStorage.Init(Internal::RamStorage::kRamBufferInitialSize); if (err != CHIP_NO_ERROR) { ChipLogProgress(DeviceLayer, "Cannot init KVS keys storage with id: %d. Error: %s", kNvmId_KvsKeys, ErrorStr(err)); } - // Set values storage to a big RAM buffer size as a temporary fix for TC-RR-1.1. - err = sValuesStorage.Init(kKVS_RamBufferSize, true); + + err = sValuesStorage.Init(Internal::RamStorage::kRamBufferInitialSize, true); if (err != CHIP_NO_ERROR) { ChipLogProgress(DeviceLayer, "Cannot init KVS values storage with id: %d. Error: %s", kNvmId_KvsValues, ErrorStr(err)); } + err = sSubscriptionStorage.Init(Internal::RamStorage::kRamBufferInitialSize); + if (err != CHIP_NO_ERROR) + { + ChipLogProgress(DeviceLayer, "Cannot init KVS subscription storage with id: %d. Error: %s", kNvmId_KvsSubscription, + ErrorStr(err)); + } + + err = sGroupsStorage.Init(Internal::RamStorage::kRamBufferInitialSize, true); + if (err != CHIP_NO_ERROR) + { + ChipLogProgress(DeviceLayer, "Cannot init KVS groups storage with id: %d. Error: %s", kNvmId_KvsGroups, ErrorStr(err)); + } + +#if CONFIG_CHIP_K32W0_KVS_MOVE_KEYS_TO_SPECIFIC_STORAGE + ChipLogProgress(DeviceLayer, "Moving some keys to dedicated storage"); + MoveKeysAndValues(); +#endif /* CONFIG_CHIP_K32W0_KVS_MOVE_KEYS_TO_SPECIFIC_STORAGE */ + return err; } @@ -105,10 +167,10 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t if (keyId < kMaxNumberOfKeys) { - // This is the ID of the actual data + /* Use kKeyId_KvsValues as base key id for all keys. */ pdmInternalId = Internal::RamStorageKey::GetInternalId(kKeyId_KvsValues, keyId); ChipLogProgress(DeviceLayer, "KVS, get the value of Matter key [%s] with PDM id: %i", key, pdmInternalId); - err = KeyValueStoreManagerImpl::sValuesStorage.Read(pdmInternalId, 0, (uint8_t *) value, &valueSize); + err = GetValStorage(key)->Read(pdmInternalId, 0, (uint8_t *) value, &valueSize); *read_bytes_size = valueSize; } else @@ -140,11 +202,11 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, keyId = freeKeyId; } + /* Use kKeyId_KvsValues as base key id for all keys. */ pdmInternalId = Internal::RamStorageKey::GetInternalId(kKeyId_KvsValues, keyId); ChipLogProgress(DeviceLayer, "KVS, save in flash the value of the Matter key [%s] with PDM id: %i", key, pdmInternalId); - err = sValuesStorage.Write(pdmInternalId, (uint8_t *) value, value_size); - + err = GetValStorage(key)->Write(pdmInternalId, (uint8_t *) value, value_size); /* save the 'key' in flash such that it can be retrieved later on */ if (err == CHIP_NO_ERROR) { @@ -154,7 +216,7 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, ChipLogProgress(DeviceLayer, "KVS, save in flash the Matter key [%s] with PDM id: %i and length %d", key, pdmInternalId, strlen(key) + 1); - err = sKeysStorage.Write(pdmInternalId, (uint8_t *) key, strlen(key) + 1); + err = GetKeyStorage(key)->Write(pdmInternalId, (uint8_t *) key, strlen(key) + 1); if (err != CHIP_NO_ERROR) { ChipLogProgress(DeviceLayer, "KVS, Error while saving in flash the Matter key [%s] with PDM id: %i", key, @@ -188,16 +250,17 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key) pdmInternalId = Internal::RamStorageKey::GetInternalId(kKeyId_KvsKeys, keyId); ChipLogProgress(DeviceLayer, "KVS, delete from flash the Matter key [%s] with PDM id: %i", key, pdmInternalId); - err = sKeysStorage.Delete(pdmInternalId, -1); + err = GetKeyStorage(key)->Delete(pdmInternalId, -1); /* also delete the 'key string' from flash */ if (err == CHIP_NO_ERROR) { + /* Use kKeyId_KvsValues as base key id for all keys. */ pdmInternalId = Internal::RamStorageKey::GetInternalId(kKeyId_KvsValues, keyId); ChipLogProgress(DeviceLayer, "KVS, delete from flash the value of the Matter key [%s] with PDM id: %i", key, pdmInternalId); - err = sValuesStorage.Delete(pdmInternalId, -1); + err = GetValStorage(key)->Delete(pdmInternalId, -1); if (err != CHIP_NO_ERROR) { ChipLogProgress(DeviceLayer, @@ -220,6 +283,8 @@ void KeyValueStoreManagerImpl::FactoryResetStorage(void) { sKeysStorage.OnFactoryReset(); sValuesStorage.OnFactoryReset(); + sSubscriptionStorage.OnFactoryReset(); + sGroupsStorage.OnFactoryReset(); } void KeyValueStoreManagerImpl::ConvertError(CHIP_ERROR & err) @@ -230,6 +295,54 @@ void KeyValueStoreManagerImpl::ConvertError(CHIP_ERROR & err) } } +#if CONFIG_CHIP_K32W0_KVS_MOVE_KEYS_TO_SPECIFIC_STORAGE +static CHIP_ERROR MoveToDedicatedStorage(const char * key, uint8_t * buffer, uint16_t len, uint16_t keyId, uint16_t valId) +{ + ReturnErrorOnFailure(GetKeyStorage(key)->Write(keyId, (uint8_t *) key, strlen(key) + 1)); + + ReturnErrorOnFailure(KeyValueStoreManagerImpl::sValuesStorage.Read(valId, 0, buffer, &len)); + ReturnErrorOnFailure(GetValStorage(key)->Write(valId, buffer, len)); + + ReturnErrorOnFailure(KeyValueStoreManagerImpl::sKeysStorage.Delete(keyId, -1)); + ReturnErrorOnFailure(KeyValueStoreManagerImpl::sValuesStorage.Delete(valId, -1)); + + return CHIP_NO_ERROR; +} + +static CHIP_ERROR MoveKeysAndValues() +{ + uint16_t len = 1024; // Should be enough for Matter keys + uint16_t keyId = 0; + uint16_t valId = 0; + uint16_t keySize = kMaxKeyValueBytes; + char key[kMaxKeyValueBytes] = { 0 }; + Platform::ScopedMemoryBuffer buffer; + + buffer.Calloc(len); + ReturnErrorCodeIf(buffer.Get() == nullptr, CHIP_ERROR_NO_MEMORY); + + for (uint8_t id = 0; id < kMaxNumberOfKeys; id++) + { + keySize = kMaxKeyValueBytes; + keyId = Internal::RamStorageKey::GetInternalId(kKeyId_KvsKeys, id); + valId = Internal::RamStorageKey::GetInternalId(kKeyId_KvsValues, id); + + auto err = KeyValueStoreManagerImpl::sKeysStorage.Read(keyId, 0, (uint8_t *) key, &keySize); + if (err == CHIP_NO_ERROR) + { + if (!IsKeyRelatedToGroups(key) && !IsKeyRelatedToSubscriptions(key)) + continue; + + err = MoveToDedicatedStorage(key, buffer.Get(), len, keyId, valId); + VerifyOrDo(err != CHIP_NO_ERROR, ChipLogProgress(DeviceLayer, "Key [%s] was moved successfully", key)); + VerifyOrDo(err == CHIP_NO_ERROR, ChipLogProgress(DeviceLayer, "Error in moving key [%s] to dedicated storage", key)); + } + } + + return CHIP_NO_ERROR; +} +#endif // CONFIG_CHIP_K32W0_KVS_MOVE_KEYS_TO_SPECIFIC_STORAGE + } // namespace PersistedStorage } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.h b/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.h index a83a29b8a2e3ef..718b92df6beb39 100644 --- a/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.h +++ b/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.h @@ -37,6 +37,10 @@ class KeyValueStoreManagerImpl final : public KeyValueStoreManager static Internal::RamStorage sKeysStorage; /* Storage for KVS values. Cleared during factory reset. */ static Internal::RamStorage sValuesStorage; + /* Storage for KVS subscription keys and values. Cleared during factory reset. */ + static Internal::RamStorage sSubscriptionStorage; + /* Storage for KVS groups keys and values. Cleared during factory reset. */ + static Internal::RamStorage sGroupsStorage; // Allow the KeyValueStoreManager interface class to delegate method calls to // the implementation methods provided by this class. diff --git a/src/platform/nxp/k32w/k32w0/Logging.cpp b/src/platform/nxp/k32w/k32w0/Logging.cpp index 537ceed1181694..5fc5b64d4404d9 100644 --- a/src/platform/nxp/k32w/k32w0/Logging.cpp +++ b/src/platform/nxp/k32w/k32w0/Logging.cpp @@ -27,7 +27,6 @@ static constexpr uint8_t category_max_len_bytes = 3; #include #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD -static bool isLogInitialized; extern "C" uint32_t otPlatAlarmMilliGetNow(void); namespace chip { @@ -105,12 +104,6 @@ void ENFORCE_FORMAT(1, 0) GenericLog(const char * format, va_list arg, const cha char formattedMsg[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE - 1] = { 0 }; size_t prefixLen, writtenLen; - if (!isLogInitialized) - { - isLogInitialized = true; - otPlatUartEnable(); - } - /* Prefix is composed of [Time Reference][Debug String][Module Name String] */ FillPrefix(formattedMsg, CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE - 1, module, category); prefixLen = strlen(formattedMsg); diff --git a/src/platform/nxp/k32w/k32w0/ThreadStackManagerImpl.cpp b/src/platform/nxp/k32w/k32w0/ThreadStackManagerImpl.cpp index 0435d168a99305..c74c2a9af4d907 100644 --- a/src/platform/nxp/k32w/k32w0/ThreadStackManagerImpl.cpp +++ b/src/platform/nxp/k32w/k32w0/ThreadStackManagerImpl.cpp @@ -72,10 +72,8 @@ void ThreadStackManagerImpl::ProcessThreadActivity() * by doing this, we avoid allocating a new stack for short-lived * BLE processing (e.g.: only during Matter commissioning) */ -#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE auto * bleManager = &chip::DeviceLayer::Internal::BLEMgrImpl(); bleManager->DoBleProcessing(); -#endif #if defined(chip_with_low_power) && (chip_with_low_power == 1) if (isThreadInitialized()) diff --git a/src/platform/nxp/k32w/k32w0/args.gni b/src/platform/nxp/k32w/k32w0/args.gni index 59a41ae6931585..404daaa3e916db 100644 --- a/src/platform/nxp/k32w/k32w0/args.gni +++ b/src/platform/nxp/k32w/k32w0/args.gni @@ -13,10 +13,14 @@ # limitations under the License. import("//build_overrides/chip.gni") -import("//build_overrides/k32w0_sdk.gni") +import("//build_overrides/nxp_sdk.gni") import("//build_overrides/openthread.gni") -chip_device_platform = "k32w0" +nxp_platform = "k32w/k32w0" +nxp_sdk_name = "k32w0_sdk" +nxp_device_layer = "nxp/${nxp_platform}" +nxp_use_lwip = false +nxp_use_mbedtls_port = false if (getenv("NXP_K32W0_SDK_ROOT") == "") { k32w0_sdk_root = "${chip_root}/third_party/nxp/k32w0_sdk/repo/core" @@ -24,7 +28,21 @@ if (getenv("NXP_K32W0_SDK_ROOT") == "") { k32w0_sdk_root = getenv("NXP_K32W0_SDK_ROOT") } -lwip_platform = "k32w0" +# 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_openthread_ftd = false chip_inet_config_enable_ipv4 = false @@ -47,7 +65,7 @@ chip_mdns = "platform" chip_system_config_use_open_thread_inet_endpoints = true chip_with_lwip = false -mbedtls_target = "${chip_root}/third_party/nxp/k32w0_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/platform/nxp/k32w/k32w1/BUILD.gn b/src/platform/nxp/k32w/k32w1/BUILD.gn index bb3e74dc034527..53a4b4dce10509 100644 --- a/src/platform/nxp/k32w/k32w1/BUILD.gn +++ b/src/platform/nxp/k32w/k32w1/BUILD.gn @@ -30,6 +30,8 @@ if (chip_crypto == "platform") { } static_library("nxp_platform") { + defines = [ "CHIP_DEVICE_K32W1=1" ] + sources = [ "../../../SingletonConfigurationManager.cpp", "../common/BLEManagerCommon.cpp", @@ -65,7 +67,7 @@ static_library("nxp_platform") { "${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/DefaultTestEventTriggerDelegate.h", "${chip_root}/src/platform/nxp/k32w/k32w1/SMU2Manager.h", ] @@ -107,7 +109,7 @@ static_library("nxp_platform") { ] if (chip_convert_dac_private_key == 1) { - defines = [ "CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY=1" ] + defines += [ "CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY=1" ] } } diff --git a/src/platform/nxp/k32w/k32w1/DiagnosticDataProviderImpl.cpp b/src/platform/nxp/k32w/k32w1/DiagnosticDataProviderImpl.cpp index 212d0b5ea39fa6..3a3412eb031d36 100644 --- a/src/platform/nxp/k32w/k32w1/DiagnosticDataProviderImpl.cpp +++ b/src/platform/nxp/k32w/k32w1/DiagnosticDataProviderImpl.cpp @@ -99,8 +99,7 @@ CHIP_ERROR DiagnosticDataProviderImpl::GetThreadMetrics(ThreadMetrics ** threadM { ThreadMetrics * thread = (ThreadMetrics *) pvPortMalloc(sizeof(ThreadMetrics)); - strncpy(thread->NameBuf, taskStatusArray[x].pcTaskName, kMaxThreadNameLength - 1); - thread->NameBuf[kMaxThreadNameLength] = '\0'; + Platform::CopyString(thread->NameBuf, taskStatusArray[x].pcTaskName); thread->name.Emplace(CharSpan::fromCharString(thread->NameBuf)); thread->id = taskStatusArray[x].xTaskNumber; diff --git a/src/platform/nxp/k32w/k32w1/FactoryDataProviderImpl.cpp b/src/platform/nxp/k32w/k32w1/FactoryDataProviderImpl.cpp index 10ae6d0dd4ab05..06741ef770dcc4 100644 --- a/src/platform/nxp/k32w/k32w1/FactoryDataProviderImpl.cpp +++ b/src/platform/nxp/k32w/k32w1/FactoryDataProviderImpl.cpp @@ -36,18 +36,11 @@ FactoryDataProviderImpl::~FactoryDataProviderImpl() 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) { diff --git a/src/platform/nxp/k32w/k32w1/K32W1Config.cpp b/src/platform/nxp/k32w/k32w1/K32W1Config.cpp index 489d6363d8f4e9..2019fce5811eba 100644 --- a/src/platform/nxp/k32w/k32w1/K32W1Config.cpp +++ b/src/platform/nxp/k32w/k32w1/K32W1Config.cpp @@ -35,10 +35,6 @@ #include #endif -#if (defined(K32W_LOG_ENABLED) && (K32W_LOG_ENABLED > 0)) -// #include "fsl_component_log.h" -// #include "fsl_component_log_backend_debugconsole.h" -#endif #include "FreeRTOS.h" #include "FunctionLib.h" #include "NVM_Interface.h" diff --git a/src/platform/nxp/rt/rw61x/BUILD.gn b/src/platform/nxp/rt/rw61x/BUILD.gn index 0631c8ccd19c4e..3fca99ff0fb7c9 100644 --- a/src/platform/nxp/rt/rw61x/BUILD.gn +++ b/src/platform/nxp/rt/rw61x/BUILD.gn @@ -33,8 +33,20 @@ config("nxp_platform_config") { ".", "../../common/factory_data", ] - defines += [ "CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA=1" ] - defines += [ "EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/common/factory_data/FactoryDataProviderFwkImpl.h\"" ] + defines += [ + "CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA=1", + "CONFIG_CHIP_ENCRYPTED_FACTORY_DATA=1", + ] + + if (chip_enable_secure_dac_private_key_storage == 1) { + defines += [ "EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/rt/rw61x/FactoryDataProviderImpl.h\"" ] + } else { + defines += [ "EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/common/factory_data/FactoryDataProviderFwkImpl.h\"" ] + } + } + if (chip_enable_wifi && chip_enable_openthread) { + # Disable thread nwk commissioning instance on endpoint 0, when OTBR is enabled + defines += [ "_NO_NETWORK_COMMISSIONING_DRIVER_" ] } } @@ -68,12 +80,14 @@ static_library("nxp_platform") { "../../common/ram_storage.c", "../../common/ram_storage.h", ] - } else { + } else if (rt_nvm_component == "key_storage") { sources += [ "../../common/NXPConfigKS.cpp" ] } public_deps = [ "${chip_root}/src/platform:platform_base" ] + deps += [ "${chip_root}/src/platform/logging:headers" ] + if (chip_enable_ble) { sources += [ # Adding random file which defines the function sys_csrand_get which is called by BLEManagerImpl from Zephyr @@ -98,7 +112,9 @@ static_library("nxp_platform") { "../../common/NetworkCommissioningDriver.h", "../../common/NetworkCommissioningWiFiDriver.cpp", ] + defines += [ "WIFI_DFS_OPTIMIZATION=1" ] } + if (chip_enable_ota_requestor) { sources += [ "../../common/OTAImageProcessorImpl.cpp", @@ -116,13 +132,18 @@ static_library("nxp_platform") { ] deps += [ "${chip_root}/third_party/openthread:openthread" ] + public_deps += [ "${chip_root}/third_party/openthread:openthread-platform" ] if (chip_mdns == "platform") { - sources += [ - "../../../OpenThread/DnssdImpl.cpp", - "../../../OpenThread/OpenThreadDnssdImpl.cpp", - "../../../OpenThread/OpenThreadDnssdImpl.h", - ] + if (chip_enable_wifi) { + sources += [ "../../common/DnssdImpl.cpp" ] + } else { + sources += [ + "../../../OpenThread/DnssdImpl.cpp", + "../../../OpenThread/OpenThreadDnssdImpl.cpp", + "../../../OpenThread/OpenThreadDnssdImpl.h", + ] + } deps += [ "${chip_root}/src/lib/dnssd:platform_header" ] } } @@ -131,9 +152,27 @@ static_library("nxp_platform") { sources += [ "../../common/factory_data/FactoryDataProvider.cpp", "../../common/factory_data/FactoryDataProvider.h", - "../../common/factory_data/FactoryDataProviderFwkImpl.cpp", - "../../common/factory_data/FactoryDataProviderFwkImpl.h", ] + if (chip_enable_secure_dac_private_key_storage == 1) { + sources += [ + # TO BE MOVED TO THE SDK + "ELSFactoryData.c", + "ELSFactoryData.h", + "FactoryDataProviderImpl.cpp", + "FactoryDataProviderImpl.h", + ] + } else { + sources += [ + "../../common/factory_data/FactoryDataProviderFwkImpl.cpp", + "../../common/factory_data/FactoryDataProviderFwkImpl.h", + ] + } + + deps += [ "${chip_root}/src/credentials:credentials_header" ] + } + + if (chip_convert_dac_private_key == 1) { + defines += [ "CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY=1" ] } deps += [ "${nxp_sdk_build_root}:nxp_sdk" ] diff --git a/src/platform/nxp/rt/rw61x/CHIPPlatformConfig.h b/src/platform/nxp/rt/rw61x/CHIPPlatformConfig.h index eedd1101802b3f..caa7e32a9e3000 100644 --- a/src/platform/nxp/rt/rw61x/CHIPPlatformConfig.h +++ b/src/platform/nxp/rt/rw61x/CHIPPlatformConfig.h @@ -32,6 +32,11 @@ /* Default NXP platform adaptations are used */ +/* In src/crypto/CHIPCryptoPALmbedTLS.cpp we verify kMAX_Hash_SHA256_Context_Size >= sizeof(mbedtls_sha256_context) + * sizeof(mbedtls_sha256_context) is 392 bytes with els_pkc mbedtls port + */ +#define CHIP_CONFIG_SHA256_CONTEXT_SIZE (sizeof(unsigned int) * 98) + // ==================== Security Adaptations ==================== /* Default NXP Platform security adaptations are used */ diff --git a/src/platform/nxp/rt/rw61x/ELSFactoryData.c b/src/platform/nxp/rt/rw61x/ELSFactoryData.c new file mode 100644 index 00000000000000..a440c42569ffbd --- /dev/null +++ b/src/platform/nxp/rt/rw61x/ELSFactoryData.c @@ -0,0 +1,453 @@ +/* + * Copyright 2023 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "ELSFactoryData.h" + +uint8_t * append_u32(uint8_t * pos, uint32_t val) +{ + *pos++ = 4; + *pos++ = (val >> 24) & 0xFF; + *pos++ = (val >> 16) & 0xFF; + *pos++ = (val >> 8) & 0xFF; + *pos++ = val & 0xFF; + return pos; +} + +uint8_t * append_u16(uint8_t * pos, uint32_t val) +{ + *pos++ = 2; + *pos++ = (val >> 8) & 0xFF; + *pos++ = val & 0xFF; + return pos; +} + +void write_uint32_msb_first(uint8_t * pos, uint32_t data) +{ + pos[0] = ((data) >> 24) & 0xFF; + pos[1] = ((data) >> 16) & 0xFF; + pos[2] = ((data) >> 8) & 0xFF; + pos[3] = ((data) >> 0) & 0xFF; +} + +void printf_buffer(const char * name, const unsigned char * buffer, size_t size) +{ +#define PP_BYTES_PER_LINE (32) + char line_buffer[PP_BYTES_PER_LINE * 2 + 2]; + const unsigned char * pos = buffer; + size_t remaining = size; + while (remaining > 0) + { + size_t block_size = remaining > PP_BYTES_PER_LINE ? PP_BYTES_PER_LINE : remaining; + uint32_t len = 0; + for (size_t i = 0; i < block_size; i++) + { + line_buffer[len++] = nibble_to_char[((*pos) & 0xf0) >> 4]; + line_buffer[len++] = nibble_to_char[(*pos++) & 0x0f]; + } + line_buffer[len++] = '\n'; + line_buffer[len++] = '\0'; + PRINTF("%s (%p): %s", name, pos, line_buffer); + remaining -= block_size; + } +} + +uint32_t get_required_keyslots(mcuxClEls_KeyProp_t prop) +{ + return prop.bits.ksize == MCUXCLELS_KEYPROPERTY_KEY_SIZE_128 ? 1U : 2U; +} + +bool els_is_active_keyslot(mcuxClEls_KeyIndex_t keyIdx) +{ + mcuxClEls_KeyProp_t key_properties; + key_properties.word.value = ((const volatile uint32_t *) (&ELS->ELS_KS0))[keyIdx]; + return key_properties.bits.kactv; +} + +status_t els_enable() +{ + PLOG_INFO("Enabling ELS..."); + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_Enable_Async()); + + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_Enable_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) + { + PLOG_ERROR("mcuxClEls_Enable_Async failed: 0x%08x", result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); + + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); + + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) + { + PLOG_ERROR("mcuxClEls_WaitForOperation failed: 0x%08x", result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); + return STATUS_SUCCESS; +} + +status_t els_get_key_properties(mcuxClEls_KeyIndex_t key_index, mcuxClEls_KeyProp_t * key_properties) +{ + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_GetKeyProperties(key_index, key_properties)); + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_GetKeyProperties) != token) || (MCUXCLELS_STATUS_OK != result)) + { + PLOG_ERROR("mcuxClEls_GetKeyProperties failed: 0x%08lx", result); + return STATUS_ERROR_GENERIC; + } + + MCUX_CSSL_FP_FUNCTION_CALL_END(); + return STATUS_SUCCESS; +} + +mcuxClEls_KeyIndex_t els_get_free_keyslot(uint32_t required_keyslots) +{ + for (mcuxClEls_KeyIndex_t keyIdx = 0U; keyIdx <= (MCUXCLELS_KEY_SLOTS - required_keyslots); keyIdx++) + { + bool is_valid_keyslot = true; + for (uint32_t i = 0U; i < required_keyslots; i++) + { + if (els_is_active_keyslot(keyIdx + i)) + { + is_valid_keyslot = false; + break; + } + } + + if (is_valid_keyslot) + { + return keyIdx; + } + } + return MCUXCLELS_KEY_SLOTS; +} + +status_t els_derive_key(mcuxClEls_KeyIndex_t src_key_index, mcuxClEls_KeyProp_t key_prop, const uint8_t * dd, + mcuxClEls_KeyIndex_t * dst_key_index) +{ + uint32_t required_keyslots = get_required_keyslots(key_prop); + + *dst_key_index = els_get_free_keyslot(required_keyslots); + + if (!(*dst_key_index < MCUXCLELS_KEY_SLOTS)) + { + PLOG_ERROR("no free keyslot found"); + return STATUS_ERROR_GENERIC; + } + + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_Ckdf_Sp800108_Async(src_key_index, *dst_key_index, key_prop, dd)); + + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_Ckdf_Sp800108_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) + { + PLOG_ERROR("mcuxClEls_Ckdf_Sp800108_Async failed: 0x%08x", result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); + + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) + { + PLOG_ERROR("mcuxClEls_WaitForOperation failed: 0x%08x", result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); + return STATUS_SUCCESS; +} + +status_t els_delete_key(mcuxClEls_KeyIndex_t key_index) +{ + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_KeyDelete_Async(key_index)); + + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_KeyDelete_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) + { + PLOG_ERROR("mcuxClEls_KeyDelete_Async failed: 0x%08x", result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); + + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) + { + PLOG_ERROR("mcuxClEls_WaitForOperation failed: 0x%08x", result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); + return STATUS_SUCCESS; +} + +status_t els_import_key(const uint8_t * wrapped_key, size_t wrapped_key_size, mcuxClEls_KeyProp_t key_prop, + mcuxClEls_KeyIndex_t unwrap_key_index, mcuxClEls_KeyIndex_t * dst_key_index) +{ + uint32_t required_keyslots = get_required_keyslots(key_prop); + *dst_key_index = els_get_free_keyslot(required_keyslots); + + if (!(*dst_key_index < MCUXCLELS_KEY_SLOTS)) + { + PLOG_ERROR("no free keyslot found"); + return STATUS_ERROR_GENERIC; + } + + mcuxClEls_KeyImportOption_t options; + options.bits.kfmt = MCUXCLELS_KEYIMPORT_KFMT_RFC3394; + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN( + result, token, mcuxClEls_KeyImport_Async(options, wrapped_key, wrapped_key_size, unwrap_key_index, *dst_key_index)); + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_KeyImport_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) + { + PLOG_ERROR("mcuxClEls_KeyImport_Async failed: 0x%08lx", result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); + + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) + { + PLOG_ERROR("mcuxClEls_WaitForOperation failed: 0x%08lx", result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); + return STATUS_SUCCESS; +} + +status_t els_keygen(mcuxClEls_KeyIndex_t key_index, uint8_t * public_key, size_t * public_key_size) +{ + status_t status = STATUS_SUCCESS; + + mcuxClEls_EccKeyGenOption_t key_gen_options; + key_gen_options.word.value = 0u; + key_gen_options.bits.kgsign = MCUXCLELS_ECC_PUBLICKEY_SIGN_DISABLE; + key_gen_options.bits.kgsrc = MCUXCLELS_ECC_OUTPUTKEY_DETERMINISTIC; + key_gen_options.bits.skip_pbk = MCUXCLELS_ECC_GEN_PUBLIC_KEY; + + mcuxClEls_KeyProp_t key_properties; + status = els_get_key_properties(key_index, &key_properties); + STATUS_SUCCESS_OR_EXIT_MSG("get_key_properties failed: 0x%08x", status); + + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN( + result, token, + mcuxClEls_EccKeyGen_Async(key_gen_options, (mcuxClEls_KeyIndex_t) 0, key_index, key_properties, NULL, &public_key[0])); + + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_EccKeyGen_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) + { + PRINTF("Css_EccKeyGen_Async failed: 0x%08lx\r\n", result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); + + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) + { + PRINTF("Css_EccKeyGen_Async WaitForOperation failed: 0x%08lx\r\n", result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); +exit: + return status; +} + +status_t calculate_psa_import_blob_cmac(uint8_t * psa_import_blob, size_t psa_import_blob_length_before_mac, + size_t psa_import_blob_size) +{ + status_t status = STATUS_SUCCESS; + mcuxClEls_KeyIndex_t mac_key_index = MCUXCLELS_KEY_SLOTS; + + assert(psa_import_blob_size >= psa_import_blob_length_before_mac + AES_BLOCK_SIZE); + + uint8_t * pos = &psa_import_blob[psa_import_blob_length_before_mac]; + uint8_t mac[AES_BLOCK_SIZE] = { 0 }; + uint32_t missing_bytes_to_fill_block = AES_BLOCK_SIZE - (psa_import_blob_length_before_mac % AES_BLOCK_SIZE); + + mcuxClEls_CmacOption_t cmac_options = { 0U }; + cmac_options.bits.initialize = MCUXCLELS_CMAC_INITIALIZE_ENABLE; + cmac_options.bits.finalize = MCUXCLELS_CMAC_FINALIZE_ENABLE; + cmac_options.bits.extkey = MCUXCLELS_CMAC_EXTERNAL_KEY_DISABLE; + // ELS needs us to pad the message, it does not do that itself :-( + if (missing_bytes_to_fill_block != 0) + { + memset(pos, 0, missing_bytes_to_fill_block); + *pos = 0x80; + } + + PLOG_INFO("Deriving cmac key for integrity protection on key blob..."); + status = els_derive_key(DIE_INT_MK_SK_INDEX, mac_key_prop, ckdf_derivation_data_mac, &mac_key_index); + STATUS_SUCCESS_OR_EXIT_MSG("derive_key failed: 0x%08x", status); + + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN( + result, token, + mcuxClEls_Cmac_Async(cmac_options, mac_key_index, NULL, 0, psa_import_blob, psa_import_blob_length_before_mac, mac)); + + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_Cmac_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) + { + PLOG_ERROR("mcuxClEls_Cmac_Async failed: 0x%08x", result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); + + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) + { + PLOG_ERROR("mcuxClEls_WaitForOperation failed: 0x%08x\n", result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); + + status = els_delete_key(mac_key_index); + STATUS_SUCCESS_OR_EXIT_MSG("delete_key failed: 0x%08x", status); + + memcpy(pos, mac, sizeof(mac)); +exit: + return status; +} + +status_t create_psa_import_blob(const uint8_t * els_key_blob, size_t els_key_blob_size, const psa_key_attributes_t * attributes, + uint8_t * output, size_t * output_size) +{ + assert(els_key_blob_size <= 48); + assert(sizeof(key_blob_magic) < 0x80); + + status_t status = STATUS_SUCCESS; + // clang-format off + size_t required_output_size = 0 + + 2 + sizeof(key_blob_magic) + + 2 + 4 // key_id + + 2 + 4 // algorithms + + 2 + 4 // usage + + 2 + 2 // type + + 2 + 4 // bits + + 2 + 4 // lifetime + + 2 + 4 // device lifecycle + + 2 + 4 // wrapping key id + + 2 + 4 // wrapping algorithm + + 2 + 4 // signing key id + + 2 + 4 // signing algorithm + + 2 + els_key_blob_size // key blob from S50 + + 2 + AES_BLOCK_SIZE; // CMAC + // clang-format on + + if (*output_size < required_output_size) + { + PLOG_ERROR("key blob buffer too small"); + return STATUS_ERROR_GENERIC; + } + *output_size = required_output_size; + + uint32_t key_id = psa_get_key_id(attributes); + uint32_t key_alg = psa_get_key_algorithm(attributes); + uint32_t key_usage = psa_get_key_usage_flags(attributes); + uint16_t key_type = psa_get_key_type(attributes); + uint32_t key_bits = psa_get_key_bits(attributes); + uint32_t key_lifetime = psa_get_key_lifetime(attributes); + uint32_t device_lifecycle = 0x1; // 0x01: OPEN, 0x02: CLOSED, 0x04: CLOSED_LOCKED + uint32_t wrapping_key_id = NXP_DIE_INT_IMPORT_KEK_SK; + uint32_t signing_key_id = NXP_DIE_INT_IMPORT_AUTH_SK; + + PLOG_INFO("Creating key blob..."); + uint8_t * pos = output; + + *pos++ = 0x40; + *pos++ = sizeof(key_blob_magic); + memcpy(pos, key_blob_magic, sizeof(key_blob_magic)); + pos += sizeof(key_blob_magic); + + *pos++ = 0x41; + pos = append_u32(pos, key_id); + + *pos++ = 0x42; + pos = append_u32(pos, key_alg); + + *pos++ = 0x43; + pos = append_u32(pos, key_usage); + + *pos++ = 0x44; + pos = append_u16(pos, key_type); + + *pos++ = 0x45; + pos = append_u32(pos, key_bits); + + *pos++ = 0x46; + pos = append_u32(pos, key_lifetime); + + *pos++ = 0x47; + pos = append_u32(pos, device_lifecycle); + + *pos++ = 0x50; + pos = append_u32(pos, wrapping_key_id); + + *pos++ = 0x51; + pos = append_u32(pos, 0x01); // ELS RFC3394 wrapping + + *pos++ = 0x53; + pos = append_u32(pos, signing_key_id); + + *pos++ = 0x54; + pos = append_u32(pos, 0x01); // CMAC + + *pos++ = 0x55; + *pos++ = els_key_blob_size; + memcpy(pos, els_key_blob, els_key_blob_size); + pos += els_key_blob_size; + + // signature + *pos++ = 0x5E; + *pos++ = AES_BLOCK_SIZE; + size_t psa_import_blob_length_before_mac = pos - output; + + status = calculate_psa_import_blob_cmac(output, psa_import_blob_length_before_mac, *output_size); + return status; +} + +status_t import_die_int_wrapped_key_into_els(const uint8_t * wrapped_key, size_t wrapped_key_size, + mcuxClEls_KeyProp_t key_properties, mcuxClEls_KeyIndex_t * index_output) +{ + status_t status = STATUS_SUCCESS; + mcuxClEls_KeyIndex_t index_unwrap = MCUXCLELS_KEY_SLOTS; + + PLOG_INFO("Deriving wrapping key for import of die_int wrapped key on ELS..."); + status = els_derive_key(DIE_INT_MK_SK_INDEX, wrap_out_key_prop, ckdf_derivation_data_wrap_out, &index_unwrap); + STATUS_SUCCESS_OR_EXIT_MSG("derive_key failed: 0x%08x", status); + + status = els_import_key(wrapped_key, wrapped_key_size, key_properties, index_unwrap, index_output); + STATUS_SUCCESS_OR_EXIT_MSG("import_wrapped_key failed: 0x%08x", status); + + status = els_delete_key(index_unwrap); + STATUS_SUCCESS_OR_EXIT_MSG("delete_key failed: 0x%08x", status); + index_unwrap = MCUXCLELS_KEY_SLOTS; + +exit: + if (index_unwrap < MCUXCLELS_KEY_SLOTS) + { + (void) els_delete_key(index_unwrap); + } + return status; +} + +status_t ELS_sign_hash(uint8_t * digest, mcuxClEls_EccByte_t * ecc_signature, mcuxClEls_EccSignOption_t * sign_options, + mcuxClEls_KeyIndex_t key_index) +{ + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, + mcuxClEls_EccSign_Async( // Perform signature generation. + *sign_options, // Set the prepared configuration. + key_index, // Set index of private key in keystore. + digest, NULL, (size_t) 0U, // Pre-hashed data to sign. Note that inputLength parameter is + // ignored since pre-hashed data has a fixed length. + ecc_signature // Output buffer, which the operation will write the signature to. + )); + PLOG_DEBUG_BUFFER("mcuxClEls_EccSign_Async ecc_signature", ecc_signature, MCUXCLELS_ECC_SIGNATURE_SIZE); + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_EccSign_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) + { + PLOG_ERROR("mcuxClEls_EccSign_Async failed. token: 0x%08x, result: 0x%08x", token, result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); + + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) + { + PLOG_ERROR("mcuxClEls_WaitForOperation failed. token: 0x%08x, result: 0x%08x", token, result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); + return STATUS_SUCCESS; +} diff --git a/src/platform/nxp/rt/rw61x/ELSFactoryData.h b/src/platform/nxp/rt/rw61x/ELSFactoryData.h new file mode 100644 index 00000000000000..0ac259a66a4158 --- /dev/null +++ b/src/platform/nxp/rt/rw61x/ELSFactoryData.h @@ -0,0 +1,247 @@ +/* + * Copyright 2023 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __ELS_FACTORY_DATA_H__ +#define __ELS_FACTORY_DATA_H__ + +#include +#include + +#include "fsl_common.h" +#include "mbedtls/bignum.h" +#include "mbedtls/ecp.h" +#include "mcuxClAes.h" +#include "mcuxClEls_Cipher.h" +#include "mcuxClEls_Cmac.h" +#include "mcuxClEls_Ecc.h" +#include "mcuxClEls_Hash.h" +#include "mcuxClEls_Kdf.h" +#include "mcuxClEls_KeyManagement.h" +#include "mcuxClEls_Rng.h" +#include "mcuxClEls_Types.h" +#include "mcuxClHash_Constants.h" + +#include "psa/crypto.h" +#include "psa/crypto_values.h" + +#include "mbedtls/ecdh.h" +#include "mbedtls/entropy.h" +#include "mbedtls/nist_kw.h" + +#define BLOCK_SIZE_16_BYTES 16 +#define SHA256_OUTPUT_SIZE 32 +#define HASH_ID 0xCE47BA5E +#define HASH_LEN 4 +#define CBC_INITIAL_VECTOR_SIZE 16 + +#define STATUS_SUCCESS 0 +#define STATUS_ERROR_GENERIC 1 + +#define AES_BLOCK_SIZE 16U +#define DIE_INT_MK_SK_INDEX 0U + +#define ELS_BLOB_METADATA_SIZE 8 +#define MAX_ELS_KEY_SIZE 32 +#define ELS_WRAP_OVERHEAD 8 + +#if FACTORY_DATA_PROVIDER_LOG +#define PLOG_ERROR(...) \ + for (;;) \ + { \ + PRINTF("ERROR "); \ + PRINTF(__VA_ARGS__); \ + PRINTF(" (%s:%d)\n", __FILE__, __LINE__); \ + break; \ + } +#else +#define PLOG_ERROR(...) +#endif + +#if FACTORY_DATA_PROVIDER_LOG +#define PLOG_INFO(...) \ + for (;;) \ + { \ + PRINTF("INFO "); \ + PRINTF(__VA_ARGS__); \ + PRINTF("\n"); \ + break; \ + } +#else +#define PLOG_INFO(...) +#endif + +#if FACTORY_DATA_PROVIDER_LOG +#define PLOG_DEBUG(...) \ + for (;;) \ + { \ + PRINTF("DEBUG "); \ + PRINTF(__VA_ARGS__); \ + PRINTF("\n"); \ + break; \ + } +#else +#define PLOG_DEBUG(...) +#endif + +#if FACTORY_DATA_PROVIDER_LOG +#define PLOG_DEBUG_BUFFER(...) printf_buffer(__VA_ARGS__) +#else +#define PLOG_DEBUG_BUFFER(...) +#endif + +#define RET_MBEDTLS_SUCCESS_OR_EXIT_MSG(MSG, ...) \ + if (0 != ret) \ + { \ + status = STATUS_ERROR_GENERIC; \ + PLOG_ERROR(MSG, __VA_ARGS__); \ + goto exit; \ + } + +#define STATUS_SUCCESS_OR_EXIT_MSG(MSG, ...) \ + if (STATUS_SUCCESS != status) \ + { \ + PLOG_ERROR(MSG, __VA_ARGS__); \ + goto exit; \ + } + +// common flags +#define PSA_KEY_LOCATION_NXP_FLAG 0x400000U +#define PSA_KEY_LOCATION_EL2GO_FLAG 0x200000U +#define PSA_KEY_LOCATION_S50_FLAG 0x000001U +#define PSA_KEY_LOCATION_COMMON_FLAG \ + (PSA_KEY_LOCATION_VENDOR_FLAG | PSA_KEY_LOCATION_NXP_FLAG | PSA_KEY_LOCATION_EL2GO_FLAG | PSA_KEY_LOCATION_S50_FLAG) + +// key/data +#define PSA_KEY_LOCATION_KEY_FLAG 0x000000 +#define PSA_KEY_LOCATION_DATA_FLAG 0x008000 + +// blob/encrypted +#define PSA_KEY_LOCATION_BLOB_STORAGE_FLAG 0x000000 +#define PSA_KEY_LOCATION_ENC_STORAGE_FLAG 0x000100 +#define PSA_KEY_LOCATION_TEMP_STORAGE_FLAG 0x000200 +#define PSA_KEY_LOCATION_KEY_GEN_STORAGE_FLAG 0x000300 + +#define PSA_KEY_LOCATION_S50_BLOB_STORAGE \ + ((PSA_KEY_LOCATION_COMMON_FLAG | PSA_KEY_LOCATION_BLOB_STORAGE_FLAG | PSA_KEY_LOCATION_KEY_FLAG)) +#define MCUXCLPSADRIVER_IS_S50_BLOB_STORAGE(location) ((location) == PSA_KEY_LOCATION_S50_BLOB_STORAGE) +#define PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(persistence, location) ((location) << 8 | (persistence)) + +#define NXP_DIE_INT_IMPORT_KEK_SK 0x7FFF817CU +#define NXP_DIE_INT_IMPORT_AUTH_SK 0x7FFF817EU + +const mcuxClEls_KeyProp_t keypair_prop = { .bits = { + .ksize = MCUXCLELS_KEYPROPERTY_KEY_SIZE_256, + .upprot_priv = MCUXCLELS_KEYPROPERTY_PRIVILEGED_TRUE, + .upprot_sec = MCUXCLELS_KEYPROPERTY_SECURE_TRUE, + + } }; + +const mcuxClEls_KeyProp_t shared_secret_prop = { + .bits = + { + .ksize = MCUXCLELS_KEYPROPERTY_KEY_SIZE_128, + .uckdf = MCUXCLELS_KEYPROPERTY_CKDF_TRUE, + .upprot_priv = MCUXCLELS_KEYPROPERTY_PRIVILEGED_TRUE, + .upprot_sec = MCUXCLELS_KEYPROPERTY_SECURE_TRUE, + + + }, +}; + +const mcuxClEls_KeyProp_t wrap_in_key_prop = { + .bits = + { + .ksize = MCUXCLELS_KEYPROPERTY_KEY_SIZE_128, + .kactv = MCUXCLELS_KEYPROPERTY_ACTIVE_TRUE, + .ukuok = MCUXCLELS_KEYPROPERTY_KUOK_TRUE, + .upprot_priv = MCUXCLELS_KEYPROPERTY_PRIVILEGED_TRUE, + .upprot_sec = MCUXCLELS_KEYPROPERTY_SECURE_TRUE, + + }, +}; + +const uint8_t ckdf_derivation_data_wrap_in[12] = { + 0xc8, 0xac, 0x48, 0x88, 0xa6, 0x1b, 0x3d, 0x9b, 0x56, 0xa9, 0x75, 0xe7, +}; + +const mcuxClEls_KeyProp_t wrap_out_key_prop = { + .bits = + { + .ksize = MCUXCLELS_KEYPROPERTY_KEY_SIZE_256, + .kactv = MCUXCLELS_KEYPROPERTY_ACTIVE_TRUE, + .ukwk = MCUXCLELS_KEYPROPERTY_KWK_TRUE, + .upprot_priv = MCUXCLELS_KEYPROPERTY_PRIVILEGED_TRUE, + .upprot_sec = MCUXCLELS_KEYPROPERTY_SECURE_TRUE, + + + }, +}; + +const uint8_t ckdf_derivation_data_wrap_out[12] = { + 0x4e, 0x5f, 0x0a, 0x1c, 0x43, 0x37, 0x2c, 0xd0, 0x54, 0x8e, 0x46, 0xc9, +}; + +const mcuxClEls_KeyProp_t mac_key_prop = { + .bits = + { + .ksize = MCUXCLELS_KEYPROPERTY_KEY_SIZE_256, + .kactv = MCUXCLELS_KEYPROPERTY_ACTIVE_TRUE, + .ucmac = MCUXCLELS_KEYPROPERTY_CMAC_TRUE, + .upprot_priv = MCUXCLELS_KEYPROPERTY_PRIVILEGED_TRUE, + .upprot_sec = MCUXCLELS_KEYPROPERTY_SECURE_TRUE, + }, +}; + +const uint8_t ckdf_derivation_data_mac[12] = { + 0xea, 0x93, 0x05, 0x7a, 0x50, 0xb6, 0x4d, 0x58, 0x0a, 0xe6, 0x6b, 0x57, +}; + +const uint8_t import_die_int_ecdh_sk[32] = { + 0x82, 0x9b, 0xb4, 0x4a, 0x3b, 0x6d, 0x73, 0x35, 0x09, 0x5e, 0xd9, 0x8d, 0xf6, 0x09, 0x89, 0x98, + 0xac, 0x63, 0xab, 0x4e, 0x4e, 0x78, 0xf6, 0x0a, 0x70, 0xea, 0x64, 0x92, 0xd4, 0xfc, 0xe4, 0x92, +}; + +const uint8_t import_die_int_ecdh_pk[64] = { + 0x8c, 0xe2, 0x3a, 0x89, 0xe7, 0xc5, 0xe9, 0xb1, 0x3e, 0x89, 0xed, 0xdb, 0x69, 0xb9, 0x22, 0xf8, + 0xc2, 0x8f, 0x5d, 0xcc, 0x59, 0x3e, 0x5f, 0x7b, 0x6e, 0x5a, 0x6c, 0xb3, 0x62, 0xc0, 0x17, 0x8a, + 0x2f, 0xda, 0xe8, 0x72, 0x67, 0x7b, 0xdf, 0xfe, 0xdb, 0x4a, 0x6e, 0x39, 0x2a, 0x1b, 0xae, 0xf8, + 0x88, 0x8f, 0xc5, 0x11, 0xc3, 0x67, 0x85, 0x5a, 0xc5, 0x54, 0xbb, 0xeb, 0x19, 0xf6, 0x52, 0x66, +}; + +const uint8_t key_blob_magic[7] = { 'k', 'e', 'y', 'b', 'l', 'o', 'b' }; + +const size_t s50_blob_size = 100; + +const char nibble_to_char[16] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', +}; + +uint8_t * append_u32(uint8_t * pos, uint32_t val); +uint8_t * append_u16(uint8_t * pos, uint32_t val); +void write_uint32_msb_first(uint8_t * pos, uint32_t data); +void printf_buffer(const char * name, const unsigned char * buffer, size_t size); +uint32_t get_required_keyslots(mcuxClEls_KeyProp_t prop); +bool els_is_active_keyslot(mcuxClEls_KeyIndex_t keyIdx); +status_t els_enable(); +status_t els_get_key_properties(mcuxClEls_KeyIndex_t key_index, mcuxClEls_KeyProp_t * key_properties); +mcuxClEls_KeyIndex_t els_get_free_keyslot(uint32_t required_keyslots); +status_t els_derive_key(mcuxClEls_KeyIndex_t src_key_index, mcuxClEls_KeyProp_t key_prop, const uint8_t * dd, + mcuxClEls_KeyIndex_t * dst_key_index); +status_t els_delete_key(mcuxClEls_KeyIndex_t key_index); +status_t els_import_key(const uint8_t * wrapped_key, size_t wrapped_key_size, mcuxClEls_KeyProp_t key_prop, + mcuxClEls_KeyIndex_t unwrap_key_index, mcuxClEls_KeyIndex_t * dst_key_index); +status_t els_keygen(mcuxClEls_KeyIndex_t key_index, uint8_t * public_key, size_t * public_key_size); +status_t calculate_psa_import_blob_cmac(uint8_t * psa_import_blob, size_t psa_import_blob_length_before_mac, + size_t psa_import_blob_size); +status_t create_psa_import_blob(const uint8_t * els_key_blob, size_t els_key_blob_size, const psa_key_attributes_t * attributes, + uint8_t * output, size_t * output_size); +status_t import_die_int_wrapped_key_into_els(const uint8_t * wrapped_key, size_t wrapped_key_size, + mcuxClEls_KeyProp_t key_properties, mcuxClEls_KeyIndex_t * index_output); +status_t ELS_sign_hash(uint8_t * digest, mcuxClEls_EccByte_t * ecc_signature, mcuxClEls_EccSignOption_t * sign_options, + mcuxClEls_KeyIndex_t key_index); + +#endif diff --git a/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.cpp b/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.cpp new file mode 100644 index 00000000000000..299a018fabd092 --- /dev/null +++ b/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.cpp @@ -0,0 +1,900 @@ +/* + * + * Copyright (c) 2020-2022 Project CHIP Authors + * Copyright 2023 NXP + * + * 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 "FactoryDataProviderImpl.h" + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +#include "ELSFactoryData.h" +#include "mflash_drv.h" + +#if CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY +#include "fsl_adapter_flash.h" +#endif + +#ifndef FACTORY_DATA_PROVIDER_RUN_TESTS +#define FACTORY_DATA_PROVIDER_RUN_TESTS 0 +#endif + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +#ifndef FACTORY_DATA_PROVIDER_LOG +#define FACTORY_DATA_PROVIDER_LOG 0 +#endif + +#if FACTORY_DATA_PROVIDER_LOG +#include "fsl_debug_console.h" +#define FACTORY_DATA_PROVIDER_PRINTF(...) \ + PRINTF("[%s] ", __FUNCTION__); \ + PRINTF(__VA_ARGS__); \ + PRINTF("\n\r"); +#else +#define FACTORY_DATA_PROVIDER_PRINTF(...) +#endif + +/* Grab symbol for the base address from the linker file. */ +extern uint32_t __FACTORY_DATA_START_OFFSET[]; +extern uint32_t __FACTORY_DATA_SIZE[]; + +using namespace ::chip::Credentials; +using namespace ::chip::Crypto; + +namespace chip { +namespace DeviceLayer { + +FactoryDataProviderImpl FactoryDataProviderImpl::sInstance; + +CHIP_ERROR FactoryDataProviderImpl::SearchForId(uint8_t searchedType, uint8_t * pBuf, size_t bufLength, uint16_t & length, + uint32_t * contentAddr) +{ + CHIP_ERROR err = CHIP_ERROR_NOT_FOUND; + uint8_t type = 0; + uint32_t index = 0; + uint8_t * addrContent = NULL; + uint8_t * factoryDataAddress = &factoryDataRamBuffer[0]; + uint32_t factoryDataSize = sizeof(factoryDataRamBuffer); + uint16_t currentLen = 0; + + while (index < factoryDataSize) + { + /* Read the type */ + memcpy((uint8_t *) &type, factoryDataAddress + index, sizeof(type)); + index += sizeof(type); + + /* Read the len */ + memcpy((uint8_t *) ¤tLen, factoryDataAddress + index, sizeof(currentLen)); + index += sizeof(currentLen); + + /* Check if the type gotten is the expected one */ + if (searchedType == type) + { + FACTORY_DATA_PROVIDER_PRINTF("type = %d, currentLen = %d, bufLength =%d", type, currentLen, bufLength); + /* If pBuf is null it means that we only want to know if the Type has been found */ + if (pBuf != NULL) + { + /* If the buffer given is too small, fill only the available space */ + if (bufLength < currentLen) + { + currentLen = bufLength; + } + memcpy((uint8_t *) pBuf, factoryDataAddress + index, currentLen); + } + length = currentLen; + if (contentAddr != NULL) + { + *contentAddr = (uint32_t) factoryDataAddress + index; + } + err = CHIP_NO_ERROR; + break; + } + else if (type == 0) + { + /* No more type available , break the loop */ + break; + } + else + { + /* Jump to next data */ + index += currentLen; + } + } + + return err; +} + +CHIP_ERROR FactoryDataProviderImpl::SignWithDacKey(const ByteSpan & digestToSign, MutableByteSpan & outSignBuffer) +{ + uint8_t els_key_blob[MAX_ELS_KEY_SIZE + ELS_BLOB_METADATA_SIZE + ELS_WRAP_OVERHEAD]; + uint16_t keySize = 0; + uint32_t keyAddr; + status_t status = STATUS_SUCCESS; + size_t els_key_blob_size = sizeof(els_key_blob); + uint8_t digest[kSHA256_Hash_Length]; + uint8_t public_key[64] = { 0 }; + size_t public_key_size = sizeof(public_key); + mcuxClEls_KeyIndex_t key_index = MCUXCLELS_KEY_SLOTS; + + mcuxClEls_KeyProp_t plain_key_properties = { + .word = { .value = MCUXCLELS_KEYPROPERTY_VALUE_SECURE | MCUXCLELS_KEYPROPERTY_VALUE_PRIVILEGED | + MCUXCLELS_KEYPROPERTY_VALUE_KEY_SIZE_256 | MCUXCLELS_KEYPROPERTY_VALUE_KGSRC } + }; + + mcuxClEls_EccSignOption_t sign_options = { 0 }; + mcuxClEls_EccByte_t ecc_signature[MCUXCLELS_ECC_SIGNATURE_SIZE]; + uint8_t psa_import_blob[256]; + size_t psa_import_blob_size = sizeof(psa_import_blob); + + /* Search key ID FactoryDataId::kDacPrivateKeyId */ + ReturnErrorOnFailure(SearchForId(FactoryDataId::kDacPrivateKeyId, NULL, 0, keySize, &keyAddr)); + memcpy(els_key_blob, (uint8_t *) keyAddr, keySize); + + PLOG_DEBUG_BUFFER("els_key_blob", els_key_blob, els_key_blob_size); + + /* Calculate message HASH to sign */ + memset(&digest[0], 0, sizeof(digest)); + ReturnErrorOnFailure(Hash_SHA256(digestToSign.data(), digestToSign.size(), &digest[0])); + + PLOG_DEBUG_BUFFER("digestToSign", digestToSign.data(), digestToSign.size()); + + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&attributes, 256); + psa_set_key_lifetime( + &attributes, + PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_LIFETIME_PERSISTENT, PSA_KEY_LOCATION_S50_BLOB_STORAGE)); + psa_set_key_id(&attributes, 0x3E000021); + + /*To satisfy PSA APIs and to bind key attributes on PSA level to the key, a TLV structure is created + containing the els_key_blob and metadata. That TLV structure gets a CMAC. This structure is quasi + identical to what EdgeLock 2GO is creating. Note that the TLV structure is not used below but + required in case a blob shall be imported into TF-M for RW61x. */ + status = create_psa_import_blob(els_key_blob, els_key_blob_size, &attributes, psa_import_blob, &psa_import_blob_size); + STATUS_SUCCESS_OR_EXIT_MSG("export_key_from_els failed: 0x%08x", status); + PLOG_DEBUG_BUFFER("psa_import_blob", psa_import_blob, psa_import_blob_size); + + /* Import blob DAC key into SE50 (reserved key slot) */ + status = import_die_int_wrapped_key_into_els(els_key_blob, els_key_blob_size, plain_key_properties, &key_index); + STATUS_SUCCESS_OR_EXIT_MSG("import_die_int_wrapped_key_into_els failed: 0x%08x", status); + + /* For ECC keys that were created from plain key material, there is the + neceessity to convert them to a key. Converting to a key also yields the public key. + The conversion can be done either before re-wrapping (when importing the plain key) + or after (when importing the blob).*/ + status = els_keygen(key_index, &public_key[0], &public_key_size); + STATUS_SUCCESS_OR_EXIT_MSG("els_keygen failed: 0x%08x", status); + + /* The key is usable for signing. */ + PLOG_DEBUG_BUFFER("public_key", public_key, public_key_size); + + /* ECC sign message hash with the key index slot reserved during the blob importation */ + ELS_sign_hash(digest, ecc_signature, &sign_options, key_index); + + /* Delete SE50 key with the index slot reserved during the blob importation (free key slot) */ + els_delete_key(key_index); + + /* Generate MutableByteSpan with ECC signature and ECC signature size */ + return CopySpanToMutableSpan(ByteSpan{ ecc_signature, MCUXCLELS_ECC_SIGNATURE_SIZE }, outSignBuffer); +exit: + els_delete_key(key_index); + return CHIP_ERROR_INVALID_SIGNATURE; +} + +CHIP_ERROR FactoryDataProviderImpl::Init(void) +{ +#if FACTORY_DATA_PROVIDER_RUN_TESTS + unittest(); +#else + els_enable(); + + uint16_t len; + status_t status; + uint32_t factoryDataAddress = (uint32_t) __FACTORY_DATA_START_OFFSET; + uint32_t factoryDataSize = (uint32_t) __FACTORY_DATA_SIZE; + uint32_t hashId; + uint8_t currentBlock[BLOCK_SIZE_16_BYTES]; + uint8_t calculatedHash[SHA256_OUTPUT_SIZE]; + uint16_t i; + CHIP_ERROR res; + + /* Init mflash */ + status = mflash_drv_init(); + + if (status != kStatus_Success || factoryDataSize > sizeof(factoryDataRamBuffer)) + return CHIP_ERROR_INTERNAL; + + /* Read hash id saved in flash */ + if (mflash_drv_read(factoryDataAddress, (uint32_t *) &mHeader, sizeof(mHeader)) != kStatus_Success) + { + return CHIP_ERROR_INTERNAL; + } + + if (mHeader.hashId != HASH_ID) + { + return CHIP_ERROR_NOT_FOUND; + } + + /* Update address to start after hash id to read size of factory data */ + factoryDataAddress += sizeof(mHeader); + + /* Load the buffer into RAM by reading each 16 bytes blocks */ + for (i = 0; i < (factoryDataSize / BLOCK_SIZE_16_BYTES); i++) + { + if (mflash_drv_read(factoryDataAddress + i * BLOCK_SIZE_16_BYTES, (uint32_t *) ¤tBlock[0], sizeof(currentBlock)) != + kStatus_Success) + { + return CHIP_ERROR_INTERNAL; + } + + /* Store the block unencrypted */ + memcpy(&factoryDataRamBuffer[i * BLOCK_SIZE_16_BYTES], ¤tBlock[0], sizeof(currentBlock)); + } + + /* Calculate SHA256 value over the factory data and compare with stored value */ + res = Hash256(&factoryDataRamBuffer[0], mHeader.size, &calculatedHash[0]); + + if (res != CHIP_NO_ERROR) + return res; + + if (memcmp(&calculatedHash[0], &mHeader.hash[0], HASH_LEN) != 0) + { + return CHIP_ERROR_NOT_FOUND; + } + + ReturnErrorOnFailure(SearchForId(FactoryDataId::kVerifierId, NULL, 0, len)); + FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kVerifierId, len); + ReturnErrorOnFailure(SearchForId(FactoryDataId::kSaltId, NULL, 0, len)); + FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kSaltId, len); + ReturnErrorOnFailure(SearchForId(FactoryDataId::kIcId, NULL, 0, len)); + FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kIcId, len); + ReturnErrorOnFailure(SearchForId(FactoryDataId::kDacPrivateKeyId, NULL, 0, len)); + FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kDacPrivateKeyId, len); + ReturnErrorOnFailure(SearchForId(FactoryDataId::kDacCertificateId, NULL, 0, len)); + FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kDacCertificateId, len); + ReturnErrorOnFailure(SearchForId(FactoryDataId::kPaiCertificateId, NULL, 0, len)); + FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kPaiCertificateId, len); + ReturnErrorOnFailure(SearchForId(FactoryDataId::kDiscriminatorId, NULL, 0, len)); + +#if CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY + ReturnErrorOnFailure(ELS_ConvertDacKey()); +#endif +#endif + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProviderImpl::Hash256(const uint8_t * input, size_t inputSize, uint8_t * output) +{ + CHIP_ERROR res; + res = Hash_SHA256(input, inputSize, output); + + return res; +} + +#if CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY +static inline uint32_t els_get_key_size(mcuxClEls_KeyIndex_t keyIdx) +{ + mcuxClEls_KeyProp_t key_properties; + key_properties.word.value = ((const volatile uint32_t *) (&ELS->ELS_KS0))[keyIdx]; + return (key_properties.bits.ksize == MCUXCLELS_KEYPROPERTY_KEY_SIZE_256) ? (256U / 8U) : (128U / 8U); +} + +static status_t els_export_key(mcuxClEls_KeyIndex_t src_key_index, mcuxClEls_KeyIndex_t wrap_key_index, uint8_t * els_key_out_blob, + size_t * els_key_out_blob_size) + +{ + uint32_t key_size = els_get_key_size(src_key_index); + uint32_t required_blob_size = ELS_BLOB_METADATA_SIZE + key_size + ELS_WRAP_OVERHEAD; + assert(required_blob_size <= *els_key_out_blob_size); + + *els_key_out_blob_size = required_blob_size; + + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_KeyExport_Async(wrap_key_index, src_key_index, els_key_out_blob)); + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_KeyExport_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) + { + PLOG_ERROR("mcuxClEls_KeyExport_Async failed: 0x%08lx", result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); + + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) + { + PLOG_ERROR("mcuxClEls_WaitForOperation failed: 0x%08lx", result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); + return STATUS_SUCCESS; +} + +static status_t export_key_from_els(mcuxClEls_KeyIndex_t key_index, uint8_t * output, size_t * output_size) +{ + assert(output != NULL); + status_t status = STATUS_SUCCESS; + + mcuxClEls_KeyIndex_t key_wrap_out_index = MCUXCLELS_KEY_SLOTS; + PLOG_INFO("Deriving wrapping key for export on ELS..."); + status = els_derive_key(DIE_INT_MK_SK_INDEX, wrap_out_key_prop, ckdf_derivation_data_wrap_out, &key_wrap_out_index); + STATUS_SUCCESS_OR_EXIT_MSG("derive_key failed: 0x%08x", status); + + PLOG_INFO("Exporting/wrapping key..."); + status = els_export_key(key_index, key_wrap_out_index, output, output_size); + STATUS_SUCCESS_OR_EXIT_MSG("export_key failed: 0x%08x", status); + + status = els_delete_key(key_wrap_out_index); + STATUS_SUCCESS_OR_EXIT_MSG("delete_key failed: 0x%08x", status); + key_wrap_out_index = MCUXCLELS_KEY_SLOTS; +exit: + return status; +} + +CHIP_ERROR FactoryDataProviderImpl::ELS_ConvertDacKey() +{ + size_t blobSize = MAX_ELS_KEY_SIZE + ELS_BLOB_METADATA_SIZE + ELS_WRAP_OVERHEAD; + size_t newSize = sizeof(Header) + mHeader.size + (ELS_BLOB_METADATA_SIZE + ELS_WRAP_OVERHEAD); + uint8_t blob[Crypto::kP256_PrivateKey_Length + (ELS_BLOB_METADATA_SIZE + ELS_WRAP_OVERHEAD)] = { 0 }; + uint32_t KeyAddr; + uint32_t factoryDataAddress = (uint32_t) __FACTORY_DATA_START_OFFSET; + uint32_t factoryDataSize = (uint32_t) __FACTORY_DATA_SIZE; + uint8_t * data = static_cast(chip::Platform::MemoryAlloc(newSize)); + + VerifyOrReturnError(factoryDataRamBuffer != nullptr, CHIP_ERROR_INTERNAL); + + /* Import pain DAC key and generate the blob */ + ReturnErrorOnFailure(ELS_ExportBlob(blob, &blobSize, KeyAddr)); + ChipLogError(DeviceLayer, "SSS: extracted blob from DAC private key"); + + /* Read all factory data */ + hal_flash_status_t status = + HAL_FlashRead(factoryDataAddress + MFLASH_BASE_ADDRESS, newSize - (ELS_BLOB_METADATA_SIZE + ELS_WRAP_OVERHEAD), data); + VerifyOrReturnError(status == kStatus_HAL_Flash_Success, CHIP_ERROR_INTERNAL); + ChipLogError(DeviceLayer, "SSS: cached factory data in RAM"); + + /* Replace private plain DAC key by the blob into factory data RAM buffer (the blob length is higher then the plain key length) + */ + ReturnErrorOnFailure(ReplaceWithBlob(data, blob, blobSize, KeyAddr)); + ChipLogError(DeviceLayer, "SSS: replaced DAC private key with secured blob"); + PLOG_DEBUG_BUFFER("ReplaceWithBlob", data, newSize); + + /* Erase flash factory data sectors */ + status = HAL_FlashEraseSector(factoryDataAddress + MFLASH_BASE_ADDRESS, factoryDataSize); + VerifyOrReturnError(status == kStatus_HAL_Flash_Success, CHIP_ERROR_INTERNAL); + /* Write new factory data into flash */ + status = HAL_FlashProgramUnaligned(factoryDataAddress + MFLASH_BASE_ADDRESS, newSize, data); + VerifyOrReturnError(status == kStatus_HAL_Flash_Success, CHIP_ERROR_INTERNAL); + ChipLogError(DeviceLayer, "SSS: updated factory data"); + + return CHIP_NO_ERROR; +} + +static status_t els_generate_keypair(mcuxClEls_KeyIndex_t * dst_key_index, uint8_t * public_key, size_t * public_key_size) +{ + if (*public_key_size < 64) + { + PLOG_ERROR("insufficient space for public key"); + return STATUS_ERROR_GENERIC; + } + + mcuxClEls_EccKeyGenOption_t options = { 0 }; + options.bits.kgsrc = MCUXCLELS_ECC_OUTPUTKEY_RANDOM; + options.bits.kgtypedh = MCUXCLELS_ECC_OUTPUTKEY_KEYEXCHANGE; + + uint32_t keypair_required_keyslots = get_required_keyslots(keypair_prop); + *dst_key_index = (mcuxClEls_KeyIndex_t) els_get_free_keyslot(keypair_required_keyslots); + + if (!(*dst_key_index < MCUXCLELS_KEY_SLOTS)) + { + PLOG_ERROR("no free keyslot found"); + return STATUS_ERROR_GENERIC; + } + + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN( + result, token, + mcuxClEls_EccKeyGen_Async(options, (mcuxClEls_KeyIndex_t) 0U, *dst_key_index, keypair_prop, NULL, public_key)); + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_EccKeyGen_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) + { + PLOG_ERROR("mcuxClEls_EccKeyGen_Async failed: 0x%08x", result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); + + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) + { + PLOG_ERROR("mcuxClEls_WaitForOperation failed: 0x%08x", result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); + + *public_key_size = 64; + return STATUS_SUCCESS; +} + +static status_t els_get_random(unsigned char * out, size_t out_size) +{ + /* Get random IV for sector metadata encryption. */ + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClCss_Rng_DrbgRequest_Async(out, out_size)); + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClCss_Rng_DrbgRequest_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) + { + PRINTF("mcuxClCss_Rng_DrbgRequest_Async failed: 0x%08lx\r\n", result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); + + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClCss_WaitForOperation(MCUXCLCSS_ERROR_FLAGS_CLEAR)); + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) + { + PRINTF("Css_EccKeyGen_Async WaitForOperation failed: 0x%08lx\r\n", result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); + return STATUS_SUCCESS; +} + +static int get_random_mbedtls_callback(void * ctx, unsigned char * out, size_t out_size) +{ + status_t status = els_get_random(out, out_size); + if (status != STATUS_SUCCESS) + { + return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; + } + return 0; +} + +static status_t host_perform_key_agreement(const uint8_t * public_key, size_t public_key_size, uint8_t * shared_secret, + size_t * shared_secret_size) +{ + assert(public_key != NULL); + assert(public_key_size == 64); + assert(shared_secret != NULL); + assert(*shared_secret_size >= 32); + + status_t status = STATUS_SUCCESS; + + int ret = 0; + mbedtls_ecp_group grp; + mbedtls_ecp_point qB; + mbedtls_mpi dA, zA; + mbedtls_ecp_group_init(&grp); + mbedtls_ecp_point_init(&qB); + mbedtls_mpi_init(&dA); + mbedtls_mpi_init(&zA); + + unsigned char strbuf[128] = { 0 }; + size_t strlen = sizeof(strbuf); + + uint8_t public_key_compressed[65] = { 0 }; + public_key_compressed[0] = 0x04; + + *shared_secret_size = 32; + ret = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1); + RET_MBEDTLS_SUCCESS_OR_EXIT_MSG("mbedtls_ecp_group_load failed: 0x%08x", ret); + + ret = mbedtls_mpi_read_binary(&dA, import_die_int_ecdh_sk, sizeof(import_die_int_ecdh_sk)); + RET_MBEDTLS_SUCCESS_OR_EXIT_MSG("mbedtls_mpi_read_binary failed: 0x%08x", ret); + + memcpy(&public_key_compressed[1], public_key, public_key_size); + + ret = mbedtls_ecp_point_read_binary(&grp, &qB, public_key_compressed, sizeof(public_key_compressed)); + RET_MBEDTLS_SUCCESS_OR_EXIT_MSG("mbedtls_ecp_point_read_binary failed: 0x%08x", ret); + + ret = mbedtls_ecdh_compute_shared(&grp, &zA, &qB, &dA, &get_random_mbedtls_callback, NULL); + RET_MBEDTLS_SUCCESS_OR_EXIT_MSG("mbedtls_ecdh_compute_shared failed: 0x%08x", ret); + + mbedtls_ecp_point_write_binary(&grp, &qB, MBEDTLS_ECP_PF_UNCOMPRESSED, &strlen, &strbuf[0], sizeof(strbuf)); + printf_buffer("public_key", strbuf, strlen); + + mbedtls_mpi_write_binary(&zA, shared_secret, *shared_secret_size); + PLOG_DEBUG_BUFFER("shared_secret", shared_secret, *shared_secret_size); +exit: + return status; +} + +static status_t host_derive_key(const uint8_t * input_key, size_t input_key_size, const uint8_t * derivation_data, + size_t derivation_data_size, uint32_t key_properties, uint8_t * output, size_t * output_size) +{ + status_t status = STATUS_SUCCESS; + + int ret = 0; + uint32_t counter = 1; + mbedtls_cipher_context_t ctx; + memset(&ctx, 0, sizeof(ctx)); + bool ctx_valid = false; + + assert(input_key != NULL); + assert(input_key_size == 32); + assert(derivation_data != NULL); + assert(derivation_data_size == 12); + assert(output != NULL); + assert(*output_size == 32); + + uint32_t lsbit = key_properties & 0x01; + uint32_t length_blocks = 1 + lsbit; + uint32_t length_bytes = length_blocks * AES_BLOCK_SIZE; + assert(*output_size >= length_bytes); + *output_size = length_bytes; + + // KDF in counter mode implementation as described in Section 5.1 + // of NIST SP 800-108, Recommendation for Key Derivation Using Pseudorandom Functions + // Derivation data[191:0](sic!) = software_derivation_data[95:0] || 64'h0 || requested_ + // properties[31:0 || length[31:0] || counter[31:0] + + uint8_t dd[32] = { 0 }; + memcpy(&dd[0], derivation_data, derivation_data_size); + memset(&dd[12], 0, 8); + write_uint32_msb_first(&dd[20], key_properties); + write_uint32_msb_first(&dd[24], length_bytes * 8); // expected in bits! + write_uint32_msb_first(&dd[28], counter); + + mbedtls_cipher_type_t mbedtls_cipher_type = MBEDTLS_CIPHER_AES_256_ECB; + const mbedtls_cipher_info_t * cipher_info = mbedtls_cipher_info_from_type(mbedtls_cipher_type); + + PLOG_DEBUG_BUFFER("input_key", input_key, input_key_size); + PLOG_DEBUG_BUFFER("dd", dd, sizeof(dd)); + + uint8_t * pos = output; + do + { + mbedtls_cipher_init(&ctx); + ctx_valid = true; + + ret = mbedtls_cipher_setup(&ctx, cipher_info); + RET_MBEDTLS_SUCCESS_OR_EXIT_MSG("mbedtls_cipher_setup failed: 0x%08x", ret); + + ret = mbedtls_cipher_cmac_starts(&ctx, input_key, input_key_size * 8); + RET_MBEDTLS_SUCCESS_OR_EXIT_MSG("mbedtls_cipher_cmac_starts failed: 0x%08x", ret); + + ret = mbedtls_cipher_cmac_update(&ctx, dd, sizeof(dd)); + RET_MBEDTLS_SUCCESS_OR_EXIT_MSG("mbedtls_cipher_cmac_update failed: 0x%08x", ret); + + ret = mbedtls_cipher_cmac_finish(&ctx, pos); + RET_MBEDTLS_SUCCESS_OR_EXIT_MSG("mbedtls_cipher_cmac_finish failed: 0x%08x", ret); + + mbedtls_cipher_free(&ctx); + ctx_valid = false; + + write_uint32_msb_first(&dd[28], ++counter); + pos += AES_BLOCK_SIZE; + } while (counter * AES_BLOCK_SIZE <= length_bytes); + + PLOG_DEBUG_BUFFER("output", output, length_bytes); + +exit: + if (ctx_valid) + { + mbedtls_cipher_free(&ctx); + ctx_valid = false; + } + + return status; +} + +static status_t host_wrap_key(const uint8_t * data, size_t data_size, const uint8_t * key, size_t key_size, uint8_t * output, + size_t * output_size) +{ + status_t status = STATUS_SUCCESS; + int ret = 0; + mbedtls_nist_kw_context ctx; + mbedtls_nist_kw_init(&ctx); + ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, key_size * 8, true); + RET_MBEDTLS_SUCCESS_OR_EXIT_MSG("mbedtls_nist_kw_setkey failed: 0x%08x", ret); + ret = mbedtls_nist_kw_wrap(&ctx, MBEDTLS_KW_MODE_KW, data, data_size, output, output_size, *output_size); + RET_MBEDTLS_SUCCESS_OR_EXIT_MSG("mbedtls_nist_kw_wrap failed: 0x%08x", ret); + PLOG_DEBUG_BUFFER("wrapped buffer", output, *output_size); +exit: + mbedtls_nist_kw_free(&ctx); + return status; +} + +static status_t create_els_import_keyblob(const uint8_t * plain_key, size_t plain_key_size, mcuxClEls_KeyProp_t plain_key_prop, + const uint8_t * key_wrap_in, size_t key_wrap_in_size, uint8_t * blob, size_t * blob_size) +{ + assert(plain_key_size == 16 || plain_key_size == 32); + assert(key_wrap_in_size == 16); + + uint8_t buffer[ELS_BLOB_METADATA_SIZE + MAX_ELS_KEY_SIZE] = { 0 }; + size_t buffer_size = ELS_BLOB_METADATA_SIZE + plain_key_size; + + // Enforce the wrpok bit - the key needs to be re-wrappable! + plain_key_prop.bits.wrpok = MCUXCLELS_KEYPROPERTY_WRAP_TRUE; + + // This is what ELS documentation says. It does not work though?? + // memset(&buffer[0], 0xA6, 8); + // write_uint32_msb_first(&buffer[8], plain_key_prop.word.value); + // memset(&buffer[12], 0, 4); + // memcpy(&buffer[16], plain_key, plain_key_size); + + write_uint32_msb_first(&buffer[0], plain_key_prop.word.value); + memset(&buffer[4], 0, 4); + memcpy(&buffer[8], plain_key, plain_key_size); + PLOG_DEBUG_BUFFER("plain buffer before wrapping for import", buffer, buffer_size); + + status_t status = host_wrap_key(buffer, buffer_size, key_wrap_in, key_wrap_in_size, blob, blob_size); + return status; +} + +static status_t els_perform_key_agreement(mcuxClEls_KeyIndex_t keypair_index, mcuxClEls_KeyProp_t shared_secret_prop, + mcuxClEls_KeyIndex_t * dst_key_index, const uint8_t * public_key, size_t public_key_size) +{ + uint32_t shared_secret_required_keyslots = get_required_keyslots(shared_secret_prop); + *dst_key_index = els_get_free_keyslot(shared_secret_required_keyslots); + + if (!(*dst_key_index < MCUXCLELS_KEY_SLOTS)) + { + PLOG_ERROR("no free keyslot found"); + return STATUS_ERROR_GENERIC; + } + + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, + mcuxClEls_EccKeyExchange_Async(keypair_index, public_key, *dst_key_index, shared_secret_prop)); + + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_EccKeyExchange_Async) != token) || (MCUXCLELS_STATUS_OK_WAIT != result)) + { + PLOG_ERROR("mcuxClEls_EccKeyExchange_Async failed: 0x%08x", result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); + + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != token) || (MCUXCLELS_STATUS_OK != result)) + { + PLOG_ERROR("mcuxClEls_WaitForOperation failed: 0x%08x", result); + return STATUS_ERROR_GENERIC; + } + MCUX_CSSL_FP_FUNCTION_CALL_END(); + + return STATUS_SUCCESS; +} + +static status_t import_plain_key_into_els(const uint8_t * plain_key, size_t plain_key_size, mcuxClEls_KeyProp_t key_properties, + mcuxClEls_KeyIndex_t * index_output) +{ + status_t status = STATUS_SUCCESS; + mcuxClEls_KeyIndex_t index_plain = MCUXCLELS_KEY_SLOTS; + mcuxClEls_KeyIndex_t index_shared_secret = MCUXCLELS_KEY_SLOTS; + mcuxClEls_KeyIndex_t index_unwrap = MCUXCLELS_KEY_SLOTS; + mcuxClEls_KeyIndex_t * potentially_used_key_indices[] = { &index_plain, &index_shared_secret, &index_unwrap }; + + uint8_t els_key_in_blob[ELS_BLOB_METADATA_SIZE + MAX_ELS_KEY_SIZE + ELS_WRAP_OVERHEAD]; + size_t els_key_in_blob_size = sizeof(els_key_in_blob); + + uint8_t shared_secret[32] = { 0 }; + size_t shared_secret_len = sizeof(shared_secret); + + uint8_t key_wrap_in[32]; + size_t key_wrap_in_size = sizeof(key_wrap_in); + + PLOG_INFO("Generating random ECC keypair..."); + uint8_t public_key[64] = { 0u }; + size_t public_key_size = sizeof(public_key); + status = els_generate_keypair(&index_plain, &public_key[0], &public_key_size); + STATUS_SUCCESS_OR_EXIT_MSG("generate_keypair failed: 0x%08x", status); + + PLOG_INFO("Calculating shared secret on host..."); + status = host_perform_key_agreement(public_key, public_key_size, &shared_secret[0], &shared_secret_len); + STATUS_SUCCESS_OR_EXIT_MSG("perform_key_agreement_host failed: 0x%08x", status); + + PLOG_INFO("Deriving wrapping key for import on host..."); + status = host_derive_key(shared_secret, shared_secret_len, ckdf_derivation_data_wrap_in, sizeof(ckdf_derivation_data_wrap_in), + wrap_in_key_prop.word.value, &key_wrap_in[0], &key_wrap_in_size); + STATUS_SUCCESS_OR_EXIT_MSG("ckdf_host failed: 0x%08x", status); + + PLOG_INFO("Creating ELS keyblob for import..."); + + status = create_els_import_keyblob(plain_key, plain_key_size, key_properties, key_wrap_in, key_wrap_in_size, + &els_key_in_blob[0], &els_key_in_blob_size); + STATUS_SUCCESS_OR_EXIT_MSG("create_els_import_keyblob failed: 0x%08x", status); + + PLOG_INFO("Calculating shared secret on ELS..."); + status = els_perform_key_agreement(index_plain, shared_secret_prop, &index_shared_secret, import_die_int_ecdh_pk, + sizeof(import_die_int_ecdh_pk)); + STATUS_SUCCESS_OR_EXIT_MSG("perform_key_agreement failed: 0x%08x", status); + + status = els_delete_key(index_plain); + STATUS_SUCCESS_OR_EXIT_MSG("delete_key failed: 0x%08x", status); + index_plain = MCUXCLELS_KEY_SLOTS; + + PLOG_INFO("Deriving wrapping key for import on ELS..."); + status = els_derive_key(index_shared_secret, wrap_in_key_prop, ckdf_derivation_data_wrap_in, &index_unwrap); + STATUS_SUCCESS_OR_EXIT_MSG("derive_key failed: 0x%08x", status); + + status = els_delete_key(index_shared_secret); + STATUS_SUCCESS_OR_EXIT_MSG("delete_key failed: 0x%08x", status); + index_shared_secret = MCUXCLELS_KEY_SLOTS; + + PLOG_INFO("Importing wrapped key..."); + status = els_import_key(els_key_in_blob, els_key_in_blob_size, key_properties, index_unwrap, index_output); + STATUS_SUCCESS_OR_EXIT_MSG("import_wrapped_key failed: 0x%08x", status); + + status = els_delete_key(index_unwrap); + STATUS_SUCCESS_OR_EXIT_MSG("delete_key failed: 0x%08x", status); + index_unwrap = MCUXCLELS_KEY_SLOTS; + +exit: + for (size_t i = 0; i < ARRAY_SIZE(potentially_used_key_indices); i++) + { + mcuxClEls_KeyIndex_t key_index = *(potentially_used_key_indices[i]); + if (key_index < MCUXCLELS_KEY_SLOTS) + { + (void) els_delete_key(key_index); + } + } + return status; +} + +CHIP_ERROR FactoryDataProviderImpl::ELS_ExportBlob(uint8_t * data, size_t * dataLen, uint32_t & addr) +{ + uint8_t keyBuf[Crypto::kP256_PrivateKey_Length]; + MutableByteSpan dacPrivateKeySpan(keyBuf); + uint16_t keySize = 0; + + status_t status = STATUS_SUCCESS; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&attributes, 256); + psa_set_key_lifetime( + &attributes, + PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_LIFETIME_PERSISTENT, PSA_KEY_LOCATION_S50_BLOB_STORAGE)); + psa_set_key_id(&attributes, 0x3E000021); + + /* Search key ID FactoryDataId::kDacPrivateKeyId */ + ReturnErrorOnFailure( + SearchForId(FactoryDataId::kDacPrivateKeyId, dacPrivateKeySpan.data(), dacPrivateKeySpan.size(), keySize, &addr)); + dacPrivateKeySpan.reduce_size(keySize); + PLOG_DEBUG_BUFFER("Private DAC key plain", dacPrivateKeySpan.data(), dacPrivateKeySpan.size()); + + mcuxClEls_KeyProp_t plain_key_properties = { + .word = { .value = MCUXCLELS_KEYPROPERTY_VALUE_SECURE | MCUXCLELS_KEYPROPERTY_VALUE_PRIVILEGED | + MCUXCLELS_KEYPROPERTY_VALUE_KEY_SIZE_256 | MCUXCLELS_KEYPROPERTY_VALUE_KGSRC } + }; + + mcuxClEls_KeyIndex_t key_index = MCUXCLELS_KEY_SLOTS; + /* Import plain DAC key into S50 */ + status = import_plain_key_into_els(dacPrivateKeySpan.data(), dacPrivateKeySpan.size(), plain_key_properties, &key_index); + STATUS_SUCCESS_OR_EXIT_MSG("derive_key failed: 0x%08x", status); + + /* ELS generate key blob. The blob created here is one that can be directly imported into ELS again. */ + status = export_key_from_els(key_index, data, dataLen); + STATUS_SUCCESS_OR_EXIT_MSG("export_key_from_els failed: 0x%08x", status); + + status = els_delete_key(key_index); + STATUS_SUCCESS_OR_EXIT_MSG("delete_key failed: 0x%08x", status); +exit: + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProviderImpl::ReplaceWithBlob(uint8_t * data, uint8_t * blob, size_t blobLen, uint32_t KeyAddr) +{ + size_t newSize = mHeader.size + ELS_BLOB_METADATA_SIZE + ELS_WRAP_OVERHEAD; + FactoryDataProviderImpl::Header * header = reinterpret_cast(data); + uint8_t * payload = data + sizeof(FactoryDataProviderImpl::Header); + uint8_t offset = (uint8_t *) (KeyAddr - kValueOffset) - (uint8_t *) &factoryDataRamBuffer[0]; + size_t subsequentDataOffset = offset + kValueOffset + Crypto::kP256_PrivateKey_Length; + + memmove(payload + subsequentDataOffset + ELS_BLOB_METADATA_SIZE + ELS_WRAP_OVERHEAD, payload + subsequentDataOffset, + mHeader.size - subsequentDataOffset); + header->size = newSize; + /* Update associated TLV length */ + memcpy(payload + offset + kLengthOffset, (uint16_t *) &blobLen, sizeof(uint16_t)); + /* Replace private plain DAC key by the blob */ + memcpy(payload + offset + kValueOffset, blob, blobLen); + + /* Update Header with new hash value */ + 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 + +CHIP_ERROR FactoryDataProviderImpl::unittest(void) +{ +#if FACTORY_DATA_PROVIDER_RUN_TESTS + CHIP_ERROR res; + + uint8_t ecc_message[295] = { + 0x15, 0x30, 0x01, 0xec, 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, 0x26, 0xa2, 0x18, 0x25, 0x03, 0x01, 0x03, 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, 0xc3, 0xbf, 0xd1, 0xcb, 0xed, 0x21, + 0x1e, 0x54, 0x76, 0x81, 0xa6, 0xfa, 0x08, 0x8f, 0x26, 0xce, 0x14, 0x8c, 0x72, 0xae, 0x1b, 0x6f, 0x61, 0x18, 0x0f, 0x6f, + 0x01, 0xc2, 0x75, 0xad, 0x6e, 0x5e, 0x02, 0x20, 0x31, 0x11, 0x00, 0x88, 0xcc, 0xc9, 0x98, 0x55, 0x0e, 0xf1, 0xd2, 0x42, + 0x07, 0x7a, 0xaa, 0x41, 0x0c, 0xd2, 0xd3, 0xd4, 0x76, 0xab, 0xd5, 0xaf, 0x32, 0x2c, 0x45, 0x75, 0xfa, 0xcc, 0x51, 0x5b, + 0x30, 0x02, 0x20, 0x73, 0x09, 0xbb, 0x01, 0xa5, 0xae, 0x2f, 0xfc, 0x0b, 0x7f, 0xee, 0xcb, 0xa0, 0xc4, 0x94, 0xf1, 0xd3, + 0x61, 0xce, 0x4a, 0x83, 0x21, 0x5e, 0x84, 0x07, 0xcf, 0x42, 0xc5, 0xee, 0xea, 0x1a, 0x2e, 0x24, 0x03, 0x00, 0x18, 0x90, + 0x75, 0x48, 0x87, 0x85, 0x5f, 0x73, 0xb0, 0xcb, 0x3e, 0x38, 0xa7, 0xbd, 0xad, 0x22, 0xf4 + }; + + const uint8_t kDevelopmentDAC_Cert_FFF1_8002[492] = { + 0x30, 0x82, 0x01, 0xe8, 0x30, 0x82, 0x01, 0x8e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x52, 0x72, 0x4d, 0x21, 0xe2, + 0xc1, 0x74, 0xaf, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x3d, 0x31, 0x25, 0x30, + 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1c, 0x4d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x44, 0x65, 0x76, 0x20, 0x50, + 0x41, 0x49, 0x20, 0x30, 0x78, 0x46, 0x46, 0x46, 0x31, 0x20, 0x6e, 0x6f, 0x20, 0x50, 0x49, 0x44, 0x31, 0x14, 0x30, 0x12, + 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, 0x02, 0x01, 0x0c, 0x04, 0x46, 0x46, 0x46, 0x31, 0x30, 0x20, + 0x17, 0x0d, 0x32, 0x32, 0x30, 0x32, 0x30, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x39, 0x39, 0x39, + 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x53, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x1c, 0x4d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x44, 0x65, 0x76, 0x20, 0x44, 0x41, 0x43, 0x20, + 0x30, 0x78, 0x46, 0x46, 0x46, 0x31, 0x2f, 0x30, 0x78, 0x38, 0x30, 0x30, 0x32, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, + 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, 0x02, 0x01, 0x0c, 0x04, 0x46, 0x46, 0x46, 0x31, 0x31, 0x14, 0x30, 0x12, 0x06, + 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, 0x02, 0x02, 0x0c, 0x04, 0x38, 0x30, 0x30, 0x32, 0x30, 0x59, 0x30, + 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, + 0x03, 0x42, 0x00, 0x04, 0xda, 0x93, 0xf1, 0x67, 0x36, 0x25, 0x67, 0x50, 0xd9, 0x03, 0xb0, 0x34, 0xba, 0x45, 0x88, 0xab, + 0xaf, 0x58, 0x95, 0x4f, 0x77, 0xaa, 0x9f, 0xd9, 0x98, 0x9d, 0xfd, 0x40, 0x0d, 0x7a, 0xb3, 0xfd, 0xc9, 0x75, 0x3b, 0x3b, + 0x92, 0x1b, 0x29, 0x4c, 0x95, 0x0f, 0xd9, 0xd2, 0x80, 0xd1, 0x4c, 0x43, 0x86, 0x2f, 0x16, 0xdc, 0x85, 0x4b, 0x00, 0xed, + 0x39, 0xe7, 0x50, 0xba, 0xbf, 0x1d, 0xc4, 0xca, 0xa3, 0x60, 0x30, 0x5e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, + 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, + 0x07, 0x80, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xef, 0x06, 0x56, 0x11, 0x9c, 0x1c, 0x91, + 0xa7, 0x9a, 0x94, 0xe6, 0xdc, 0xf3, 0x79, 0x79, 0xdb, 0xd0, 0x7f, 0xf8, 0xa3, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, + 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x63, 0x54, 0x0e, 0x47, 0xf6, 0x4b, 0x1c, 0x38, 0xd1, 0x38, 0x84, 0xa4, 0x62, 0xd1, + 0x6c, 0x19, 0x5d, 0x8f, 0xfb, 0x3c, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, + 0x00, 0x30, 0x45, 0x02, 0x20, 0x46, 0x86, 0x81, 0x07, 0x33, 0xbf, 0x0d, 0xc8, 0xff, 0x4c, 0xb5, 0x14, 0x5a, 0x6b, 0xfa, + 0x1a, 0xec, 0xff, 0xa8, 0xb6, 0xda, 0xb6, 0xc3, 0x51, 0xaa, 0xee, 0xcd, 0xaf, 0xb8, 0xbe, 0x95, 0x7d, 0x02, 0x21, 0x00, + 0xe8, 0xc2, 0x8d, 0x6b, 0xfc, 0xc8, 0x7a, 0x7d, 0x54, 0x2e, 0xad, 0x6e, 0xda, 0xca, 0x14, 0x8d, 0x5f, 0xa5, 0x06, 0x1e, + 0x51, 0x7c, 0xbe, 0x4f, 0x24, 0xa7, 0x20, 0xe1, 0xc0, 0x59, 0xde, 0x1a, + }; + const uint8_t kDevelopmentDAC_PublicKey_FFF1_8002[65] = { + 0x04, 0xda, 0x93, 0xf1, 0x67, 0x36, 0x25, 0x67, 0x50, 0xd9, 0x03, 0xb0, 0x34, 0xba, 0x45, 0x88, 0xab, + 0xaf, 0x58, 0x95, 0x4f, 0x77, 0xaa, 0x9f, 0xd9, 0x98, 0x9d, 0xfd, 0x40, 0x0d, 0x7a, 0xb3, 0xfd, 0xc9, + 0x75, 0x3b, 0x3b, 0x92, 0x1b, 0x29, 0x4c, 0x95, 0x0f, 0xd9, 0xd2, 0x80, 0xd1, 0x4c, 0x43, 0x86, 0x2f, + 0x16, 0xdc, 0x85, 0x4b, 0x00, 0xed, 0x39, 0xe7, 0x50, 0xba, 0xbf, 0x1d, 0xc4, 0xca, + }; + + /* Sign using the example attestation private key */ + P256ECDSASignature da_signature; + MutableByteSpan out_sig_span(da_signature.Bytes(), da_signature.Capacity()); + CHIP_ERROR err = SignWithDacKey(ByteSpan{ ecc_message, sizeof(ecc_message) }, out_sig_span); + assert(err == CHIP_NO_ERROR); + + assert(out_sig_span.size() == kP256_ECDSA_Signature_Length_Raw); + da_signature.SetLength(out_sig_span.size()); + + /* Get DAC from the provider */ + uint8_t dac_cert_buf[kMaxDERCertLength]; + MutableByteSpan dac_cert_span(dac_cert_buf); + + memcpy(dac_cert_span.data(), kDevelopmentDAC_Cert_FFF1_8002, 492); + + /* Extract public key from DAC, prior to signature verification */ + P256PublicKey dac_public_key; + err = ExtractPubkeyFromX509Cert(dac_cert_span, dac_public_key); + assert(err == CHIP_NO_ERROR); + assert(dac_public_key.Length() == 65); + assert(0 == memcmp(dac_public_key.ConstBytes(), kDevelopmentDAC_PublicKey_FFF1_8002, 65)); + + /* Verify round trip signature */ + err = dac_public_key.ECDSA_validate_msg_signature(&ecc_message[0], sizeof(ecc_message), da_signature); + assert(err == CHIP_NO_ERROR); + PRINTF("ECDSA signature validated with SUCCESS \n"); +#endif + return CHIP_NO_ERROR; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.h b/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.h new file mode 100644 index 00000000000000..43a759fa8ee15c --- /dev/null +++ b/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.h @@ -0,0 +1,79 @@ +/* + * + * Copyright (c) 2020-2022 Project CHIP Authors + * Copyright 2023 NXP + * + * 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 + +#define FACTORY_DATA_MAX_SIZE 4096 + +namespace chip { +namespace DeviceLayer { + +/** + * @brief This class provides Commissionable data and Device Attestation Credentials. + * + * This implementation allows to use the ELS hardware module to load the Matter factory + * dataset in RAM at the boot. + * + * + */ + +class FactoryDataProviderImpl : public FactoryDataProvider +{ +public: + static FactoryDataProviderImpl sInstance; + + CHIP_ERROR Init(void); + CHIP_ERROR SearchForId(uint8_t searchedType, uint8_t * pBuf, size_t bufLength, uint16_t & length, + uint32_t * contentAddr = NULL); + CHIP_ERROR SignWithDacKey(const ByteSpan & digestToSign, MutableByteSpan & outSignBuffer); + +private: + struct Header + { + uint32_t hashId; + uint32_t size; + uint8_t hash[4]; + }; + uint8_t factoryDataRamBuffer[FACTORY_DATA_MAX_SIZE]; + Header mHeader; + + /* TLV offset */ + static constexpr uint32_t kLengthOffset = 1; + static constexpr uint32_t kValueOffset = 3; + CHIP_ERROR Hash256(const uint8_t * input, size_t inputSize, uint8_t * output); + CHIP_ERROR unittest(void); + + CHIP_ERROR ReplaceWithBlob(uint8_t * data, uint8_t * blob, size_t blobLen, uint32_t offset); + CHIP_ERROR ELS_ExportBlob(uint8_t * data, size_t * dataLen, uint32_t & offset); + CHIP_ERROR ELS_ConvertDacKey(); +}; + +inline FactoryDataProvider & FactoryDataPrvd() +{ + return FactoryDataProviderImpl::sInstance; +} + +inline FactoryDataProviderImpl & FactoryDataPrvdImpl() +{ + return FactoryDataProviderImpl::sInstance; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/rt/rw61x/args.gni b/src/platform/nxp/rt/rw61x/args.gni index 9e7cf8a37d0292..0c2d183aca8646 100644 --- a/src/platform/nxp/rt/rw61x/args.gni +++ b/src/platform/nxp/rt/rw61x/args.gni @@ -42,6 +42,12 @@ declare_args() { # if rw610_mbedtls_port_els_pkc is set to false software mbedtls is used instead rw610_mbedtls_port_els_pkc = true + + # Enable DAC private key secure usage, chip_with_factory_data must be set to 1 + chip_enable_secure_dac_private_key_storage = 0 + + # Generate DAC private key blob for factory data, chip_enable_secure_dac_private_key_storage must be set to 1 + chip_convert_dac_private_key = 0 } # TODO : Enable the OTA Requestor by default. @@ -54,11 +60,6 @@ declare_args() { no_mcuboot = true } -# As a temporary workaround, we are disabling the session resumption because currently -# the mbedtls port does not support this. -# If not disabled, reconnecting to the OTA Provider node will fail. -chip_enable_session_resumption = false - mbedtls_target = "${nxp_sdk_build_root}:nxp_mbedtls" openthread_external_mbedtls = mbedtls_target diff --git a/src/system/BUILD.gn b/src/system/BUILD.gn index 9f24ad171be72a..afeab8d343f9df 100644 --- a/src/system/BUILD.gn +++ b/src/system/BUILD.gn @@ -58,8 +58,6 @@ if (chip_device_platform == "cc13x2_26x2") { } else if (chip_device_platform == "qpg") { import("//build_overrides/qpg_sdk.gni") 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 == "nxp") { import("//build_overrides/nxp_sdk.gni") } else if (chip_device_platform == "psoc6") { @@ -184,9 +182,6 @@ source_set("system_config_header") { if (chip_device_platform == "qpg") { public_deps += [ "${qpg_sdk_build_root}:qpg_sdk" ] } - if (chip_device_platform == "k32w0") { - public_deps += [ "${k32w0_sdk_build_root}:k32w0_sdk" ] - } if (chip_device_platform == "nxp") { public_deps += [ "${nxp_sdk_build_root}:nxp_sdk" ] } diff --git a/src/transport/tests/BUILD.gn b/src/transport/tests/BUILD.gn index 18987c6c8c38e9..8e3f9365d023c8 100644 --- a/src/transport/tests/BUILD.gn +++ b/src/transport/tests/BUILD.gn @@ -45,7 +45,8 @@ chip_test_suite_using_nltest("tests") { ] if (chip_device_platform != "mbed" && chip_device_platform != "efr32" && - chip_device_platform != "esp32" && chip_device_platform != "nrfconnect") { + chip_device_platform != "esp32" && chip_device_platform != "nrfconnect" && + chip_device_platform != "nxp") { test_sources += [ "TestSecureSessionTable.cpp" ] } diff --git a/third_party/nxp/k32w0_sdk/BUILD.gn b/third_party/nxp/k32w0_sdk/BUILD.gn index efc1d786420239..6052497bd43145 100644 --- a/third_party/nxp/k32w0_sdk/BUILD.gn +++ b/third_party/nxp/k32w0_sdk/BUILD.gn @@ -13,11 +13,14 @@ # limitations under the License. import("//build_overrides/chip.gni") -import("//build_overrides/k32w0_sdk.gni") +import("//build_overrides/chip.gni") import("//build_overrides/mbedtls.gni") +import("//build_overrides/nxp_sdk.gni") -import("${k32w0_sdk_build_root}/k32w0_sdk.gni") import("${mbedtls_root}/mbedtls.gni") +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") declare_args() { # Build target to use for k32w0 SDK. Use this to set global SDK defines. @@ -26,7 +29,7 @@ declare_args() { assert(k32w0_sdk_target != "", "k32w0_sdk_target must be specified") -group("k32w0_sdk") { +group("nxp_sdk") { public_deps = [ k32w0_sdk_target ] } @@ -95,7 +98,7 @@ mbedtls_target("mbedtls") { public_configs = [ ":mbedtls_k32w0_config" ] public_deps = [ - ":k32w0_sdk", + ":nxp_sdk", "${chip_root}/third_party/openthread/platforms/nxp/k32w/k32w0:openthread_mbedtls_config_k32w0", ] } diff --git a/third_party/nxp/k32w0_sdk/k32w0_sdk.gni b/third_party/nxp/k32w0_sdk/k32w0_sdk.gni index 754ac91df80875..509a4584316a9f 100644 --- a/third_party/nxp/k32w0_sdk/k32w0_sdk.gni +++ b/third_party/nxp/k32w0_sdk/k32w0_sdk.gni @@ -14,14 +14,15 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") -import("//build_overrides/k32w0_sdk.gni") import("//build_overrides/mbedtls.gni") +import("//build_overrides/nxp_sdk.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/nxp/k32w/k32w0/args.gni") +import("${chip_root}/src/platform/device.gni") +import("${chip_root}/src/platform/nxp/${nxp_platform}/args.gni") declare_args() { # Location of the k32w0 SDK. @@ -38,7 +39,6 @@ declare_args() { board = "k32w061dk6" chip_with_ntag = 1 chip_with_high_power = 0 - chip_with_factory_data = 0 use_fro_32k = 0 use_custom_factory_provider = 0 chip_crypto_flavor = "NXP-Ultrafast-P256" @@ -52,15 +52,6 @@ declare_args() { chip_with_ota_encryption = 0 chip_with_ota_key = "1234567890ABCDEFA1B2C3D4E5F6F1B4" chip_with_sdk_package = 1 - - # ICD Matter Configuration flags - nxp_ot_idle_interval_ms = 2000 # 2s Idle Intervals - nxp_ot_active_interval_ms = 500 # 500ms Active Intervals - - nxp_idle_mode_duration_s = 600 # 10min Idle Mode Interval - nxp_active_mode_duration_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 } assert(k32w0_sdk_root != "", "k32w0_sdk_root must be specified") @@ -108,6 +99,16 @@ template("k32w0_sdk") { chip_with_factory_data == 1, "Please set chip_with_factory_data=1 if using default factory data processor.") + assert( + chip_enable_ota_factory_data_processor == 0 || + chip_enable_ota_firmware_processor == 1, + "Please set chip_enable_ota_firmware_processor=1 if using default factory data processor.") + + assert( + chip_enable_ota_factory_data_processor == 0 || + chip_with_factory_data == 1, + "Please set chip_with_factory_data=1 if using default factory data processor.") + if (build_for_k32w041am == 1 || build_for_k32w041a == 1 || build_for_k32w041 == 1) { build_for_k32w061 = 0 @@ -162,6 +163,7 @@ template("k32w0_sdk") { print("OTA default factory data processor: ", chip_enable_ota_factory_data_processor) print("PDM Encryption: ", chip_with_pdm_encryption) + print("Antenna Diversity enabled: ", use_antenna_diversity) if (chip_with_low_power == 1 && chip_logging == true) { print( @@ -375,6 +377,11 @@ template("k32w0_sdk") { "NXP_ICD_SUPPORTED_CLIENTS_PER_FABRIC=${nxp_icd_supported_clients_per_fabric}", ] + if (use_antenna_diversity == 1) { + print("Check ADO/ADE pin configuration when using Antenna Diversity.") + defines += [ "ANTENNA_DIVERSITY_ENABLE" ] + } + # If OTA default processors are enabled, then OTA custom entry structure # will be saved in external flash: gOTACustomOtaEntryMemory=OTACustomStorage_ExtFlash (1) if (chip_enable_ota_firmware_processor == 1) { @@ -413,6 +420,12 @@ template("k32w0_sdk") { defines += [ "PDM_ENCRYPTION=0" ] } + if (chip_with_pdm_encryption == 1) { + defines += [ "PDM_ENCRYPTION=1" ] + } else { + defines += [ "PDM_ENCRYPTION=0" ] + } + if (chip_with_ota_encryption == 1) { defines += [ "OTA_ENCRYPTION_ENABLE=1", diff --git a/third_party/nxp/k32w0_sdk/nxp_arm.gni b/third_party/nxp/k32w0_sdk/nxp_arm.gni new file mode 100644 index 00000000000000..5afd55a8b3129f --- /dev/null +++ b/third_party/nxp/k32w0_sdk/nxp_arm.gni @@ -0,0 +1,22 @@ +# 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/k32w0", "${nxp_platform} must be k32w/k32w0.") + +arm_float_abi = "soft" +arm_cpu = "cortex-m4" +arm_arch = "armv7e-m" diff --git a/third_party/nxp/k32w0_sdk/k32w0_executable.gni b/third_party/nxp/k32w0_sdk/nxp_executable.gni similarity index 100% rename from third_party/nxp/k32w0_sdk/k32w0_executable.gni rename to third_party/nxp/k32w0_sdk/nxp_executable.gni diff --git a/third_party/nxp/k32w1_sdk/k32w1_sdk.gni b/third_party/nxp/k32w1_sdk/k32w1_sdk.gni index d6d9f6146086d7..5a9e37991e149c 100644 --- a/third_party/nxp/k32w1_sdk/k32w1_sdk.gni +++ b/third_party/nxp/k32w1_sdk/k32w1_sdk.gni @@ -36,6 +36,7 @@ declare_args() { use_smu2_dynamic = false use_hw_sha256 = false use_hw_aes = false + chip_config_dimmable_led = false } openthread_nxp_root = "${chip_root}/third_party/openthread/ot-nxp" @@ -157,6 +158,10 @@ template("k32w1_sdk") { "${chip_root}/src/platform/nxp/k32w/k32w1", ] + if (chip_config_dimmable_led) { + _sdk_include_dirs += [ "${k32w1_sdk_root}/components/pwm" ] + } + if (sdk_release == 1) { _sdk_include_dirs += [ "${k32w1_sdk_root}/middleware/wireless/bluetooth/application/common/matter", @@ -419,6 +424,10 @@ template("k32w1_sdk") { "${k32w1_sdk_root}/middleware/wireless/bluetooth/application/common/matter/ble_init.c", ] + if (chip_config_dimmable_led) { + sources += [ "${k32w1_sdk_root}/devices/K32W1480/drivers/fsl_tpm.c" ] + } + if (chip_enable_pw_rpc) { sources += [ "${k32w1_sdk_root}/devices/K32W1480/drivers/fsl_edma.c", @@ -547,6 +556,10 @@ template("k32w1_sdk") { "${k32w1_sdk_root}/rtos/freertos/freertos_kernel/timers.c", ] + if (chip_config_dimmable_led) { + sources += [ "${k32w1_sdk_root}/components/pwm/fsl_adapter_pwm_tpm.c" ] + } + if (chip_with_low_power == 1) { sources += [] } diff --git a/third_party/nxp/rt_sdk/BUILD.gn b/third_party/nxp/rt_sdk/BUILD.gn index 90640e8b1eb2ed..0fd636441543b1 100644 --- a/third_party/nxp/rt_sdk/BUILD.gn +++ b/third_party/nxp/rt_sdk/BUILD.gn @@ -25,18 +25,16 @@ import( "${nxp_sdk_build_root}/${nxp_sdk_name}/${rt_platform}/${rt_platform}.gni") import("${nxp_sdk_build_root}/${nxp_sdk_name}/bt_ble/bt_ble.gni") import("${nxp_sdk_build_root}/${nxp_sdk_name}/lwip/lwip.gni") -import("${nxp_sdk_build_root}/${nxp_sdk_name}/mbedtls/mbedtls.gni") import("//build_overrides/openthread.gni") import("${chip_root}/src/platform/device.gni") import("${chip_root}/src/platform/nxp/${nxp_platform}/args.gni") -mbedtls_root = "${rt_sdk_root}/middleware/mbedtls" - group("nxp_sdk") { public_deps = [ ":nxp_transceiver", + "${nxp_sdk_build_root}/${nxp_sdk_name}/${rt_platform}:nxp_sdk", nxp_sdk_driver_target, nxp_sdk_target, ] @@ -53,76 +51,6 @@ group("nxp_sdk") { } } -config("mbedtls_ksdk_config") { - include_dirs = [ "${mbedtls_root}/port/ksdk" ] - defines = [ "MBEDTLS_PORT_INCLUDE=" ] - if (chip_enable_openthread) { - defines += [ "MBEDTLS_CONFIG_FILE=" ] - } else { - defines += [ "MBEDTLS_CONFIG_FILE=" ] - include_dirs += [ "${nxp_sdk_build_root}/${nxp_sdk_name}/mbedtls/config" ] - } -} - -config("mbedtls_els_pkc_config") { - include_dirs = [ - "${mbedtls_root}/port/els", - "${mbedtls_root}/port/pkc", - ] - defines = [ "MBEDTLS_PORT_INCLUDE=" ] - - if (chip_enable_openthread) { - defines += [ "MBEDTLS_CONFIG_FILE=" ] - } else { - defines += [ "MBEDTLS_CONFIG_FILE=" ] - } -} - -mbedtls_target("nxp_els_pkc_mbedtls") { - sources = [] - public_deps = [ ":nxp_sdk" ] - public_configs = [ ":mbedtls_els_pkc_config" ] - sources += [ - # els port - "${mbedtls_root}/port/els/aes_alt.c", - "${mbedtls_root}/port/els/cbc_mac_alt.c", - "${mbedtls_root}/port/els/cmac_alt.c", - "${mbedtls_root}/port/els/ctr_drbg_alt.c", - "${mbedtls_root}/port/els/els_mbedtls.c", - "${mbedtls_root}/port/els/entropy_poll_alt.c", - "${mbedtls_root}/port/els/gcm_alt.c", - "${mbedtls_root}/port/els/sha256_alt.c", - "${mbedtls_root}/port/els/sha512_alt.c", - - # pkc port - "${mbedtls_root}/port/pkc/ecc_alt.c", - "${mbedtls_root}/port/pkc/ecdh_alt.c", - "${mbedtls_root}/port/pkc/ecdsa_alt.c", - "${mbedtls_root}/port/pkc/els_pkc_mbedtls.c", - "${mbedtls_root}/port/pkc/rsa_alt.c", - ] -} - -mbedtls_target("nxp_ksdk_mbedtls") { - sources = [] - public_deps = [ ":nxp_sdk" ] - public_configs = [ ":mbedtls_ksdk_config" ] - sources += [ - "${mbedtls_root}/port/ksdk/aes_alt.c", - "${mbedtls_root}/port/ksdk/des_alt.c", - "${mbedtls_root}/port/ksdk/ecp_alt.c", - "${mbedtls_root}/port/ksdk/ecp_alt_ksdk.c", - "${mbedtls_root}/port/ksdk/ecp_curves_alt.c", - "${mbedtls_root}/port/ksdk/ksdk_mbedtls.c", - ] - - # Allow a platform to use a software implementation of ksdk_mbedtls.c if provided - if (defined(ksdk_mbedtls_sw_impl)) { - sources -= [ "${mbedtls_root}/port/ksdk/ksdk_mbedtls.c" ] - sources += [ "${ksdk_mbedtls_sw_impl}" ] - } -} - group("nxp_mbedtls") { public_deps = [ "${nxp_sdk_build_root}/${nxp_sdk_name}/${rt_platform}:nxp_mbedtls" ] @@ -141,7 +69,10 @@ config("lwip_rt_config") { } else if (chip_enable_openthread) { include_dirs += [ "lwip/openthread" ] } else if (chip_enable_wifi) { - include_dirs += [ "lwip/wifi" ] + include_dirs += [ + "lwip/wifi", + "${rt_sdk_root}/middleware/wifi_nxp/port/lwip", + ] } } @@ -157,6 +88,14 @@ lwip_target("nxp_lwip") { "${rt_sdk_root}/middleware/lwip/port/enet_ethernetif_kinetis.c", ] } + + if (chip_enable_wifi) { + sources += [ + "${rt_sdk_root}/middleware/wifi_nxp/port/lwip/net.c", + "${rt_sdk_root}/middleware/wifi_nxp/port/lwip/wifi_netif.c", + ] + } + public_configs = [ ":lwip_rt_config" ] public_deps = [ ":nxp_sdk" ] diff --git a/third_party/nxp/rt_sdk/bt_ble/bt_ble.gni b/third_party/nxp/rt_sdk/bt_ble/bt_ble.gni index e039a6072d38f5..83d2495ed9808d 100644 --- a/third_party/nxp/rt_sdk/bt_ble/bt_ble.gni +++ b/third_party/nxp/rt_sdk/bt_ble/bt_ble.gni @@ -48,8 +48,8 @@ template("bt_ble_target") { #edgefast_bluetooth "${rt_sdk_root}/middleware/edgefast_bluetooth/include", "${rt_sdk_root}/middleware/edgefast_bluetooth/source/porting", + "${rt_sdk_root}/middleware/edgefast_bluetooth/source/impl/ethermind/host", "${rt_sdk_root}/middleware/edgefast_bluetooth/source/impl/ethermind/platform", - "${rt_sdk_root}/middleware/edgefast_bluetooth/source/impl/ethermind/platform/configs", #ethermind "${rt_sdk_root}/middleware/wireless/ethermind/bluetooth/export/include", @@ -108,6 +108,15 @@ template("bt_ble_target") { [ "${rt_sdk_root}/middleware/wireless/ethermind/port/pal/mcux" ] } + if (is_sdk_2_15) { + bt_ble_include_dirs += [ + #sdk hook for fatfs config file required for ethermind include files + "${nxp_sdk_build_root}/${nxp_sdk_name}/sdk_hook/fatfs/config", + ] + } else { + bt_ble_include_dirs += [ "${rt_sdk_root}/middleware/edgefast_bluetooth/source/impl/ethermind/platform/configs" ] + } + defines += [ #BT config, "CONFIG_BT_PERIPHERAL=1", @@ -215,9 +224,8 @@ template("bt_ble_target") { deps = [] } - # Adding a dependency to platform_buildconfig to make sure that the file platform_buildconfig.h is generated first - # In fact depending on the build order, issue could happen if the file platform_buildconfig.h is not generated before building rand32.cpp - deps += [ "${chip_root}/src/platform:platform_buildconfig" ] + defines = + [ "vApplicationMallocFailedHook=vApplicationMallocFailedHookBTBLE" ] if (!defined(public_configs)) { public_configs = [] diff --git a/third_party/nxp/rt_sdk/lwip/common/lwipopts_common.h b/third_party/nxp/rt_sdk/lwip/common/lwipopts_common.h index 0cd0675469cc49..14b8fad5823d85 100644 --- a/third_party/nxp/rt_sdk/lwip/common/lwipopts_common.h +++ b/third_party/nxp/rt_sdk/lwip/common/lwipopts_common.h @@ -409,9 +409,11 @@ Some MCU allow computing and verifying the IP, UDP, TCP and ICMP checksums by ha #define TCP_QUEUE_OOSEQ 0 #define ARP_QUEUEING (0) -// TODO: seems like this is unnecessary on Thread-only platforms +// For Thread-only platforms this is unnecessary but Border router config needs to redefine to larger value #define LWIP_RAW 1 +#ifndef MEMP_NUM_RAW_PCB #define MEMP_NUM_RAW_PCB (1) +#endif // TODO: verify count @@ -469,11 +471,17 @@ Some MCU allow computing and verifying the IP, UDP, TCP and ICMP checksums by ha #define PBUF_LINK_HLEN (14) #if LWIP_IPV6 +#ifndef LWIP_IPV6_NUM_ADDRESSES #define LWIP_IPV6_NUM_ADDRESSES 5 +#endif #define LWIP_IPV6_MLD 1 #define LWIP_ND6_QUEUEING 0 + +#ifndef LWIP_IPV6_SCOPES #define LWIP_IPV6_SCOPES 0 +#endif + #endif /* LWIP_IPV6 */ #define LWIP_MULTICAST_PING 0 diff --git a/third_party/nxp/rt_sdk/lwip/ethernet/lwipopts.h b/third_party/nxp/rt_sdk/lwip/ethernet/lwipopts.h new file mode 100644 index 00000000000000..7e59f4c48df3ee --- /dev/null +++ b/third_party/nxp/rt_sdk/lwip/ethernet/lwipopts.h @@ -0,0 +1,39 @@ +/* + * + * Copyright (c) 2020 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Compile-time configuration for LwIP + */ + +#ifndef __LWIPOPTS_H__ +#define __LWIPOPTS_H__ + +#define LWIP_DISABLE_PBUF_POOL_SIZE_SANITY_CHECKS 1 +#define PBUF_POOL_SIZE 15 +#define TCP_MSS (1500 - 40) /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */ +#define TCP_WND (8 * TCP_MSS) /* ENET_RXBD_NUM minus spare buffer */ +#define ENET_RXBUFF_NUM 14 +#define ENET_RXBD_NUM 9 + +#define LWIP_ETHERNET 1 +#define LWIP_IPV4 0 + +#include "lwipopts_common.h" + +#endif /* __LWIPOPTS_H__ */ diff --git a/third_party/nxp/rt_sdk/lwip/wifi_openthread/lwipopts.h b/third_party/nxp/rt_sdk/lwip/wifi_openthread/lwipopts.h index 92439d19d3e2ed..f45675af6f7166 100644 --- a/third_party/nxp/rt_sdk/lwip/wifi_openthread/lwipopts.h +++ b/third_party/nxp/rt_sdk/lwip/wifi_openthread/lwipopts.h @@ -28,6 +28,31 @@ #define MEMP_NUM_NETCONN (4) #define NETIF_MAX_HWADDR_LEN 8U +// BR specific defines +#define LWIP_IPV6_SCOPES 1 +#define MAX_SOCKETS_UDP 10 +#define MEMP_NUM_UDP_PCB (MAX_SOCKETS_UDP + 2) +#define LWIP_IPV6_NUM_ADDRESSES 8 +#define LWIP_IPV6_FORWARD 1 +#define MEMP_NUM_RAW_PCB (2) +// Note: According to Thread Conformance v1.2.0, a Thread Border Router MUST be able to hold a Multicast Listeners Table +// in memory with at least seventy five (75) entries. +#define MEMP_NUM_MLD6_GROUP 10 + 75 + +// DHCPv6 Prefix Delegation +#define LWIP_IPV6_DHCP6 1 +#define LWIP_IPV6_DHCP6_STATEFUL 1 +#define LWIP_IPV6_DHCP6_PD 1 + +// Header file with lwIP hooks +#define LWIP_HOOK_FILENAME "lwip_hooks.h" + +// Hook for multicast forwarding and other filtering +#define LWIP_HOOK_IP6_CANFORWARD lwipCanForwardHook + +// Hook for filtering of input traffic +#define LWIP_HOOK_IP6_INPUT lwipInputHook + #include "lwipopts_common.h" #endif /* __LWIPOPTS_H__ */ diff --git a/third_party/nxp/rt_sdk/mbedtls/mbedtls.gni b/third_party/nxp/rt_sdk/mbedtls/mbedtls.gni index d5595ab2683f2b..04f628686d29a9 100644 --- a/third_party/nxp/rt_sdk/mbedtls/mbedtls.gni +++ b/third_party/nxp/rt_sdk/mbedtls/mbedtls.gni @@ -77,6 +77,7 @@ template("mbedtls_target") { "${_mbedtls_root}/library/hmac_drbg.c", "${_mbedtls_root}/library/md.c", "${_mbedtls_root}/library/md5.c", + "${_mbedtls_root}/library/nist_kw.c", "${_mbedtls_root}/library/oid.c", "${_mbedtls_root}/library/padlock.c", "${_mbedtls_root}/library/pem.c", @@ -89,6 +90,7 @@ template("mbedtls_target") { "${_mbedtls_root}/library/platform.c", "${_mbedtls_root}/library/platform_util.c", "${_mbedtls_root}/library/poly1305.c", + "${_mbedtls_root}/library/psa_crypto_client.c", "${_mbedtls_root}/library/ripemd160.c", "${_mbedtls_root}/library/rsa.c", "${_mbedtls_root}/library/rsa_internal.c", @@ -99,6 +101,7 @@ template("mbedtls_target") { "${_mbedtls_root}/library/ssl_ciphersuites.c", "${_mbedtls_root}/library/ssl_cli.c", "${_mbedtls_root}/library/ssl_cookie.c", + "${_mbedtls_root}/library/ssl_msg.c", "${_mbedtls_root}/library/ssl_srv.c", "${_mbedtls_root}/library/ssl_ticket.c", "${_mbedtls_root}/library/ssl_tls.c", diff --git a/third_party/nxp/rt_sdk/rt_executable.gni b/third_party/nxp/rt_sdk/rt_executable.gni index 2acfe190a2d960..e1ad6698062939 100644 --- a/third_party/nxp/rt_sdk/rt_executable.gni +++ b/third_party/nxp/rt_sdk/rt_executable.gni @@ -20,7 +20,7 @@ import("${build_root}/toolchain/flashable_executable.gni") template("rt_executable") { output_base_name = get_path_info(invoker.output_name, "name") objcopy_image_name = output_base_name + ".hex" - objcopy_image_format = "srec" + objcopy_image_format = "ihex" objcopy = "arm-none-eabi-objcopy" # Copy flashing dependencies to the output directory so that the output diff --git a/third_party/nxp/rt_sdk/rt_sdk.gni b/third_party/nxp/rt_sdk/rt_sdk.gni index 20cffacc1a150e..9063361f7b9d4d 100644 --- a/third_party/nxp/rt_sdk/rt_sdk.gni +++ b/third_party/nxp/rt_sdk/rt_sdk.gni @@ -24,7 +24,7 @@ import("${nxp_sdk_build_root}/nxp_sdk.gni") # declares some sdk args such as declare_args() { # Location of the rt SDK. - rt_sdk_root = "${chip_root}/third_party/nxp/rt_sdk/repo" + rt_sdk_root = "${chip_root}/third_party/nxp/rt_sdk/repo/sdk-2.15" # Enables Matter over Ethernet support chip_enable_ethernet = false @@ -41,6 +41,10 @@ declare_args() { # Could be used only if k32w0_transceiver is enabled hci_spinel_single_uart = false + # Enables spinel communication over spi + # Could be used only if iwx12_transceiver is enabled + spinel_over_spi = false + # Allows to enable OTW logs to see # firmware download logs for K32W0 transceiver otw_logs_enabled = false @@ -48,7 +52,10 @@ declare_args() { # Defines the RT NVM component supported rt_nvm_component = "littlefs" + # KeyStorage enable only for RW61x + #if(nxp_platform == "rt/rw61x"){ #rt_nvm_component = "key_storage" + #} # Enable wifi PTA support wifi_enable_pta = false @@ -67,6 +74,12 @@ declare_args() { # Enables Watchdog support use_watchdog = 0 + + # SDK 2.15 support + is_sdk_2_15 = false + + # Describe the transceiver detail flags + nxp_transceiver_interface_detail = "WIFI_IW612_BOARD_MURATA_2EL_USD" } declare_args() { @@ -84,6 +97,19 @@ if (!defined(rt_fwk_platform)) { assert(rt_sdk_root != "", "rt_sdk_root must be specified") +# Assuming 2.15 SDK support for RT1170 +if (rt_platform == "rt1060" || rt_platform == "rt1170") { + is_sdk_2_15 = true +} + +if (rt_platform == "rt1060") { + nxp_transceiver_interface_detail = "WIFI_IW612_BOARD_MURATA_2EL_M2" +} + +if (iwx12_transceiver && chip_enable_openthread) { + spinel_over_spi = true +} + rt_sdk_freertos_kernel = "${rt_sdk_root}/rtos/freertos/freertos-kernel" template("rt_transceiver") { @@ -98,8 +124,8 @@ template("rt_transceiver") { if (iw416_transceiver || w8801_transceiver || iwx12_transceiver) { _transceiver_include_dirs += [ # Transceiver files - "${rt_sdk_root}/middleware/wifi_nxp/wifi_bt_firmware", "${rt_sdk_root}/middleware/wifi_nxp/wifidriver", + "${rt_sdk_root}/middleware/wifi_nxp/wifidriver/incl", "${rt_sdk_root}/middleware/sdmmc/common", "${rt_sdk_root}/middleware/sdmmc/sdio", "${rt_sdk_root}/middleware/sdmmc/host/usdhc", @@ -110,7 +136,21 @@ template("rt_transceiver") { "${rt_sdk_root}/middleware/wifi_nxp/incl/port/os", "${rt_sdk_root}/middleware/wifi_nxp/wifidriver", "${rt_sdk_root}/middleware/wifi_nxp/wifidriver/incl", + "${rt_sdk_root}/middleware/wifi_nxp/fwdnld_intf_abs", + "${rt_sdk_root}/middleware/wifi_nxp/sdio_nxp_abs/incl", + "${rt_sdk_root}/middleware/wifi_nxp/firmware_dnld", ] + if (is_sdk_2_15) { + _transceiver_include_dirs += [ + "${rt_sdk_root}/middleware/wifi_nxp/wifi_bt_firmware/nw61x", + "${rt_sdk_root}/middleware/wifi_nxp/fwdnld_intf_abs", + "${rt_sdk_root}/middleware/wifi_nxp/sdio_nxp_abs/incl", + "${rt_sdk_root}/middleware/wifi_nxp/firmware_dnld", + ] + } else { + _transceiver_include_dirs += + [ "${rt_sdk_root}/middleware/wifi_nxp/wifi_bt_firmware" ] + } } libs = [] @@ -145,10 +185,21 @@ template("rt_transceiver") { "${rt_sdk_root}/middleware/sdmmc/host/usdhc/non_blocking/fsl_sdmmc_host.c", "${rt_sdk_root}/middleware/sdmmc/osa/fsl_sdmmc_osa.c", "${rt_sdk_root}/middleware/sdmmc/sdio/fsl_sdio.c", - "${rt_sdk_root}/middleware/wifi_nxp/wifidriver/firmware_dnld.c", - "${rt_sdk_root}/middleware/wifi_nxp/wifidriver/mlan_sdio.c", "${rt_sdk_root}/middleware/wifi_nxp/wifidriver/sdio.c", ] + if (is_sdk_2_15) { + sources += [ + "${rt_sdk_root}/middleware/wifi_nxp/firmware_dnld/firmware_dnld.c", + "${rt_sdk_root}/middleware/wifi_nxp/fwdnld_intf_abs/fwdnld_intf_abs.c", + "${rt_sdk_root}/middleware/wifi_nxp/sdio_nxp_abs/fwdnld_sdio.c", + "${rt_sdk_root}/middleware/wifi_nxp/sdio_nxp_abs/mlan_sdio.c", + ] + } else { + sources += [ + "${rt_sdk_root}/middleware/wifi_nxp/wifidriver/firmware_dnld.c", + "${rt_sdk_root}/middleware/wifi_nxp/wifidriver/mlan_sdio.c", + ] + } } if (!defined(public_configs)) { @@ -191,7 +242,6 @@ template("rt_wifi") { defines += [ "CHIP_DEVICE_CONFIG_ENABLE_WPA", "CONFIG_IPV6=1", # missing in wifi_config.h - "CONFIG_MAX_IPV6_ADDRESSES=5", # missing in wifi_config.h ] if (wifi_enable_pta) { @@ -223,8 +273,6 @@ template("rt_wifi") { "${rt_sdk_root}/middleware/wifi_nxp/dhcpd/dhcp-server-main.c", "${rt_sdk_root}/middleware/wifi_nxp/dhcpd/dhcp-server.c", "${rt_sdk_root}/middleware/wifi_nxp/dhcpd/dns-server.c", - "${rt_sdk_root}/middleware/wifi_nxp/port/lwip/net.c", - "${rt_sdk_root}/middleware/wifi_nxp/port/lwip/wifi_netif.c", "${rt_sdk_root}/middleware/wifi_nxp/port/os/os.c", "${rt_sdk_root}/middleware/wifi_nxp/wifidriver/mlan_11ac.c", "${rt_sdk_root}/middleware/wifi_nxp/wifidriver/mlan_11d.c", @@ -305,6 +353,7 @@ template("rt_sdk") { "${rt_core_sdk_root}/components/wifi_bt_module/AzureWave/tx_pwr_limits", "${rt_core_sdk_root}/components/wifi_bt_module/Murata/tx_pwr_limits", "${rt_core_sdk_root}/components/wifi_bt_module/template", + "${rt_core_sdk_root}/components/wifi_bt_module/incl", "${rt_core_sdk_root}/components/messaging", "${rt_core_sdk_root}/components/mem_manager", "${rt_core_sdk_root}/components/flash/mflash", @@ -320,6 +369,8 @@ template("rt_sdk") { "${rt_sdk_root}/middleware/wireless/framework/FSAbstraction", "${rt_sdk_root}/middleware/wireless/framework/KeyStorage", + #"${rt_sdk_root}/middleware/wireless/framework/DBG", + #littlefs "${rt_sdk_root}/middleware/littlefs", ] @@ -382,11 +433,6 @@ template("rt_sdk") { "PRINTF_ADVANCED_ENABLE=1", ] - if (rt_platform != "rw61x") { - # This adds a temporary workakound to fix mbdetls concurrent access to crypto hardware - defines += [ "RT_MATTER_SUPPORT" ] - } - if (use_watchdog != 0) { defines += [ "WATCHDOG_ALLOWED" ] } @@ -423,6 +469,11 @@ template("rt_sdk") { # No OSA main task "FSL_OSA_MAIN_FUNC_ENABLE=0", ] + if (chip_enable_openthread) { + defines += [ "CONFIG_MAX_IPV6_ADDRESSES=8" ] + } else { + defines += [ "CONFIG_MAX_IPV6_ADDRESSES=5" ] + } } if (chip_enable_ethernet) { @@ -451,7 +502,7 @@ template("rt_sdk") { if (iwx12_transceiver) { defines += [ - "WIFI_IW61x_BOARD_RD_USD", + nxp_transceiver_interface_detail, "SDIO_ENABLED", ] } @@ -523,6 +574,10 @@ template("rt_sdk") { cflags += [ "-isystem" + rebase_path(include_dir, root_build_dir) ] } + if (is_sdk_2_15) { + defines += [ "NXP_SDK_2_15_SUPPORT" ] + } + #Adding pre-include files cflags += [ "-include" + rebase_path( "${nxp_sdk_build_root}/${nxp_sdk_name}/transceiver/app_transceiver_config.h", @@ -589,6 +644,11 @@ template("rt_sdk") { "${rt_sdk_root}/middleware/wireless/framework/FileCache/fwk_file_cache.c", "${rt_sdk_root}/middleware/wireless/framework/KeyStorage/fwk_key_storage.c", ] + sources += [ + #littlefs + "${rt_sdk_root}/middleware/littlefs/lfs.c", + "${rt_sdk_root}/middleware/littlefs/lfs_util.c", + ] } if (rt_nvm_component == "littlefs") { diff --git a/third_party/nxp/rt_sdk/rw61x/BUILD.gn b/third_party/nxp/rt_sdk/rw61x/BUILD.gn index 007d83ee40c036..2b439c6e55ef14 100644 --- a/third_party/nxp/rt_sdk/rw61x/BUILD.gn +++ b/third_party/nxp/rt_sdk/rw61x/BUILD.gn @@ -21,33 +21,80 @@ import("${nxp_sdk_build_root}/nxp_sdk.gni") # Allows to get various RT gn options import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") +import( + "${nxp_sdk_build_root}/${nxp_sdk_name}/${rt_platform}/${rt_platform}.gni") + #allows to get common NXP SDK gn options import("${nxp_sdk_build_root}/nxp_sdk.gni") -group("nxp_mbedtls") { - public_deps = [] - # mbedtls port - if (rw610_mbedtls_port_els_pkc) { - public_deps += - [ "${nxp_sdk_build_root}/${nxp_sdk_name}:nxp_els_pkc_mbedtls" ] +import("${nxp_sdk_build_root}/${nxp_sdk_name}/mbedtls/mbedtls.gni") +rt_mbedtls_root = "${rt_sdk_root}/middleware/mbedtls" + +config("mbedtls_els_pkc_config") { + include_dirs = [ + "${rt_mbedtls_root}/port/els", + "${rt_mbedtls_root}/port/pkc", + ] + defines = [ "MBEDTLS_PORT_INCLUDE=" ] + + if (chip_enable_openthread) { + defines += [ "MBEDTLS_CONFIG_FILE=" ] } else { - public_deps += [ "${nxp_sdk_build_root}/${nxp_sdk_name}:nxp_ksdk_mbedtls" ] + defines += [ "MBEDTLS_CONFIG_FILE=" ] + } +} + +mbedtls_target("nxp_els_pkc_mbedtls") { + sources = [] + public_configs = [ ":mbedtls_els_pkc_config" ] + public_deps = [ nxp_sdk_driver_target ] + sources += [ + # els port + "${rt_mbedtls_root}/port/els/aes_alt.c", + "${rt_mbedtls_root}/port/els/cbc_mac_alt.c", + "${rt_mbedtls_root}/port/els/cmac_alt.c", + "${rt_mbedtls_root}/port/els/ctr_drbg_alt.c", + "${rt_mbedtls_root}/port/els/els_mbedtls.c", + "${rt_mbedtls_root}/port/els/entropy_poll_alt.c", + "${rt_mbedtls_root}/port/els/gcm_alt.c", + "${rt_mbedtls_root}/port/els/sha256_alt.c", + "${rt_mbedtls_root}/port/els/sha512_alt.c", + + # pkc port + "${rt_mbedtls_root}/port/pkc/ecc_alt.c", + "${rt_mbedtls_root}/port/pkc/ecdh_alt.c", + "${rt_mbedtls_root}/port/pkc/ecdsa_alt.c", + "${rt_mbedtls_root}/port/pkc/els_pkc_mbedtls.c", + "${rt_mbedtls_root}/port/pkc/rsa_alt.c", + ] + if (chip_enable_openthread) { + public_deps += [ "${openthread_root}/src/core:libopenthread_core_headers" ] } } group("nxp_sdk_mbedtls_config") { - public_configs = [] - - # mbedtls port - if (rw610_mbedtls_port_els_pkc) { - public_configs += - [ "${nxp_sdk_build_root}/${nxp_sdk_name}:nxp_els_pkc_mbedtls_config" ] - public_configs += - [ "${nxp_sdk_build_root}/${nxp_sdk_name}:mbedtls_els_pkc_config" ] - } else { - public_configs += - [ "${nxp_sdk_build_root}/${nxp_sdk_name}:nxp_ksdk_mbedtls_config" ] - public_configs += - [ "${nxp_sdk_build_root}/${nxp_sdk_name}:mbedtls_ksdk_config" ] + public_configs = [ ":mbedtls_els_pkc_config" ] +} + +group("nxp_mbedtls") { + public_deps = [ ":nxp_els_pkc_mbedtls" ] +} + +source_set("nxp_sdk_mbedtls_dep") { + # Add here SDK source files which have a dependency on mbedtls + # this approach helps avoid circular dependencies between mbedtls and rw61x_sdk_drivers targets + if (chip_enable_secure_dac_private_key_storage == 0) { + sources = [ "${rt_sdk_root}/middleware/wireless/framework/FactoryDataProvider/fwk_factory_data_provider.c" ] } + + deps = [ + "${nxp_sdk_build_root}/${nxp_sdk_name}/${rt_platform}:nxp_mbedtls", + "${nxp_sdk_build_root}/${nxp_sdk_name}/${rt_platform}:nxp_sdk_mbedtls_config", + nxp_sdk_driver_target, + ] +} + +group("nxp_sdk") { + # Add SDK's source set which depends on mbedtls + public_deps = [ ":nxp_sdk_mbedtls_dep" ] } diff --git a/third_party/nxp/rt_sdk/rw61x/rw61x.gni b/third_party/nxp/rt_sdk/rw61x/rw61x.gni index 24251d3a6def36..c15b4dbabf5e22 100644 --- a/third_party/nxp/rt_sdk/rw61x/rw61x.gni +++ b/third_party/nxp/rt_sdk/rw61x/rw61x.gni @@ -244,56 +244,60 @@ template("rw61x_sdk_drivers") { ] _rw61x_sdk_drivers_include_dirs += [ "${ELS_PKC_CL_PATH}", - "${ELS_PKC_CL_PATH}/src/platforms/redfinchSdk_sample", - "${ELS_PKC_CL_PATH}/src/platforms/redfinchSdk_sample/inc", - "${ELS_PKC_CL_PATH}/src/inc", - "${ELS_PKC_CL_PATH}/src/inc/impl", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClEls/inc", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClEls/inc/internal", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClHash/inc", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClSession/inc", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClSession/inc/internal", - "${ELS_PKC_CL_PATH}/src/comps/mcuxCsslFlowProtection/inc", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClCore/inc", - "${ELS_PKC_CL_PATH}/src/comps/mcuxCsslSecureCounter/inc", - "${ELS_PKC_CL_PATH}/src/comps/mcuxCsslCPreProcessor/inc", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClMemory/inc", - "${ELS_PKC_CL_PATH}/src/comps/mcuxCsslMemory/inc", - "${ELS_PKC_CL_PATH}/src/comps/mcuxCsslParamIntegrity/inc", "${ELS_PKC_CL_PATH}/src/compiler", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClRandom/inc", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClRandom/inc/internal", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClRandomModes/inc", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClRandomModes/inc/internal", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClAead/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClAead/inc/internal", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClAeadModes/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClAeadModes/inc/internal", "${ELS_PKC_CL_PATH}/src/comps/mcuxClAes/inc", "${ELS_PKC_CL_PATH}/src/comps/mcuxClAes/inc/internal", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClKey/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClCipher/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClCipher/inc/internal", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClCipherModes/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClCipherModes/inc/internal", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClCore/inc", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/inc", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/inc/internal", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClTrng/inc", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClTrng/inc/internal", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClPrng/inc", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClPrng/inc/internal", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClMath/inc", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClMath/inc/internal", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClPkc/inc", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClRsa/inc", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClMacModes/inc", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClMacModes/inc/internal", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClEls/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClEls/inc/internal", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClHash/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClHashModes/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClHashModes/inc/internal", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClHmac/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClKey/inc", "${ELS_PKC_CL_PATH}/src/comps/mcuxClMac/inc", "${ELS_PKC_CL_PATH}/src/comps/mcuxClMac/inc/internal", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClMacModes/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClMacModes/inc/internal", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClMath/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClMath/inc/internal", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClMemory/inc", "${ELS_PKC_CL_PATH}/src/comps/mcuxClPadding/inc", "${ELS_PKC_CL_PATH}/src/comps/mcuxClPadding/inc/internal", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClAeadModes/inc", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClAeadModes/inc/internal", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClAead/inc", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClAead/inc/internal", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClCipherModes/inc", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClCipherModes/inc/internal", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClCipher/inc", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClCipher/inc/internal", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClPkc/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClPkc/inc/internal", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClPrng/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClPrng/inc/internal", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClRandom/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClRandom/inc/internal", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClRandomModes/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClRandomModes/inc/internal", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClRsa/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClSession/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClSession/inc/internal", "${ELS_PKC_CL_PATH}/src/comps/mcuxClTrng/inc", "${ELS_PKC_CL_PATH}/src/comps/mcuxClTrng/inc/internal", + "${ELS_PKC_CL_PATH}/src/comps/mcuxCsslCPreProcessor/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxCsslDataIntegrity/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxCsslFlowProtection/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxCsslMemory/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxCsslMemory/inc/internal", + "${ELS_PKC_CL_PATH}/src/comps/mcuxCsslParamIntegrity/inc", + "${ELS_PKC_CL_PATH}/src/comps/mcuxCsslSecureCounter/inc", + "${ELS_PKC_CL_PATH}/src/inc", + "${ELS_PKC_CL_PATH}/src/inc/impl", + "${ELS_PKC_CL_PATH}/src/platforms/rw61x", + "${ELS_PKC_CL_PATH}/src/platforms/rw61x/inc", ] } @@ -302,7 +306,7 @@ template("rw61x_sdk_drivers") { "${rt_sdk_root}/middleware/wifi_nxp/wifidriver", # Include lpm.h and host_sleep.h files - "${rt_sdk_root}/boards/rdrw612bga/wifi_examples/wifi_cli", + "${rt_sdk_root}/boards/rdrw612bga/wifi_examples/common/lpm", # wifi config file path "${WIFI_BT_TEMPLATE_PATH}", @@ -444,9 +448,6 @@ template("rw61x_sdk_drivers") { # framework coex file to initialize controllers "${rt_sdk_root}/middleware/wireless/framework/platform/${rt_fwk_platform}/fwk_platform_coex.c", - - # other framework files - "${rt_sdk_root}/middleware/wireless/framework/FactoryDataProvider/fwk_factory_data_provider.c", ] if (sdk_fsl_assert_support) { @@ -457,30 +458,41 @@ template("rw61x_sdk_drivers") { # els_pkc component for mbedtls els_pkc port sources += [ "${ELS_PKC_CL_PATH}/src/comps/mcuxClAead/src/mcuxClAead.c", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClAeadModes/src/mcuxClAeadModes_ELS_AesCcm.c", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClAeadModes/src/mcuxClAeadModes_ELS_AesGcm.c", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClAeadModes/src/mcuxClAeadModes_ELS_CcmEngineAes.c", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClAeadModes/src/mcuxClAeadModes_ELS_Constants.c", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClAeadModes/src/mcuxClAeadModes_ELS_GcmEngineAes.c", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClAeadModes/src/mcuxClAeadModes_ELS_MultiPart.c", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClAeadModes/src/mcuxClAeadModes_ELS_OneShot.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClAeadModes/src/mcuxClAeadModes_Els_AesCcm.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClAeadModes/src/mcuxClAeadModes_Els_AesGcm.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClAeadModes/src/mcuxClAeadModes_Els_CcmEngineAes.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClAeadModes/src/mcuxClAeadModes_Els_GcmEngineAes.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClAeadModes/src/mcuxClAeadModes_Els_Modes.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClAeadModes/src/mcuxClAeadModes_Els_Multipart.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClAeadModes/src/mcuxClAeadModes_Els_Oneshot.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClAes/src/mcuxClAes_KeyTypes.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClCipher/src/mcuxClCipher.c", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClCipherModes/src/mcuxClCipherModes_ELS_Aes.c", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClCipherModes/src/mcuxClCipherModes_ELS_EngineAes.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClCipherModes/src/mcuxClCipherModes_Els_Aes.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClCipherModes/src/mcuxClCipherModes_Els_EngineAes.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClCipherModes/src/mcuxClCipherModes_Helper.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClCipherModes/src/mcuxClCipherModes_Modes.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Constants.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_EdDSA_GenerateKeyPair.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_EdDSA_GenerateKeyPair_FUP.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_EdDSA_GenerateSignature.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_EdDSA_GenerateSignatureMode.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_EdDSA_GenerateSignature_FUP.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_EdDSA_InitPrivKeyInputMode.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_EdDSA_Internal_CalcHashModN.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_EdDSA_Internal_CalcHashModN_FUP.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_EdDSA_Internal_DecodePoint_Ed25519.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_EdDSA_Internal_DecodePoint_Ed448.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_EdDSA_Internal_DecodePoint_FUP.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_EdDSA_Internal_SetupEnvironment.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_EdDSA_Internal_SignatureMechanisms.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_EdDSA_VerifySignature.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Internal_BlindedScalarMult.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Internal_Convert_FUP.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Internal_GenerateMultiplicativeBlinding.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Internal_InterleaveScalar.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Internal_InterleaveTwoScalars.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Internal_Interleave_FUP.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Internal_PointComparison_FUP.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Internal_RecodeAndReorderScalar.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Internal_SetupEnvironment.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Internal_SetupEnvironment_FUP.c", @@ -501,6 +513,7 @@ template("rw61x_sdk_drivers") { "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_TwEd_Internal_PlainVarScalarMult.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_TwEd_Internal_PointArithmeticEd25519.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_TwEd_Internal_PointArithmeticEd25519_FUP.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_TwEd_Internal_PointSubtraction_FUP.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_TwEd_Internal_PointValidation_FUP.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_TwEd_Internal_PrecPointImportAndValidate.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_TwEd_Internal_VarScalarMult.c", @@ -510,6 +523,7 @@ template("rw61x_sdk_drivers") { "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_WeierECC_Internal_GenerateDomainParams_FUP.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_WeierECC_Internal_SetupEnvironment.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Weier_Internal_ConvertPoint_FUP.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Weier_Internal_FUP.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Weier_Internal_KeyGen.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Weier_Internal_KeyGen_FUP.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Weier_Internal_PointArithmetic.c", @@ -521,6 +535,7 @@ template("rw61x_sdk_drivers") { "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Weier_Internal_SecurePointMult_CoZMontLadder_FUP.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Weier_Internal_SetupEnvironment.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Weier_KeyGen.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Weier_KeyGen_FUP.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Weier_PointMult.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Weier_PointMult_FUP.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEcc/src/mcuxClEcc_Weier_Sign.c", @@ -531,9 +546,8 @@ template("rw61x_sdk_drivers") { "${ELS_PKC_CL_PATH}/src/comps/mcuxClEls/src/mcuxClEls_Cipher.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEls/src/mcuxClEls_Cmac.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEls/src/mcuxClEls_Common.c", - - #"${ELS_PKC_CL_PATH}/src/comps/mcuxClEls/src/mcuxClEls_Crc.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEls/src/mcuxClEls_Ecc.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClEls/src/mcuxClEls_GlitchDetector.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEls/src/mcuxClEls_Hash.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEls/src/mcuxClEls_Hmac.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClEls/src/mcuxClEls_Kdf.c", @@ -542,18 +556,21 @@ template("rw61x_sdk_drivers") { "${ELS_PKC_CL_PATH}/src/comps/mcuxClHash/src/mcuxClHash_api_multipart_common.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClHash/src/mcuxClHash_api_multipart_compute.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClHash/src/mcuxClHash_api_oneshot_compute.c", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClHash/src/mcuxClHash_core_els_sha2.c", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClHash/src/mcuxClHash_internal_els_sha2.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClHashModes/src/mcuxClHashModes_Core_els_sha2.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClHashModes/src/mcuxClHashModes_Internal_els_sha2.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClHmac/src/mcuxClHmac_Els.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClHmac/src/mcuxClHmac_Functions.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClHmac/src/mcuxClHmac_Helper.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClHmac/src/mcuxClHmac_KeyTypes.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClHmac/src/mcuxClHmac_Modes.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClHmac/src/mcuxClHmac_Sw.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClKey/src/mcuxClKey.c", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClKey/src/mcuxClKey_KeyTypes.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClKey/src/mcuxClKey_Protection.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClMac/src/mcuxClMac.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClMacModes/src/mcuxClMacModes.c", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClMacModes/src/mcuxClMacModes_ELS_CBCMAC.c", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClMacModes/src/mcuxClMacModes_ELS_CMAC.c", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClMacModes/src/mcuxClMacModes_ELS_Functions.c", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClMacModes/src/mcuxClMacModes_ELS_HMAC.c", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClMacModes/src/mcuxClMacModes_Helper.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClMacModes/src/mcuxClMacModes_Els_Cbcmac.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClMacModes/src/mcuxClMacModes_Els_Cmac.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClMacModes/src/mcuxClMacModes_Els_Functions.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClMacModes/src/mcuxClMacModes_Modes.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClMath/src/mcuxClMath_ExactDivide.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClMath/src/mcuxClMath_ExactDivideOdd.c", @@ -617,14 +634,15 @@ template("rw61x_sdk_drivers") { "${ELS_PKC_CL_PATH}/src/comps/mcuxClRsa/src/mcuxClRsa_Verify.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClRsa/src/mcuxClRsa_VerifyE.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxClSession/src/mcuxClSession.c", - "${ELS_PKC_CL_PATH}/src/comps/mcuxClTrng/src/mcuxClTrng_RNG4.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxClTrng/src/mcuxClTrng_SA_TRNG.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxCsslMemory/src/mcuxCsslMemory_Clear.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxCsslMemory/src/mcuxCsslMemory_Compare.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxCsslMemory/src/mcuxCsslMemory_Copy.c", + "${ELS_PKC_CL_PATH}/src/comps/mcuxCsslMemory/src/mcuxCsslMemory_Internal_SecureCompare_Stub.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxCsslMemory/src/mcuxCsslMemory_Set.c", "${ELS_PKC_CL_PATH}/src/comps/mcuxCsslParamIntegrity/src/mcuxCsslParamIntegrity.c", - "${ELS_PKC_CL_PATH}/src/platforms/redfinchSdk_sample/mcux_els.c", - "${ELS_PKC_CL_PATH}/src/platforms/redfinchSdk_sample/mcux_pkc.c", + "${ELS_PKC_CL_PATH}/src/platforms/rw61x/mcux_els.c", + "${ELS_PKC_CL_PATH}/src/platforms/rw61x/mcux_pkc.c", ] } @@ -675,9 +693,6 @@ template("rw61x_sdk_drivers") { public_configs += [ ":${target_name}_config" ] public_deps += [ nxp_sdk_target ] - # The FactoryDataProvider/fwk_factory_data_provider.c component has a dependency to mbedtls - deps += [ "${nxp_sdk_build_root}/${nxp_sdk_name}/${rt_platform}:nxp_sdk_mbedtls_config" ] - if (chip_enable_openthread) { #Dep to ot header files required for mbedtls as mbedtls config file has a dependency to ot deps += [ "${openthread_root}/src/core:libopenthread_core_headers" ] diff --git a/third_party/nxp/rt_sdk/sdk_hook/fatfs/config/ffconf.h b/third_party/nxp/rt_sdk/sdk_hook/fatfs/config/ffconf.h new file mode 100644 index 00000000000000..7138317b86f169 --- /dev/null +++ b/third_party/nxp/rt_sdk/sdk_hook/fatfs/config/ffconf.h @@ -0,0 +1,302 @@ +/*----------------------------------------------------------------------------/ +/ FatFs - Generic FAT Filesystem Module R0.14b / +/-----------------------------------------------------------------------------/ +/ +/ Copyright (C) 2021, ChaN, all right reserved. +/ Copyright 2023 NXP +/ +/ +/ FatFs module is an open source software. Redistribution and use of FatFs in +/ source and binary forms, with or without modification, are permitted provided +/ that the following condition is met: +/ +/ 1. Redistributions of source code must retain the above copyright notice, +/ this condition and the following disclaimer. +/ +/ This software is provided by the copyright holder and contributors "AS IS" +/ and any warranties related to this software are DISCLAIMED. +/ The copyright owner or contributors be NOT LIABLE for any damages caused +/ by use of this software. +/ +/----------------------------------------------------------------------------*/ + +#ifndef _FFCONF_H_ +#define _FFCONF_H_ + +/*---------------------------------------------------------------------------/ +/ FatFs Functional Configurations +/---------------------------------------------------------------------------*/ + +#define FFCONF_DEF 80286 /* Revision ID */ + +/*---------------------------------------------------------------------------/ +/ MSDK adaptation configuration +/---------------------------------------------------------------------------*/ +#define USB_DISK_ENABLE + +/*---------------------------------------------------------------------------/ +/ Function Configurations +/---------------------------------------------------------------------------*/ + +#define FF_FS_READONLY 0 +/* This option switches read-only configuration. (0:Read/Write or 1:Read-only) +/ Read-only configuration removes writing API functions, f_write(), f_sync(), +/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree() +/ and optional writing functions as well. */ + +#define FF_FS_MINIMIZE 0 +/* This option defines minimization level to remove some basic API functions. +/ +/ 0: Basic functions are fully enabled. +/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename() +/ are removed. +/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1. +/ 3: f_lseek() function is removed in addition to 2. */ + +#define FF_USE_STRFUNC 1 +/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf(). +/ +/ 0: Disable string functions. +/ 1: Enable without LF-CRLF conversion. +/ 2: Enable with LF-CRLF conversion. */ + +#define FF_USE_FIND 0 +/* This option switches filtered directory read functions, f_findfirst() and +/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */ + +#define FF_USE_MKFS 0 +/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ + +#define FF_USE_FASTSEEK 0 +/* This option switches fast seek function. (0:Disable or 1:Enable) */ + +#define FF_USE_EXPAND 0 +/* This option switches f_expand function. (0:Disable or 1:Enable) */ + +#define FF_USE_CHMOD 1 +/* This option switches attribute manipulation functions, f_chmod() and f_utime(). +/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */ + +#define FF_USE_LABEL 0 +/* This option switches volume label functions, f_getlabel() and f_setlabel(). +/ (0:Disable or 1:Enable) */ + +#define FF_USE_FORWARD 0 +/* This option switches f_forward() function. (0:Disable or 1:Enable) */ + +/*---------------------------------------------------------------------------/ +/ Locale and Namespace Configurations +/---------------------------------------------------------------------------*/ + +#define FF_CODE_PAGE 932 +/* This option specifies the OEM code page to be used on the target system. +/ Incorrect code page setting can cause a file open failure. +/ +/ 437 - U.S. +/ 720 - Arabic +/ 737 - Greek +/ 771 - KBL +/ 775 - Baltic +/ 850 - Latin 1 +/ 852 - Latin 2 +/ 855 - Cyrillic +/ 857 - Turkish +/ 860 - Portuguese +/ 861 - Icelandic +/ 862 - Hebrew +/ 863 - Canadian French +/ 864 - Arabic +/ 865 - Nordic +/ 866 - Russian +/ 869 - Greek 2 +/ 932 - Japanese (DBCS) +/ 936 - Simplified Chinese (DBCS) +/ 949 - Korean (DBCS) +/ 950 - Traditional Chinese (DBCS) +/ 0 - Include all code pages above and configured by f_setcp() +*/ + +#define FF_USE_LFN 1 +#define FF_MAX_LFN 255 +/* The FF_USE_LFN switches the support for LFN (long file name). +/ +/ 0: Disable LFN. FF_MAX_LFN has no effect. +/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe. +/ 2: Enable LFN with dynamic working buffer on the STACK. +/ 3: Enable LFN with dynamic working buffer on the HEAP. +/ +/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function +/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and +/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled. +/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can +/ be in range of 12 to 255. It is recommended to be set it 255 to fully support LFN +/ specification. +/ When use stack for the working buffer, take care on stack overflow. When use heap +/ memory for the working buffer, memory management functions, ff_memalloc() and +/ ff_memfree() exemplified in ffsystem.c, need to be added to the project. */ + +#define FF_LFN_UNICODE 0 +/* This option switches the character encoding on the API when LFN is enabled. +/ +/ 0: ANSI/OEM in current CP (TCHAR = char) +/ 1: Unicode in UTF-16 (TCHAR = WCHAR) +/ 2: Unicode in UTF-8 (TCHAR = char) +/ 3: Unicode in UTF-32 (TCHAR = DWORD) +/ +/ Also behavior of string I/O functions will be affected by this option. +/ When LFN is not enabled, this option has no effect. */ + +#define FF_LFN_BUF 255 +#define FF_SFN_BUF 12 +/* This set of options defines size of file name members in the FILINFO structure +/ which is used to read out directory items. These values should be suffcient for +/ the file names to read. The maximum possible length of the read file name depends +/ on character encoding. When LFN is not enabled, these options have no effect. */ + +#define FF_STRF_ENCODE 3 +/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(), +/ f_putc(), f_puts and f_printf() convert the character encoding in it. +/ This option selects assumption of character encoding ON THE FILE to be +/ read/written via those functions. +/ +/ 0: ANSI/OEM in current CP +/ 1: Unicode in UTF-16LE +/ 2: Unicode in UTF-16BE +/ 3: Unicode in UTF-8 +*/ + +#define FF_FS_RPATH 0 +/* This option configures support for relative path. +/ +/ 0: Disable relative path and remove related functions. +/ 1: Enable relative path. f_chdir() and f_chdrive() are available. +/ 2: f_getcwd() function is available in addition to 1. +*/ + +/*---------------------------------------------------------------------------/ +/ Drive/Volume Configurations +/---------------------------------------------------------------------------*/ + +#define FF_VOLUMES 3 +/* Number of volumes (logical drives) to be used. (1-10) */ + +#define FF_STR_VOLUME_ID 0 +#define FF_VOLUME_STRS "RAM", "NAND", "CF", "SD", "SD2", "USB", "USB2", "USB3" +/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings. +/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive +/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each +/ logical drives. Number of items must not be less than FF_VOLUMES. Valid +/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are +/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is +/ not defined, a user defined volume string table needs to be defined as: +/ +/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",... +*/ + +#define FF_MULTI_PARTITION 0 +/* This option switches support for multiple volumes on the physical drive. +/ By default (0), each logical drive number is bound to the same physical drive +/ number and only an FAT volume found on the physical drive will be mounted. +/ When this function is enabled (1), each logical drive number can be bound to +/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk() +/ funciton will be available. */ + +#define FF_MIN_SS 512 +#define FF_MAX_SS 4096 +/* This set of options configures the range of sector size to be supported. (512, +/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and +/ harddisk. But a larger value may be required for on-board flash memory and some +/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured +/ for variable sector size mode and disk_ioctl() function needs to implement +/ GET_SECTOR_SIZE command. */ + +#define FF_LBA64 0 +/* This option switches support for 64-bit LBA. (0:Disable or 1:Enable) +/ To enable the 64-bit LBA, also exFAT needs to be enabled. (FF_FS_EXFAT == 1) */ + +#define FF_MIN_GPT 0x100000000 +/* Minimum number of sectors to switch GPT format to create partition in f_mkfs and +/ f_fdisk function. 0x100000000 max. This option has no effect when FF_LBA64 == 0. */ + +#define FF_USE_TRIM 0 +/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable) +/ To enable Trim function, also CTRL_TRIM command should be implemented to the +/ disk_ioctl() function. */ + +/*---------------------------------------------------------------------------/ +/ System Configurations +/---------------------------------------------------------------------------*/ + +#define FF_FS_TINY 0 +/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny) +/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes. +/ Instead of private sector buffer eliminated from the file object, common sector +/ buffer in the filesystem object (FATFS) is used for the file data transfer. */ + +#define FF_FS_EXFAT 0 +/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable) +/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1) +/ Note that enabling exFAT discards ANSI C (C89) compatibility. */ + +#define FF_FS_NORTC 1 +#define FF_NORTC_MON 1 +#define FF_NORTC_MDAY 1 +#define FF_NORTC_YEAR 2018 +/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have +/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable +/ the timestamp function. Every object modified by FatFs will have a fixed timestamp +/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time. +/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be +/ added to the project to read current time form real-time clock. FF_NORTC_MON, +/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect. +/ These options have no effect in read-only configuration (FF_FS_READONLY = 1). */ + +#define FF_FS_NOFSINFO 0 +/* If you need to know correct free space on the FAT32 volume, set bit 0 of this +/ option, and f_getfree() function at first time after volume mount will force +/ a full FAT scan. Bit 1 controls the use of last allocated cluster number. +/ +/ bit0=0: Use free cluster count in the FSINFO if available. +/ bit0=1: Do not trust free cluster count in the FSINFO. +/ bit1=0: Use last allocated cluster number in the FSINFO if available. +/ bit1=1: Do not trust last allocated cluster number in the FSINFO. +*/ + +#define FF_FS_LOCK 0 +/* The option FF_FS_LOCK switches file lock function to control duplicated file open +/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY +/ is 1. +/ +/ 0: Disable file lock function. To avoid volume corruption, application program +/ should avoid illegal open, remove and rename to the open objects. +/ >0: Enable file lock function. The value defines how many files/sub-directories +/ can be opened simultaneously under file lock control. Note that the file +/ lock control is independent of re-entrancy. */ + +#define FF_FS_REENTRANT 0 +#define FF_FS_TIMEOUT 5000 +#if FF_FS_REENTRANT +#include "FreeRTOS.h" +#include "semphr.h" +#define FF_SYNC_t SemaphoreHandle_t +#endif +/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs +/ module itself. Note that regardless of this option, file access to different +/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs() +/ and f_fdisk() function, are always not re-entrant. Only file/directory access +/ to the same volume is under control of this function. +/ +/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect. +/ 1: Enable re-entrancy. Also user provided synchronization handlers, +/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj() +/ function, must be added to the project. Samples are available in +/ option/syscall.c. +/ +/ The FF_FS_TIMEOUT defines timeout period in unit of time tick. +/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*, +/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be +/ included somewhere in the scope of ff.h. */ + +/*--- End of configuration options ---*/ + +#endif /* _FFCONF_H_ */ diff --git a/third_party/nxp/rt_sdk/sdk_hook/zephyr/bluetooth/hci.h b/third_party/nxp/rt_sdk/sdk_hook/zephyr/bluetooth/hci.h new file mode 100644 index 00000000000000..effc18d6095571 --- /dev/null +++ b/third_party/nxp/rt_sdk/sdk_hook/zephyr/bluetooth/hci.h @@ -0,0 +1,17 @@ +/* + * Copyright 2023 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#if defined(__cplusplus) +extern "C" { +#endif /* _cplusplus */ + +#include + +#if defined(__cplusplus) +} +#endif diff --git a/third_party/nxp/rt_sdk/transceiver/app_transceiver_config.h b/third_party/nxp/rt_sdk/transceiver/app_transceiver_config.h index 2422b61dbf0b1c..c4dd38750c2bd0 100644 --- a/third_party/nxp/rt_sdk/transceiver/app_transceiver_config.h +++ b/third_party/nxp/rt_sdk/transceiver/app_transceiver_config.h @@ -9,8 +9,9 @@ #define CONTROLLER_ID kUSB_ControllerEhci0 #if defined(WIFI_IW416_BOARD_AW_AM457_USD) || defined(WIFI_IW416_BOARD_AW_AM510_USD) || \ - defined(WIFI_88W8987_BOARD_AW_CM358_USD) || defined(WIFI_IW61x_BOARD_RD_USD) || defined(WIFI_BOARD_RW610) || \ - defined(WIFI_88W8801_BOARD_MURATA_2DS_USD) + defined(WIFI_88W8987_BOARD_AW_CM358_USD) || defined(WIFI_IW612_BOARD_RD_USD) || defined(WIFI_BOARD_RW610) || \ + defined(WIFI_88W8801_BOARD_MURATA_2DS_USD) || defined(WIFI_IW612_BOARD_MURATA_2EL_USD) || \ + defined(WIFI_IW612_BOARD_MURATA_2EL_M2) #define WIFI_TRANSCEIVER_SUPPORT 1 #else #define WIFI_TRANSCEIVER_SUPPORT 0 @@ -27,9 +28,16 @@ #endif /* CHIP_DEVICE_CONFIG_ENABLE_WPA || CHIP_DEVICE_CONFIG_ENABLE_THREAD */ #if WIFI_TRANSCEIVER_SUPPORT +#ifdef NXP_SDK_2_15_SUPPORT +/* comes from: /components/wifi_bt_module/incl/wifi_bt_module_config.h */ +#include "wifi_bt_module_config.h" +#else #define NOT_DEFINE_DEFAULT_WIFI_MODULE -/* app_config.h comes from: /components/wifi_bt_module/template/wifi_config.h */ +/* app_config.h comes from: /components/wifi_bt_module/template */ #include "app_config.h" +#endif +/* comes from: /components/wifi_bt_module/template/wifi_config.h */ +#include "wifi_config.h" #endif /* WIFI_TRANSCEIVER_SUPPORT */ #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE diff --git a/third_party/openthread/ot-nxp b/third_party/openthread/ot-nxp index 0a8fcca1828cac..2128e8dbe8af40 160000 --- a/third_party/openthread/ot-nxp +++ b/third_party/openthread/ot-nxp @@ -1 +1 @@ -Subproject commit 0a8fcca1828cac3e3d70577010c365b4dc8e3d66 +Subproject commit 2128e8dbe8af40d0cce55fc514a39a0b1376a95b diff --git a/third_party/openthread/platforms/nxp/k32w/k32w0/BUILD.gn b/third_party/openthread/platforms/nxp/k32w/k32w0/BUILD.gn index a67158170d0a18..7ebd860e571371 100644 --- a/third_party/openthread/platforms/nxp/k32w/k32w0/BUILD.gn +++ b/third_party/openthread/platforms/nxp/k32w/k32w0/BUILD.gn @@ -14,11 +14,13 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") -import("//build_overrides/k32w0_sdk.gni") +import("//build_overrides/nxp_sdk.gni") import("//build_overrides/openthread.gni") import("${build_root}/config/compiler/compiler.gni") -import("${chip_root}/third_party/nxp/k32w0_sdk/k32w0_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" @@ -90,8 +92,8 @@ source_set("libopenthread-k32w0") { public_deps = [ ":openthread_core_config_k32w0", - "${k32w0_sdk_build_root}:k32w0_sdk", - "${k32w0_sdk_build_root}:mbedtls", + "${nxp_sdk_build_root}:nxp_sdk", + "${nxp_sdk_build_root}/${nxp_sdk_name}:mbedtls", "${openthread_root}/src/core:libopenthread_core_headers", "../../..:libopenthread-platform", "../../..:libopenthread-platform-utils", diff --git a/third_party/openthread/platforms/nxp/k32w/k32w1/BUILD.gn b/third_party/openthread/platforms/nxp/k32w/k32w1/BUILD.gn index 446768b23b778c..b004389a09fa64 100644 --- a/third_party/openthread/platforms/nxp/k32w/k32w1/BUILD.gn +++ b/third_party/openthread/platforms/nxp/k32w/k32w1/BUILD.gn @@ -30,7 +30,6 @@ config("openthread_k32w1_config") { "OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE=1", "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", ] diff --git a/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn b/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn index 98cc50084dfd50..318276cc0aa666 100644 --- a/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn +++ b/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn @@ -28,6 +28,7 @@ openthread_nxp_root = "${chip_root}/third_party/openthread/ot-nxp" config("openthread_rw61x_config") { include_dirs = [ "${openthread_nxp_root}/src/common", + "${openthread_nxp_root}/src/common/br", "${openthread_nxp_root}/src/rw/rw612", "${openthread_nxp_root}/third_party/mbedtls/configs", "${openthread_root}/third_party/mbedtls", @@ -36,6 +37,22 @@ config("openthread_rw61x_config") { if (spinel_interface_rpmsg) { include_dirs += [ "${openthread_nxp_root}/src/common/spinel" ] } + if (chip_enable_wifi && chip_enable_openthread) { + defines = [ + "OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE=1", + "OPENTHREAD_CONFIG_COMMISSIONER_ENABLE=1", + "OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE=1", + "OPENTHREAD_CONFIG_MDNS_SERVER_ENABLE=1", + "OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE=1", + "OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE=1", + "OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS=3", + "OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE=1", + "OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE=1", + "OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE=1", + "OT_APP_BR_LWIP_HOOKS_EN=1", + "OPENTHREAD_CONFIG_GENERIC_TASKLET_ENABLE=1", + ] + } } #Config used by the openthread stack to get the path to OpenthreadConfig.h @@ -45,6 +62,7 @@ source_set("openthread_core_config_rw61x") { } source_set("libopenthread-rw61x") { + deps = [] sources = [ "${openthread_nxp_root}/src/common/alarm_freertos.c", "${openthread_nxp_root}/src/common/logging.c", @@ -52,6 +70,17 @@ source_set("libopenthread-rw61x") { "${openthread_nxp_root}/src/rw/rw612/platform/entropy.c", ] + if (chip_enable_wifi && chip_enable_openthread) { + sources += [ + "${openthread_nxp_root}/src/common/br/border_agent.c", + "${openthread_nxp_root}/src/common/br/br_rtos_manager.c", + "${openthread_nxp_root}/src/common/br/infra_if.c", + "${openthread_nxp_root}/src/common/br/lwip_hooks.c", + "${openthread_nxp_root}/src/common/br/lwip_mcast.c", + "${openthread_nxp_root}/src/common/br/udp_plat.c", + ] + deps += [ "${nxp_sdk_build_root}:nxp_lwip" ] + } if (spinel_interface_rpmsg) { sources += [ "${openthread_nxp_root}/src/common/spinel/misc.c", @@ -72,8 +101,8 @@ source_set("libopenthread-rw61x") { sources += [ "${openthread_nxp_root}/src/common/flash_nvm.c" ] } else if (rt_nvm_component == "littlefs") { sources += [ "${openthread_nxp_root}/src/common/flash_littlefs.c" ] - } else { - sources += [ "${openthread_nxp_root}/src/common/flash_ks.c" ] + } else if (rt_nvm_component == "key_storage") { + sources += [ "${openthread_nxp_root}/src/common/flash_fsa.c" ] } defines = [ @@ -83,7 +112,7 @@ source_set("libopenthread-rw61x") { public_configs = [ ":openthread_rw61x_config" ] - deps = [ + deps += [ "${nxp_sdk_build_root}:nxp_mbedtls", "../../..:libopenthread-platform-utils", nxp_sdk_target,