diff --git a/.github/workflows/examples-nxp.yaml b/.github/workflows/examples-nxp.yaml index 747813d6aa1037..975d9292a18941 100644 --- a/.github/workflows/examples-nxp.yaml +++ b/.github/workflows/examples-nxp.yaml @@ -29,8 +29,8 @@ env: CHIP_NO_LOG_TIMESTAMPS: true jobs: - k32w: - name: K32W + k32w0: + name: K32W0 env: BUILD_TYPE: gn_k32w @@ -39,7 +39,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-k32w:66 + image: ghcr.io/project-chip/chip-build-k32w:71 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: @@ -66,8 +66,6 @@ jobs: --target nxp-k32w0-freertos-contact-sensor \ --target nxp-k32w0-freertos-contact-sensor-low-power \ --target nxp-k32w0-freertos-contact-sensor-low-power-factory \ - --target nxp-k32w1-freertos-lighting \ - --target nxp-k32w1-freertos-contact-sensor-low-power \ build \ --copy-artifacts-to out/artifacts \ " @@ -77,16 +75,62 @@ jobs: nxp k32w0+release light \ out/artifacts/nxp-k32w0-freertos-lighting/chip-k32w0x-light-example.elf \ /tmp/bloat_reports/ - .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ - nxp k32w1+release light \ - out/artifacts/nxp-k32w1-freertos-lighting/chip-k32w1-light-example.elf \ - /tmp/bloat_reports/ - name: Get contact sensor size stats run: | .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nxp k32w0+release contact \ out/artifacts/nxp-k32w0-freertos-contact-sensor-low-power/chip-k32w0x-contact-example.elf \ /tmp/bloat_reports/ + - name: Uploading Size Reports + uses: ./.github/actions/upload-size-reports + if: ${{ !env.ACT }} + with: + platform-name: K32W0 + k32w1: + name: K32W1 + + env: + BUILD_TYPE: gn_k32w + + runs-on: ubuntu-latest + if: github.actor != 'restyled-io[bot]' + + container: + image: ghcr.io/project-chip/chip-build-nxp:71 + 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: nxp + extra-submodule-parameters: --recursive + + - name: Set up environment for size reports + uses: ./.github/actions/setup-size-reports + if: ${{ !env.ACT }} + with: + gh-context: ${{ toJson(github) }} + + - name: Build examples + run: | + scripts/run_in_build_env.sh "\ + ./scripts/build/build_examples.py \ + --target nxp-k32w1-freertos-lighting \ + --target nxp-k32w1-freertos-contact-sensor-low-power \ + build \ + --copy-artifacts-to out/artifacts \ + " + - name: Get lighting app size stats + run: | + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + nxp k32w1+release light \ + out/artifacts/nxp-k32w1-freertos-lighting/chip-k32w1-light-example.elf \ + /tmp/bloat_reports/ + - name: Get contact sensor size stats + run: | .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nxp k32w1+release contact \ out/artifacts/nxp-k32w1-freertos-contact-sensor-low-power/chip-k32w1-contact-example.elf \ @@ -95,7 +139,7 @@ jobs: uses: ./.github/actions/upload-size-reports if: ${{ !env.ACT }} with: - platform-name: K32W + platform-name: K32W1 rw61x: name: RW61X diff --git a/examples/contact-sensor-app/nxp/common/AppTask.cpp b/examples/contact-sensor-app/nxp/common/AppTask.cpp new file mode 100644 index 00000000000000..f49c603cbb16a6 --- /dev/null +++ b/examples/contact-sensor-app/nxp/common/AppTask.cpp @@ -0,0 +1,53 @@ +/* + * + * 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 "AppTask.h" + +#if CONFIG_LOW_POWER +#include "PWR_Interface.h" +#endif + +#include + +void ContactSensorApp::AppTask::PreInitMatterStack() +{ + ChipLogProgress(DeviceLayer, "Welcome to NXP Contact Sensor Demo App"); +} + +#if CONFIG_LOW_POWER +void ContactSensorApp::AppTask::AppMatter_DisallowDeviceToSleep() +{ + PWR_DisallowDeviceToSleep(); +} + +void ContactSensorApp::AppTask::AppMatter_AllowDeviceToSleep() +{ + PWR_AllowDeviceToSleep(); +} +#endif + +ContactSensorApp::AppTask & ContactSensorApp::AppTask::GetDefaultInstance() +{ + static ContactSensorApp::AppTask sAppTask; + return sAppTask; +} + +chip::NXP::App::AppTaskBase & chip::NXP::App::GetAppTask() +{ + return ContactSensorApp::AppTask::GetDefaultInstance(); +} diff --git a/examples/contact-sensor-app/nxp/common/DeviceCallbacks.cpp b/examples/contact-sensor-app/nxp/common/DeviceCallbacks.cpp new file mode 100644 index 00000000000000..8cd301d81f5aa6 --- /dev/null +++ b/examples/contact-sensor-app/nxp/common/DeviceCallbacks.cpp @@ -0,0 +1,69 @@ +/* + * + * 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 + +#include "DeviceCallbacks.h" +#if CONFIG_ENABLE_FEEDBACK +#include "UserInterfaceFeedback.h" +#endif + +#include +#include +#include + +using namespace ::chip; +using namespace ::chip::app::Clusters; + +void logBooleanStateEvent(bool state) +{ + chip::EventNumber eventNumber; + chip::app::Clusters::BooleanState::Events::StateChange::Type event{ state }; + if (CHIP_NO_ERROR != chip::app::LogEvent(event, 1, eventNumber)) + { + ChipLogProgress(Zcl, "booleanstate: failed to reacord state-change event"); + } +} + +void ContactSensorApp::DeviceCallbacks::PostAttributeChangeCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, + chip::AttributeId attributeId, uint8_t type, uint16_t size, + uint8_t * value) +{ + if (clusterId == BooleanState::Id) + { + if (attributeId != BooleanState::Attributes::StateValue::Id) + { + ChipLogProgress(Zcl, "Unknown attribute ID: " ChipLogFormatMEI, ChipLogValueMEI(attributeId)); + return; + } +#if CONFIG_ENABLE_FEEDBACK + FeedbackMgr().RestoreState(); +#endif + logBooleanStateEvent(static_cast(*value)); + } + else + { + ChipLogProgress(Zcl, "Unknown attribute ID: " ChipLogFormatMEI, ChipLogValueMEI(attributeId)); + } +} + +chip::DeviceManager::CHIPDeviceManagerCallbacks & chip::NXP::App::GetDeviceCallbacks() +{ + static ContactSensorApp::DeviceCallbacks sDeviceCallbacks; + return sDeviceCallbacks; +} diff --git a/examples/contact-sensor-app/nxp/common/ZclCallbacks.cpp b/examples/contact-sensor-app/nxp/common/ZclCallbacks.cpp new file mode 100644 index 00000000000000..cbadc5510d27aa --- /dev/null +++ b/examples/contact-sensor-app/nxp/common/ZclCallbacks.cpp @@ -0,0 +1,38 @@ +/* + * + * 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 +#include + +#if CONFIG_ENABLE_FEEDBACK +#include "UserInterfaceFeedback.h" +#endif + +/** @brief BooleanState Cluster Init + * + * This function is called when a specific cluster is initialized. It gives the + * application an opportunity to take care of cluster initialization procedures. + * It is called exactly once for each endpoint where cluster is present. + */ +void emberAfBooleanStateClusterInitCallback(chip::EndpointId endpoint) +{ + ChipLogProgress(Zcl, "emberAfBooleanStateClusterInitCallback\n"); +#if CONFIG_ENABLE_FEEDBACK + FeedbackMgr().RestoreState(); +#endif +} diff --git a/src/platform/nxp/k32w/k32w1/DefaultTestEventTriggerDelegate.cpp b/examples/contact-sensor-app/nxp/common/include/AppEvent.h similarity index 62% rename from src/platform/nxp/k32w/k32w1/DefaultTestEventTriggerDelegate.cpp rename to examples/contact-sensor-app/nxp/common/include/AppEvent.h index 69935bb024559d..b292afaddf8c18 100644 --- a/src/platform/nxp/k32w/k32w1/DefaultTestEventTriggerDelegate.cpp +++ b/examples/contact-sensor-app/nxp/common/include/AppEvent.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2022 Project CHIP Authors + * Copyright (c) 2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,16 +16,12 @@ * limitations under the License. */ -#include "DefaultTestEventTriggerDelegate.h" +#pragma once -#include -#include +struct AppEvent; +typedef void (*EventHandler)(const AppEvent &); -namespace chip { - -bool DefaultTestEventTriggerDelegate::DoesEnableKeyMatch(const ByteSpan & enableKey) const +struct AppEvent { - return !mEnableKey.empty() && mEnableKey.data_equal(enableKey); -} - -} // namespace chip + EventHandler Handler; +}; diff --git a/examples/contact-sensor-app/nxp/common/include/AppTask.h b/examples/contact-sensor-app/nxp/common/include/AppTask.h new file mode 100644 index 00000000000000..69b3ffc8200804 --- /dev/null +++ b/examples/contact-sensor-app/nxp/common/include/AppTask.h @@ -0,0 +1,50 @@ +/* + * + * 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 "AppConfig.h" +#include "AppTaskFreeRTOS.h" + +#include + +namespace ContactSensorApp { + +class AppTask : public chip::NXP::App::AppTaskFreeRTOS +{ +public: + // AppTaskFreeRTOS virtual methods + void PreInitMatterStack() override; +#if CONFIG_LOW_POWER + void AppMatter_DisallowDeviceToSleep() override; + void AppMatter_AllowDeviceToSleep() override; +#endif + + // This returns an instance of this class. + static AppTask & GetDefaultInstance(); +}; + +} // namespace ContactSensorApp + +/** + * 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/contact-sensor-app/nxp/common/include/DeviceCallbacks.h b/examples/contact-sensor-app/nxp/common/include/DeviceCallbacks.h new file mode 100644 index 00000000000000..7234c2b8c74f53 --- /dev/null +++ b/examples/contact-sensor-app/nxp/common/include/DeviceCallbacks.h @@ -0,0 +1,51 @@ +/* + * + * 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. + */ + +/** + * @file DeviceCallbacks.h + * + * Lighting app implementation for the DeviceManager callbacks for all applications + * + **/ + +#pragma once + +#include "CHIPDeviceManager.h" +#include "CommonDeviceCallbacks.h" + +namespace ContactSensorApp { + +class DeviceCallbacks : public chip::NXP::App::CommonDeviceCallbacks +{ +public: + void PostAttributeChangeCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, chip::AttributeId attributeId, + uint8_t type, uint16_t size, uint8_t * value) override; +}; + +} // namespace ContactSensorApp + +namespace chip::NXP::App { +/** + * 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 chip::NXP::App diff --git a/examples/contact-sensor-app/nxp/common/main.cpp b/examples/contact-sensor-app/nxp/common/main.cpp new file mode 100644 index 00000000000000..d9672b5402c867 --- /dev/null +++ b/examples/contact-sensor-app/nxp/common/main.cpp @@ -0,0 +1,39 @@ +/* + * + * 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 "AppTask.h" +#include "FreeRTOS.h" + +#if configAPPLICATION_ALLOCATED_HEAP +uint8_t __attribute__((section(".heap"))) ucHeap[configTOTAL_HEAP_SIZE]; +#endif + +#if FSL_OSA_MAIN_FUNC_ENABLE +extern "C" void main_task(void const * argument) +{ + chip::DeviceLayer::PlatformMgrImpl().HardwareInit(); + chip::NXP::App::GetAppTask().Start(); +} +#else +extern "C" int main(int argc, char * argv[]) +{ + chip::DeviceLayer::PlatformMgrImpl().HardwareInit(); + chip::NXP::App::GetAppTask().Start(); + vTaskStartScheduler(); +} +#endif diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/BUILD.gn b/examples/contact-sensor-app/nxp/k32w/k32w1/BUILD.gn deleted file mode 100644 index f4ccc1ec4d8c39..00000000000000 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/BUILD.gn +++ /dev/null @@ -1,186 +0,0 @@ -# Copyright (c) 2021-2023 Project CHIP Authors -# Copyright (c) 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/chip.gni") -import("//build_overrides/nxp_sdk.gni") -import("//build_overrides/openthread.gni") - -import("${nxp_sdk_build_root}/nxp_sdk.gni") - -import("${nxp_sdk_build_root}/${nxp_sdk_name}/nxp_executable.gni") - -import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") - -import("${chip_root}/src/app/icd/icd.gni") -import("${chip_root}/src/crypto/crypto.gni") -import("${chip_root}/src/lib/core/core.gni") -import("${chip_root}/src/platform/device.gni") -import("${chip_root}/src/platform/nxp/${nxp_platform}/args.gni") - -declare_args() { - chip_software_version = 0 - - # 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") - -k32w1_sdk("sdk") { - sources = [ - "${k32w1_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", - "${k32w1_platform_dir}/app/project_include", - "${k32w1_platform_dir}/app/support", - "${k32w1_platform_dir}/util/include", - ] - - 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}", - ] - } - - 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") { - output_name = "chip-k32w1-contact-example" - - defines = [] - - sources = [ - "${k32w1_platform_dir}/util/LEDWidget.cpp", - "${k32w1_platform_dir}/util/include/LEDWidget.h", - "main/AppTask.cpp", - "main/ContactSensorManager.cpp", - "main/ZclCallbacks.cpp", - "main/include/AppEvent.h", - "main/include/AppTask.h", - "main/include/ContactSensorManager.h", - "main/main.cpp", - ] - - include_dirs = [ "${common_example_dir}/diagnostic_logs" ] - - deps = [ - ":sdk", - "${chip_root}/examples/common/QRCode", - "${chip_root}/examples/providers:device_info_provider", - "${chip_root}/src/lib", - "${chip_root}/src/platform:syscalls_stub", - "${chip_root}/src/platform/logging:default", - "${chip_root}/third_party/mbedtls:mbedtls", - "${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 += [ - "${openthread_root}:libopenthread-cli-ftd", - "${openthread_root}:libopenthread-ftd", - ] - } else { - deps += [ - "${openthread_root}:libopenthread-cli-mtd", - "${openthread_root}:libopenthread-mtd", - ] - } - - #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/" ] - } - - cflags = [ "-Wconversion" ] - - output_dir = root_out_dir - - ldscript = "${k32w1_sdk_root}/middleware/wireless/framework/Common/devices/kw45_k32w1/gcc/connectivity.ld" - - inputs = [ ldscript ] - - ldflags = [ - "-Wl,--defsym=__heap_size__=0", - "-Wl,--defsym=__stack_size__=0x480", - "-Wl,--defsym=lp_ram_lower_limit=0x04000000", - "-Wl,--defsym=lp_ram_upper_limit=0x2001C000", - "-Wl,-print-memory-usage", - "-Wl,--no-warn-rwx-segments", - "-T" + rebase_path(ldscript, root_build_dir), - ] - - if (chip_with_factory_data == 1) { - 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 -} - -group("k32w1") { - deps = [ ":contact_sensor_app" ] -} - -group("default") { - deps = [ ":k32w1" ] -} diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/build_overrides b/examples/contact-sensor-app/nxp/k32w/k32w1/build_overrides deleted file mode 120000 index ad07557834803a..00000000000000 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/build_overrides +++ /dev/null @@ -1 +0,0 @@ -../../../../build_overrides/ \ No newline at end of file diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/main/AppTask.cpp b/examples/contact-sensor-app/nxp/k32w/k32w1/main/AppTask.cpp deleted file mode 100644 index 6f0459178cd173..00000000000000 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/main/AppTask.cpp +++ /dev/null @@ -1,908 +0,0 @@ -/* - * - * Copyright (c) 2022-2023 Project CHIP Authors - * Copyright (c) 2022 Google LLC. - * Copyright (c) 2023 NXP - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "AppTask.h" -#include "AppEvent.h" -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#if CONFIG_DIAG_LOGS_DEMO -#include "DiagnosticLogsProviderDelegateImpl.h" -#endif - -#include -#include -#include -#include - -/* OTA related includes */ -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR -#include "OtaSupport.h" -#include -#include -#include -#include -#include -#endif - -#include - -#include "K32W1PersistentStorageOpKeystore.h" - -#include "LEDWidget.h" -#include "app.h" -#include "app_config.h" -#include "fsl_component_button.h" -#include "fwk_platform.h" - -#define FACTORY_RESET_TRIGGER_TIMEOUT 6000 -#define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 3000 -#define APP_TASK_PRIORITY 2 -#define APP_EVENT_QUEUE_SIZE 10 - -TimerHandle_t sFunctionTimer; // FreeRTOS app sw timer. - -static QueueHandle_t sAppEventQueue; - -#if !defined(chip_with_low_power) || (chip_with_low_power == 0) -/* - * The status LED and the external flash CS pin are wired together. - * The OTA image writing may fail if used together. - */ -#ifndef CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR -static LEDWidget sStatusLED; -#endif -static LEDWidget sContactSensorLED; -#endif - -static bool sIsThreadProvisioned = false; -static bool sHaveBLEConnections = false; -#if CHIP_ENABLE_LIT -static bool sIsDeviceCommissioned = false; -#endif - -static uint32_t eventMask = 0; - -#if CHIP_DEVICE_CONFIG_THREAD_ENABLE_CLI -extern "C" void otPlatUartProcess(void); -#endif - -extern "C" void PWR_DisallowDeviceToSleep(void); -extern "C" void PWR_AllowDeviceToSleep(void); - -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 -static AppTask::FactoryDataProvider sFactoryDataProvider; -#endif - -static Identify gIdentify = { chip::EndpointId{ 1 }, AppTask::OnIdentifyStart, AppTask::OnIdentifyStop, - Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator }; - -/* OTA related variables */ -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR -static DefaultOTARequestor gRequestorCore __attribute__((section(".data"))); -static DefaultOTARequestorStorage gRequestorStorage __attribute__((section(".data"))); -static DeviceLayer::DefaultOTARequestorDriver gRequestorUser __attribute__((section(".data"))); -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 - * should be posted to app task. */ -} - -static void app_gatt_callback(deviceId_t id, gattServerEvent_t * event) -{ - /* This callback is called in the context of BLE task, so event processing - * should be posted to app task. */ -} - -CHIP_ERROR AppTask::StartAppTask() -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - sAppEventQueue = xQueueCreate(APP_EVENT_QUEUE_SIZE, sizeof(AppEvent)); - if (sAppEventQueue == NULL) - { - err = APP_ERROR_EVENT_QUEUE_FAILED; - K32W_LOG("Failed to allocate app event queue"); - assert(err == CHIP_NO_ERROR); - } - - return err; -} - -CHIP_ERROR AppTask::Init() -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - if (ContactSensorMgr().Init() != 0) - { - K32W_LOG("ContactSensorMgr().Init() failed"); - 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); - - // Init ZCL Data Model and start server - PlatformMgr().ScheduleWork(InitServer, 0); - -#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA - ReturnErrorOnFailure(sFactoryDataProvider.Init()); - SetDeviceInstanceInfoProvider(&sFactoryDataProvider); - SetDeviceAttestationCredentialsProvider(&sFactoryDataProvider); - SetCommissionableDataProvider(&sFactoryDataProvider); -#else - SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); -#endif // CONFIG_CHIP_LOAD_REAL_FACTORY_DATA - - // QR code will be used with CHIP Tool - AppTask::PrintOnboardingInfo(); - -#if !defined(chip_with_low_power) || (chip_with_low_power == 0) - /* start with all LEDS turnedd off */ -#ifndef CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - sStatusLED.Init(SYSTEM_STATE_LED, false); -#endif - - sContactSensorLED.Init(CONTACT_SENSOR_STATE_LED, false); - sContactSensorLED.Set(ContactSensorMgr().IsContactClosed()); -#endif - - UpdateDeviceState(); - - /* intialize the Keyboard and button press callback */ - BUTTON_InstallCallback((button_handle_t) g_buttonHandle[0], KBD_Callback, (void *) BLE_BUTTON); - BUTTON_InstallCallback((button_handle_t) g_buttonHandle[1], KBD_Callback, (void *) CONTACT_SENSOR_BUTTON); - - // 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); - } - - ContactSensorMgr().SetCallback(OnStateChanged); - - // 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); - } - - uint32_t currentVersion; - err = ConfigurationMgr().GetSoftwareVersion(currentVersion); - - K32W_LOG("Current Software Version: %s, %d", currentSoftwareVer, currentVersion); - - auto & bleManager = chip::DeviceLayer::Internal::BLEMgrImpl(); - bleManager.RegisterAppCallbacks(app_gap_callback, app_gatt_callback); - - return err; -} - -void LockOpenThreadTask(void) -{ - PWR_DisallowDeviceToSleep(); - chip::DeviceLayer::ThreadStackMgr().LockThreadStack(); -} - -void UnlockOpenThreadTask(void) -{ - chip::DeviceLayer::ThreadStackMgr().UnlockThreadStack(); - PWR_AllowDeviceToSleep(); -} - -void AppTask::InitServer(intptr_t arg) -{ - static chip::CommonCaseDeviceServerInitParams initParams; - (void) initParams.InitializeStaticResourcesBeforeServerInit(); - -#if CHIP_CRYPTO_PLATFORM - static chip::K32W1PersistentStorageOpKeystore sK32W1PersistentStorageOpKeystore; - VerifyOrDie((sK32W1PersistentStorageOpKeystore.Init(initParams.persistentStorageDelegate)) == CHIP_NO_ERROR); - initParams.operationalKeystore = &sK32W1PersistentStorageOpKeystore; -#endif - - // 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); - -#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() -{ - chip::PayloadContents payload; - CHIP_ERROR err = GetPayloadContents(payload, chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); - if (err != CHIP_NO_ERROR) - { - ChipLogError(AppServer, "GetPayloadContents() failed: %" CHIP_ERROR_FORMAT, err.Format()); - } - payload.commissioningFlow = chip::CommissioningFlow::kUserActionRequired; - PrintOnboardingCodes(payload); -} - -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR -void AppTask::InitOTA(intptr_t arg) -{ - // Initialize and interconnect the Requestor and Image Processor objects -- START - SetRequestorInstance(&gRequestorCore); - - gRequestorStorage.Init(chip::Server::GetInstance().GetPersistentStorage()); - gRequestorCore.Init(chip::Server::GetInstance(), gRequestorStorage, gRequestorUser, gDownloader); - gRequestorUser.SetMaxDownloadBlockSize(requestedOtaBlockSize); - auto & imageProcessor = OTAImageProcessorImpl::GetDefaultInstance(); - gRequestorUser.Init(&gRequestorCore, &imageProcessor); - CHIP_ERROR err = imageProcessor.Init(&gDownloader); - if (err != CHIP_NO_ERROR) - { - K32W_LOG("Image processor init failed"); - assert(err == CHIP_NO_ERROR); - } - - // Connect the gDownloader and Image Processor objects - gDownloader.SetImageProcessorDelegate(&imageProcessor); - // Initialize and interconnect the Requestor and Image Processor objects -- END -} -#endif - -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); - -#if defined(chip_with_low_power) && (chip_with_low_power == 1) - xTicksToWait = portMAX_DELAY; -#endif - - 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()) - { -#if CHIP_DEVICE_CONFIG_THREAD_ENABLE_CLI - otPlatUartProcess(); -#endif - - sHaveBLEConnections = (ConnectivityMgr().NumBLEConnections() != 0); - PlatformMgr().UnlockChipStack(); - } - - // Update the status LED if factory reset or identify process have 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 !defined(chip_with_low_power) || (chip_with_low_power == 0) -#ifndef CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - if (sAppTask.mFunction != Function::kFactoryReset && sAppTask.mFunction != Function::kIdentify) - { - if (sIsThreadProvisioned) - { - sStatusLED.Blink(950, 50); - } - else if (sHaveBLEConnections) - { - sStatusLED.Blink(100, 100); - } - else - { - sStatusLED.Blink(50, 950); - } - } - - sStatusLED.Animate(); -#endif - - sContactSensorLED.Animate(); -#endif - } -} - -void AppTask::ButtonEventHandler(uint8_t pin_no, uint8_t button_action) -{ - if ((pin_no != RESET_BUTTON) && (pin_no != CONTACT_SENSOR_BUTTON) && (pin_no != SOFT_RESET_BUTTON) && (pin_no != BLE_BUTTON)) - { - return; - } - - AppEvent button_event; - button_event.Type = AppEvent::kButton; - 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 == CONTACT_SENSOR_BUTTON) - { - button_event.Handler = ContactActionEventHandler; - } - else if (pin_no == SOFT_RESET_BUTTON) - { - // Soft reset ensures that platform manager shutdown procedure is called. - button_event.Handler = SoftResetHandler; - } - else if (pin_no == BLE_BUTTON) - { - button_event.Handler = BleHandler; - - if (button_action == RESET_BUTTON_PUSH) - { - button_event.Handler = ResetActionEventHandler; - } -#if CHIP_ENABLE_LIT - else if (button_action == USER_ACTIVE_MODE_TRIGGER_PUSH) - { - button_event.Handler = UserActiveModeHandler; - } -#endif - } - - sAppTask.PostEvent(&button_event); -} - -button_status_t AppTask::KBD_Callback(void * buttonHandle, button_callback_message_t * message, void * callbackParam) -{ - uint32_t pinNb = (uint32_t) callbackParam; - switch (message->event) - { - case kBUTTON_EventOneClick: - case kBUTTON_EventShortPress: - switch (pinNb) - { - case BLE_BUTTON: - K32W_LOG("pb1 short press"); - if (sAppTask.mResetTimerActive) - { - ButtonEventHandler(BLE_BUTTON, RESET_BUTTON_PUSH); - } -#if CHIP_ENABLE_LIT - else if (sIsDeviceCommissioned) - { - ButtonEventHandler(BLE_BUTTON, USER_ACTIVE_MODE_TRIGGER_PUSH); - } -#endif - else - { - ButtonEventHandler(BLE_BUTTON, BLE_BUTTON_PUSH); - } - break; - - case CONTACT_SENSOR_BUTTON: - K32W_LOG("pb2 short press"); - ButtonEventHandler(CONTACT_SENSOR_BUTTON, CONTACT_SENSOR_BUTTON_PUSH); - break; - } - break; - - case kBUTTON_EventLongPress: - switch (pinNb) - { - case BLE_BUTTON: - K32W_LOG("pb1 long press"); - ButtonEventHandler(BLE_BUTTON, RESET_BUTTON_PUSH); - break; - - case CONTACT_SENSOR_BUTTON: - K32W_LOG("pb2 long press"); - ButtonEventHandler(SOFT_RESET_BUTTON, SOFT_RESET_BUTTON_PUSH); - break; - } - break; - - default: - /* No action required */ - break; - } - return kStatus_BUTTON_Success; -} - -void AppTask::TimerEventHandler(TimerHandle_t xTimer) -{ - AppEvent event; - event.Type = AppEvent::kTimer; - event.TimerEvent.Context = (void *) xTimer; - event.Handler = FunctionTimerEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FunctionTimerEventHandler(void * aGenericEvent) -{ - AppEvent * aEvent = (AppEvent *) aGenericEvent; - - if (aEvent->Type != AppEvent::kTimer) - return; - - K32W_LOG("Device will factory reset..."); - - // Actually trigger Factory Reset - chip::Server::GetInstance().ScheduleFactoryReset(); -} - -void AppTask::ResetActionEventHandler(void * aGenericEvent) -{ - AppEvent * aEvent = (AppEvent *) aGenericEvent; - - if (aEvent->ButtonEvent.PinNo != RESET_BUTTON && aEvent->ButtonEvent.PinNo != BLE_BUTTON) - return; - - if (sAppTask.mResetTimerActive) - { - sAppTask.CancelTimer(); - sAppTask.mFunction = Function::kNoneSelected; - -#if !defined(chip_with_low_power) || (chip_with_low_power == 0) - /* restore initial state for the LED indicating contact state */ - if (!ContactSensorMgr().IsContactClosed()) - { - sContactSensorLED.Set(false); - } - else - { - sContactSensorLED.Set(true); - } -#endif - - K32W_LOG("Factory Reset was cancelled!"); - } - else - { - uint32_t resetTimeout = FACTORY_RESET_TRIGGER_TIMEOUT; - - if (sAppTask.mFunction != Function::kNoneSelected) - { - K32W_LOG("Another function is scheduled. Could not initiate Factory Reset!"); - return; - } - - K32W_LOG("Factory Reset Triggered. Push the RESET button within %lu ms to cancel!", resetTimeout); - sAppTask.mFunction = Function::kFactoryReset; - - /* LEDs will start blinking to signal that a Factory Reset was scheduled */ -#if !defined(chip_with_low_power) || (chip_with_low_power == 0) -#ifndef CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - sStatusLED.Set(false); - sStatusLED.Blink(500); -#endif - sContactSensorLED.Set(false); - sContactSensorLED.Blink(500); -#endif - - sAppTask.StartTimer(FACTORY_RESET_TRIGGER_TIMEOUT); - } -} - -void AppTask::ContactActionEventHandler(void * aGenericEvent) -{ - AppEvent * aEvent = (AppEvent *) aGenericEvent; - ContactSensorManager::Action action = ContactSensorManager::Action::kInvalid; - CHIP_ERROR err = CHIP_NO_ERROR; - bool state_changed = false; - - if (sAppTask.mFunction != Function::kNoneSelected) - { - K32W_LOG("Another function is scheduled. Could not change contact state."); - return; - } - - if (aEvent->Type == AppEvent::kContact) - { - action = static_cast(aEvent->ContactEvent.Action); - } - else if (aEvent->Type == AppEvent::kButton) - { - if (ContactSensorMgr().IsContactClosed()) - { - action = ContactSensorManager::Action::kSignalLost; - } - else - { - action = ContactSensorManager::Action::kSignalDetected; - } - - sAppTask.SetSyncClusterToButtonAction(true); - } - else - { - err = APP_ERROR_UNHANDLED_EVENT; - action = ContactSensorManager::Action::kInvalid; - } - - if (err == CHIP_NO_ERROR) - { - ContactSensorMgr().InitiateAction(action); - } -} - -void AppTask::SoftResetHandler(void * aGenericEvent) -{ - AppEvent * aEvent = (AppEvent *) aGenericEvent; - if (aEvent->ButtonEvent.PinNo != SOFT_RESET_BUTTON) - return; - - PlatformMgrImpl().CleanReset(); -} - -void AppTask::BleHandler(void * aGenericEvent) -{ - AppEvent * aEvent = (AppEvent *) aGenericEvent; - - if (aEvent->ButtonEvent.PinNo != BLE_BUTTON) - return; - - if (sAppTask.mFunction != Function::kNoneSelected) - { - K32W_LOG("Another function is scheduled. Could not toggle BLE state!"); - return; - } - PlatformMgr().ScheduleWork(AppTask::BleStartAdvertising, 0); -} - -void AppTask::BleStartAdvertising(intptr_t arg) -{ - 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"); - } - } -} - -#if CHIP_ENABLE_LIT -void AppTask::UserActiveModeHandler(void * aGenericEvent) -{ - AppEvent * aEvent = (AppEvent *) aGenericEvent; - - if (aEvent->ButtonEvent.PinNo != BLE_BUTTON) - return; - - if (sAppTask.mFunction != Function::kNoneSelected) - { - K32W_LOG("Another function is scheduled. Could not request ICD Active Mode!"); - return; - } - PlatformMgr().ScheduleWork(AppTask::UserActiveModeTrigger, 0); -} - -void AppTask::UserActiveModeTrigger(intptr_t arg) -{ - ICDNotifier::GetInstance().NotifyNetworkActivityNotification(); -} -#endif - -void AppTask::MatterEventHandler(const ChipDeviceEvent * event, intptr_t) -{ - if (event->Type == DeviceEventType::kServiceProvisioningChange && event->ServiceProvisioningChange.IsServiceProvisioned) - { - if (event->ServiceProvisioningChange.IsServiceProvisioned) - { - sIsThreadProvisioned = TRUE; - } - else - { - sIsThreadProvisioned = FALSE; - } - } -#if CHIP_ENABLE_LIT - else if (event->Type == DeviceEventType::kCommissioningComplete) - { - sIsDeviceCommissioned = TRUE; - } -#endif - -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - if (event->Type == DeviceEventType::kDnssdInitialized) - { - K32W_LOG("Dnssd platform initialized."); - PlatformMgr().ScheduleWork(InitOTA, 0); - } -#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::OnStateChanged(ContactSensorManager::State aState) -{ - // If the contact state was changed, update LED state and cluster state (only if button was pressed). - // - turn on the contact LED if contact sensor is in closed state. - // - turn off the lock LED if contact sensor is in opened state. - if (ContactSensorManager::State::kContactClosed == aState) - { - K32W_LOG("Contact state changed to closed.") -#if !defined(chip_with_low_power) || (chip_with_low_power == 0) - sContactSensorLED.Set(true); -#endif - } - else if (ContactSensorManager::State::kContactOpened == aState) - { - K32W_LOG("Contact state changed to opened.") -#if !defined(chip_with_low_power) || (chip_with_low_power == 0) - sContactSensorLED.Set(false); -#endif - } - - if (sAppTask.IsSyncClusterToButtonAction()) - { - sAppTask.UpdateClusterState(); - } - - sAppTask.mFunction = Function::kNoneSelected; -} - -void AppTask::OnIdentifyStart(Identify * identify) -{ - if (Clusters::Identify::EffectIdentifierEnum::kBlink == identify->mCurrentEffectIdentifier) - { - if (Function::kNoneSelected != sAppTask.mFunction) - { - K32W_LOG("Another function is scheduled. Could not initiate Identify process!"); - return; - } - K32W_LOG("Identify process has started. Status LED should blink every 0.5 seconds."); - sAppTask.mFunction = Function::kIdentify; -#if !defined(chip_with_low_power) || (chip_with_low_power == 0) -#ifndef CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - sStatusLED.Set(false); - sStatusLED.Blink(500); -#endif -#endif - } -} - -void AppTask::OnIdentifyStop(Identify * identify) -{ - if (Clusters::Identify::EffectIdentifierEnum::kBlink == identify->mCurrentEffectIdentifier) - { - K32W_LOG("Identify process has stopped."); - sAppTask.mFunction = Function::kNoneSelected; - } -} - -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; - event.Type = AppEvent::kContact; - event.ContactEvent.Action = static_cast(aAction); - event.Handler = ContactActionEventHandler; - PostEvent(&event); -} - -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 defined(chip_with_low_power) && (chip_with_low_power == 1) - /* specific processing for events sent from App_PostCallbackMessage (see main.cpp) */ - if (aEvent->Type == AppEvent::kEventType_Lp) - { - aEvent->Handler(aEvent->param); - } - else -#endif - - if (aEvent->Handler) - { - aEvent->Handler(aEvent); - } - else - { - K32W_LOG("Event received with no handler. Dropping event."); - } -} - -void AppTask::UpdateClusterState(void) -{ - PlatformMgr().ScheduleWork(UpdateClusterStateInternal, 0); -} -extern void logBooleanStateEvent(bool state); -void AppTask::UpdateClusterStateInternal(intptr_t arg) -{ - uint8_t newValue = ContactSensorMgr().IsContactClosed(); - - // write the new on/off value - Protocols::InteractionModel::Status status = app::Clusters::BooleanState::Attributes::StateValue::Set(1, newValue); - - if (status != Protocols::InteractionModel::Status::Success) - { - ChipLogError(NotSpecified, "ERR: updating boolean status value %x", to_underlying(status)); - } - logBooleanStateEvent(newValue); -} - -void AppTask::UpdateDeviceState(void) -{ - PlatformMgr().ScheduleWork(UpdateDeviceStateInternal, 0); -} - -void AppTask::UpdateDeviceStateInternal(intptr_t arg) -{ - bool stateValueAttrValue = 0; - - /* get onoff attribute value */ - (void) app::Clusters::BooleanState::Attributes::StateValue::Get(1, &stateValueAttrValue); - -#if !defined(chip_with_low_power) || (chip_with_low_power == 0) - /* set the device state */ - sContactSensorLED.Set(stateValueAttrValue); -#endif -} - -extern "C" void OTAIdleActivities(void) -{ -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - OTA_TransactionResume(); -#endif -} diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/main/ContactSensorManager.cpp b/examples/contact-sensor-app/nxp/k32w/k32w1/main/ContactSensorManager.cpp deleted file mode 100644 index 9e0a665cbb5aa9..00000000000000 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/main/ContactSensorManager.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * - * Copyright (c) 2022-2023 Project CHIP Authors - * Copyright (c) 2022 Google LLC. - * Copyright (c) 2023 NXP - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ContactSensorManager.h" - -#include "AppTask.h" -#include "FreeRTOS.h" - -#include "app_config.h" - -ContactSensorManager ContactSensorManager::sContactSensor; - -int ContactSensorManager::Init() -{ - int err = 0; - - mState = State::kContactOpened; - mCallbackStateChanged = nullptr; - - return err; -} - -void ContactSensorManager::SetCallback(CallbackStateChanged aCallbackStateChanged) -{ - mCallbackStateChanged = aCallbackStateChanged; -} - -bool ContactSensorManager::IsContactClosed() -{ - return mState == State::kContactClosed; -} - -void ContactSensorManager::InitiateAction(Action aAction) -{ - AppEvent event; - event.Type = AppEvent::kContact; - event.ContactEvent.Action = static_cast(aAction); - event.Handler = HandleAction; - GetAppTask().PostEvent(&event); -} - -void ContactSensorManager::HandleAction(void * aGenericEvent) -{ - AppEvent * event = static_cast(aGenericEvent); - Action action = static_cast(event->ContactEvent.Action); - // Change current state based on action: - // - if state is closed and action is signal lost, change state to opened - // - if state is opened and action is signal detected, change state to closed - // - else, the state/action combination does not change the state. - if (State::kContactClosed == sContactSensor.mState && Action::kSignalLost == action) - { - sContactSensor.mState = State::kContactOpened; - } - else if (State::kContactOpened == sContactSensor.mState && Action::kSignalDetected == action) - { - sContactSensor.mState = State::kContactClosed; - } - - if (sContactSensor.mCallbackStateChanged != nullptr) - { - sContactSensor.mCallbackStateChanged(sContactSensor.mState); - } - else - { - K32W_LOG("Callback for state change was not set. Please set an appropriate callback."); - } -} diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/main/ZclCallbacks.cpp b/examples/contact-sensor-app/nxp/k32w/k32w1/main/ZclCallbacks.cpp deleted file mode 100644 index e69daab9803d23..00000000000000 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/main/ZclCallbacks.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - * - * Copyright (c) 2022-2023 Project CHIP Authors - * Copyright (c) 2023 NXP - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include "AppTask.h" -#include "ContactSensorManager.h" - -#include -#include -#include -#include -#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) -{ - ChipLogProgress(Zcl, "MatterPostAttributeChangeCallback, value:%d\n", *value); - if (path.mClusterId != BooleanState::Id) - { - ChipLogProgress(Zcl, "Unknown cluster ID: " ChipLogFormatMEI, ChipLogValueMEI(path.mClusterId)); - return; - } - - if (path.mAttributeId != BooleanState::Attributes::StateValue::Id) - { - ChipLogProgress(Zcl, "Unknown attribute ID: " ChipLogFormatMEI, ChipLogValueMEI(path.mAttributeId)); - return; - } - - AppTask & task = GetAppTask(); - // If the callback is called after the cluster attribute was changed due to pressing a button, - // set the sync value to false. Both LED and attribute were updated at this point. - // On the other hand, if the cluster attribute was changed due to a cluster command, - // forward the request to AppTask in order to update the LED state. - if (task.IsSyncClusterToButtonAction()) - { - task.SetSyncClusterToButtonAction(false); - } - else - { - task.PostContactActionRequest(*value ? ContactSensorManager::Action::kSignalDetected - : ContactSensorManager::Action::kSignalLost); - } -} - -/** @brief OnOff Cluster Init - * - * This function is called when a specific cluster is initialized. It gives the - * application an opportunity to take care of cluster initialization procedures. - * It is called exactly once for each endpoint where cluster is present. - * - * @param endpoint Ver.: always - * - * TODO Issue #3841 - * emberAfOnOffClusterInitCallback happens before the stack initialize the cluster - * attributes to the default value. - * The logic here expects something similar to the deprecated Plugins callback - * emberAfPluginOnOffClusterServerPostInitCallback. - * - */ -void emberAfBooleanStateClusterInitCallback(EndpointId endpoint) -{ - ChipLogProgress(Zcl, "emberAfBooleanStateClusterInitCallback\n"); - GetAppTask().UpdateClusterState(); -} - -void logBooleanStateEvent(bool state) -{ - EventNumber eventNumber; - Events::StateChange::Type event{ state }; - if (CHIP_NO_ERROR != LogEvent(event, 1, eventNumber)) - { - 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/AppEvent.h b/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/AppEvent.h deleted file mode 100644 index f3e0d729abe2e7..00000000000000 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/AppEvent.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * - * Copyright (c) 2022 Nest Labs, Inc. - * Copyright (c) 2023 NXP - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -struct AppEvent; -typedef void (*EventHandler)(void *); - -struct AppEvent -{ - enum AppEventTypes - { - kButton = 0, - kTimer, - kContact, - kInstall, -#if defined(chip_with_low_power) && (chip_with_low_power == 1) - kEventType_Lp, -#endif - kOTAResume, - }; - - AppEventTypes Type; - - union - { - struct - { - uint8_t PinNo; - uint8_t Action; - } ButtonEvent; - struct - { - void * Context; - } TimerEvent; - struct - { - uint8_t Action; - } ContactEvent; - }; - - EventHandler Handler; - -#if defined(chip_with_low_power) && (chip_with_low_power == 1) - void * param; -#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 deleted file mode 100644 index 64842e310561b2..00000000000000 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/AppTask.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * - * Copyright (c) 2022 Google LLC. - * Copyright (c) 2023 NXP - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include - -#include "AppEvent.h" -#include "ContactSensorManager.h" - -#include "CHIPProjectConfig.h" - -#include -#include - -#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA -#include -#endif - -#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. -#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) -#define APP_ERROR_PM_REGISTER_LP_CALLBACK_FAILED CHIP_APPLICATION_ERROR(0x07) - -class AppTask -{ -public: -#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA - using FactoryDataProvider = chip::DeviceLayer::FactoryDataProviderImpl; -#endif - CHIP_ERROR StartAppTask(); - static void AppTaskMain(void * pvParameter); - - void PostContactActionRequest(ContactSensorManager::Action aAction); - void PostEvent(const AppEvent * event); - - void UpdateClusterState(void); - void UpdateDeviceState(void); - - bool IsSyncClusterToButtonAction(); - void SetSyncClusterToButtonAction(bool value); - // Identify cluster callbacks. - 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); - - CHIP_ERROR Init(); - - static void OnStateChanged(ContactSensorManager::State aState); - - void CancelTimer(void); - - void DispatchEvent(AppEvent * event); - - static void FunctionTimerEventHandler(void * aGenericEvent); - static button_status_t KBD_Callback(void * buttonHandle, button_callback_message_t * message, void * callbackParam); - static void HandleKeyboard(void); - static void SoftResetHandler(void * aGenericEvent); - static void BleHandler(void * aGenericEvent); - static void BleStartAdvertising(intptr_t arg); - static void ContactActionEventHandler(void * aGenericEvent); - static void ResetActionEventHandler(void * aGenericEvent); - static void InstallEventHandler(void * aGenericEvent); -#if CHIP_ENABLE_LIT - static void UserActiveModeHandler(void * aGenericEvent); - static void UserActiveModeTrigger(intptr_t arg); -#endif - - 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); - - void StartTimer(uint32_t aTimeoutInMs); - -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - static void InitOTA(intptr_t arg); -#endif - - static void UpdateClusterStateInternal(intptr_t arg); - static void UpdateDeviceStateInternal(intptr_t arg); - static void InitServer(intptr_t arg); - static void PrintOnboardingInfo(); - - enum class Function : uint8_t - { - kNoneSelected = 0, - kFactoryReset, - kContact, - kIdentify, - kInvalid - }; - - Function mFunction = Function::kNoneSelected; - bool mResetTimerActive = false; - bool mSyncClusterToButtonAction = false; - - static AppTask sAppTask; -}; - -inline AppTask & GetAppTask(void) -{ - return AppTask::sAppTask; -} - -inline bool AppTask::IsSyncClusterToButtonAction() -{ - return mSyncClusterToButtonAction; -} - -inline void AppTask::SetSyncClusterToButtonAction(bool value) -{ - mSyncClusterToButtonAction = value; -} diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/ContactSensorManager.h b/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/ContactSensorManager.h deleted file mode 100644 index 69a71ee14ee344..00000000000000 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/ContactSensorManager.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * Copyright (c) 2022 Google LLC. - * Copyright (c) 2023 NXP - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include - -#include "AppEvent.h" - -#include "FreeRTOS.h" -#include "timers.h" // provides FreeRTOS timer support - -class ContactSensorManager -{ -public: - enum class Action : uint8_t - { - kSignalDetected = 0, - kSignalLost, - kInvalid - }; - - enum class State : uint8_t - { - kContactClosed = 0, - kContactOpened, - kInvalid - }; - - int Init(); - bool IsContactClosed(); - void InitiateAction(Action aAction); - - typedef void (*CallbackStateChanged)(State aState); - void SetCallback(CallbackStateChanged aCallbackStateChanged); - - static void HandleAction(void * aGenericEvent); - -private: - friend ContactSensorManager & ContactSensorMgr(void); - State mState; - CallbackStateChanged mCallbackStateChanged; - static ContactSensorManager sContactSensor; -}; - -inline ContactSensorManager & ContactSensorMgr(void) -{ - return ContactSensorManager::sContactSensor; -} diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/app_config.h b/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/app_config.h deleted file mode 100644 index 7001f636dbd0d7..00000000000000 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/app_config.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * Copyright (c) 2022 Google LLC. - * Copyright (c) 2023 NXP - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -// ---- Contact Example App Config ---- - -#define RESET_BUTTON 1 -#define CONTACT_SENSOR_BUTTON 2 -#define SOFT_RESET_BUTTON 3 -#define BLE_BUTTON 4 - -#define RESET_BUTTON_PUSH 1 -#define CONTACT_SENSOR_BUTTON_PUSH 2 -#define SOFT_RESET_BUTTON_PUSH 3 -#define BLE_BUTTON_PUSH 4 -#define USER_ACTIVE_MODE_TRIGGER_PUSH 5 - -#define APP_BUTTON_PUSH 1 - -#define CONTACT_SENSOR_STATE_LED 1 -#define SYSTEM_STATE_LED 0 - -// ---- Contact 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/contact-sensor-app/nxp/k32w/k32w1/main/main.cpp b/examples/contact-sensor-app/nxp/k32w/k32w1/main/main.cpp deleted file mode 100644 index 700bbc5ad9356c..00000000000000 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/main/main.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * - * Copyright (c) 2022 Google LLC. - * Copyright (c) 2023 NXP - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// ================================================================================ -// Main Code -// ================================================================================ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "FreeRtosHooks.h" -#include "app_config.h" -#include "openthread/platform/logging.h" - -using namespace ::chip; -using namespace ::chip::Inet; -using namespace ::chip::DeviceLayer; -using namespace ::chip::Logging; - -#include - -typedef void (*InitFunc)(void); -extern InitFunc __init_array_start; -extern InitFunc __init_array_end; - -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; - } - - /* Used for HW initializations */ - otSysInit(0, NULL); - - if (err != CHIP_NO_ERROR) - { - return; - } - - K32W_LOG("Welcome to NXP Contact Sensor 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(); - - err = PlatformMgr().InitChipStack(); - if (err != CHIP_NO_ERROR) - { - K32W_LOG("Error during PlatformMgr().InitMatterStack()"); - goto exit; - } - - err = ThreadStackMgr().InitThreadStack(); - if (err != CHIP_NO_ERROR) - { - K32W_LOG("Error during ThreadStackMgr().InitThreadStack()"); - goto exit; - } - - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); - if (err != CHIP_NO_ERROR) - { - goto exit; - } - - // Start OpenThread task - err = ThreadStackMgrImpl().StartThreadTask(); - if (err != CHIP_NO_ERROR) - { - K32W_LOG("Error during ThreadStackMgrImpl().StartThreadTask()"); - goto exit; - } - - err = GetAppTask().StartAppTask(); - if (err != CHIP_NO_ERROR) - { - K32W_LOG("Error during GetAppTask().StartAppTask()"); - goto exit; - } - - err = PlatformMgr().StartEventLoopTask(); - if (err != 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) -{ - BaseType_t yieldRequired = ThreadStackMgrImpl().SignalThreadActivityPendingFromISR(); - portYIELD_FROM_ISR(yieldRequired); -} diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/third_party/connectedhomeip b/examples/contact-sensor-app/nxp/k32w/k32w1/third_party/connectedhomeip deleted file mode 120000 index 305f2077ffe860..00000000000000 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/third_party/connectedhomeip +++ /dev/null @@ -1 +0,0 @@ -../../../../../.. \ No newline at end of file diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/.gn b/examples/contact-sensor-app/nxp/k32w1/.gn similarity index 93% rename from examples/contact-sensor-app/nxp/k32w/k32w1/.gn rename to examples/contact-sensor-app/nxp/k32w1/.gn index 1e848295f6aa5b..885f306753076d 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/.gn +++ b/examples/contact-sensor-app/nxp/k32w1/.gn @@ -28,5 +28,5 @@ default_args = { import("//args.gni") # Import default platform configs - import("${chip_root}/src/platform/nxp/k32w/k32w1/args.gni") + import("${chip_root}/src/platform/nxp/k32w1/args.gni") } diff --git a/examples/contact-sensor-app/nxp/k32w1/BUILD.gn b/examples/contact-sensor-app/nxp/k32w1/BUILD.gn new file mode 100644 index 00000000000000..119dc5cf722eac --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w1/BUILD.gn @@ -0,0 +1,261 @@ +# Copyright (c) 2021-2023 Project CHIP Authors +# Copyright (c) 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/chip.gni") +import("//build_overrides/nxp_sdk.gni") +import("//build_overrides/openthread.gni") + +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +import("${nxp_sdk_build_root}/${nxp_sdk_name}/nxp_executable.gni") + +import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") + +import("${chip_root}/src/app/icd/icd.gni") +import("${chip_root}/src/crypto/crypto.gni") +import("${chip_root}/src/platform/device.gni") +import("${chip_root}/src/platform/nxp/${nxp_platform}/args.gni") + +declare_args() { + # Setup discriminator as argument + setup_discriminator = 3840 + chip_with_diag_logs_demo = true +} + +assert(current_os == "freertos") +assert(target_os == "freertos") + +example_platform_dir = "${chip_root}/examples/platform/nxp/${nxp_platform}" +common_example_dir = "${chip_root}/examples/platform/nxp/common" + +k32w1_sdk("sdk") { + defines = [] + include_dirs = [] + sources = [] + + # 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" ] + + include_dirs += [ + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1", + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/K32W1480", + ] + + sources += [ + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/K32W1480/clock_config.c", + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/K32W1480/pin_mux.c", + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/app_services_init.c", + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board.c", + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_comp.c", + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_dcdc.c", + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_extflash.c", + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_lp.c", + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/hardware_init.c", + ] + + if (is_debug) { + defines += [ "BUILD_RELEASE=0" ] + } else { + defines += [ "BUILD_RELEASE=1" ] + } + + defines += [ + "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setup_discriminator}", + ] + + if (chip_key_storage == "littlefs") { + include_dirs += [ "${example_platform_dir}/board" ] + sources += [ + "${example_platform_dir}/board/peripherals.c", + "${example_platform_dir}/board/peripherals.h", + ] + } +} + +k32w1_executable("contact_sensor_app") { + output_name = "chip-k32w1-contact-example" + + defines = [] + deps = [] + include_dirs = [] + sources = [] + + # Defines used by common code + defines += [ + "CONFIG_NET_L2_OPENTHREAD=1", + "CONFIG_NETWORK_LAYER_BLE=1", + "CONFIG_THREAD_DEVICE_TYPE=kThreadDeviceType_SleepyEndDevice", + "CONFIG_OPERATIONAL_KEYSTORE=1", + "EXTERNAL_FACTORY_DATA_PROVIDER_HEADER=\"platform/nxp/common/legacy/FactoryDataProvider.h\"", + ] + + if (chip_with_diag_logs_demo) { + defines += [ "CONFIG_DIAG_LOGS_DEMO=1" ] + } + + if (chip_with_low_power == 1) { + defines += [ "CONFIG_LOW_POWER=1" ] + } else { + defines += [ + "CONFIG_ENABLE_FEEDBACK=1", + "APP_QUEUE_TICKS_TO_WAIT=pdMS_TO_TICKS(10)", + ] + } + + # App common files + include_dirs += [ + "${common_example_dir}/app_task/include", + "${common_example_dir}/matter_button/include", + "${common_example_dir}/clusters/include", + "${common_example_dir}/device_callbacks/include", + "${common_example_dir}/device_manager/include", + "${common_example_dir}/diagnostic_logs/include", + "${common_example_dir}/factory_data/include", + "${common_example_dir}/led_widget/include", + "${common_example_dir}/low_power/include", + "${common_example_dir}/operational_keystore/include", + "${common_example_dir}/ui_feedback/include", + ] + + sources += [ + "${common_example_dir}/app_task/source/AppTaskBase.cpp", + "${common_example_dir}/app_task/source/AppTaskFreeRTOS.cpp", + "${common_example_dir}/clusters/source/ZclCallbacks.cpp", + "${common_example_dir}/device_callbacks/source/CommonDeviceCallbacks.cpp", + "${common_example_dir}/device_manager/source/CHIPDeviceManager.cpp", + "${example_platform_dir}/factory_data/source/AppFactoryDataExample.cpp", + ] + + if (chip_with_low_power == 1) { + sources += [ "${common_example_dir}/low_power/source/LowPower.cpp" ] + } + + if (chip_with_factory_data == 1) { + include_dirs += [ "${chip_root}/src/platform/nxp/common/legacy" ] + deps += [ "${chip_root}/src/platform/nxp:nxp_factory_data" ] + } + + if (chip_enable_ota_requestor) { + defines += [ + "CONFIG_CHIP_OTA_IMAGE_PROCESSOR_HEADER=\"platform/nxp/common/legacy/OTAImageProcessorImpl.h\"", + + # The status LED and the external flash CS pin are wired together. The OTA image writing may fail if used together. + "LED_MANAGER_ENABLE_STATUS_LED=0", + ] + + include_dirs += [ "${common_example_dir}/ota_requestor/include" ] + sources += [ "${common_example_dir}/ota_requestor/source/OTARequestorInitiatorMultiImage.cpp" ] + deps += [ "${chip_root}/src/platform/nxp:nxp_ota" ] + } + + if (chip_with_diag_logs_demo) { + sources += [ + "${common_example_dir}/diagnostic_logs/source/DiagnosticLogsDemo.cpp", + "${common_example_dir}/diagnostic_logs/source/DiagnosticLogsProviderDelegateImpl.cpp", + ] + } + + # Platform specific files + include_dirs += [ + "${example_platform_dir}/util", + "${example_platform_dir}/app/support", + "${example_platform_dir}/button", + ] + + sources += [ + "${example_platform_dir}/button/ButtonManager.cpp", + "${example_platform_dir}/clusters/Identify.cpp", + "${example_platform_dir}/operational_keystore/OperationalKeystore.cpp", + ] + + if (chip_enable_ota_requestor) { + sources += [ "${example_platform_dir}/ota/OtaUtils.cpp" ] + } + + include_dirs += [ + "include/config", + "../common/include", + ] + + sources += [ + "../common/AppTask.cpp", + "../common/DeviceCallbacks.cpp", + "../common/ZclCallbacks.cpp", + "../common/main.cpp", + ] + + if (chip_with_low_power == 0) { + sources += [ + "${common_example_dir}/ui_feedback/source/LedManager.cpp", + "${example_platform_dir}/util/LedOnOff.cpp", + ] + } + + deps += [ + "${chip_root}/examples/providers:device_info_provider", + "${chip_root}/src/platform/logging:default", + ] + + #lit and sit are using different zap files + if (chip_enable_icd_lit) { + deps += [ "${chip_root}/examples/contact-sensor-app/nxp/zap-lit/" ] + } else { + deps += [ "${chip_root}/examples/contact-sensor-app/nxp/zap-sit/" ] + } + + if (chip_openthread_ftd) { + deps += [ + "${openthread_root}:libopenthread-cli-ftd", + "${openthread_root}:libopenthread-ftd", + ] + } else { + deps += [ + "${openthread_root}:libopenthread-cli-mtd", + "${openthread_root}:libopenthread-mtd", + ] + } + + cflags = [ "-Wconversion" ] + + ldscript = "${k32w1_sdk_root}/middleware/wireless/framework/Common/devices/kw45_k32w1/gcc/connectivity.ld" + + inputs = [ ldscript ] + + ldflags = [ + "-Wl,--defsym=__heap_size__=0", + "-Wl,--defsym=__stack_size__=0x480", + "-Wl,--defsym=lp_ram_lower_limit=0x04000000", + "-Wl,--defsym=lp_ram_upper_limit=0x2001C000", + "-Wl,-print-memory-usage", + "-Wl,--no-warn-rwx-segments", + "-T" + rebase_path(ldscript, root_build_dir), + ] + + if (chip_with_factory_data == 1) { + ldflags += [ "-Wl,--defsym=gUseFactoryData_d=1" ] + } + + output_dir = root_out_dir +} + +group("default") { + deps = [ ":contact_sensor_app" ] +} diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/README.md b/examples/contact-sensor-app/nxp/k32w1/README.md similarity index 83% rename from examples/contact-sensor-app/nxp/k32w/k32w1/README.md rename to examples/contact-sensor-app/nxp/k32w1/README.md index f3896a01b8362e..7a70f746f6e445 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/README.md +++ b/examples/contact-sensor-app/nxp/k32w1/README.md @@ -14,29 +14,29 @@ into an existing Matter network and can be controlled by this network.
- [Matter K32W1 Contact Sensor Example Application](#matter-k32w1-contact-sensor-example-application) -- [Introduction](#introduction) - - [Bluetooth LE Advertising](#bluetooth-le-advertising) - - [Bluetooth LE Rendezvous](#bluetooth-le-rendezvous) -- [Device UI](#device-ui) -- [Building](#building) -- [Long Idle Time ICD Support](#long-idle-time-icd-support) -- [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) -- [Low power](#low-power) - - + - [Introduction](#introduction) + - [Bluetooth LE Advertising](#bluetooth-le-advertising) + - [Bluetooth LE Rendezvous](#bluetooth-le-rendezvous) + - [Thread Provisioning](#thread-provisioning) + - [Device UI](#device-ui) + - [Building](#building) + - [Long Idle Time ICD Support](#long-idle-time-icd-support) + - [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) + - [OTA factory data](#ota-factory-data) + - [Running OTA](#running-ota) + - [Low power](#low-power) + - [Known issues](#known-issues) ## Introduction -![K32W1 EVK](../../../../platform/nxp/k32w/k32w1/doc/images/k32w1-evk.jpg) +![K32W1 EVK](../../../platform/nxp/k32w1/doc/images/k32w1-evk.jpg) The K32W1 contact sensor example application provides a working demonstration of a connected contact sensor device, built using the Matter codebase and the NXP @@ -118,23 +118,50 @@ Matter shutdown procedure. ## Building -In order to build the Matter example, we recommend using a Linux distribution -(the demo-application was compiled on Ubuntu 20.04). +In order to build the Project CHIP example, we recommend using a Linux +distribution. Supported Operating Systems and prerequisites are listed in +[BUILDING](../../../../docs/guides/BUILDING.md). -- Download [K32W1 SDK for Matter](https://mcuxpresso.nxp.com/). 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 K32W1 SDK. - The SDK Builder UI selection should be similar with the one from the image - below. - ![MCUXpresso SDK Download](../../../../platform/nxp/k32w/k32w1/doc/images/mcux-sdk-download.jpg) +- Make sure that below prerequisites are correctly installed + +``` +sudo apt-get install git gcc g++ pkg-config libssl-dev libdbus-1-dev \ + libglib2.0-dev libavahi-client-dev ninja-build python3-venv python3-dev \ + python3-pip unzip libgirepository1.0-dev libcairo2-dev libreadline-dev +``` + +- Step 1: checkout NXP specific submodules only ``` -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 -user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w/k32w1$ ninja -C out/debug +``` + +- Step 2: activate local environment + +``` +user@ubuntu:~/Desktop/git/connectedhomeip$ source scripts/activate.sh +``` + +If the script says the environment is out of date, you can update it by running +the following command: + +``` +user@ubuntu:~/Desktop/git/connectedhomeip$ source scripts/bootstrap.sh +``` + +- Step 3: Init NXP SDK(s) + +``` +user@ubuntu:~/Desktop/git/connectedhomeip$ scripts/setup/nxp/update_nxp_sdk.py --platform common_sdk +``` + +Note: By default setup/nxp/update_nxp_sdk.py will try to initialize all NXP +SDKs. Arg "-- help" could be used to view all available options. + +``` +user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/contact-sensor-app/nxp/k32w1 +user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w1$ gn gen out/debug +user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w1$ ninja -C out/debug ``` In case that Openthread CLI is needed, chip_with_ot_cli build argument must be @@ -185,7 +212,7 @@ using Fibonacci backoff for retries pacing. Use `chip_with_factory_data=1` in the gn build command to enable factory data. For a full guide on manufacturing flow, please see -[Guide for writing manufacturing data on NXP devices](../../../../../docs/guides/nxp/nxp_manufacturing_flow.md). +[Guide for writing manufacturing data on NXP devices](../../../../docs/guides/nxp/nxp_manufacturing_flow.md). ## Flashing @@ -248,7 +275,7 @@ One option for debugging would be to use MCUXpresso IDE. - Drag-and-drop the zip file containing the NXP SDK in the "Installed SDKs" tab: -![Installed SDKs](../../../../platform/nxp/k32w/k32w1/doc/images/installed_sdks.jpg) +![Installed SDKs](../../../platform/nxp/k32w1/doc/images/installed_sdks.jpg) - Import any demo application from the installed SDK: @@ -256,7 +283,7 @@ One option for debugging would be to use MCUXpresso IDE. Import SDK example(s).. -> choose a demo app (demo_apps -> hello_world) -> Finish ``` -![Import demo](../../../../platform/nxp/k32w/k32w1/doc/images/import_demo.jpg) +![Import demo](../../../platform/nxp/k32w1/doc/images/import_demo.jpg) - Flash the previously imported demo application on the board: @@ -275,7 +302,7 @@ resulted after ot-nxp compilation. File -> Import -> C/C++ -> Existing Code as Makefile Project ``` -![New Project](../../../../platform/nxp/k32w/k32w1/doc/images/new_project.jpg) +![New Project](../../../platform/nxp/k32w1/doc/images/new_project.jpg) - Replace the path of the existing demo application with the path of the K32W1 application: @@ -284,7 +311,7 @@ File -> Import -> C/C++ -> Existing Code as Makefile Project Run -> Debug Configurations... -> C/C++ Application ``` -![Debug K32W1](../../../../platform/nxp/k32w/k32w1/doc/images/debug_k32w1.jpg) +![Debug K32W1](../../../platform/nxp/k32w1/doc/images/debug_k32w1.jpg) ## OTA @@ -312,16 +339,21 @@ In `OTAP` application In order to build an OTA image, use NXP wrapper over the standard tool `src/app/ota_image_tool.py`: -- `scripts/tools/nxp/factory_data_generator/ota_image_tool.py` The tool can be - used to generate an OTA image with the following format: - `| OTA image header | TLV1 | TLV2 | ... | TLVn |` where each TLV is in the - form `|tag|length|value|` +- `scripts/tools/nxp/factory_data_generator/ota_image_tool.py`. + +The tool can be used to generate an OTA image with the following format: + +``` + | OTA image header | TLV1 | TLV2 | ... | TLVn | +``` + +where each TLV is in the form `|tag|length|value|`. Note that "standard" TLV format is used. Matter TLV format is only used for factory data TLV value. Please see more in the -[OTA image tool guide](../../../../../scripts/tools/nxp/ota/README.md). +[OTA image tool guide](../../../../scripts/tools/nxp/ota/README.md). Here is an example that generates an OTA image with application update TLV from a `sb3` file: @@ -338,12 +370,24 @@ having a correct OTA process, the OTA header version should be the same as the binary embedded software version. A user can set a custom software version in the gn build args by setting `chip_software_version` to the wanted version. +### OTA factory data + +A user can update the factory data through OTA, at the same time the application +firmware is updated by enabling the following processor in the `gn args`: + +- `chip_enable_ota_factory_data_processor=1` to enable default factory data + update processor (disabled by default). + +The OTA image used must be updated to include the new factory data. + +[OTA image tool guide](../../../../scripts/tools/nxp/ota/README.md). + ### Running OTA The OTA topology used for OTA testing is illustrated in the figure below. Topology is similar with the one used for Matter Test Events. -![OTA_TOPOLOGY](../../../../platform/nxp/k32w/k32w1/doc/images/ota_topology.JPG) +![OTA_TOPOLOGY](../../../platform/nxp/k32w1/doc/images/ota_topology.JPG) The concept for OTA is the next one: diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/args.gni b/examples/contact-sensor-app/nxp/k32w1/args.gni similarity index 84% rename from examples/contact-sensor-app/nxp/k32w/k32w1/args.gni rename to examples/contact-sensor-app/nxp/k32w1/args.gni index 23e6730b79045c..cb952c94bd74d1 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/args.gni +++ b/examples/contact-sensor-app/nxp/k32w1/args.gni @@ -17,12 +17,17 @@ import("//build_overrides/chip.gni") import("${chip_root}/config/standalone/args.gni") # SDK target. This is overridden to add our SDK app_config.h & defines. -k32w1_sdk_target = get_label_info(":sdk", "label_no_toolchain") +nxp_sdk_target = get_label_info(":sdk", "label_no_toolchain") +nxp_device = "K32W1480" chip_enable_ota_requestor = true chip_stack_lock_tracking = "fatal" chip_enable_ble = true +chip_system_config_provide_statistics = false +chip_system_config_use_open_thread_inet_endpoints = true +chip_with_lwip = false + chip_enable_icd_server = true chip_enable_icd_lit = false icd_enforce_sit_slow_poll_limit = true diff --git a/examples/contact-sensor-app/nxp/k32w1/build_overrides b/examples/contact-sensor-app/nxp/k32w1/build_overrides new file mode 120000 index 00000000000000..ee19c065d619a2 --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w1/build_overrides @@ -0,0 +1 @@ +../../../build_overrides/ \ No newline at end of file diff --git a/examples/contact-sensor-app/nxp/k32w1/include/config/AppConfig.h b/examples/contact-sensor-app/nxp/k32w1/include/config/AppConfig.h new file mode 100644 index 00000000000000..0c8019d8e7e33c --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w1/include/config/AppConfig.h @@ -0,0 +1,29 @@ +/* + * Copyright 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 + +/* ---- App Config ---- */ +#define APP_DEVICE_TYPE_ENDPOINT 1 +#define APP_CLUSTER_ATTRIBUTE chip::app::Clusters::BooleanState::Attributes::StateValue + +/* ---- Button Manager Config ---- */ +#define BUTTON_MANAGER_FACTORY_RESET_TIMEOUT_MS 6000 + +/* ---- LED Manager Config ---- */ +#define LED_MANAGER_STATUS_LED_INDEX 0 +#define LED_MANAGER_LIGHT_LED_INDEX 1 diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h b/examples/contact-sensor-app/nxp/k32w1/include/config/CHIPProjectConfig.h similarity index 98% rename from examples/contact-sensor-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h rename to examples/contact-sensor-app/nxp/k32w1/include/config/CHIPProjectConfig.h index 0d9a4e3b503bee..a16c1bb8b3341c 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h +++ b/examples/contact-sensor-app/nxp/k32w1/include/config/CHIPProjectConfig.h @@ -192,6 +192,13 @@ #define CHIP_DEVICE_CONFIG_ENABLE_SED 1 +/** + * @def CHIP_DEVICE_CONFIG_KVS_WEAR_STATS + * + * @brief Toggle support for key value store wear stats on or off. + */ +#define CHIP_DEVICE_CONFIG_KVS_WEAR_STATS 1 + /** * @def CHIP_IM_MAX_NUM_COMMAND_HANDLER * diff --git a/examples/contact-sensor-app/nxp/k32w1/third_party/connectedhomeip b/examples/contact-sensor-app/nxp/k32w1/third_party/connectedhomeip new file mode 120000 index 00000000000000..59307833b4fee9 --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w1/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../.. \ No newline at end of file diff --git a/examples/lighting-app/nxp/common/AppTask.cpp b/examples/lighting-app/nxp/common/AppTask.cpp new file mode 100644 index 00000000000000..6bca4669760c2a --- /dev/null +++ b/examples/lighting-app/nxp/common/AppTask.cpp @@ -0,0 +1,37 @@ +/* + * + * 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 "AppTask.h" + +#include + +void LightingApp::AppTask::PreInitMatterStack() +{ + ChipLogProgress(DeviceLayer, "Welcome to NXP Lighting Demo App"); +} + +LightingApp::AppTask & LightingApp::AppTask::GetDefaultInstance() +{ + static LightingApp::AppTask sAppTask; + return sAppTask; +} + +chip::NXP::App::AppTaskBase & chip::NXP::App::GetAppTask() +{ + return LightingApp::AppTask::GetDefaultInstance(); +} diff --git a/examples/lighting-app/nxp/k32w/k32w1/main/ZclCallbacks.cpp b/examples/lighting-app/nxp/common/DeviceCallbacks.cpp similarity index 51% rename from examples/lighting-app/nxp/k32w/k32w1/main/ZclCallbacks.cpp rename to examples/lighting-app/nxp/common/DeviceCallbacks.cpp index 97a3fb9aa72a98..140cdffb9febe2 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/main/ZclCallbacks.cpp +++ b/examples/lighting-app/nxp/common/DeviceCallbacks.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,59 +18,72 @@ #include -#include "AppTask.h" -#include "LightingManager.h" +#include "DeviceCallbacks.h" +#if CONFIG_ENABLE_FEEDBACK +#include "UserInterfaceFeedback.h" +#endif #include #include -#include -#include using namespace ::chip; using namespace ::chip::app::Clusters; -void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & path, uint8_t type, uint16_t size, uint8_t * value) +void LightingApp::DeviceCallbacks::PostAttributeChangeCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, + chip::AttributeId attributeId, uint8_t type, uint16_t size, + uint8_t * value) { - if (path.mClusterId == OnOff::Id) + if (clusterId == OnOff::Id) { - if (path.mAttributeId != OnOff::Attributes::OnOff::Id) + if (attributeId != OnOff::Attributes::OnOff::Id) { - ChipLogProgress(Zcl, "Unknown attribute ID: " ChipLogFormatMEI, ChipLogValueMEI(path.mAttributeId)); + ChipLogProgress(Zcl, "Unknown attribute ID: " ChipLogFormatMEI, ChipLogValueMEI(attributeId)); return; } - - LightingMgr().InitiateAction(0, *value ? LightingManager::TURNON_ACTION : LightingManager::TURNOFF_ACTION, *value); +#if CONFIG_ENABLE_FEEDBACK + FeedbackMgr().RestoreState(); +#endif } - else if (path.mClusterId == LevelControl::Id) + else if (clusterId == LevelControl::Id) { - if (path.mAttributeId != LevelControl::Attributes::CurrentLevel::Id) + if (attributeId != LevelControl::Attributes::CurrentLevel::Id) { - ChipLogProgress(Zcl, "Unknown attribute ID: " ChipLogFormatMEI, ChipLogValueMEI(path.mAttributeId)); + ChipLogProgress(Zcl, "Unknown attribute ID: " ChipLogFormatMEI, ChipLogValueMEI(attributeId)); return; } - +#if LIGHTING_MANAGER_ENABLE_DIMMABLE_LED if (*value > 1 && *value < 254) { ChipLogProgress(Zcl, "Setting value: %d", *value); - LightingMgr().InitiateAction(0, LightingManager::DIM_ACTION, *value); + // The cluster attribute value will be read in RestoreState and the proper action will be taken: e.g. ApplyDim. +#if CONFIG_ENABLE_FEEDBACK + FeedbackMgr().RestoreState(); +#endif } +#endif } - else if (path.mClusterId == ColorControl::Id) + else if (clusterId == ColorControl::Id) { ChipLogProgress(Zcl, "Color Control attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u", - ChipLogValueMEI(path.mAttributeId), type, *value, size); + ChipLogValueMEI(attributeId), type, *value, size); // WIP Apply attribute change to Light } - else if (path.mClusterId == OnOffSwitchConfiguration::Id) + else if (clusterId == OnOffSwitchConfiguration::Id) { ChipLogProgress(Zcl, "OnOff Switch Configuration attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u", - ChipLogValueMEI(path.mAttributeId), type, *value, size); + ChipLogValueMEI(attributeId), type, *value, size); // WIP Apply attribute change to Light } else { - ChipLogProgress(Zcl, "Unknown attribute ID: " ChipLogFormatMEI, ChipLogValueMEI(path.mAttributeId)); + ChipLogProgress(Zcl, "Unknown attribute ID: " ChipLogFormatMEI, ChipLogValueMEI(attributeId)); } } + +chip::DeviceManager::CHIPDeviceManagerCallbacks & chip::NXP::App::GetDeviceCallbacks() +{ + static LightingApp::DeviceCallbacks sDeviceCallbacks; + return sDeviceCallbacks; +} diff --git a/src/platform/nxp/k32w/k32w1/DefaultTestEventTriggerDelegate.h b/examples/lighting-app/nxp/common/include/AppEvent.h similarity index 60% rename from src/platform/nxp/k32w/k32w1/DefaultTestEventTriggerDelegate.h rename to examples/lighting-app/nxp/common/include/AppEvent.h index 0bfd4c5b0fa725..b292afaddf8c18 100644 --- a/src/platform/nxp/k32w/k32w1/DefaultTestEventTriggerDelegate.h +++ b/examples/lighting-app/nxp/common/include/AppEvent.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2022 Project CHIP Authors + * Copyright (c) 2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,19 +18,10 @@ #pragma once -#include +struct AppEvent; +typedef void (*EventHandler)(const AppEvent &); -namespace chip { - -class DefaultTestEventTriggerDelegate : public TestEventTriggerDelegate +struct AppEvent { -public: - explicit DefaultTestEventTriggerDelegate(const ByteSpan & enableKey) : mEnableKey(enableKey) {} - - bool DoesEnableKeyMatch(const ByteSpan & enableKey) const override; - -private: - ByteSpan mEnableKey; + EventHandler Handler; }; - -} // namespace chip diff --git a/examples/lighting-app/nxp/common/include/AppTask.h b/examples/lighting-app/nxp/common/include/AppTask.h new file mode 100644 index 00000000000000..9f73d340f35957 --- /dev/null +++ b/examples/lighting-app/nxp/common/include/AppTask.h @@ -0,0 +1,46 @@ +/* + * + * 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 "AppConfig.h" +#include "AppTaskFreeRTOS.h" + +#include + +namespace LightingApp { + +class AppTask : public chip::NXP::App::AppTaskFreeRTOS +{ +public: + // AppTaskFreeRTOS virtual methods + void PreInitMatterStack() override; + + // This returns an instance of this class. + static AppTask & GetDefaultInstance(); +}; + +} // namespace LightingApp + +/** + * 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/lighting-app/nxp/common/include/DeviceCallbacks.h b/examples/lighting-app/nxp/common/include/DeviceCallbacks.h new file mode 100644 index 00000000000000..555021b36ebb16 --- /dev/null +++ b/examples/lighting-app/nxp/common/include/DeviceCallbacks.h @@ -0,0 +1,51 @@ +/* + * + * 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. + */ + +/** + * @file DeviceCallbacks.h + * + * Lighting app implementation for the DeviceManager callbacks for all applications + * + **/ + +#pragma once + +#include "CHIPDeviceManager.h" +#include "CommonDeviceCallbacks.h" + +namespace LightingApp { + +class DeviceCallbacks : public chip::NXP::App::CommonDeviceCallbacks +{ +public: + void PostAttributeChangeCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, chip::AttributeId attributeId, + uint8_t type, uint16_t size, uint8_t * value) override; +}; + +} // namespace LightingApp + +namespace chip::NXP::App { +/** + * 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 chip::NXP::App diff --git a/examples/lighting-app/nxp/common/main.cpp b/examples/lighting-app/nxp/common/main.cpp new file mode 100644 index 00000000000000..d9672b5402c867 --- /dev/null +++ b/examples/lighting-app/nxp/common/main.cpp @@ -0,0 +1,39 @@ +/* + * + * 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 "AppTask.h" +#include "FreeRTOS.h" + +#if configAPPLICATION_ALLOCATED_HEAP +uint8_t __attribute__((section(".heap"))) ucHeap[configTOTAL_HEAP_SIZE]; +#endif + +#if FSL_OSA_MAIN_FUNC_ENABLE +extern "C" void main_task(void const * argument) +{ + chip::DeviceLayer::PlatformMgrImpl().HardwareInit(); + chip::NXP::App::GetAppTask().Start(); +} +#else +extern "C" int main(int argc, char * argv[]) +{ + chip::DeviceLayer::PlatformMgrImpl().HardwareInit(); + chip::NXP::App::GetAppTask().Start(); + vTaskStartScheduler(); +} +#endif diff --git a/examples/lighting-app/nxp/k32w/k32w1/BUILD.gn b/examples/lighting-app/nxp/k32w/k32w1/BUILD.gn deleted file mode 100644 index dd40445e0e7b79..00000000000000 --- a/examples/lighting-app/nxp/k32w/k32w1/BUILD.gn +++ /dev/null @@ -1,196 +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/nxp_sdk.gni") -import("//build_overrides/openthread.gni") -import("${nxp_sdk_build_root}/nxp_sdk.gni") - -import("${nxp_sdk_build_root}/${nxp_sdk_name}/nxp_executable.gni") - -import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") - -import("${chip_root}/src/crypto/crypto.gni") -import("${chip_root}/src/lib/core/core.gni") -import("${chip_root}/src/platform/device.gni") -import("${chip_root}/src/platform/nxp/${nxp_platform}/args.gni") - -import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni") - -if (chip_enable_pw_rpc) { - import("//build_overrides/pigweed.gni") - import("$dir_pw_build/target_types.gni") - import("${chip_root}/examples/platform/nxp/pw_rpc_server.gni") -} - -declare_args() { - chip_software_version = 0 - - # Setup discriminator as argument - setup_discriminator = 3840 -} - -assert(current_os == "freertos") - -k32w1_platform_dir = "${chip_root}/examples/platform/nxp/k32w/k32w1" -k32w1_sdk_root = getenv("NXP_K32W1_SDK_ROOT") - -k32w1_sdk("sdk") { - sources = [ - "${k32w1_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", - "${k32w1_platform_dir}/app/project_include", - "${k32w1_platform_dir}/app/support", - "${k32w1_platform_dir}/app/ldscripts", - "${k32w1_platform_dir}/util/include", - ] - - 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}", - ] - } - - if (chip_enable_pw_rpc) { - defines += [ - "PW_RPC_ENABLED", - "STREAMER_UART_FLUSH_DELAY_MS=0", - "STREAMER_UART_SERIAL_MANAGER_RING_BUFFER_SIZE=512", - "BOARD_APP_UART_CLK_FREQ=96000000", - ] - } - - defines += [ - "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setup_discriminator}", - ] -} - -k32w1_executable("light_app") { - output_name = "chip-k32w1-light-example" - - 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, "*") - } else { - cflags = [ "-Wconversion" ] - } - - sources += [ - "${k32w1_platform_dir}/util/LEDWidget.cpp", - "${k32w1_platform_dir}/util/include/LEDWidget.h", - "main/AppTask.cpp", - "main/LightingManager.cpp", - "main/ZclCallbacks.cpp", - "main/include/AppEvent.h", - "main/include/AppTask.h", - "main/include/LightingManager.h", - "main/main.cpp", - ] - - 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/providers:device_info_provider", - "${chip_root}/src/lib", - "${chip_root}/src/platform:syscalls_stub", - "${chip_root}/src/platform/logging:default", - "${chip_root}/third_party/mbedtls:mbedtls", - "${k32w1_platform_dir}/app/support:freertos_mbedtls_utils", - ] - - if (chip_openthread_ftd) { - deps += [ - "${openthread_root}:libopenthread-cli-ftd", - "${openthread_root}:libopenthread-ftd", - ] - } else { - deps += [ - "${openthread_root}:libopenthread-cli-mtd", - "${openthread_root}:libopenthread-mtd", - ] - } - - if (use_smu2_static) { - ldscript = "${k32w1_platform_dir}/app/ldscripts/k32w1_app.ld" - base_ldscript_dir = "${k32w1_sdk_root}/middleware/wireless/framework/Common/devices/kw45_k32w1/gcc" - } else { - ldscript = "${k32w1_sdk_root}/middleware/wireless/framework/Common/devices/kw45_k32w1/gcc/connectivity.ld" - } - - inputs = [ ldscript ] - - ldflags = [ - "-Wl,--defsym=__heap_size__=0", - "-Wl,--defsym=__stack_size__=0x480", - "-Wl,--defsym=gUseFactoryData_d=1", - "-Wl,-print-memory-usage", - "-Wl,--no-warn-rwx-segments", - "-T" + rebase_path(ldscript, root_build_dir), - ] - - if (chip_with_factory_data == 1) { - ldflags += [ "-Wl,--defsym=gUseFactoryData_d=1" ] - } - - if (use_smu2_static) { - ldflags += [ "-L" + rebase_path(base_ldscript_dir, root_build_dir) ] - } - - output_dir = root_out_dir -} - -group("k32w1") { - deps = [ ":light_app" ] -} - -group("default") { - deps = [ ":k32w1" ] -} diff --git a/examples/lighting-app/nxp/k32w/k32w1/build_overrides b/examples/lighting-app/nxp/k32w/k32w1/build_overrides deleted file mode 120000 index ad07557834803a..00000000000000 --- a/examples/lighting-app/nxp/k32w/k32w1/build_overrides +++ /dev/null @@ -1 +0,0 @@ -../../../../build_overrides/ \ No newline at end of file diff --git a/examples/lighting-app/nxp/k32w/k32w1/include/FreeRTOSConfig.h b/examples/lighting-app/nxp/k32w/k32w1/include/FreeRTOSConfig.h deleted file mode 100644 index 95279e6337a7f7..00000000000000 --- a/examples/lighting-app/nxp/k32w/k32w1/include/FreeRTOSConfig.h +++ /dev/null @@ -1,181 +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 -/* Ensure stdint is only used by the compiler, and not the assembler. */ -#if defined(__ICCARM__) || defined(__ARMCC_VERSION) || defined(__GNUC__) -#include -extern uint32_t SystemCoreClock; -#endif -#define configCPU_CLOCK_HZ (SystemCoreClock) -#define configTICK_RATE_HZ ((TickType_t) 100) -#define configMAX_PRIORITIES (8) -// idle task stack size needs to be increased for OTA EEPROM processing -#define configMINIMAL_STACK_SIZE ((unsigned short) 450) -#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 -#define configUSE_TIME_SLICING 0 -#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 1 -#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 (360) - -/* 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)) - -#ifndef configENABLE_FPU -#define configENABLE_FPU 0 -#endif -#ifndef configENABLE_MPU -#define configENABLE_MPU 0 -#endif -#ifndef configENABLE_TRUSTZONE -#define configENABLE_TRUSTZONE 0 -#endif -#ifndef configRUN_FREERTOS_SECURE_ONLY -#define configRUN_FREERTOS_SECURE_ONLY 1 -#endif - -/* 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/lighting-app/nxp/k32w/k32w1/main/AppTask.cpp b/examples/lighting-app/nxp/k32w/k32w1/main/AppTask.cpp deleted file mode 100644 index 4c1d0875470ee4..00000000000000 --- a/examples/lighting-app/nxp/k32w/k32w1/main/AppTask.cpp +++ /dev/null @@ -1,932 +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 -#if defined(USE_SMU2_DYNAMIC) -#include -#endif - -#include -#include -#include -#include - -/* OTA related includes */ -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR -#include "OtaSupport.h" -#include -#include -#include -#include -#include -#endif - -#include "K32W1PersistentStorageOpKeystore.h" - -#include "LEDWidget.h" -#include "app.h" -#include "app_config.h" -#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 -#define APP_EVENT_QUEUE_SIZE 10 - -TimerHandle_t sFunctionTimer; // FreeRTOS app sw timer. - -static QueueHandle_t sAppEventQueue; - -/* - * The status LED and the external flash CS pin are wired together. - * The OTA image writing may fail if used together. - */ -#ifndef CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR -static LEDWidget sStatusLED; -#endif -static LEDWidget sLightLED; - -static bool sIsThreadProvisioned = false; -#ifndef CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR -static bool sHaveFullConnectivity = false; -#endif -static bool sHaveBLEConnections = false; - -#if CHIP_DEVICE_CONFIG_THREAD_ENABLE_CLI -extern "C" void otPlatUartProcess(void); -#endif - -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; -using namespace chip; -using namespace chip::app; - -AppTask AppTask::sAppTask; -#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA -static AppTask::FactoryDataProvider sFactoryDataProvider; -#endif - -// This key is for testing/certification only and should not be used in production devices. -// For production devices this key must be provided from factory data. -uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; - -static Identify gIdentify = { chip::EndpointId{ 1 }, AppTask::OnIdentifyStart, AppTask::OnIdentifyStop, - Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator, AppTask::OnTriggerEffect, - // Use invalid value for identifiers to enable TriggerEffect command - // to stop Identify command for each effect - Clusters::Identify::EffectIdentifierEnum::kUnknownEnumValue, - Clusters::Identify::EffectVariantEnum::kDefault }; - -/* OTA related variables */ -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR -static DefaultOTARequestor gRequestorCore; -static DefaultOTARequestorStorage gRequestorStorage; -static DeviceLayer::DefaultOTARequestorDriver gRequestorUser; -static BDXDownloader gDownloader; - -constexpr uint16_t requestedOtaBlockSize = 1024; -#endif - -CHIP_ERROR AppTask::StartAppTask() -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - sAppEventQueue = xQueueCreate(APP_EVENT_QUEUE_SIZE, sizeof(AppEvent)); - if (sAppEventQueue == NULL) - { - err = APP_ERROR_EVENT_QUEUE_FAILED; - K32W_LOG("Failed to allocate app event queue"); - assert(err == CHIP_NO_ERROR); - } - - return err; -} - -CHIP_ERROR AppTask::Init() -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - PlatformMgr().AddEventHandler(MatterEventHandler, 0); - - // Init ZCL Data Model and start server - PlatformMgr().ScheduleWork(InitServer, 0); - -#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA - ReturnErrorOnFailure(sFactoryDataProvider.Init()); - SetDeviceInstanceInfoProvider(&sFactoryDataProvider); - SetDeviceAttestationCredentialsProvider(&sFactoryDataProvider); - SetCommissionableDataProvider(&sFactoryDataProvider); -#else - SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); -#endif // CONFIG_CHIP_LOAD_REAL_FACTORY_DATA - - // QR code will be used with CHIP Tool - AppTask::PrintOnboardingInfo(); - - if (LightingMgr().Init() != 0) - { - K32W_LOG("LightingMgr().Init() failed"); - assert(0); - } - - LightingMgr().SetCallbacks(ActionInitiated, ActionCompleted); - - /* start with all LEDS turnedd off */ -#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 */ - BUTTON_InstallCallback((button_handle_t) g_buttonHandle[0], KBD_Callback, (void *) BLE_BUTTON); - BUTTON_InstallCallback((button_handle_t) g_buttonHandle[1], KBD_Callback, (void *) LIGHT_BUTTON); - - // 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); - } - - uint32_t currentVersion; - err = ConfigurationMgr().GetSoftwareVersion(currentVersion); - - K32W_LOG("Current Software Version: %s, %d", currentSoftwareVer, currentVersion); - - 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(); - -#if CHIP_CRYPTO_PLATFORM - static chip::K32W1PersistentStorageOpKeystore sK32W1PersistentStorageOpKeystore; - VerifyOrDie((sK32W1PersistentStorageOpKeystore.Init(initParams.persistentStorageDelegate)) == CHIP_NO_ERROR); - initParams.operationalKeystore = &sK32W1PersistentStorageOpKeystore; -#endif - -#if defined(USE_SMU2_DYNAMIC) - VerifyOrDie(SMU2::Init() == CHIP_NO_ERROR); -#endif - - // Init ZCL Data Model and start server - static DefaultTestEventTriggerDelegate sTestEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; - initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate; - chip::Inet::EndPointStateOpenThread::OpenThreadEndpointInitParam nativeParams; - nativeParams.lockCb = LockOpenThreadTask; - nativeParams.unlockCb = UnlockOpenThreadTask; - nativeParams.openThreadInstancePtr = chip::DeviceLayer::ThreadStackMgrImpl().OTInstance(); - initParams.endpointNativeParams = static_cast(&nativeParams); - VerifyOrDie((chip::Server::GetInstance().Init(initParams)) == CHIP_NO_ERROR); -} - -void AppTask::PrintOnboardingInfo() -{ - chip::PayloadContents payload; - CHIP_ERROR err = GetPayloadContents(payload, chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); - if (err != CHIP_NO_ERROR) - { - ChipLogError(AppServer, "GetPayloadContents() failed: %" CHIP_ERROR_FORMAT, err.Format()); - } - payload.commissioningFlow = chip::CommissioningFlow::kUserActionRequired; - PrintOnboardingCodes(payload); -} - -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR -void AppTask::InitOTA(intptr_t arg) -{ - // Initialize and interconnect the Requestor and Image Processor objects -- START - SetRequestorInstance(&gRequestorCore); - - gRequestorStorage.Init(chip::Server::GetInstance().GetPersistentStorage()); - gRequestorCore.Init(chip::Server::GetInstance(), gRequestorStorage, gRequestorUser, gDownloader); - gRequestorUser.SetMaxDownloadBlockSize(requestedOtaBlockSize); - auto & imageProcessor = OTAImageProcessorImpl::GetDefaultInstance(); - gRequestorUser.Init(&gRequestorCore, &imageProcessor); - CHIP_ERROR err = imageProcessor.Init(&gDownloader); - if (err != CHIP_NO_ERROR) - { - K32W_LOG("Image processor init failed"); - assert(err == CHIP_NO_ERROR); - } - - // Connect the gDownloader and Image Processor objects - gDownloader.SetImageProcessorDelegate(&imageProcessor); - // Initialize and interconnect the Requestor and Image Processor objects -- END -} -#endif - -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) - { - BaseType_t eventReceived = xQueueReceive(sAppEventQueue, &event, pdMS_TO_TICKS(10)); - 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()) - { -#if CHIP_DEVICE_CONFIG_THREAD_ENABLE_CLI - otPlatUartProcess(); -#endif - - sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); - sHaveBLEConnections = (ConnectivityMgr().NumBLEConnections() != 0); - PlatformMgr().UnlockChipStack(); - } - - // Update the status LED if factory reset or identify process have 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) - { -#ifndef CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - if (sHaveFullConnectivity) - { - sStatusLED.Set(true); - } - else if (sIsThreadProvisioned) - { - sStatusLED.Blink(950, 50); - } - else if (sHaveBLEConnections) - { - sStatusLED.Blink(100, 100); - } - else - { - sStatusLED.Blink(50, 950); - } -#endif - } - -#ifndef CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - sStatusLED.Animate(); -#endif - sLightLED.Animate(); - } -} - -void AppTask::ButtonEventHandler(uint8_t pin_no, uint8_t button_action) -{ - if ((pin_no != RESET_BUTTON) && (pin_no != LIGHT_BUTTON) && (pin_no != SOFT_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 == LIGHT_BUTTON) - { - button_event.Handler = LightActionEventHandler; - } - else if (pin_no == SOFT_RESET_BUTTON) - { - // Soft reset ensures that platform manager shutdown procedure is called. - button_event.Handler = SoftResetHandler; - } - else if (pin_no == BLE_BUTTON) - { - button_event.Handler = BleHandler; - - if (button_action == RESET_BUTTON_PUSH) - { - button_event.Handler = ResetActionEventHandler; - } - } - sAppTask.PostEvent(&button_event); -} - -button_status_t AppTask::KBD_Callback(void * buttonHandle, button_callback_message_t * message, void * callbackParam) -{ - uint32_t pinNb = (uint32_t) callbackParam; - switch (message->event) - { - case kBUTTON_EventOneClick: - case kBUTTON_EventShortPress: - switch (pinNb) - { - case BLE_BUTTON: - // K32W_LOG("pb1 short press"); - if (sAppTask.mResetTimerActive) - { - ButtonEventHandler(BLE_BUTTON, RESET_BUTTON_PUSH); - } - else - { - ButtonEventHandler(BLE_BUTTON, BLE_BUTTON_PUSH); - } - break; - - case LIGHT_BUTTON: - // K32W_LOG("pb2 short press"); - ButtonEventHandler(LIGHT_BUTTON, LIGHT_BUTTON_PUSH); - break; - } - break; - - case kBUTTON_EventLongPress: - switch (pinNb) - { - case BLE_BUTTON: - // K32W_LOG("pb1 long press"); - ButtonEventHandler(BLE_BUTTON, RESET_BUTTON_PUSH); - break; - - case LIGHT_BUTTON: - // K32W_LOG("pb2 long press"); - ButtonEventHandler(SOFT_RESET_BUTTON, SOFT_RESET_BUTTON_PUSH); - break; - } - break; - - default: - /* No action required */ - break; - } - return kStatus_BUTTON_Success; -} - -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; - - RestoreLightingState(); - - K32W_LOG("Factory Reset was cancelled!"); - } - else - { - uint32_t resetTimeout = FACTORY_RESET_TRIGGER_TIMEOUT; - - 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 %lu ms to cancel!", resetTimeout); - sAppTask.mFunction = kFunction_FactoryReset; - - /* LEDs will start blinking to signal that a Factory Reset was scheduled */ -#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); -#endif - sLightLED.Blink(500); - - sAppTask.StartTimer(FACTORY_RESET_TRIGGER_TIMEOUT); - } -} - -void AppTask::LightActionEventHandler(AppEvent * aEvent) -{ - LightingManager::Action_t action; - CHIP_ERROR err = CHIP_NO_ERROR; - int32_t actor = 0; - bool initiated = false; - - if (sAppTask.mFunction != kFunction_NoneSelected) - { - K32W_LOG("Another function is scheduled. Could not initiate ON/OFF Light command!"); - return; - } - - if (aEvent->Type == AppEvent::kEventType_TurnOn) - { - action = static_cast(aEvent->LightEvent.Action); - actor = aEvent->LightEvent.Actor; - } - else if (aEvent->Type == AppEvent::kEventType_Button) - { - actor = AppEvent::kEventType_Button; - - if (LightingMgr().IsTurnedOff()) - { - action = LightingManager::TURNON_ACTION; - } - else - { - action = LightingManager::TURNOFF_ACTION; - } - } - else - { - err = APP_ERROR_UNHANDLED_EVENT; - action = LightingManager::INVALID_ACTION; - } - - if (err == CHIP_NO_ERROR) - { - initiated = LightingMgr().InitiateAction(actor, action, LightingMgr().IsTurnedOff() ? 0 : 1); - - if (!initiated) - { - K32W_LOG("Action is already in progress or active."); - } - } -} - -void AppTask::SoftResetHandler(AppEvent * aEvent) -{ - if (aEvent->ButtonEvent.PinNo != SOFT_RESET_BUTTON) - return; - - PlatformMgrImpl().CleanReset(); -} - -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; - } - PlatformMgr().ScheduleWork(AppTask::BleStartAdvertising, 0); -} - -void AppTask::BleStartAdvertising(intptr_t arg) -{ - 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::MatterEventHandler(const ChipDeviceEvent * event, intptr_t) -{ -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - if (event->Type == DeviceEventType::kDnssdInitialized) - { - K32W_LOG("Dnssd platform initialized."); - PlatformMgr().ScheduleWork(InitOTA, 0); - } -#else - if (event->Type == DeviceEventType::kDnssdInitialized) - { - sHaveFullConnectivity = TRUE; - } -#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::ActionInitiated(LightingManager::Action_t aAction, int32_t aActor) -{ - // start flashing the LEDs rapidly to indicate action initiation. - if (aAction == LightingManager::TURNON_ACTION) - { - K32W_LOG("Turn on Action has been initiated") - } - else if (aAction == LightingManager::TURNOFF_ACTION) - { - 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) - { - sAppTask.mSyncClusterToButtonAction = true; - } - - sAppTask.mFunction = kFunctionTurnOnTurnOff; -} - -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) - { - sAppTask.UpdateClusterState(); - sAppTask.mSyncClusterToButtonAction = false; - } - - sAppTask.mFunction = kFunction_NoneSelected; -} - -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()) - { - sLightLED.Set(false); - } - else - { - sLightLED.Set(true); - } -#endif -} - -void AppTask::OnIdentifyStart(Identify * identify) -{ - if ((kFunction_NoneSelected != sAppTask.mFunction) && (kFunction_TriggerEffect != sAppTask.mFunction)) - { - K32W_LOG("Another function is scheduled. Could not initiate Identify process!"); - return; - } - - if (kFunction_TriggerEffect == sAppTask.mFunction) - { - chip::DeviceLayer::SystemLayer().CancelTimer(OnTriggerEffectComplete, identify); - OnTriggerEffectComplete(&chip::DeviceLayer::SystemLayer(), 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); -} - -void AppTask::OnIdentifyStop(Identify * identify) -{ - if (kFunction_Identify == sAppTask.mFunction) - { - ChipLogProgress(Zcl, "Identify process has stopped."); - sAppTask.mFunction = kFunction_NoneSelected; - - RestoreLightingState(); - } -} - -void AppTask::OnTriggerEffectComplete(chip::System::Layer * systemLayer, void * appState) -{ - // Let Identify command take over if called during TriggerEffect already running - if (kFunction_TriggerEffect == sAppTask.mFunction) - { - ChipLogProgress(Zcl, "TriggerEffect has stopped."); - sAppTask.mFunction = kFunction_NoneSelected; - - // TriggerEffect finished - reset identifiers - // Use invalid value for identifiers to enable TriggerEffect command - // to stop Identify command for each effect - gIdentify.mCurrentEffectIdentifier = Clusters::Identify::EffectIdentifierEnum::kUnknownEnumValue; - gIdentify.mTargetEffectIdentifier = Clusters::Identify::EffectIdentifierEnum::kUnknownEnumValue; - gIdentify.mEffectVariant = Clusters::Identify::EffectVariantEnum::kDefault; - - RestoreLightingState(); - } -} - -void AppTask::OnTriggerEffect(Identify * identify) -{ - // Allow overlapping TriggerEffect calls - if ((kFunction_NoneSelected != sAppTask.mFunction) && (kFunction_TriggerEffect != sAppTask.mFunction)) - { - K32W_LOG("Another function is scheduled. Could not initiate Identify process!"); - return; - } - - sAppTask.mFunction = kFunction_TriggerEffect; - uint16_t timerDelay = 0; - - ChipLogProgress(Zcl, "TriggerEffect has started."); - - switch (identify->mCurrentEffectIdentifier) - { - case Clusters::Identify::EffectIdentifierEnum::kBlink: - timerDelay = 2; - break; - - case Clusters::Identify::EffectIdentifierEnum::kBreathe: - timerDelay = 15; - break; - - case Clusters::Identify::EffectIdentifierEnum::kOkay: - timerDelay = 4; - break; - - case Clusters::Identify::EffectIdentifierEnum::kChannelChange: - ChipLogProgress(Zcl, "Channel Change effect not supported, using effect %d", - to_underlying(Clusters::Identify::EffectIdentifierEnum::kBlink)); - timerDelay = 2; - break; - - case Clusters::Identify::EffectIdentifierEnum::kFinishEffect: - chip::DeviceLayer::SystemLayer().CancelTimer(OnTriggerEffectComplete, identify); - timerDelay = 1; - break; - - case Clusters::Identify::EffectIdentifierEnum::kStopEffect: - chip::DeviceLayer::SystemLayer().CancelTimer(OnTriggerEffectComplete, identify); - OnTriggerEffectComplete(&chip::DeviceLayer::SystemLayer(), identify); - break; - - default: - ChipLogProgress(Zcl, "Invalid effect identifier."); - } - - 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); - } -} - -void AppTask::PostTurnOnActionRequest(int32_t aActor, LightingManager::Action_t aAction) -{ - AppEvent event; - event.Type = AppEvent::kEventType_TurnOn; - event.LightEvent.Actor = aActor; - event.LightEvent.Action = aAction; - event.Handler = LightActionEventHandler; - PostEvent(&event); -} - -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"); - } - - portYIELD_FROM_ISR(taskToWake); - } - else - { - if (!xQueueSend(sAppEventQueue, aEvent, 1)) - { - 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."); - } -} - -void AppTask::UpdateClusterState(void) -{ - PlatformMgr().ScheduleWork(UpdateClusterStateInternal, 0); -} - -void AppTask::UpdateClusterStateInternal(intptr_t arg) -{ - uint8_t newValue = !LightingMgr().IsTurnedOff(); - - // write the new on/off value - Protocols::InteractionModel::Status status = app::Clusters::OnOff::Attributes::OnOff::Set(1, newValue); - if (status != Protocols::InteractionModel::Status::Success) - { - ChipLogError(NotSpecified, "ERR: updating on/off %x", to_underlying(status)); - } -} - -void AppTask::UpdateDeviceState(void) -{ - PlatformMgr().ScheduleWork(UpdateDeviceStateInternal, 0); -} - -void AppTask::UpdateDeviceStateInternal(intptr_t arg) -{ - bool onoffAttrValue = 0; - - /* get onoff attribute value */ - (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); -} - -extern "C" void OTAIdleActivities(void) -{ -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - OTA_TransactionResume(); -#endif -} diff --git a/examples/lighting-app/nxp/k32w/k32w1/main/LightingManager.cpp b/examples/lighting-app/nxp/k32w/k32w1/main/LightingManager.cpp deleted file mode 100644 index 2627138043bbe4..00000000000000 --- a/examples/lighting-app/nxp/k32w/k32w1/main/LightingManager.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - * - * Copyright (c) 2021 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 "LightingManager.h" - -#if CHIP_CONFIG_ENABLE_DIMMABLE_LED -#include "LED_Dimmer.h" -#endif - -#include "AppTask.h" -#include "FreeRTOS.h" - -#include "app_config.h" - -LightingManager LightingManager::sLight; - -int LightingManager::Init() -{ - mState = kState_On; - - mLevel = kLevel_Max; - - return 0; -} - -void LightingManager::SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB) -{ - mActionInitiated_CB = aActionInitiated_CB; - mActionCompleted_CB = aActionCompleted_CB; -} - -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; -} - -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; - current_state = kState_Off; - } - else if (mState == kState_Off && aAction == TURNON_ACTION) - { - action_initiated = true; - 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) - { - if (mActionInitiated_CB) - { - 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, kValue); - } - } - - return action_initiated; -} diff --git a/examples/lighting-app/nxp/k32w/k32w1/main/include/AppEvent.h b/examples/lighting-app/nxp/k32w/k32w1/main/include/AppEvent.h deleted file mode 100644 index 902c70b3cb656f..00000000000000 --- a/examples/lighting-app/nxp/k32w/k32w1/main/include/AppEvent.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * Copyright (c) 2021 Nest Labs, Inc. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -struct AppEvent; -typedef void (*EventHandler)(AppEvent *); - -struct AppEvent -{ - enum AppEventTypes - { - kEventType_None = 0, - kEventType_Button, - kEventType_Timer, - kEventType_TurnOn, - kEventType_Install, - kEventType_OTAResume, - }; - - AppEventTypes Type; - - union - { - struct - { - uint8_t PinNo; - uint8_t Action; - } ButtonEvent; - struct - { - void * Context; - } TimerEvent; - struct - { - uint8_t Action; - int32_t Actor; - } LightEvent; - }; - - EventHandler Handler; -}; diff --git a/examples/lighting-app/nxp/k32w/k32w1/main/include/AppTask.h b/examples/lighting-app/nxp/k32w/k32w1/main/include/AppTask.h deleted file mode 100644 index 096690c680b1d2..00000000000000 --- a/examples/lighting-app/nxp/k32w/k32w1/main/include/AppTask.h +++ /dev/null @@ -1,126 +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 "LightingManager.h" - -#include -#include - -#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA -#include -#endif - -#include "FreeRTOS.h" -#include "fsl_component_button.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: -#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA - using FactoryDataProvider = chip::DeviceLayer::FactoryDataProviderImpl; -#endif - CHIP_ERROR StartAppTask(); - static void AppTaskMain(void * pvParameter); - - void PostTurnOnActionRequest(int32_t aActor, LightingManager::Action_t aAction); - void PostEvent(const AppEvent * event); - - void UpdateClusterState(void); - void UpdateDeviceState(void); - - // Identify cluster callbacks. - static void OnIdentifyStart(Identify * identify); - static void OnIdentifyStop(Identify * identify); - static void OnTriggerEffect(Identify * identify); - static void OnTriggerEffectComplete(chip::System::Layer * systemLayer, void * appState); - static void ButtonEventHandler(uint8_t pin_no, uint8_t button_action); - -private: - friend AppTask & GetAppTask(void); - - CHIP_ERROR Init(); - - static void ActionInitiated(LightingManager::Action_t aAction, int32_t aActor); - static void ActionCompleted(LightingManager::Action_t aAction, uint8_t level); - - void CancelTimer(void); - - void DispatchEvent(AppEvent * event); - - static void FunctionTimerEventHandler(AppEvent * aEvent); - static button_status_t KBD_Callback(void * buttonHandle, button_callback_message_t * message, void * callbackParam); - static void SoftResetHandler(AppEvent * aEvent); - static void BleHandler(AppEvent * aEvent); - static void BleStartAdvertising(intptr_t arg); - static void LightActionEventHandler(AppEvent * aEvent); - static void ResetActionEventHandler(AppEvent * aEvent); - static void InstallEventHandler(AppEvent * aEvent); - - static void TimerEventHandler(TimerHandle_t xTimer); - - static void MatterEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); - void StartTimer(uint32_t aTimeoutInMs); - - static void RestoreLightingState(void); - -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - static void InitOTA(intptr_t arg); - static void StartOTAQuery(intptr_t arg); -#endif - - static void UpdateClusterStateInternal(intptr_t arg); - static void UpdateDeviceStateInternal(intptr_t arg); - static void InitServer(intptr_t arg); - static void PrintOnboardingInfo(); - - enum Function_t - { - kFunction_NoneSelected = 0, - kFunction_FactoryReset, - kFunctionTurnOnTurnOff, - kFunction_Identify, - kFunction_TriggerEffect, - 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/lighting-app/nxp/k32w/k32w1/main/include/LightingManager.h b/examples/lighting-app/nxp/k32w/k32w1/main/include/LightingManager.h deleted file mode 100644 index f96d6c7ecae40c..00000000000000 --- a/examples/lighting-app/nxp/k32w/k32w1/main/include/LightingManager.h +++ /dev/null @@ -1,74 +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 "FreeRTOS.h" -#include "timers.h" // provides FreeRTOS timer support - -class LightingManager -{ -public: - enum Action_t - { - TURNON_ACTION = 0, - TURNOFF_ACTION, - DIM_ACTION, - INVALID_ACTION - } Action; - - enum State_t - { - kState_On = 0, - kState_Off, - } State; - - static const uint8_t kLevel_Max = 254; - static const uint8_t kLevel_Min = 0; - - int Init(); - bool IsTurnedOff(); - 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, 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; - - static LightingManager sLight; -}; - -inline LightingManager & LightingMgr(void) -{ - return LightingManager::sLight; -} diff --git a/examples/lighting-app/nxp/k32w/k32w1/main/include/app_config.h b/examples/lighting-app/nxp/k32w/k32w1/main/include/app_config.h deleted file mode 100644 index 1478b53b11aba1..00000000000000 --- a/examples/lighting-app/nxp/k32w/k32w1/main/include/app_config.h +++ /dev/null @@ -1,49 +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 - -// ---- Light Example App Config ---- - -#define RESET_BUTTON 1 -#define LIGHT_BUTTON 2 -#define SOFT_RESET_BUTTON 3 -#define BLE_BUTTON 4 - -#define RESET_BUTTON_PUSH 1 -#define LIGHT_BUTTON_PUSH 2 -#define SOFT_RESET_BUTTON_PUSH 3 -#define BLE_BUTTON_PUSH 4 - -#define APP_BUTTON_PUSH 1 - -#define LIGHT_STATE_LED 1 -#define SYSTEM_STATE_LED 0 - -// Time it takes for the light to switch on/off -#define ACTUATOR_MOVEMENT_PERIOS_MS 50 - -// ---- Light 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/lighting-app/nxp/k32w/k32w1/main/main.cpp b/examples/lighting-app/nxp/k32w/k32w1/main/main.cpp deleted file mode 100644 index 53a6efbbb3ffd5..00000000000000 --- a/examples/lighting-app/nxp/k32w/k32w1/main/main.cpp +++ /dev/null @@ -1,156 +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 "openthread/platform/logging.h" -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "FreeRtosHooks.h" -#include "app_config.h" -#include "pin_mux.h" - -using namespace ::chip; -using namespace ::chip::Inet; -using namespace ::chip::DeviceLayer; -using namespace ::chip::Logging; - -#include - -#if PW_RPC_ENABLED -#include "Rpc.h" -#endif - -typedef void (*InitFunc)(void); -extern InitFunc __init_array_start; -extern InitFunc __init_array_end; - -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; - } - - /* Used for HW initializations */ - otSysInit(0, NULL); - -#if PW_RPC_ENABLED - /* set clock */ - CLOCK_SetIpSrc(kCLOCK_Lpuart1, kCLOCK_IpSrcFro192M); - /* enable clock */ - CLOCK_EnableClock(kCLOCK_Lpuart1); - - BOARD_InitPinLPUART1_TX(); - BOARD_InitPinLPUART1_RX(); - chip::rpc::Init(); -#endif - - K32W_LOG("Welcome to NXP Lighting Demo App"); - - /* Mbedtls Threading support is needed because both - * Thread and Matter tasks are using it */ - freertos_mbedtls_mutex_init(); - - // Init Chip memory management before the stack - chip::Platform::MemoryInit(); - - err = PlatformMgr().InitChipStack(); - if (err != CHIP_NO_ERROR) - { - K32W_LOG("Error during PlatformMgr().InitMatterStack()"); - goto exit; - } - - err = ThreadStackMgr().InitThreadStack(); - if (err != CHIP_NO_ERROR) - { - K32W_LOG("Error during ThreadStackMgr().InitThreadStack()"); - goto exit; - } - - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); - - if (err != CHIP_NO_ERROR) - { - goto exit; - } - - // Start OpenThread task - err = ThreadStackMgrImpl().StartThreadTask(); - if (err != CHIP_NO_ERROR) - { - K32W_LOG("Error during ThreadStackMgrImpl().StartThreadTask()"); - goto exit; - } - - err = GetAppTask().StartAppTask(); - if (err != CHIP_NO_ERROR) - { - K32W_LOG("Error during GetAppTask().StartAppTask()"); - goto exit; - } - - err = PlatformMgr().StartEventLoopTask(); - if (err != 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) -{ - { - BaseType_t yieldRequired = ThreadStackMgrImpl().SignalThreadActivityPendingFromISR(); - portYIELD_FROM_ISR(yieldRequired); - } -} diff --git a/examples/lighting-app/nxp/k32w/k32w1/third_party/connectedhomeip b/examples/lighting-app/nxp/k32w/k32w1/third_party/connectedhomeip deleted file mode 120000 index 305f2077ffe860..00000000000000 --- a/examples/lighting-app/nxp/k32w/k32w1/third_party/connectedhomeip +++ /dev/null @@ -1 +0,0 @@ -../../../../../.. \ No newline at end of file diff --git a/examples/lighting-app/nxp/k32w/k32w1/.gn b/examples/lighting-app/nxp/k32w1/.gn similarity index 93% rename from examples/lighting-app/nxp/k32w/k32w1/.gn rename to examples/lighting-app/nxp/k32w1/.gn index a88f6f5aa7cb3f..afa5bfea46aca8 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/.gn +++ b/examples/lighting-app/nxp/k32w1/.gn @@ -27,5 +27,5 @@ default_args = { import("//args.gni") # Import default platform configs - import("${chip_root}/src/platform/nxp/k32w/k32w1/args.gni") + import("${chip_root}/src/platform/nxp/k32w1/args.gni") } diff --git a/examples/lighting-app/nxp/k32w1/BUILD.gn b/examples/lighting-app/nxp/k32w1/BUILD.gn new file mode 100644 index 00000000000000..b6e6db814ad221 --- /dev/null +++ b/examples/lighting-app/nxp/k32w1/BUILD.gn @@ -0,0 +1,268 @@ +# 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/nxp_sdk.gni") +import("//build_overrides/openthread.gni") + +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +import("${nxp_sdk_build_root}/${nxp_sdk_name}/nxp_executable.gni") + +import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") + +import("${chip_root}/src/crypto/crypto.gni") +import("${chip_root}/src/platform/device.gni") +import("${chip_root}/src/platform/nxp/${nxp_platform}/args.gni") + +import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni") + +if (chip_enable_pw_rpc) { + import("//build_overrides/pigweed.gni") + import("$dir_pw_build/target_types.gni") + import("${chip_root}/examples/platform/nxp/pw_rpc_server.gni") +} + +declare_args() { + # Setup discriminator as argument + setup_discriminator = 3840 +} + +assert(current_os == "freertos") +assert(target_os == "freertos") + +example_platform_dir = "${chip_root}/examples/platform/nxp/${nxp_platform}" +common_example_dir = "${chip_root}/examples/platform/nxp/common" + +k32w1_sdk("sdk") { + defines = [] + include_dirs = [] + sources = [] + + # 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" ] + + include_dirs += [ + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1", + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/K32W1480", + ] + + sources += [ + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/K32W1480/clock_config.c", + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/K32W1480/pin_mux.c", + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/app_services_init.c", + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board.c", + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_comp.c", + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_dcdc.c", + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_extflash.c", + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/board_lp.c", + "${k32w1_sdk_root}/middleware/wireless/framework/boards/kw45_k32w1/hardware_init.c", + ] + + if (is_debug) { + defines += [ "BUILD_RELEASE=0" ] + } else { + defines += [ "BUILD_RELEASE=1" ] + } + + if (chip_enable_pw_rpc) { + defines += [ + "CONFIG_ENABLE_PW_RPC", + "STREAMER_UART_FLUSH_DELAY_MS=0", + "STREAMER_UART_SERIAL_MANAGER_RING_BUFFER_SIZE=512", + "BOARD_APP_UART_CLK_FREQ=96000000", + ] + } + + defines += [ + "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setup_discriminator}", + ] + + if (chip_key_storage == "littlefs") { + include_dirs += [ "${example_platform_dir}/board" ] + sources += [ + "${example_platform_dir}/board/peripherals.c", + "${example_platform_dir}/board/peripherals.h", + ] + } +} + +k32w1_executable("light_app") { + output_name = "chip-k32w1-light-example" + + defines = [] + deps = [] + sources = [] + + if (chip_enable_pw_rpc) { + forward_variables_from(pw_rpc_server, "*") + } else { + include_dirs = [] + cflags = [ "-Wconversion" ] + } + + # Defines used by common code + defines += [ + "CONFIG_NET_L2_OPENTHREAD=1", + "CONFIG_NETWORK_LAYER_BLE=1", + "CONFIG_OPERATIONAL_KEYSTORE=1", + "CONFIG_ENABLE_FEEDBACK=1", + "APP_QUEUE_TICKS_TO_WAIT=pdMS_TO_TICKS(10)", + "EXTERNAL_FACTORY_DATA_PROVIDER_HEADER=\"platform/nxp/common/legacy/FactoryDataProvider.h\"", + ] + + # App common files + include_dirs += [ + "${common_example_dir}/app_task/include", + "${common_example_dir}/matter_button/include", + "${common_example_dir}/clusters/include", + "${common_example_dir}/device_callbacks/include", + "${common_example_dir}/device_manager/include", + "${common_example_dir}/factory_data/include", + "${common_example_dir}/led_widget/include", + "${common_example_dir}/operational_keystore/include", + "${common_example_dir}/rpc/include", + "${common_example_dir}/ui_feedback/include", + ] + + sources += [ + "${common_example_dir}/app_task/source/AppTaskBase.cpp", + "${common_example_dir}/app_task/source/AppTaskFreeRTOS.cpp", + "${common_example_dir}/clusters/source/ZclCallbacks.cpp", + "${common_example_dir}/device_callbacks/source/CommonDeviceCallbacks.cpp", + "${common_example_dir}/device_manager/source/CHIPDeviceManager.cpp", + "${example_platform_dir}/factory_data/source/AppFactoryDataExample.cpp", + ] + + if (chip_enable_ota_requestor) { + defines += [ + "CONFIG_CHIP_OTA_IMAGE_PROCESSOR_HEADER=\"platform/nxp/common/legacy/OTAImageProcessorImpl.h\"", + + # The status LED and the external flash CS pin are wired together. The OTA image writing may fail if used together. + "LED_MANAGER_ENABLE_STATUS_LED=0", + ] + + include_dirs += [ "${common_example_dir}/ota_requestor/include" ] + sources += [ "${common_example_dir}/ota_requestor/source/OTARequestorInitiatorMultiImage.cpp" ] + deps += [ "${chip_root}/src/platform/nxp:nxp_ota" ] + } + + # Platform specific files + include_dirs += [ + "${example_platform_dir}/util", + "${example_platform_dir}/app/support", + "${example_platform_dir}/button", + ] + + sources += [ + "${example_platform_dir}/button/ButtonManager.cpp", + "${example_platform_dir}/clusters/Identify.cpp", + "${example_platform_dir}/operational_keystore/OperationalKeystore.cpp", + ] + + if (chip_enable_ota_requestor) { + sources += [ "${example_platform_dir}/ota/OtaUtils.cpp" ] + } + + if (chip_enable_pw_rpc) { + sources += [ "${example_platform_dir}/rpc/AppRpc.cpp" ] + } + + if (chip_with_factory_data == 1) { + include_dirs += [ "${chip_root}/src/platform/nxp/common/legacy" ] + deps += [ "${chip_root}/src/platform/nxp:nxp_factory_data" ] + } + + sources += [ + "../common/AppTask.cpp", + "../common/DeviceCallbacks.cpp", + "../common/main.cpp", + ] + + include_dirs += [ + "../common", + "../common/include", + "include/config", + ] + + deps += [ + "${chip_root}/examples/providers:device_info_provider", + "${chip_root}/src/platform/logging:default", + ] + + if (chip_config_dimmable_led) { + defines += [ "LIGHTING_MANAGER_ENABLE_DIMMABLE_LED=1" ] + sources += [ + "${common_example_dir}/led_widget/include/LedDimmer.h", + "${example_platform_dir}/util/LedDimmer.cpp", + "${example_platform_dir}/util/LightingManagerDimmable.cpp", + ] + deps += [ "${chip_root}/examples/lighting-app/lighting-common/" ] + } else { + sources += [ + "${common_example_dir}/ui_feedback/source/LedManager.cpp", + "${example_platform_dir}/util/LedOnOff.cpp", + ] + deps += [ "${chip_root}/examples/lighting-app/nxp/zap/" ] + } + + if (chip_openthread_ftd) { + deps += [ + "${openthread_root}:libopenthread-cli-ftd", + "${openthread_root}:libopenthread-ftd", + ] + } else { + deps += [ + "${openthread_root}:libopenthread-cli-mtd", + "${openthread_root}:libopenthread-mtd", + ] + } + + if (use_smu2_static) { + ldscript = "${example_platform_dir}/app/ldscripts/k32w1_app.ld" + base_ldscript_dir = "${k32w1_sdk_root}/middleware/wireless/framework/Common/devices/kw45_k32w1/gcc" + } else { + ldscript = "${k32w1_sdk_root}/middleware/wireless/framework/Common/devices/kw45_k32w1/gcc/connectivity.ld" + } + + inputs = [ ldscript ] + + ldflags = [ + "-Wl,--defsym=__heap_size__=0", + "-Wl,--defsym=__stack_size__=0x480", + "-Wl,-print-memory-usage", + "-Wl,--no-warn-rwx-segments", + "-T" + rebase_path(ldscript, root_build_dir), + ] + + if (chip_with_factory_data == 1) { + ldflags += [ "-Wl,--defsym=gUseFactoryData_d=1" ] + } + + if (use_smu2_static) { + ldflags += [ "-L" + rebase_path(base_ldscript_dir, root_build_dir) ] + } + + output_dir = root_out_dir +} + +group("default") { + deps = [ ":light_app" ] +} diff --git a/examples/lighting-app/nxp/k32w/k32w1/README.md b/examples/lighting-app/nxp/k32w1/README.md similarity index 80% rename from examples/lighting-app/nxp/k32w/k32w1/README.md rename to examples/lighting-app/nxp/k32w1/README.md index 3bf2ab8105481b..349deef640727d 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/README.md +++ b/examples/lighting-app/nxp/k32w1/README.md @@ -16,30 +16,32 @@ into an existing Matter network and can be controlled by this network.
- [Matter K32W1 Lighting Example Application](#matter-k32w1-lighting-example-application) -- [Introduction](#introduction) - - [Bluetooth LE Advertising](#bluetooth-le-advertising) - - [Bluetooth LE Rendezvous](#bluetooth-le-rendezvous) -- [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) + - [Introduction](#introduction) + - [Bluetooth LE Advertising](#bluetooth-le-advertising) + - [Bluetooth LE Rendezvous](#bluetooth-le-rendezvous) + - [Thread Provisioning](#thread-provisioning) + - [Device UI](#device-ui) + - [Building](#building) + - [`SMU2` Memory](#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) + - [OTA factory data](#ota-factory-data) + - [Running OTA](#running-ota) + - [Known issues](#known-issues) + - [Running RPC console](#running-rpc-console) ## Introduction -![K32W1 EVK](../../../../platform/nxp/k32w/k32w1/doc/images/k32w1-evk.jpg) +![K32W1 EVK](../../../platform/nxp/k32w1/doc/images/k32w1-evk.jpg) The K32W1 lighting example application provides a working demonstration of a light bulb device, built using the Matter codebase and the NXP K32W1 SDK. The @@ -119,26 +121,52 @@ does a clean soft reset that takes into account Matter shutdown procedure. ## Building -In order to build the Matter example, we recommend using a Linux distribution -(the demo-application was compiled on Ubuntu 20.04). +In order to build the Project CHIP example, we recommend using a Linux +distribution. Supported Operating Systems and prerequisites are listed in +[BUILDING](../../../../docs/guides/BUILDING.md). -- Download [K32W1 SDK for Matter](https://mcuxpresso.nxp.com/). 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 K32W148-EVK - MCUXpresso SDK. The SDK Builder UI selection should be similar with the one - from the image below. +- Make sure that below prerequisites are correctly installed - ![MCUXpresso SDK Download](../../../../platform/nxp/k32w/k32w1/doc/images/mcux-sdk-download.jpg) +``` +sudo apt-get install git gcc g++ pkg-config libssl-dev libdbus-1-dev \ + libglib2.0-dev libavahi-client-dev ninja-build python3-venv python3-dev \ + python3-pip unzip libgirepository1.0-dev libcairo2-dev libreadline-dev +``` - Please refer to Matter release notes for getting the latest released SDK. +- Step 1: checkout NXP specific submodules only ``` -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 -user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w/k32w1$ ninja -C out/debug +``` + +- Step 2: activate local environment + +``` +user@ubuntu:~/Desktop/git/connectedhomeip$ source scripts/activate.sh +``` + +If the script says the environment is out of date, you can update it by running +the following command: + +``` +user@ubuntu:~/Desktop/git/connectedhomeip$ source scripts/bootstrap.sh +``` + +- Step 3: Init NXP SDK(s) + +``` +user@ubuntu:~/Desktop/git/connectedhomeip$ scripts/setup/nxp/update_nxp_sdk.py --platform common_sdk +``` + +Note: By default setup/nxp/update_nxp_sdk.py will try to initialize all NXP +SDKs. Arg "-- help" could be used to view all available options. + +- Start building the application. + +``` +user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/lighting-app/nxp/k32w1 +user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w1$ gn gen out/debug +user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w1$ ninja -C out/debug ``` In case that Openthread CLI is needed, `chip_with_ot_cli` build argument must be @@ -162,8 +190,8 @@ memory: 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 changed, the names must be updated in `k32w1_app.ld`. See -[k32w1_app.ld](../../../../platform/nxp/k32w/k32w1/app/ldscripts/k32w1_app.ld) -for names and `SMU2` memory range size. +[k32w1_app.ld](../../../platform/nxp/k32w1/app/ldscripts/k32w1_app.ld) for names +and `SMU2` memory range size. The OpenThread buffers can be allocated from a 13KB `SMU2` range after a successful commissioning process until a factory reset is initiated. This way, @@ -171,6 +199,8 @@ 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`. +`use_smu2_static` and `use_smu2_dynamic` are set to `true` by default. + ### LED PWM In the default configuration, the onboard RGB LED pins are configured as GPIO @@ -180,14 +210,14 @@ 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). +[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. For a full guide on manufacturing flow, please see -[Guide for writing manufacturing data on NXP devices](../../../../../docs/guides/nxp/nxp_manufacturing_flow.md). +[Guide for writing manufacturing data on NXP devices](../../../../docs/guides/nxp/nxp_manufacturing_flow.md). ## Flashing @@ -250,7 +280,7 @@ One option for debugging would be to use MCUXpresso IDE. - Drag-and-drop the zip file containing the NXP SDK in the "Installed SDKs" tab: -![Installed SDKs](../../../../platform/nxp/k32w/k32w1/doc/images/installed_sdks.jpg) +![Installed SDKs](../../../platform/nxp/k32w1/doc/images/installed_sdks.jpg) - Import any demo application from the installed SDK: @@ -258,7 +288,7 @@ One option for debugging would be to use MCUXpresso IDE. Import SDK example(s).. -> choose a demo app (demo_apps -> hello_world) -> Finish ``` -![Import demo](../../../../platform/nxp/k32w/k32w1/doc/images/import_demo.jpg) +![Import demo](../../../platform/nxp/k32w1/doc/images/import_demo.jpg) - Flash the previously imported demo application on the board: @@ -277,7 +307,7 @@ resulted after ot-nxp compilation. File -> Import -> C/C++ -> Existing Code as Makefile Project ``` -![New Project](../../../../platform/nxp/k32w/k32w1/doc/images/new_project.jpg) +![New Project](../../../platform/nxp/k32w1/doc/images/new_project.jpg) - Replace the path of the existing demo application with the path of the K32W1 application: @@ -286,7 +316,7 @@ File -> Import -> C/C++ -> Existing Code as Makefile Project Run -> Debug Configurations... -> C/C++ Application ``` -![Debug K32W1](../../../../platform/nxp/k32w/k32w1/doc/images/debug_k32w1.jpg) +![Debug K32W1](../../../platform/nxp/k32w1/doc/images/debug_k32w1.jpg) ## OTA @@ -314,16 +344,21 @@ In `OTAP` application In order to build an OTA image, use NXP wrapper over the standard tool `src/app/ota_image_tool.py`: -- `scripts/tools/nxp/factory_data_generator/ota_image_tool.py` The tool can be - used to generate an OTA image with the following format: - `| OTA image header | TLV1 | TLV2 | ... | TLVn |` where each TLV is in the - form `|tag|length|value|` +- `scripts/tools/nxp/factory_data_generator/ota_image_tool.py` + +The tool can be used to generate an OTA image with the following format: + +``` + | OTA image header | TLV1 | TLV2 | ... | TLVn | +``` + +where each TLV is in the form `|tag|length|value|`. Note that "standard" TLV format is used. Matter TLV format is only used for factory data TLV value. Please see more in the -[OTA image tool guide](../../../../../scripts/tools/nxp/ota/README.md). +[OTA image tool guide](../../../../scripts/tools/nxp/ota/README.md). Here is an example that generates an OTA image with application update TLV from a sb3 file: @@ -340,12 +375,24 @@ having a correct OTA process, the OTA header version should be the same as the binary embedded software version. A user can set a custom software version in the gn build args by setting `chip_software_version` to the wanted version. +### OTA factory data + +A user can update the factory data through OTA, at the same time the application +firmware is updated by enabling the following processor in the `gn args`: + +- `chip_enable_ota_factory_data_processor=1` to enable default factory data + update processor (disabled by default). + +The OTA image used must be updated to include the new factory data. + +[OTA image tool guide](../../../../scripts/tools/nxp/ota/README.md). + ### Running OTA The OTA topology used for OTA testing is illustrated in the figure below. Topology is similar with the one used for Matter Test Events. -![OTA_TOPOLOGY](../../../../platform/nxp/k32w/k32w1/doc/images/ota_topology.JPG) +![OTA_TOPOLOGY](../../../platform/nxp/k32w1/doc/images/ota_topology.JPG) The concept for OTA is the next one: @@ -460,10 +507,16 @@ by running: `chip-console --device /dev/tty. -b 115200 -o pw_log.out` The console should already have been installed in the virtual environment. From -the `chip-console`, a user can send specific commands to the device, e.g.: +the `chip-console`, a user can send specific commands to the device. + +For button commands, please run `rpcs.chip.rpc.Button.Event(index)` based on the +table below: + +| index | action | +| ----- | --------------------------------------------- | +| 0 | Start/stop BLE advertising | +| 1 | Factory reset the device | +| 2 | Application specific action (e.g. toggle LED) | +| 3 | Soft reset the device | -- To toggle the LED (`#define LIGHT_BUTTON 2` in `app_config.h`) - `rpcs.chip.rpc.Button.Event(idx=2)` -- To start BLE advertising (`#define BLE_BUTTON 4` in `app_config.h`) - `rpcs.chip.rpc.Button.Event(idx=4)` -- To reboot the device `rpcs.chip.rpc.Device.Reboot()` +To reboot the device, please run `rpcs.chip.rpc.Device.Reboot()`. diff --git a/examples/lighting-app/nxp/k32w/k32w1/args.gni b/examples/lighting-app/nxp/k32w1/args.gni similarity index 74% rename from examples/lighting-app/nxp/k32w/k32w1/args.gni rename to examples/lighting-app/nxp/k32w1/args.gni index d0c28a1e048545..7d5e752aae6934 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/args.gni +++ b/examples/lighting-app/nxp/k32w1/args.gni @@ -13,9 +13,11 @@ # limitations under the License. import("//build_overrides/chip.gni") +import("${chip_root}/config/standalone/args.gni") # SDK target. This is overridden to add our SDK app_config.h & defines. -k32w1_sdk_target = get_label_info(":sdk", "label_no_toolchain") +nxp_sdk_target = get_label_info(":sdk", "label_no_toolchain") +nxp_device = "K32W1480" chip_config_dimmable_led = false chip_enable_ota_requestor = true @@ -27,3 +29,10 @@ is_debug = false chip_crypto = "platform" chip_openthread_ftd = true chip_with_ot_cli = 0 + +chip_system_config_provide_statistics = false +chip_system_config_use_open_thread_inet_endpoints = true +chip_with_lwip = false + +use_smu2_static = false +use_smu2_dynamic = false diff --git a/examples/lighting-app/nxp/k32w1/build_overrides b/examples/lighting-app/nxp/k32w1/build_overrides new file mode 120000 index 00000000000000..ee19c065d619a2 --- /dev/null +++ b/examples/lighting-app/nxp/k32w1/build_overrides @@ -0,0 +1 @@ +../../../build_overrides/ \ No newline at end of file diff --git a/examples/lighting-app/nxp/k32w1/include/config/AppConfig.h b/examples/lighting-app/nxp/k32w1/include/config/AppConfig.h new file mode 100644 index 00000000000000..6dcccf749bbebe --- /dev/null +++ b/examples/lighting-app/nxp/k32w1/include/config/AppConfig.h @@ -0,0 +1,29 @@ +/* + * Copyright 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 + +/* ---- App Config ---- */ +#define APP_DEVICE_TYPE_ENDPOINT 1 +#define APP_CLUSTER_ATTRIBUTE chip::app::Clusters::OnOff::Attributes::OnOff + +/* ---- Button Manager Config ---- */ +#define BUTTON_MANAGER_FACTORY_RESET_TIMEOUT_MS 6000 + +/* ---- LED Manager Config ---- */ +#define LED_MANAGER_STATUS_LED_INDEX 0 +#define LED_MANAGER_LIGHT_LED_INDEX 1 diff --git a/examples/lighting-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h b/examples/lighting-app/nxp/k32w1/include/config/CHIPProjectConfig.h similarity index 100% rename from examples/lighting-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h rename to examples/lighting-app/nxp/k32w1/include/config/CHIPProjectConfig.h diff --git a/examples/lighting-app/nxp/k32w1/third_party/connectedhomeip b/examples/lighting-app/nxp/k32w1/third_party/connectedhomeip new file mode 120000 index 00000000000000..59307833b4fee9 --- /dev/null +++ b/examples/lighting-app/nxp/k32w1/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../.. \ No newline at end of file diff --git a/examples/lighting-app/nxp/k32w/k32w1/with_pw_rpc.gni b/examples/lighting-app/nxp/k32w1/with_pw_rpc.gni similarity index 84% rename from examples/lighting-app/nxp/k32w/k32w1/with_pw_rpc.gni rename to examples/lighting-app/nxp/k32w1/with_pw_rpc.gni index d6bea63f8402c0..c2dc1950544640 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/with_pw_rpc.gni +++ b/examples/lighting-app/nxp/k32w1/with_pw_rpc.gni @@ -17,17 +17,21 @@ import("//build_overrides/chip.gni") import("${chip_root}/config/nxp/lib/pw_rpc/pw_rpc.gni") -import("${chip_root}/examples/platform/nxp/k32w/k32w1/args.gni") -k32w1_sdk_target = get_label_info(":sdk", "label_no_toolchain") +nxp_sdk_target = get_label_info(":sdk", "label_no_toolchain") -chip_enable_ota_requestor = true -chip_stack_lock_tracking = "fatal" +chip_crypto = "platform" chip_enable_ble = true +chip_enable_ota_requestor = true chip_enable_pw_rpc = true -chip_with_ot_cli = 0 -is_debug = false chip_openthread_ftd = true -chip_crypto = "platform" +chip_stack_lock_tracking = "fatal" + +chip_system_config_provide_statistics = false +chip_system_config_use_open_thread_inet_endpoints = true + +chip_with_lwip = false +chip_with_ot_cli = 0 cpp_standard = "gnu++17" +is_debug = false diff --git a/examples/platform/nxp/Rpc.cpp b/examples/platform/nxp/Rpc.cpp index 262825386ed13c..c0cb0b933f2ac7 100644 --- a/examples/platform/nxp/Rpc.cpp +++ b/examples/platform/nxp/Rpc.cpp @@ -16,7 +16,7 @@ * limitations under the License. */ -#include "AppTask.h" +#include "AppRpc.h" #include "FreeRTOS.h" #include "PigweedLogger.h" #include "PigweedLoggerMutex.h" @@ -43,8 +43,14 @@ #include "pigweed/rpc_services/Locking.h" #endif // defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE +#ifndef RPC_TASK_STACK_SIZE #define RPC_TASK_STACK_SIZE 2048 +#endif + +#ifndef RPC_TASK_PRIORITY #define RPC_TASK_PRIORITY 1 +#endif + TaskHandle_t RpcTaskHandle; namespace chip { @@ -56,7 +62,7 @@ class NxpButton final : public Button public: pw::Status Event(const chip_rpc_ButtonEvent & request, pw_protobuf_Empty & response) override { - GetAppTask().ButtonEventHandler(request.idx, request.idx); + chip::NXP::App::Rpc::ButtonHandler(request); return pw::OkStatus(); } }; @@ -77,7 +83,7 @@ class NxpDevice final : public Device static constexpr TickType_t kRebootTimerPeriodTicks = 300; TimerHandle_t mRebootTimer; - static void RebootHandler(TimerHandle_t) { NVIC_SystemReset(); } + static void RebootHandler(TimerHandle_t) { chip::NXP::App::Rpc::Reboot(); } }; #endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE diff --git a/examples/platform/nxp/common/app_task/include/AppTaskBase.h b/examples/platform/nxp/common/app_task/include/AppTaskBase.h index 98cec56832b705..76e18df7f47eb0 100644 --- a/examples/platform/nxp/common/app_task/include/AppTaskBase.h +++ b/examples/platform/nxp/common/app_task/include/AppTaskBase.h @@ -27,9 +27,8 @@ #include #include -namespace chip { -namespace NXP { -namespace App { +namespace chip::NXP::App { + class AppTaskBase { public: @@ -97,6 +96,44 @@ class AppTaskBase */ virtual void AppMatter_RegisterCustomCliCommands(void){}; + /** + * \brief Disallow entering low power mode. + * + * This function can be overridden in order to implement a specific disallow mechanism. + * + */ + virtual void AppMatter_DisallowDeviceToSleep(void) {} + + /** + * \brief Allow entering low power mode. + * + * This function can be overridden in order to implement a specific allow mechanism. + * + */ + virtual void AppMatter_AllowDeviceToSleep(void) {} + + /** + * \brief Print onboarding information. + * + * It can be overwritten by derived classes for custom information, + * such as setting the commissioning flow to kUserActionRequired. + * + */ + virtual void PrintOnboardingInfo(); + + /** + * \brief Print current software version string and software version. + * + * It uses the ConfigurationManager API to extract the information. + */ + virtual void PrintCurrentVersion(); + + /** + * \brief Send event to the event queue. + * + */ + virtual void PostEvent(const AppEvent & event){}; + /** * \brief This function could be overridden in order to dispatch event. * @@ -142,6 +179,7 @@ class AppTaskBase private: inline static chip::CommonCaseDeviceServerInitParams initParams; + /* Functions used by the public commisioning handlers */ static void StartCommissioning(intptr_t arg); static void StopCommissioning(intptr_t arg); @@ -154,6 +192,5 @@ class AppTaskBase * Applications can use this to gain access to features of the AppTaskBase. */ extern AppTaskBase & GetAppTask(); -} // namespace App -} // namespace NXP -} // namespace chip + +} // namespace chip::NXP::App diff --git a/examples/platform/nxp/common/app_task/include/AppTaskFreeRTOS.h b/examples/platform/nxp/common/app_task/include/AppTaskFreeRTOS.h index 7ebc4a7430ccaf..0dd5c0d20652a7 100644 --- a/examples/platform/nxp/common/app_task/include/AppTaskFreeRTOS.h +++ b/examples/platform/nxp/common/app_task/include/AppTaskFreeRTOS.h @@ -21,9 +21,8 @@ #include "AppTaskBase.h" -namespace chip { -namespace NXP { -namespace App { +namespace chip::NXP::App { + class AppTaskFreeRTOS : public AppTaskBase { public: @@ -53,7 +52,7 @@ class AppTaskFreeRTOS : public AppTaskBase * \brief Send event to the event queue. * */ - void PostEvent(const AppEvent & event); + void PostEvent(const AppEvent & event) override; /** * \brief Return a pointer to the NXP Wifi Driver instance. @@ -72,9 +71,20 @@ class AppTaskFreeRTOS : public AppTaskBase */ virtual CHIP_ERROR AppMatter_Register(void) override; + /** + * \brief The app event queue handle should be static such that the concrete + * application task can initialize it during Start() call. + */ + QueueHandle_t appEventQueue; + + /** + * \brief This value is used when xQueueReceive is called to specify + * the maximum amount of time the task should block waiting for an event. + * This can be modified according to the application needs. + */ + TickType_t ticksToWait; + private: void DispatchEvent(const AppEvent & event); }; -} // namespace App -} // namespace NXP -} // namespace chip +} // namespace chip::NXP::App diff --git a/examples/platform/nxp/common/app_task/include/AppTaskZephyr.h b/examples/platform/nxp/common/app_task/include/AppTaskZephyr.h index 77cfaa0e468ccf..9a333a768e1f93 100644 --- a/examples/platform/nxp/common/app_task/include/AppTaskZephyr.h +++ b/examples/platform/nxp/common/app_task/include/AppTaskZephyr.h @@ -21,9 +21,8 @@ #include "AppTaskBase.h" -namespace chip { -namespace NXP { -namespace App { +namespace chip::NXP::App { + class AppTaskZephyr : public AppTaskBase { public: @@ -43,7 +42,7 @@ class AppTaskZephyr : public AppTaskBase * \brief Send event to the event queue. * */ - void PostEvent(const AppEvent & event); + void PostEvent(const AppEvent & event) override; /** * \brief Return a pointer to the NXP Wifi Driver instance. @@ -65,6 +64,5 @@ class AppTaskZephyr : public AppTaskBase private: void DispatchEvent(const AppEvent & event); }; -} // namespace App -} // namespace NXP -} // namespace chip + +} // namespace chip::NXP::App diff --git a/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp b/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp index 9ba90e6c146b74..10422121e5c81f 100644 --- a/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp +++ b/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp @@ -26,7 +26,6 @@ #include #include -#include #include #include @@ -37,7 +36,18 @@ #include -#ifdef EMBER_AF_PLUGIN_BINDING +#if defined(MATTER_DM_PLUGIN_USER_LABEL) || defined(MATTER_DM_PLUGIN_FIXED_LABEL) +#ifndef CONFIG_DEVICE_INFO_PROVIDER_IMPL +#define CONFIG_DEVICE_INFO_PROVIDER_IMPL 1 +#endif +#endif + +#if CONFIG_DEVICE_INFO_PROVIDER_IMPL +#include +#endif + +/* Flag generated by Zap */ +#ifdef MATTER_DM_PLUGIN_BINDING #include "binding-handler.h" #endif @@ -50,10 +60,22 @@ #include "TcpDownload.h" #endif +#if CONFIG_OPERATIONAL_KEYSTORE +#include "OperationalKeystore.h" +#endif + #if CONFIG_CHIP_OTA_PROVIDER #include #endif +#if CONFIG_DIAG_LOGS_DEMO +#include "DiagnosticLogsDemo.h" +#endif + +#if CONFIG_LOW_POWER +#include "LowPower.h" +#endif + #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR #include "OTARequestorInitiator.h" #endif @@ -66,6 +88,19 @@ #include #endif +#ifdef SMOKE_CO_ALARM +#include +#include +#endif + +#if CHIP_CONFIG_ENABLE_ICD_SERVER +#include +#endif + +#ifndef CONFIG_THREAD_DEVICE_TYPE +#define CONFIG_THREAD_DEVICE_TYPE kThreadDeviceType_Router +#endif + using namespace chip; using namespace chip::TLV; using namespace ::chip::Credentials; @@ -73,14 +108,16 @@ using namespace ::chip::DeviceLayer; using namespace ::chip::DeviceManager; using namespace ::chip::app::Clusters; +#if CONFIG_DEVICE_INFO_PROVIDER_IMPL chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; +#endif #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 +#if CHIP_CONFIG_ENABLE_ICD_SERVER || (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 }; @@ -89,12 +126,14 @@ static uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLe #if CONFIG_NET_L2_OPENTHREAD void LockOpenThreadTask(void) { + chip::NXP::App::GetAppTask().AppMatter_DisallowDeviceToSleep(); chip::DeviceLayer::ThreadStackMgr().LockThreadStack(); } void UnlockOpenThreadTask(void) { chip::DeviceLayer::ThreadStackMgr().UnlockThreadStack(); + chip::NXP::App::GetAppTask().AppMatter_AllowDeviceToSleep(); } #endif @@ -106,7 +145,26 @@ void chip::NXP::App::AppTaskBase::InitServer(intptr_t arg) static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; initParams.testEventTriggerDelegate = &testEventTriggerDelegate; #endif + +#ifdef SMOKE_CO_ALARM + static SimpleTestEventTriggerDelegate sTestEventTriggerDelegate{}; + static SmokeCOTestEventTriggerHandler sSmokeCOTestEventTriggerHandler{}; + VerifyOrDie(sTestEventTriggerDelegate.Init(ByteSpan(sTestEventTriggerEnableKey)) == CHIP_NO_ERROR); + VerifyOrDie(sTestEventTriggerDelegate.AddHandler(&sSmokeCOTestEventTriggerHandler) == CHIP_NO_ERROR); + initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate; +#endif + +#if CHIP_CONFIG_ENABLE_ICD_SERVER + static SimpleTestEventTriggerDelegate sTestEventTriggerDelegate{}; + VerifyOrDie(sTestEventTriggerDelegate.Init(ByteSpan(sTestEventTriggerEnableKey)) == CHIP_NO_ERROR); + initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate; +#endif + +#if CONFIG_OPERATIONAL_KEYSTORE + initParams.operationalKeystore = chip::NXP::App::OperationalKeystore::GetInstance(); +#endif (void) initParams.InitializeStaticResourcesBeforeServerInit(); + #if CONFIG_NET_L2_OPENTHREAD // Init ZCL Data Model and start server chip::Inet::EndPointStateOpenThread::OpenThreadEndpointInitParam nativeParams; @@ -117,12 +175,22 @@ void chip::NXP::App::AppTaskBase::InitServer(intptr_t arg) #endif VerifyOrDie((chip::Server::GetInstance().Init(initParams)) == CHIP_NO_ERROR); + auto * persistentStorage = &Server::GetInstance().GetPersistentStorage(); +#if CONFIG_OPERATIONAL_KEYSTORE + chip::NXP::App::OperationalKeystore::Init(persistentStorage); +#endif - gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); +#if CONFIG_DEVICE_INFO_PROVIDER_IMPL + gExampleDeviceInfoProvider.SetStorageDelegate(persistentStorage); chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); +#endif GetAppTask().PostInitMatterServerInstance(); +#if CONFIG_DIAG_LOGS_DEMO + chip::NXP::App::DiagnosticLogsDemo::DisplayUsage(); +#endif + #if CONFIG_CHIP_OTA_PROVIDER InitOTAServer(); #endif @@ -135,6 +203,10 @@ CHIP_ERROR chip::NXP::App::AppTaskBase::Init() /* Init Chip memory management before the stack */ chip::Platform::MemoryInit(); +#if CONFIG_LOW_POWER + chip::NXP::App::LowPower::Init(); +#endif + /* Initialize Matter factory data before initializing the Matter stack */ err = AppFactoryData_PreMatterStackInit(); @@ -187,7 +259,7 @@ CHIP_ERROR chip::NXP::App::AppTaskBase::Init() return err; } - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); + err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::CONFIG_THREAD_DEVICE_TYPE); if (err != CHIP_NO_ERROR) { return err; @@ -200,7 +272,8 @@ CHIP_ERROR chip::NXP::App::AppTaskBase::Init() */ PlatformMgr().ScheduleWork(InitServer, 0); -#ifdef EMBER_AF_PLUGIN_BINDING +/* Flag generated by Zap */ +#ifdef MATTER_DM_PLUGIN_BINDING /* Init binding handlers */ err = InitBindingHandlers(); if (err != CHIP_NO_ERROR) @@ -227,11 +300,9 @@ CHIP_ERROR chip::NXP::App::AppTaskBase::Init() 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 */ + PrintOnboardingInfo(); + + PrintCurrentVersion(); /* Start a task to run the CHIP Device event loop. */ err = PlatformMgr().StartEventLoopTask(); @@ -333,3 +404,37 @@ void chip::NXP::App::AppTaskBase::FactoryResetHandler(void) chip::Server::GetInstance().GenerateShutDownEvent(); chip::Server::GetInstance().ScheduleFactoryReset(); } + +void chip::NXP::App::AppTaskBase::PrintOnboardingInfo() +{ +#if CONFIG_NETWORK_LAYER_BLE + auto flags = chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE); +#else + auto flags = chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kOnNetwork); +#endif /* CONFIG_NETWORK_LAYER_BLE */ + + chip::PayloadContents payload; + CHIP_ERROR err = GetPayloadContents(payload, flags); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "GetPayloadContents() failed: %" CHIP_ERROR_FORMAT, err.Format()); + } +#if CONFIG_USER_ACTION_REQUIRED + payload.commissioningFlow = chip::CommissioningFlow::kUserActionRequired; +#endif + PrintOnboardingCodes(payload); +} + +void chip::NXP::App::AppTaskBase::PrintCurrentVersion() +{ + // Print the current software version + char currentSoftwareVer[ConfigurationManager::kMaxSoftwareVersionStringLength + 1] = { 0 }; + auto err = ConfigurationMgr().GetSoftwareVersionString(currentSoftwareVer, sizeof(currentSoftwareVer)); + ReturnOnFailure(err); + + uint32_t currentVersion; + err = ConfigurationMgr().GetSoftwareVersion(currentVersion); + ReturnOnFailure(err); + + ChipLogProgress(DeviceLayer, "Current Software Version: %s, %d", currentSoftwareVer, static_cast(currentVersion)); +} diff --git a/examples/platform/nxp/common/app_task/source/AppTaskFreeRTOS.cpp b/examples/platform/nxp/common/app_task/source/AppTaskFreeRTOS.cpp index c48894ed6467cf..5b8e3eab70be40 100644 --- a/examples/platform/nxp/common/app_task/source/AppTaskFreeRTOS.cpp +++ b/examples/platform/nxp/common/app_task/source/AppTaskFreeRTOS.cpp @@ -34,6 +34,14 @@ #include "AppCLIBase.h" #endif +#if CONFIG_ENABLE_FEEDBACK +#include "UserInterfaceFeedback.h" +#endif + +#if CONFIG_ENABLE_PW_RPC +#include "AppRpc.h" +#endif + #include #include @@ -45,12 +53,18 @@ #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 + +#ifndef APP_EVENT_QUEUE_SIZE #define APP_EVENT_QUEUE_SIZE 10 +#endif -static QueueHandle_t sAppEventQueue; +#ifndef APP_QUEUE_TICKS_TO_WAIT +#define APP_QUEUE_TICKS_TO_WAIT portMAX_DELAY +#endif using namespace chip; using namespace chip::TLV; @@ -71,12 +85,18 @@ chip::DeviceLayer::NetworkCommissioning::WiFiDriver * chip::NXP::App::AppTaskFre CHIP_ERROR chip::NXP::App::AppTaskFreeRTOS::AppMatter_Register() { CHIP_ERROR err = CHIP_NO_ERROR; + /* Register Matter CLI cmds */ #ifdef ENABLE_CHIP_SHELL err = chip::NXP::App::GetAppCLI().Init(); VerifyOrReturnError(err == CHIP_NO_ERROR, err, ChipLogError(DeviceLayer, "Error during CLI init")); AppMatter_RegisterCustomCliCommands(); #endif + +#if CONFIG_ENABLE_FEEDBACK + FeedbackMgr().Init(); +#endif + /* Register Matter buttons */ err = AppMatterButton_registerButtons(); if (err != CHIP_NO_ERROR) @@ -92,14 +112,30 @@ 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) +#if CONFIG_ENABLE_PW_RPC + chip::NXP::App::Rpc::Init(); +#endif + + appEventQueue = xQueueCreate(APP_EVENT_QUEUE_SIZE, sizeof(AppEvent)); + if (appEventQueue == NULL) { err = CHIP_ERROR_NO_MEMORY; ChipLogError(DeviceLayer, "Failed to allocate app event queue"); assert(err == CHIP_NO_ERROR); } + ticksToWait = APP_QUEUE_TICKS_TO_WAIT; + +#if FSL_OSA_MAIN_FUNC_ENABLE + /* When OSA is used, this code will be called from within the startup_task + * and the scheduler will be started at this point. Just call AppTaskMain to + * start the main loop instead of creating a task, since we are already in it. + * Task parameters are configured through SDK flags: + * - gMainThreadPriority_c + * - gMainThreadStackSize_c + */ + AppTaskFreeRTOS::AppTaskMain(this); +#else /* 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) @@ -108,6 +144,7 @@ CHIP_ERROR chip::NXP::App::AppTaskFreeRTOS::Start() ChipLogError(DeviceLayer, "Failed to start app task"); assert(err == CHIP_NO_ERROR); } +#endif // FSL_OSA_TASK_ENABLE return err; } @@ -122,31 +159,43 @@ void chip::NXP::App::AppTaskFreeRTOS::AppTaskMain(void * pvParameter) sAppTask->PreInitMatterStack(); err = sAppTask->Init(); + VerifyOrDieWithMsg(err == CHIP_NO_ERROR, DeviceLayer, "AppTask.Init() failed"); 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); + BaseType_t eventReceived = xQueueReceive(sAppTask->appEventQueue, &event, sAppTask->ticksToWait); while (eventReceived == pdTRUE) { sAppTask->DispatchEvent(event); - eventReceived = xQueueReceive(sAppEventQueue, &event, 0); + eventReceived = xQueueReceive(sAppTask->appEventQueue, &event, 0); } +#if CONFIG_ENABLE_FEEDBACK + FeedbackMgr().DisplayInLoop(); +#endif } } void chip::NXP::App::AppTaskFreeRTOS::PostEvent(const AppEvent & event) { - if (sAppEventQueue != NULL) + if (appEventQueue != NULL) { - if (!xQueueSend(sAppEventQueue, &event, 0)) + if (__get_IPSR()) + { + portBASE_TYPE taskToWake = pdFALSE; + if (!xQueueSendToFrontFromISR(appEventQueue, &event, &taskToWake)) + { + ChipLogError(DeviceLayer, "Failed to post event to app task event queue from ISR"); + } + + portYIELD_FROM_ISR(taskToWake); + } + else { - ChipLogError(DeviceLayer, "Failed to post event to app task event queue"); + if (!xQueueSend(appEventQueue, &event, 0)) + { + ChipLogError(DeviceLayer, "Failed to post event to app task event queue"); + } } } } diff --git a/examples/platform/nxp/common/clusters/include/Identify.h b/examples/platform/nxp/common/clusters/include/Identify.h new file mode 100644 index 00000000000000..a742e3808791bc --- /dev/null +++ b/examples/platform/nxp/common/clusters/include/Identify.h @@ -0,0 +1,31 @@ +/* + * 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 + +namespace chip::NXP::App { + +// Identify cluster callbacks. +void OnIdentifyStart(Identify * identify); +void OnIdentifyStop(Identify * identify); +void OnTriggerEffect(Identify * identify); +void OnTriggerEffectComplete(chip::System::Layer * systemLayer, void * appState); + +} // namespace chip::NXP::App diff --git a/examples/platform/nxp/common/clusters/source/ZclCallbacks.cpp b/examples/platform/nxp/common/clusters/source/ZclCallbacks.cpp new file mode 100644 index 00000000000000..99329a818cc68c --- /dev/null +++ b/examples/platform/nxp/common/clusters/source/ZclCallbacks.cpp @@ -0,0 +1,52 @@ +/* + * + * 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 "CHIPDeviceManager.h" + +#include + +#if CONFIG_DIAG_LOGS_DEMO +#include "DiagnosticLogsProviderDelegateImpl.h" +#include +#endif + +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); + } +} + +#if CONFIG_DIAG_LOGS_DEMO +/** @brief DiagnosticLogs Cluster Init + * + * This function is called when a specific cluster is initialized. It gives the + * application an opportunity to take care of cluster initialization procedures. + * It is called exactly once for each endpoint where cluster is present. + */ +void emberAfDiagnosticLogsClusterInitCallback(chip::EndpointId endpoint) +{ + auto & logProvider = chip::app::Clusters::DiagnosticLogs::LogProvider::GetInstance(); + auto & server = chip::app::Clusters::DiagnosticLogs::DiagnosticLogsServer::Instance(); + server.SetDiagnosticLogsProviderDelegate(endpoint, &logProvider); +} +#endif diff --git a/examples/platform/nxp/common/device_callbacks/source/CommonDeviceCallbacks.cpp b/examples/platform/nxp/common/device_callbacks/source/CommonDeviceCallbacks.cpp index d38d6f59f8c572..bc7a8dca431c42 100644 --- a/examples/platform/nxp/common/device_callbacks/source/CommonDeviceCallbacks.cpp +++ b/examples/platform/nxp/common/device_callbacks/source/CommonDeviceCallbacks.cpp @@ -33,7 +33,6 @@ #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 diff --git a/examples/platform/nxp/common/diagnostic_logs/include/DiagnosticLogsDemo.h b/examples/platform/nxp/common/diagnostic_logs/include/DiagnosticLogsDemo.h new file mode 100644 index 00000000000000..e801837e09a04b --- /dev/null +++ b/examples/platform/nxp/common/diagnostic_logs/include/DiagnosticLogsDemo.h @@ -0,0 +1,31 @@ +/* + * 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 + +namespace chip::NXP::App::DiagnosticLogsDemo { + +/** + * @brief Display a demo usage of the diagnostic logs provider. + * + */ +CHIP_ERROR DisplayUsage(); + +} // namespace chip::NXP::App::DiagnosticLogsDemo diff --git a/examples/platform/nxp/common/diagnostic_logs/DiagnosticLogsProviderDelegateImpl.h b/examples/platform/nxp/common/diagnostic_logs/include/DiagnosticLogsProviderDelegateImpl.h similarity index 100% rename from examples/platform/nxp/common/diagnostic_logs/DiagnosticLogsProviderDelegateImpl.h rename to examples/platform/nxp/common/diagnostic_logs/include/DiagnosticLogsProviderDelegateImpl.h diff --git a/examples/platform/nxp/common/diagnostic_logs/source/DiagnosticLogsDemo.cpp b/examples/platform/nxp/common/diagnostic_logs/source/DiagnosticLogsDemo.cpp new file mode 100644 index 00000000000000..359952609352f0 --- /dev/null +++ b/examples/platform/nxp/common/diagnostic_logs/source/DiagnosticLogsDemo.cpp @@ -0,0 +1,47 @@ +/* + * 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 "DiagnosticLogsDemo.h" +#include "DiagnosticLogsProviderDelegateImpl.h" + +#include + +CHIP_ERROR chip::NXP::App::DiagnosticLogsDemo::DisplayUsage() +{ + char diagLog[CHIP_DEVICE_CONFIG_MAX_DIAG_LOG_SIZE]; + uint16_t diagLogSize = CHIP_DEVICE_CONFIG_MAX_DIAG_LOG_SIZE; + + chip::StorageKeyName keyUser = chip::app::Clusters::DiagnosticLogs::LogProvider::GetKeyDiagUserSupport(); + chip::StorageKeyName keyNwk = chip::app::Clusters::DiagnosticLogs::LogProvider::GetKeyDiagNetwork(); + chip::StorageKeyName keyCrash = chip::app::Clusters::DiagnosticLogs::LogProvider::GetKeyDiagCrashLog(); + + auto & persistentStorage = chip::Server::GetInstance().GetPersistentStorage(); + /* The KVS wear stats are stored in the user diagnostic log key hence only + * initialize this key if the KVS wear stats are not enabled. */ +#if (CHIP_DEVICE_CONFIG_KVS_WEAR_STATS != 1) + memset(diagLog, 0, diagLogSize); + persistentStorage.SyncSetKeyValue(keyUser.KeyName(), diagLog, diagLogSize); +#endif + + memset(diagLog, 1, diagLogSize); + persistentStorage.SyncSetKeyValue(keyNwk.KeyName(), diagLog, diagLogSize); + + memset(diagLog, 2, diagLogSize); + persistentStorage.SyncSetKeyValue(keyCrash.KeyName(), diagLog, diagLogSize); + + return CHIP_NO_ERROR; +} diff --git a/examples/platform/nxp/common/diagnostic_logs/DiagnosticLogsProviderDelegateImpl.cpp b/examples/platform/nxp/common/diagnostic_logs/source/DiagnosticLogsProviderDelegateImpl.cpp similarity index 98% rename from examples/platform/nxp/common/diagnostic_logs/DiagnosticLogsProviderDelegateImpl.cpp rename to examples/platform/nxp/common/diagnostic_logs/source/DiagnosticLogsProviderDelegateImpl.cpp index 359edc3dedc9a6..929905afad828f 100644 --- a/examples/platform/nxp/common/diagnostic_logs/DiagnosticLogsProviderDelegateImpl.cpp +++ b/examples/platform/nxp/common/diagnostic_logs/source/DiagnosticLogsProviderDelegateImpl.cpp @@ -142,7 +142,7 @@ size_t LogProvider::GetSizeForIntent(IntentEnum intent) VerifyOrReturnValue(buffer.Get() != nullptr, 0); err = Server::GetInstance().GetPersistentStorage().SyncGetKeyValue(key.KeyName(), buffer.Get(), sizeForIntent); - VerifyOrReturnValue(err == CHIP_NO_ERROR, 0); + VerifyOrReturnValue(err == CHIP_ERROR_BUFFER_TOO_SMALL, 0); return sizeForIntent; } diff --git a/examples/platform/nxp/common/factory_data/source/AppFactoryDataDefaultImpl.cpp b/examples/platform/nxp/common/factory_data/source/AppFactoryDataDefaultImpl.cpp index 4fd176075f00d2..c1b85604226677 100644 --- a/examples/platform/nxp/common/factory_data/source/AppFactoryDataDefaultImpl.cpp +++ b/examples/platform/nxp/common/factory_data/source/AppFactoryDataDefaultImpl.cpp @@ -24,7 +24,10 @@ #include #if CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA -#include "FactoryDataProvider.h" +#ifndef EXTERNAL_FACTORY_DATA_PROVIDER_HEADER +#define EXTERNAL_FACTORY_DATA_PROVIDER_HEADER "platform/nxp/common/factory_data/FactoryDataProvider.h" +#endif +#include EXTERNAL_FACTORY_DATA_PROVIDER_HEADER #if CONFIG_CHIP_ENCRYPTED_FACTORY_DATA /* * Test key used to encrypt factory data before storing it to the flash. @@ -64,7 +67,7 @@ CHIP_ERROR chip::NXP::App::AppFactoryData_PostMatterStackInit(void) FactoryDataPrvdImpl().SetAes128Key(&aes128TestKey[0]); #endif /* CONFIG_CHIP_ENCRYPTED_FACTORY_DATA */ - ReturnErrorOnFailure(FactoryDataPrvdImpl().Init()); + ReturnErrorOnFailure(FactoryDataPrvd().Init()); SetDeviceInstanceInfoProvider(&FactoryDataPrvd()); SetDeviceAttestationCredentialsProvider(&FactoryDataPrvd()); diff --git a/examples/platform/nxp/common/led_widget/include/LedDimmer.h b/examples/platform/nxp/common/led_widget/include/LedDimmer.h new file mode 100644 index 00000000000000..83632738baf769 --- /dev/null +++ b/examples/platform/nxp/common/led_widget/include/LedDimmer.h @@ -0,0 +1,37 @@ +/* + * + * 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 "LedWidgetInterface.h" + +namespace chip::NXP::App { + +/** + * @brief + * A class that manages dimmer LED operations. + */ +class LedDimmer : public LedWidgetInterface +{ +public: + void Init(uint8_t index = 0, bool inverted = false) override; + void Set(uint8_t level = 0) override; + void Animate(uint32_t onTimeMS = 0, uint32_t offTimeMS = 0) override {} +}; + +} // namespace chip::NXP::App diff --git a/examples/platform/nxp/common/led_widget/include/LedOnOff.h b/examples/platform/nxp/common/led_widget/include/LedOnOff.h new file mode 100644 index 00000000000000..128bbb89aaa3cd --- /dev/null +++ b/examples/platform/nxp/common/led_widget/include/LedOnOff.h @@ -0,0 +1,47 @@ +/* + * + * 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 "LedWidgetInterface.h" + +namespace chip::NXP::App { + +/** + * @brief + * A base class that manages an on-off LED on a board. + */ +class LedOnOff : public LedWidgetInterface +{ +public: + void Init(uint8_t index = 0, bool inverted = 0) override; + void Set(uint8_t level = 0) override; + void Animate(uint32_t onTimeMS = 0, uint32_t offTimeMS = 0) override; + +private: + uint64_t mLastChangeTimeMS = 0; + uint32_t mOnTimeMS = 0; + uint32_t mOffTimeMS = 0; + uint8_t mIndex = 0; + + bool mOnLogic = true; + + void DoSet(bool state); +}; + +} // namespace chip::NXP::App diff --git a/examples/platform/nxp/k32w/k32w1/util/include/LEDWidget.h b/examples/platform/nxp/common/led_widget/include/LedWidgetInterface.h similarity index 55% rename from examples/platform/nxp/k32w/k32w1/util/include/LEDWidget.h rename to examples/platform/nxp/common/led_widget/include/LedWidgetInterface.h index a73ab8a904018b..155da65eea9d06 100644 --- a/examples/platform/nxp/k32w/k32w1/util/include/LEDWidget.h +++ b/examples/platform/nxp/common/led_widget/include/LedWidgetInterface.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2020 Google LLC. + * Copyright (c) 2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,28 +16,29 @@ * limitations under the License. */ -// #include "LED.h" -#include "EmbeddedTypes.h" #pragma once -class LEDWidget +#include "EmbeddedTypes.h" + +namespace chip::NXP::App { + +/** + * @brief + * An interface that defines LED operations. + */ +class LedWidgetInterface { 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); - void Animate(); - -private: - uint64_t mLastChangeTimeMS; - uint32_t mBlinkOnTimeMS; - uint32_t mBlinkOffTimeMS; - uint8_t mGPIONum; - bool mState; - bool mOnLogic; - - void DoSet(bool state); + virtual ~LedWidgetInterface() {} + + virtual void Init(uint8_t index = 0, bool inverted = false) = 0; + virtual void Set(uint8_t level = 0) = 0; + virtual void Animate(uint32_t onTimeMS = 0, uint32_t offTimeMS = 0) = 0; + + bool IsTurnedOff() { return !mState; } + +protected: + bool mState = false; }; + +} // namespace chip::NXP::App diff --git a/examples/platform/nxp/common/low_power/include/LowPower.h b/examples/platform/nxp/common/low_power/include/LowPower.h new file mode 100644 index 00000000000000..fc2bdd8ff0fcfd --- /dev/null +++ b/examples/platform/nxp/common/low_power/include/LowPower.h @@ -0,0 +1,32 @@ +/* + * 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 + +namespace chip::NXP::App::LowPower { + +/** + * @brief Low-power related init function. + * + * For example, it can be used to register an enter/exit low power callback. + * + */ +CHIP_ERROR Init(); + +} // namespace chip::NXP::App::LowPower diff --git a/examples/platform/nxp/common/low_power/source/LowPower.cpp b/examples/platform/nxp/common/low_power/source/LowPower.cpp new file mode 100644 index 00000000000000..9b5afd19b18bf8 --- /dev/null +++ b/examples/platform/nxp/common/low_power/source/LowPower.cpp @@ -0,0 +1,48 @@ +/* + * 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 "LowPower.h" +#include "fsl_pm_core.h" + +#include + +#define APP_ERROR_PM_REGISTER_LP_CALLBACK_FAILED CHIP_APPLICATION_ERROR(0x01) + +static status_t LowPowerCallback(pm_event_type_t type, uint8_t state, void * data); + +static pm_notify_element_t appNotifyElement = { + .notifyCallback = LowPowerCallback, + .data = NULL, +}; + +static status_t LowPowerCallback(pm_event_type_t type, uint8_t state, void * data) +{ + // This is just an example. It does nothing by default. + return kStatus_Success; +} + +namespace chip::NXP::App::LowPower { + +CHIP_ERROR Init() +{ + status_t status = PM_RegisterNotify(kPM_NotifyGroup2, &appNotifyElement); + VerifyOrReturnError(status == kStatus_Success, APP_ERROR_PM_REGISTER_LP_CALLBACK_FAILED); + + return CHIP_NO_ERROR; +} + +} // namespace chip::NXP::App::LowPower diff --git a/examples/platform/nxp/common/operational_keystore/include/OperationalKeystore.h b/examples/platform/nxp/common/operational_keystore/include/OperationalKeystore.h new file mode 100644 index 00000000000000..4bb3582fc63de0 --- /dev/null +++ b/examples/platform/nxp/common/operational_keystore/include/OperationalKeystore.h @@ -0,0 +1,41 @@ +/* + * 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 + +namespace chip::NXP::App::OperationalKeystore { + +/** + * @brief Getter for operational keystore instance. + * + * It can be overwritten to return an instance of a dervied keystore implementation. + * + */ +chip::Crypto::OperationalKeystore * GetInstance(); + +/** + * @brief Initialization entry for specific operational keystore actions. + * + * For example, it can be overwritten to register a persistent storage delegate. + * + */ +CHIP_ERROR Init(PersistentStorageDelegate * delegate); + +} // namespace chip::NXP::App::OperationalKeystore diff --git a/examples/platform/nxp/common/operational_keystore/source/OperationalKeystoreEmpty.cpp b/examples/platform/nxp/common/operational_keystore/source/OperationalKeystoreEmpty.cpp new file mode 100644 index 00000000000000..6d69720bc060c0 --- /dev/null +++ b/examples/platform/nxp/common/operational_keystore/source/OperationalKeystoreEmpty.cpp @@ -0,0 +1,31 @@ +/* + * 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 "OperationalKeystore.h" + +chip::Crypto::OperationalKeystore * chip::NXP::App::OperationalKeystore::GetInstance() +{ + // Default implementation returns a null pointer. + // Applications that have a specific operational keystore defined should implement + // this function and return a pointer to that instance. + return nullptr; +} + +CHIP_ERROR chip::NXP::App::OperationalKeystore::Init(PersistentStorageDelegate * delegate) +{ + return CHIP_NO_ERROR; +} diff --git a/examples/platform/nxp/common/ota_requestor/source/OTARequestorInitiatorMultiImage.cpp b/examples/platform/nxp/common/ota_requestor/source/OTARequestorInitiatorMultiImage.cpp new file mode 100644 index 00000000000000..527b416a86a4e4 --- /dev/null +++ b/examples/platform/nxp/common/ota_requestor/source/OTARequestorInitiatorMultiImage.cpp @@ -0,0 +1,43 @@ +/* + * + * 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 "OTARequestorInitiator.h" + +using namespace chip; + +constexpr uint16_t requestedOtaBlockSize = 1024; + +void chip::NXP::App::OTARequestorInitiator::InitOTA(intptr_t context) +{ + auto * otaRequestorInit = reinterpret_cast(context); + // Set the global instance of the OTA requestor core component + SetRequestorInstance(&otaRequestorInit->gRequestorCore); + + otaRequestorInit->gRequestorStorage.Init(chip::Server::GetInstance().GetPersistentStorage()); + otaRequestorInit->gRequestorCore.Init(chip::Server::GetInstance(), otaRequestorInit->gRequestorStorage, + otaRequestorInit->gRequestorUser, otaRequestorInit->gDownloader); + otaRequestorInit->gRequestorUser.SetMaxDownloadBlockSize(requestedOtaBlockSize); + + auto & imageProcessor = OTAImageProcessorImpl::GetDefaultInstance(); + otaRequestorInit->gRequestorUser.Init(&otaRequestorInit->gRequestorCore, &imageProcessor); + imageProcessor.Init(&otaRequestorInit->gDownloader); + // Set the image processor instance used for handling image being downloaded + otaRequestorInit->gDownloader.SetImageProcessorDelegate(&imageProcessor); +} + +void chip::NXP::App::OTARequestorInitiator::HandleSelfTest() {} diff --git a/examples/platform/nxp/common/rpc/include/AppRpc.h b/examples/platform/nxp/common/rpc/include/AppRpc.h new file mode 100644 index 00000000000000..9e56a8b80d0b00 --- /dev/null +++ b/examples/platform/nxp/common/rpc/include/AppRpc.h @@ -0,0 +1,56 @@ +/* + * 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 + +#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE +#include "pigweed/rpc_services/Button.h" +#endif + +namespace chip::NXP::App::Rpc { + +/** + * @brief Initialization of RPC-related board code. + * + * For example, enabling clock for UART interface + * and initializing board pins. + * + */ +CHIP_ERROR Init(); + +#if defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +/** + * @brief Rebooting the device. + * + * RPC implementation will delegate reboot procedure to this function. + * + */ +void Reboot(); +#endif + +#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE +/** + * @brief Handles button events. + * + * RPC implementation will delegate handling events to this function. + */ +void ButtonHandler(const chip_rpc_ButtonEvent & request); +#endif + +} // namespace chip::NXP::App::Rpc diff --git a/examples/platform/nxp/common/ui_feedback/include/LedManager.h b/examples/platform/nxp/common/ui_feedback/include/LedManager.h new file mode 100644 index 00000000000000..b14fae7aebb60c --- /dev/null +++ b/examples/platform/nxp/common/ui_feedback/include/LedManager.h @@ -0,0 +1,91 @@ +/* + * + * 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 "AppConfig.h" +#include "LedOnOff.h" +#include "LedWidgetInterface.h" +#include "UserInterfaceFeedback.h" + +#include +#include + +using namespace chip::NXP::App; + +/** + * @brief Specifies the array index of the status LED. + * + * The status LED is usually used to indicate additional information + * related to the connectivity status of the application. + */ +#ifndef LED_MANAGER_STATUS_LED_INDEX +#define LED_MANAGER_STATUS_LED_INDEX 0 +#endif + +/** + * @brief Specifies the array index of the light LED. + * + * The light LED is usually used to indicate the state of some cluster + * attribute: e.g OnOff attribute from OnOff cluster. + */ +#ifndef LED_MANAGER_LIGHT_LED_INDEX +#define LED_MANAGER_LIGHT_LED_INDEX 1 +#endif + +/** + * @brief Enable status LED. + * + */ +#ifndef LED_MANAGER_ENABLE_STATUS_LED +#define LED_MANAGER_ENABLE_STATUS_LED 0 +#endif + +/** + * @brief Manager of LedWidgetInterface concrete classes. + * + * It implements the UserInterfaceFeedback abstract interface. + */ +class LedManager : public UserInterfaceFeedback +{ +public: + void Init() override; + void DisplayInLoop() override; + void DisplayOnAction(Action action) override; + void RestoreState() override; + +private: + void ApplyTurnOn(); + void ApplyTurnOff(); + void AnimateOnAction(uint32_t onTimeMS, uint32_t offTimeMS); + +#if LED_MANAGER_ENABLE_STATUS_LED + void UpdateStatus(); + + LedOnOff statusLed; +#endif + LedOnOff lightLed; + + friend LedManager & LightingMgr(void); + static LedManager sLedManager; +}; + +inline LedManager & LightingMgr(void) +{ + return LedManager::sLedManager; +} diff --git a/examples/platform/nxp/common/ui_feedback/include/UserInterfaceFeedback.h b/examples/platform/nxp/common/ui_feedback/include/UserInterfaceFeedback.h new file mode 100644 index 00000000000000..9e844a73d9191f --- /dev/null +++ b/examples/platform/nxp/common/ui_feedback/include/UserInterfaceFeedback.h @@ -0,0 +1,72 @@ +/* + * 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 + +/** + * @brief Defines an abstract interface for providing feedback to the user. + * + * For example, the feedback can be provided through a logging mechanism or + * through LED animation. + */ +class UserInterfaceFeedback +{ +public: + /** + * @brief Set of possible actions handled by the DisplayOnAction method. + * + */ + enum class Action : uint8_t + { + kFactoryReset = 0, + kTriggerEffect, + kIdentify + }; + + virtual ~UserInterfaceFeedback() = default; + + virtual void Init() = 0; + + /** + * @brief Provide feedback in app task main loop. + * + * For a concrete example, this can be a LED animation command. + */ + virtual void DisplayInLoop() = 0; + + /** + * @brief Provide feedback on a specific action. + * + */ + virtual void DisplayOnAction(Action action) = 0; + + /** + * @brief Restore feedback state based on a default config. + * + * For example, the restoration can be based on a cluster attribute + * value, such as OnOff value in case of a LightingManager. + */ + virtual void RestoreState() = 0; +}; + +/** + * @brief Getter for the concrete class that implements the interface. + * + * It returns a reference to UserInterfaceFeedback, such that only the + * public API can be used regardless of the actual concrete class. + */ +extern UserInterfaceFeedback & FeedbackMgr(); diff --git a/examples/platform/nxp/common/ui_feedback/source/LedManager.cpp b/examples/platform/nxp/common/ui_feedback/source/LedManager.cpp new file mode 100644 index 00000000000000..ac2456f327b61c --- /dev/null +++ b/examples/platform/nxp/common/ui_feedback/source/LedManager.cpp @@ -0,0 +1,150 @@ +/* + * + * Copyright (c) 2021, 2024 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 "LedManager.h" + +#include "AppConfig.h" +#include "AppTask.h" + +#include +#include +#include +#include +#include + +LedManager LedManager::sLedManager; + +#if CONFIG_ENABLE_FEEDBACK +UserInterfaceFeedback & FeedbackMgr() +{ + return LightingMgr(); +} +#endif + +void LedManager::ApplyTurnOn() +{ + if (!lightLed.IsTurnedOff()) + return; + + lightLed.Set(true); +} + +void LedManager::ApplyTurnOff() +{ + if (lightLed.IsTurnedOff()) + return; + + lightLed.Set(false); +} + +void LedManager::Init() +{ + /* start with all LEDS turned off */ +#if LED_MANAGER_ENABLE_STATUS_LED + statusLed.Init(LED_MANAGER_STATUS_LED_INDEX, false); +#endif + /* The parameters will not be used by the dimmer init. */ + lightLed.Init(LED_MANAGER_LIGHT_LED_INDEX, false); + + RestoreState(); +} + +void LedManager::DisplayInLoop() +{ +#if LED_MANAGER_ENABLE_STATUS_LED + UpdateStatus(); + statusLed.Animate(); +#endif + lightLed.Animate(); +} + +void LedManager::DisplayOnAction(Action action) +{ + switch (action) + { + case UserInterfaceFeedback::Action::kFactoryReset: + case UserInterfaceFeedback::Action::kTriggerEffect: + AnimateOnAction(500, 500); + break; + case UserInterfaceFeedback::Action::kIdentify: + AnimateOnAction(250, 250); + break; + default: + break; + } +} + +void LedManager::RestoreState() +{ + /* restore initial state for the LED indicating Lighting state */ + lightLed.Set(false); + + chip::DeviceLayer::PlatformMgr().ScheduleWork([](intptr_t arg) { + bool val = false; + APP_CLUSTER_ATTRIBUTE::Get(APP_DEVICE_TYPE_ENDPOINT, &val); + if (val) + LightingMgr().ApplyTurnOn(); + else + LightingMgr().ApplyTurnOff(); + }); +} + +void LedManager::AnimateOnAction(uint32_t onTimeMS, uint32_t offTimeMS) +{ +#if LED_MANAGER_ENABLE_STATUS_LED + statusLed.Set(false); + statusLed.Animate(onTimeMS, offTimeMS); +#endif + + lightLed.Set(false); + lightLed.Animate(onTimeMS, offTimeMS); +} + +#if LED_MANAGER_ENABLE_STATUS_LED +void LedManager::UpdateStatus() +{ + bool isThreadProvisioned = false; + uint16_t bleConnections = 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 (chip::DeviceLayer::PlatformMgr().TryLockChipStack()) + { + isThreadProvisioned = chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned(); + bleConnections = chip::DeviceLayer::ConnectivityMgr().NumBLEConnections(); + chip::DeviceLayer::PlatformMgr().UnlockChipStack(); + } + + if (isThreadProvisioned) + { + statusLed.Animate(950, 50); + } + else if (bleConnections != 0) + { + statusLed.Animate(100, 100); + } + else + { + statusLed.Animate(50, 950); + } +} +#endif diff --git a/examples/platform/nxp/k32w/k32w1/BUILD.gn b/examples/platform/nxp/k32w/k32w1/BUILD.gn deleted file mode 100644 index 5cd2a8b31392c2..00000000000000 --- a/examples/platform/nxp/k32w/k32w1/BUILD.gn +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright (c) 2020 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import("//build_overrides/chip.gni") -import("//build_overrides/nxp_sdk.gni") - -import("${nxp_sdk_build_root}/nxp_sdk.gni") - -import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") - -config("chip_examples_project_config") { - include_dirs = [ - "app/project_include", - "${chip_root}", - ] -} - -source_set("openthread_core_config_k32w1_chip_examples") { - sources = [ "app/project_include/OpenThreadConfig.h" ] - - public_deps = [ "${chip_root}/third_party/openthread/platforms/nxp/k32w/k32w1:openthread_core_config_k32w1" ] - - public_configs = [ ":chip_examples_project_config" ] -} diff --git a/examples/platform/nxp/k32w/k32w1/app/BUILD.gn b/examples/platform/nxp/k32w/k32w1/app/BUILD.gn deleted file mode 100644 index 6671d140688df9..00000000000000 --- a/examples/platform/nxp/k32w/k32w1/app/BUILD.gn +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (c) 2020 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import("//build_overrides/chip.gni") - -config("chip_examples_project_config") { - include_dirs = [ "app/project_include" ] -} - -source_set("openthread_core_config_k32w1_chip_examples") { - sources = [ "app/project_include/OpenThreadConfig.h" ] - - public_deps = [ "${chip_root}/third_party/openthread/platforms/nxp/k32w/k32w1:openthread_core_config_k32w1" ] - - public_configs = [ ":chip_examples_project_config" ] -} diff --git a/examples/platform/nxp/k32w/k32w1/app/args.gni b/examples/platform/nxp/k32w/k32w1/app/args.gni deleted file mode 100644 index 2705c251fb807d..00000000000000 --- a/examples/platform/nxp/k32w/k32w1/app/args.gni +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (c) 2020 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import("//build_overrides/chip.gni") - -import("${chip_root}/src/platform/nxp/k32w/k32w1/args.gni") - -openthread_project_core_config_file = "OpenThreadConfig.h" - -chip_ble_project_config_include = "" -chip_device_project_config_include = "" -chip_project_config_include = "" -chip_inet_project_config_include = "" -chip_system_project_config_include = "" - -chip_system_config_provide_statistics = false -chip_with_nlfaultinjection = true diff --git a/examples/platform/nxp/k32w/k32w1/args.gni b/examples/platform/nxp/k32w/k32w1/args.gni deleted file mode 100644 index f7d9dccd82e1fd..00000000000000 --- a/examples/platform/nxp/k32w/k32w1/args.gni +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright (c) 2020 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import("//build_overrides/chip.gni") - -import("${chip_root}/src/platform/nxp/k32w/k32w1/args.gni") - -arm_float_abi = "hard" -arm_cpu = "cortex-m33" -arm_fpu = "fpv5-sp-d16" -arm_arch = "armv8-m.main+dsp+fp" - -chip_openthread_ftd = false -openthread_core_config_deps = [] -openthread_core_config_deps = [ "${chip_root}/examples/platform/nxp/k32w/k32w1:openthread_core_config_k32w1_chip_examples" ] - -chip_ble_project_config_include = "" -chip_device_project_config_include = "" -chip_project_config_include = "" -chip_inet_project_config_include = "" -chip_system_project_config_include = "" - -chip_system_config_provide_statistics = false -chip_with_nlfaultinjection = true - -chip_system_config_use_open_thread_inet_endpoints = true -chip_with_lwip = false diff --git a/examples/platform/nxp/k32w/k32w1/app/ldscripts/k32w1_app.ld b/examples/platform/nxp/k32w1/app/ldscripts/k32w1_app.ld similarity index 100% rename from examples/platform/nxp/k32w/k32w1/app/ldscripts/k32w1_app.ld rename to examples/platform/nxp/k32w1/app/ldscripts/k32w1_app.ld diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/include/FreeRTOSConfig.h b/examples/platform/nxp/k32w1/app/project_include/freeRTOS/FreeRTOSConfig.h similarity index 97% rename from examples/contact-sensor-app/nxp/k32w/k32w1/include/FreeRTOSConfig.h rename to examples/platform/nxp/k32w1/app/project_include/freeRTOS/FreeRTOSConfig.h index a4e204700672a3..286566a027b6f9 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/include/FreeRTOSConfig.h +++ b/examples/platform/nxp/k32w1/app/project_include/freeRTOS/FreeRTOSConfig.h @@ -85,14 +85,9 @@ extern uint32_t SystemCoreClock; /* 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 diff --git a/examples/platform/nxp/k32w/k32w1/app/project_include/OpenThreadConfig.h b/examples/platform/nxp/k32w1/app/project_include/openthread/OpenThreadConfig.h similarity index 100% rename from examples/platform/nxp/k32w/k32w1/app/project_include/OpenThreadConfig.h rename to examples/platform/nxp/k32w1/app/project_include/openthread/OpenThreadConfig.h diff --git a/examples/platform/nxp/k32w/k32w1/app/support/BUILD.gn b/examples/platform/nxp/k32w1/app/support/BUILD.gn similarity index 78% rename from examples/platform/nxp/k32w/k32w1/app/support/BUILD.gn rename to examples/platform/nxp/k32w1/app/support/BUILD.gn index dc688edc2c78ed..96d05e9ba29f13 100644 --- a/examples/platform/nxp/k32w/k32w1/app/support/BUILD.gn +++ b/examples/platform/nxp/k32w1/app/support/BUILD.gn @@ -15,8 +15,12 @@ import("//build_overrides/chip.gni") import("//build_overrides/nxp_sdk.gni") +import("${nxp_sdk_matter_support_root}/gn_build/nxp_sdk.gni") + +import("${chip_root}/src/platform/nxp/${nxp_platform}/args.gni") + config("support_config") { - include_dirs = [ "../../../../.." ] + include_dirs = [ "${chip_root}" ] # Link options that provides replace dynamic memory operations in standard # library with the FreeRTOS malloc in platform code. @@ -29,7 +33,7 @@ config("support_config") { "-Wl,--wrap=MemoryAlloc", # Wrap these in case internal newlib call them (e.g. strdup will) - # directly call _malloc_r) + # directly call _malloc_r "-Wl,--wrap=_malloc_r", "-Wl,--wrap=_realloc_r", "-Wl,--wrap=_free_r", @@ -38,7 +42,7 @@ config("support_config") { ] } -source_set("freertos_mbedtls_utils") { +source_set("freertos_memory_utils") { sources = [ "FreeRtosHooks.c", "FreeRtosHooks.h", @@ -49,5 +53,11 @@ source_set("freertos_mbedtls_utils") { cflags = [ "-Wconversion" ] + if (chip_key_storage == "fwk_nvm") { + defines = [ "CHIP_PLAT_NVM_SUPPORT=1" ] + } else if (chip_key_storage == "littlefs") { + defines = [ "CHIP_PLAT_NVM_SUPPORT=3" ] + } + public_configs = [ ":support_config" ] } diff --git a/examples/platform/nxp/k32w/k32w1/app/support/FreeRtosHooks.c b/examples/platform/nxp/k32w1/app/support/FreeRtosHooks.c similarity index 96% rename from examples/platform/nxp/k32w/k32w1/app/support/FreeRtosHooks.c rename to examples/platform/nxp/k32w1/app/support/FreeRtosHooks.c index a7c78a77440e03..72d5f1acc6161e 100644 --- a/examples/platform/nxp/k32w/k32w1/app/support/FreeRtosHooks.c +++ b/examples/platform/nxp/k32w1/app/support/FreeRtosHooks.c @@ -27,7 +27,11 @@ #include #include +#if (CHIP_PLAT_NVM_SUPPORT == 1) #include "NVM_Interface.h" +#elif (CHIP_PLAT_NVM_SUPPORT == 3) +#include "fwk_file_cache.h" +#endif #include "PWR_Interface.h" #include "board.h" #include "fsl_os_abstraction.h" @@ -139,8 +143,10 @@ void vApplicationIdleHook(void) // to ensure there is no context switch during the actual // writing, thus avoiding race conditions. OSA_InterruptDisable(); -#if CHIP_PLAT_NVM_SUPPORT +#if (CHIP_PLAT_NVM_SUPPORT == 1) NvIdle(); +#elif (CHIP_PLAT_NVM_SUPPORT == 3) + FC_Process(); #endif OSA_InterruptEnable(); diff --git a/examples/platform/nxp/k32w/k32w1/app/support/FreeRtosHooks.h b/examples/platform/nxp/k32w1/app/support/FreeRtosHooks.h similarity index 100% rename from examples/platform/nxp/k32w/k32w1/app/support/FreeRtosHooks.h rename to examples/platform/nxp/k32w1/app/support/FreeRtosHooks.h diff --git a/examples/platform/nxp/k32w/k32w1/app/support/Memconfig.cpp b/examples/platform/nxp/k32w1/app/support/Memconfig.cpp similarity index 100% rename from examples/platform/nxp/k32w/k32w1/app/support/Memconfig.cpp rename to examples/platform/nxp/k32w1/app/support/Memconfig.cpp diff --git a/examples/platform/nxp/k32w1/board/peripherals.c b/examples/platform/nxp/k32w1/board/peripherals.c new file mode 100644 index 00000000000000..f66203bfe2153b --- /dev/null +++ b/examples/platform/nxp/k32w1/board/peripherals.c @@ -0,0 +1,66 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * Copyright (c) 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. + */ + +/*********************************************************************************************************************** + * Included files + **********************************************************************************************************************/ +#include "peripherals.h" + +/*********************************************************************************************************************** + * BOARD_InitPeripherals functional group + **********************************************************************************************************************/ + +/* LittleFS context */ +extern struct lfs_mflash_ctx LittleFS_ctx; +const struct lfs_config LittleFS_config = { .context = (void *) &LittleFS_ctx, + .read = lfs_mflash_read, + .prog = lfs_mflash_prog, + .erase = lfs_mflash_erase, + .sync = lfs_mflash_sync, +#ifdef LFS_THREADSAFE + .lock = lfs_mutex_lock, + .unlock = lfs_mutex_unlock, +#endif + .read_size = LITTLEFS_READ_SIZE, + .prog_size = LITTLEFS_PROG_SIZE, + .block_size = LITTLEFS_BLOCK_SIZE, + .block_count = LITTLEFS_BLOCK_COUNT, + .block_cycles = LITTLEFS_BLOCK_CYCLES, + .cache_size = LITTLEFS_CACHE_SIZE, + .lookahead_size = LITTLEFS_LOOKAHEAD_SIZE }; + +/* Empty initialization function (commented out) +static void LittleFS_init(void) { +} */ + +/*********************************************************************************************************************** + * Initialization functions + **********************************************************************************************************************/ +void BOARD_InitPeripherals(void) +{ + /* Initialize components */ +} + +/*********************************************************************************************************************** + * BOARD_InitBootPeripherals function + **********************************************************************************************************************/ +void BOARD_InitBootPeripherals(void) +{ + BOARD_InitPeripherals(); +} diff --git a/examples/platform/nxp/k32w1/board/peripherals.h b/examples/platform/nxp/k32w1/board/peripherals.h new file mode 100644 index 00000000000000..38caf2657c4d0f --- /dev/null +++ b/examples/platform/nxp/k32w1/board/peripherals.h @@ -0,0 +1,101 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * Copyright (c) 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. + */ + +#ifndef _PERIPHERALS_H_ +#define _PERIPHERALS_H_ + +/*********************************************************************************************************************** + * Included files + **********************************************************************************************************************/ +#include "fsl_common.h" + +#include "lfs.h" + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*********************************************************************************************************************** + * User definitions + **********************************************************************************************************************/ +extern uint32_t NV_STORAGE_START_ADDRESS[]; +extern uint32_t NV_STORAGE_MAX_SECTORS[]; + +#define LITTLEFS_START_ADDR (uint32_t)(NV_STORAGE_START_ADDRESS) + +/*********************************************************************************************************************** + * Definitions + **********************************************************************************************************************/ +/* Definitions for BOARD_InitPeripherals functional group */ +/* Maximum block read size definition */ +#define LITTLEFS_READ_SIZE 16 +/* Maximum block program size definition */ +#define LITTLEFS_PROG_SIZE 128 +/* Erasable block size definition */ +#define LITTLEFS_BLOCK_SIZE 8192 +/* Block count definition */ +#define LITTLEFS_BLOCK_COUNT (uint32_t)(NV_STORAGE_MAX_SECTORS) +/* Block cycles definition */ +#define LITTLEFS_BLOCK_CYCLES 100 +/* Minimum block cache size definition */ +#define LITTLEFS_CACHE_SIZE 1024 +/* Minimum lookahead buffer size definition */ +#define LITTLEFS_LOOKAHEAD_SIZE 16 +/* Block starting address definition */ +#define LITTLEFS_START_ADDR (uint32_t)(NV_STORAGE_START_ADDRESS) + +/*********************************************************************************************************************** + * Global variables + **********************************************************************************************************************/ +/* LittleFS configuration */ +extern const struct lfs_config LittleFS_config; + +/*********************************************************************************************************************** + * Callback functions + **********************************************************************************************************************/ +/* LittleFS read a block region callback*/ +extern int lfs_mflash_read(const struct lfs_config *, lfs_block_t, lfs_off_t, void *, lfs_size_t); +/* LittleFS program a block region callback*/ +extern int lfs_mflash_prog(const struct lfs_config *, lfs_block_t, lfs_off_t, const void *, lfs_size_t); +/* LittleFS erase a block callback*/ +extern int lfs_mflash_erase(const struct lfs_config *, lfs_block_t); +/* LittleFS state sync callback*/ +extern int lfs_mflash_sync(const struct lfs_config *); +/* LittleFS state lock callback*/ +extern int lfs_mutex_lock(const struct lfs_config *); +/* LittleFS state unlock callback*/ +extern int lfs_mutex_unlock(const struct lfs_config *); + +/*********************************************************************************************************************** + * Initialization functions + **********************************************************************************************************************/ + +void BOARD_InitPeripherals(void); + +/*********************************************************************************************************************** + * BOARD_InitBootPeripherals function + **********************************************************************************************************************/ + +void BOARD_InitBootPeripherals(void); + +#if defined(__cplusplus) +} +#endif + +#endif /* _PERIPHERALS_H_ */ diff --git a/examples/platform/nxp/k32w1/button/ButtonManager.cpp b/examples/platform/nxp/k32w1/button/ButtonManager.cpp new file mode 100644 index 00000000000000..47e5f9fd4b6c9d --- /dev/null +++ b/examples/platform/nxp/k32w1/button/ButtonManager.cpp @@ -0,0 +1,215 @@ +/* + * + * 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 "ButtonManager.h" +#include "AppConfig.h" +#include "AppMatterButton.h" +#include "AppTask.h" +#include "UserInterfaceFeedback.h" + +#include + +extern "C" { +#include "app.h" +#include "board_comp.h" +} + +CHIP_ERROR chip::NXP::App::AppMatterButton_registerButtons(void) +{ + /* Board buttons are initialized in otSysInit, when APP_InitServices is called. */ + button_status_t bStatus; + + bStatus = BUTTON_InstallCallback((button_handle_t) g_buttonHandle[0], ButtonManager::BleCallback, NULL); + VerifyOrReturnError(bStatus == kStatus_BUTTON_Success, CHIP_ERROR_UNEXPECTED_EVENT, + ChipLogError(DeviceLayer, "button init error")); + + bStatus = BUTTON_InstallCallback((button_handle_t) g_buttonHandle[1], ButtonManager::AppActionCallback, NULL); + VerifyOrReturnError(bStatus == kStatus_BUTTON_Success, CHIP_ERROR_UNEXPECTED_EVENT, + ChipLogError(DeviceLayer, "button init error")); + + ReturnErrorOnFailure(ButtonMgr().Init()); + + return CHIP_NO_ERROR; +} + +ButtonManager ButtonManager::sInstance; + +TimerHandle_t resetTimer; + +CHIP_ERROR ButtonManager::Init() +{ + resetTimer = xTimerCreate("FnTmr", 1, false, (void *) this, [](TimerHandle_t xTimer) { + AppEvent event; + event.Handler = FunctionTimerEventHandler; + chip::NXP::App::GetAppTask().PostEvent(event); + }); + VerifyOrReturnError(resetTimer != NULL, APP_ERROR_CREATE_TIMER_FAILED); + + return CHIP_NO_ERROR; +} + +button_status_t ButtonManager::BleCallback(void * handle, button_callback_message_t * message, void * param) +{ + AppEvent event; + + switch (message->event) + { + case kBUTTON_EventOneClick: + case kBUTTON_EventShortPress: + event.Handler = ButtonManager::BleHandler; + break; + case kBUTTON_EventLongPress: + event.Handler = ButtonManager::ResetActionEventHandler; + break; + default: + /* No action required */ + break; + } + + chip::NXP::App::GetAppTask().PostEvent(event); + + return kStatus_BUTTON_Success; +} + +button_status_t ButtonManager::AppActionCallback(void * handle, button_callback_message_t * message, void * param) +{ + AppEvent event; + + switch (message->event) + { + case kBUTTON_EventOneClick: + case kBUTTON_EventShortPress: + event.Handler = ButtonManager::AppActionEventHandler; + break; + case kBUTTON_EventLongPress: + // Soft reset ensures that platform manager shutdown procedure is called. + event.Handler = ButtonManager::SoftResetHandler; + break; + default: + /* No action required */ + break; + } + + chip::NXP::App::GetAppTask().PostEvent(event); + + return kStatus_BUTTON_Success; +} + +void ButtonManager::FunctionTimerEventHandler(const AppEvent & event) +{ + ChipLogProgress(DeviceLayer, "Device will factory reset..."); + + // Actually trigger Factory Reset + chip::Server::GetInstance().ScheduleFactoryReset(); +} + +void ButtonManager::ResetActionEventHandler(const AppEvent & event) +{ + if (xTimerIsTimerActive(resetTimer)) + { + ButtonMgr().CancelTimer(); +#if CONFIG_ENABLE_FEEDBACK + FeedbackMgr().RestoreState(); +#endif + ChipLogProgress(DeviceLayer, "Factory Reset was cancelled!"); + } + else + { + uint32_t resetTimeout = BUTTON_MANAGER_FACTORY_RESET_TIMEOUT_MS; + ChipLogProgress(DeviceLayer, "Factory Reset Triggered. Push the RESET button within %lu ms to cancel!", resetTimeout); + +#if CONFIG_ENABLE_FEEDBACK + FeedbackMgr().DisplayOnAction(UserInterfaceFeedback::Action::kFactoryReset); +#endif + ButtonMgr().StartTimer(resetTimeout); + } +} + +void ButtonManager::AppActionEventHandler(const AppEvent & event) +{ + chip::DeviceLayer::PlatformMgr().ScheduleWork( + [](intptr_t arg) { + bool val = false; + APP_CLUSTER_ATTRIBUTE::Get(APP_DEVICE_TYPE_ENDPOINT, &val); + auto status = APP_CLUSTER_ATTRIBUTE::Set(APP_DEVICE_TYPE_ENDPOINT, (bool) !val); + if (status != chip::Protocols::InteractionModel::Status::Success) + { + ChipLogProgress(DeviceLayer, "Error when updating cluster attribute"); + } + }, + (intptr_t) nullptr); +} + +void ButtonManager::SoftResetHandler(const AppEvent & event) +{ + chip::DeviceLayer::PlatformMgrImpl().CleanReset(); +} + +#if CHIP_CONFIG_ENABLE_ICD_LIT +static void UserActiveModeHandler(const AppEvent & event) +{ + chip::DeviceLayer::PlatformMgr().ScheduleWork( + [](intptr_t arg) { chip::app::ICDNotifier::GetInstance().NotifyNetworkActivityNotification(); }, 0); +} +#endif + +void ButtonManager::BleHandler(const AppEvent & event) +{ + if (xTimerIsTimerActive(resetTimer)) + { + // If a factory reset is scheduled, pressing the BLE button will cancel it. + ResetActionEventHandler(event); + return; + } + +#if CHIP_CONFIG_ENABLE_ICD_LIT + if (chip::DeviceLayer::ConfigurationMgr().IsFullyProvisioned()) + { + // If the device is commissioned and a factory reset is not scheduled, switch to active mode. + UserActiveModeHandler(event); + return; + } +#endif + + chip::NXP::App::GetAppTask().SwitchCommissioningStateHandler(); +} + +void ButtonManager::CancelTimer() +{ + if (xTimerStop(resetTimer, 0) == pdFAIL) + { + ChipLogProgress(DeviceLayer, "app timer stop() failed"); + } +} + +void ButtonManager::StartTimer(uint32_t aTimeoutInMs) +{ + if (xTimerIsTimerActive(resetTimer)) + { + ChipLogProgress(DeviceLayer, "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(resetTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) != pdPASS) + { + ChipLogProgress(DeviceLayer, "app timer start() failed"); + } +} diff --git a/examples/platform/nxp/k32w1/button/ButtonManager.h b/examples/platform/nxp/k32w1/button/ButtonManager.h new file mode 100644 index 00000000000000..aec2411e1095af --- /dev/null +++ b/examples/platform/nxp/k32w1/button/ButtonManager.h @@ -0,0 +1,108 @@ +/* + * + * 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 "AppEvent.h" + +#include "FreeRTOS.h" +#include "timers.h" + +#include "fsl_component_button.h" + +#include + +// Application-defined error codes in the CHIP_ERROR space. +#define APP_ERROR_CREATE_TIMER_FAILED CHIP_APPLICATION_ERROR(0x01) + +/** + * @brief Timeout (ms) for factory data reset action. + * + * During this timeout, the factory reset action can be cancelled by pressing a button. + */ +#ifndef BUTTON_MANAGER_FACTORY_RESET_TIMEOUT_MS +#define BUTTON_MANAGER_FACTORY_RESET_TIMEOUT_MS 6000 +#endif + +/** + * @brief This class describes a manager for button callbacks. + * + */ +class ButtonManager +{ +public: + CHIP_ERROR Init(); + + // These are the callbacks registered with the buttons. They will delegate actions + // to other methods based on the button event: short press, long press etc. + static button_status_t BleCallback(void * handle, button_callback_message_t * message, void * param); + static button_status_t AppActionCallback(void * handle, button_callback_message_t * message, void * param); + +private: + /** + * @brief This callback performs a soft reset. + * + * This can be used when the user wants to clean reset the device, + * meaning that Matter is properly shutdown, unlike a RESET button + * press, where the device resets without calling the shutdown procedure. + */ + static void SoftResetHandler(const AppEvent & event); + + /** + * @brief This callback toggles between BLE start/stop advertising. + * + * It is used during commissioning to ensure a user-intent commissioning flow. + */ + static void BleHandler(const AppEvent & event); + + /** + * @brief This callback updates the application state. + * + * An example of application state would be the lighting manager light LED state. + * This handler will toggle the light LED state. + */ + static void AppActionEventHandler(const AppEvent & event); + + /** + * @brief This callback schedules a factory reset. + * + * The factory reset is scheduled based on the value of BUTTON_MANAGER_FACTORY_RESET_TIMEOUT_MS. + * Until the timer expires, the user can cancel the factory reset operation by doing an action. + * In this reference app, the action would be pressing again the factory reset button. + */ + static void ResetActionEventHandler(const AppEvent & event); + + /** + * @brief This callback performs a factory reset. + * + * This is the callback registered with the timer scheduled in ResetActionEventHandler. + * It will schedule a factory reset using the Matter server instance. + */ + static void FunctionTimerEventHandler(const AppEvent & event); + + void CancelTimer(); + void StartTimer(uint32_t aTimeoutInMs); + + friend ButtonManager & ButtonMgr(); + static ButtonManager sInstance; +}; + +inline ButtonManager & ButtonMgr() +{ + return ButtonManager::sInstance; +} diff --git a/examples/platform/nxp/k32w1/clusters/Identify.cpp b/examples/platform/nxp/k32w1/clusters/Identify.cpp new file mode 100644 index 00000000000000..2d309f975eaca0 --- /dev/null +++ b/examples/platform/nxp/k32w1/clusters/Identify.cpp @@ -0,0 +1,123 @@ +/* + * 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 "Identify.h" +#include "AppTask.h" +#include "UserInterfaceFeedback.h" + +#include + +using namespace chip; +using namespace chip::app; + +static Identify gIdentify = { EndpointId{ 1 }, NXP::App::OnIdentifyStart, NXP::App::OnIdentifyStop, + Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator, NXP::App::OnTriggerEffect, + // Use invalid value for identifiers to enable TriggerEffect command + // to stop Identify command for each effect + Clusters::Identify::EffectIdentifierEnum::kUnknownEnumValue, + Clusters::Identify::EffectVariantEnum::kDefault }; + +namespace chip::NXP::App { + +void OnIdentifyStart(Identify * identify) +{ + chip::DeviceLayer::SystemLayer().CancelTimer(OnTriggerEffectComplete, identify); + OnTriggerEffectComplete(&chip::DeviceLayer::SystemLayer(), identify); + + ChipLogProgress(Zcl, "Identify process has started. Status LED should blink with a period of 0.5 seconds."); + +#if CONFIG_ENABLE_FEEDBACK + FeedbackMgr().DisplayOnAction(UserInterfaceFeedback::Action::kIdentify); +#endif +} + +void OnIdentifyStop(Identify * identify) +{ + ChipLogProgress(Zcl, "Identify process has stopped."); + +#if CONFIG_ENABLE_FEEDBACK + FeedbackMgr().RestoreState(); +#endif +} + +void OnTriggerEffectComplete(chip::System::Layer * systemLayer, void * appState) +{ + // Let Identify command take over if called during TriggerEffect already running + ChipLogProgress(Zcl, "TriggerEffect has stopped."); + + // TriggerEffect finished - reset identifiers + // Use invalid value for identifiers to enable TriggerEffect command + // to stop Identify command for each effect + gIdentify.mCurrentEffectIdentifier = Clusters::Identify::EffectIdentifierEnum::kUnknownEnumValue; + gIdentify.mTargetEffectIdentifier = Clusters::Identify::EffectIdentifierEnum::kUnknownEnumValue; + gIdentify.mEffectVariant = Clusters::Identify::EffectVariantEnum::kDefault; + +#if CONFIG_ENABLE_FEEDBACK + FeedbackMgr().RestoreState(); +#endif +} + +void OnTriggerEffect(Identify * identify) +{ + uint16_t timerDelay = 0; + + ChipLogProgress(Zcl, "TriggerEffect has started."); + + switch (identify->mCurrentEffectIdentifier) + { + case Clusters::Identify::EffectIdentifierEnum::kBlink: + timerDelay = 2; + break; + + case Clusters::Identify::EffectIdentifierEnum::kBreathe: + timerDelay = 15; + break; + + case Clusters::Identify::EffectIdentifierEnum::kOkay: + timerDelay = 4; + break; + + case Clusters::Identify::EffectIdentifierEnum::kChannelChange: + ChipLogProgress(Zcl, "Channel Change effect not supported, using effect %d", + to_underlying(Clusters::Identify::EffectIdentifierEnum::kBlink)); + timerDelay = 2; + break; + + case Clusters::Identify::EffectIdentifierEnum::kFinishEffect: + chip::DeviceLayer::SystemLayer().CancelTimer(OnTriggerEffectComplete, identify); + timerDelay = 1; + break; + + case Clusters::Identify::EffectIdentifierEnum::kStopEffect: + chip::DeviceLayer::SystemLayer().CancelTimer(OnTriggerEffectComplete, identify); + OnTriggerEffectComplete(&chip::DeviceLayer::SystemLayer(), identify); + break; + + default: + ChipLogProgress(Zcl, "Invalid effect identifier."); + } + + if (timerDelay) + { +#if CONFIG_ENABLE_FEEDBACK + FeedbackMgr().DisplayOnAction(UserInterfaceFeedback::Action::kTriggerEffect); +#endif + chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds16(timerDelay), OnTriggerEffectComplete, identify); + } +} + +} // namespace chip::NXP::App diff --git a/examples/platform/nxp/k32w/k32w1/doc/images/debug_k32w1.jpg b/examples/platform/nxp/k32w1/doc/images/debug_k32w1.jpg similarity index 100% rename from examples/platform/nxp/k32w/k32w1/doc/images/debug_k32w1.jpg rename to examples/platform/nxp/k32w1/doc/images/debug_k32w1.jpg diff --git a/examples/platform/nxp/k32w/k32w1/doc/images/import_demo.jpg b/examples/platform/nxp/k32w1/doc/images/import_demo.jpg similarity index 100% rename from examples/platform/nxp/k32w/k32w1/doc/images/import_demo.jpg rename to examples/platform/nxp/k32w1/doc/images/import_demo.jpg diff --git a/examples/platform/nxp/k32w/k32w1/doc/images/installed_sdks.jpg b/examples/platform/nxp/k32w1/doc/images/installed_sdks.jpg similarity index 100% rename from examples/platform/nxp/k32w/k32w1/doc/images/installed_sdks.jpg rename to examples/platform/nxp/k32w1/doc/images/installed_sdks.jpg diff --git a/examples/platform/nxp/k32w/k32w1/doc/images/k32w1-evk.jpg b/examples/platform/nxp/k32w1/doc/images/k32w1-evk.jpg similarity index 100% rename from examples/platform/nxp/k32w/k32w1/doc/images/k32w1-evk.jpg rename to examples/platform/nxp/k32w1/doc/images/k32w1-evk.jpg diff --git a/examples/platform/nxp/k32w/k32w1/doc/images/mcux-sdk-download.jpg b/examples/platform/nxp/k32w1/doc/images/mcux-sdk-download.jpg similarity index 100% rename from examples/platform/nxp/k32w/k32w1/doc/images/mcux-sdk-download.jpg rename to examples/platform/nxp/k32w1/doc/images/mcux-sdk-download.jpg diff --git a/examples/platform/nxp/k32w/k32w1/doc/images/new_project.jpg b/examples/platform/nxp/k32w1/doc/images/new_project.jpg similarity index 100% rename from examples/platform/nxp/k32w/k32w1/doc/images/new_project.jpg rename to examples/platform/nxp/k32w1/doc/images/new_project.jpg diff --git a/examples/platform/nxp/k32w/k32w1/doc/images/ota_topology.JPG b/examples/platform/nxp/k32w1/doc/images/ota_topology.JPG similarity index 100% rename from examples/platform/nxp/k32w/k32w1/doc/images/ota_topology.JPG rename to examples/platform/nxp/k32w1/doc/images/ota_topology.JPG diff --git a/examples/platform/nxp/k32w1/factory_data/source/AppFactoryDataExample.cpp b/examples/platform/nxp/k32w1/factory_data/source/AppFactoryDataExample.cpp new file mode 100644 index 00000000000000..dbccc2fd7dc7f9 --- /dev/null +++ b/examples/platform/nxp/k32w1/factory_data/source/AppFactoryDataExample.cpp @@ -0,0 +1,76 @@ +/* + * + * 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 "FactoryDataDriver.h" +#include "FactoryDataProvider.h" +#else +#include +#endif + +using namespace chip; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; + +#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA && CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR +/** + * Custom factory data restore mechanism. This function must be implemented by vendors. + */ +CHIP_ERROR CustomFactoryDataRestoreMechanism(void) +{ + ChipLogProgress(DeviceLayer, "This is a custom factory data restore mechanism."); + + return CHIP_NO_ERROR; +} +#endif + +/** + * 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_LOAD_REAL_FACTORY_DATA + ReturnErrorOnFailure(FactoryDataDrv().Init()); +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR + FactoryDataPrvd().RegisterRestoreMechanism(CustomFactoryDataRestoreMechanism); +#endif + ReturnErrorOnFailure(FactoryDataPrvd().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/platform/nxp/k32w1/operational_keystore/OperationalKeystore.cpp b/examples/platform/nxp/k32w1/operational_keystore/OperationalKeystore.cpp new file mode 100644 index 00000000000000..ecd72266178984 --- /dev/null +++ b/examples/platform/nxp/k32w1/operational_keystore/OperationalKeystore.cpp @@ -0,0 +1,34 @@ +/* + * 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 "OperationalKeystore.h" +#include "K32W1PersistentStorageOpKeystore.h" + +static chip::K32W1PersistentStorageOpKeystore sInstance; + +chip::Crypto::OperationalKeystore * chip::NXP::App::OperationalKeystore::GetInstance() +{ + return &sInstance; +} + +CHIP_ERROR chip::NXP::App::OperationalKeystore::Init(PersistentStorageDelegate * delegate) +{ + VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INTERNAL); + sInstance.Init(delegate); + + return CHIP_NO_ERROR; +} diff --git a/examples/platform/nxp/k32w/k32w1/util/include/LED_Dimmer.h b/examples/platform/nxp/k32w1/ota/OtaUtils.cpp similarity index 81% rename from examples/platform/nxp/k32w/k32w1/util/include/LED_Dimmer.h rename to examples/platform/nxp/k32w1/ota/OtaUtils.cpp index 424ffa20c97bbd..4088196ba34973 100644 --- a/examples/platform/nxp/k32w/k32w1/util/include/LED_Dimmer.h +++ b/examples/platform/nxp/k32w1/ota/OtaUtils.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2020 Google LLC. + * Copyright (c) 2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,6 +16,9 @@ * limitations under the License. */ -void init_dimmable(); -void init_tpm(); -void move_to_level(uint8_t level); +#include "OtaSupport.h" + +extern "C" void OTAIdleActivities(void) +{ + OTA_TransactionResume(); +} diff --git a/examples/platform/nxp/k32w1/rpc/AppRpc.cpp b/examples/platform/nxp/k32w1/rpc/AppRpc.cpp new file mode 100644 index 00000000000000..beea8408438300 --- /dev/null +++ b/examples/platform/nxp/k32w1/rpc/AppRpc.cpp @@ -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. + */ + +#include "AppRpc.h" +#include "ButtonManager.h" +#include "clock_config.h" +#include "pin_mux.h" + +#include "Rpc.h" + +CHIP_ERROR chip::NXP::App::Rpc::Init() +{ + /* set clock */ + CLOCK_SetIpSrc(kCLOCK_Lpuart1, kCLOCK_IpSrcFro192M); + /* enable clock */ + CLOCK_EnableClock(kCLOCK_Lpuart1); + + BOARD_InitPinLPUART1_TX(); + BOARD_InitPinLPUART1_RX(); + chip::rpc::Init(); + + return CHIP_NO_ERROR; +} + +#if defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +void chip::NXP::App::Rpc::Reboot() +{ + NVIC_SystemReset(); +} +#endif + +#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE +void chip::NXP::App::Rpc::ButtonHandler(const chip_rpc_ButtonEvent & request) +{ + button_callback_message_t * message = new button_callback_message_t; + + switch (request.idx) + { + case 0: + message->event = kBUTTON_EventShortPress; + ButtonMgr().BleCallback(nullptr, message, nullptr); + break; + case 1: + message->event = kBUTTON_EventLongPress; + ButtonMgr().BleCallback(nullptr, message, nullptr); + break; + case 2: + message->event = kBUTTON_EventShortPress; + ButtonMgr().AppActionCallback(nullptr, message, nullptr); + break; + case 3: + message->event = kBUTTON_EventLongPress; + ButtonMgr().AppActionCallback(nullptr, message, nullptr); + break; + default: + break; + } + + delete message; +} +#endif diff --git a/examples/platform/nxp/k32w/k32w1/util/LED_Dimmer.cpp b/examples/platform/nxp/k32w1/util/LedDimmer.cpp similarity index 97% rename from examples/platform/nxp/k32w/k32w1/util/LED_Dimmer.cpp rename to examples/platform/nxp/k32w1/util/LedDimmer.cpp index 02a62724716e53..c682abb5c1480a 100644 --- a/examples/platform/nxp/k32w/k32w1/util/LED_Dimmer.cpp +++ b/examples/platform/nxp/k32w1/util/LedDimmer.cpp @@ -17,7 +17,7 @@ * limitations under the License. */ -#include "LED_Dimmer.h" +#include "LedDimmer.h" #include "fsl_common.h" #include "fsl_port.h" #include "fsl_tpm.h" @@ -36,9 +36,11 @@ #define DEMO_PWM_FREQUENCY (24000U) #endif +namespace chip::NXP::App { + volatile uint8_t updatedDutycycle = 0U; -void init_dimmable() +static void initConfig() { const port_pin_config_t porta20_pin17_config = { /* Internal pull-up/down resistor is disabled */ (uint16_t) kPORT_PullDisable, @@ -105,15 +107,15 @@ void init_dimmable() }; /* PORTA19 (pin 14) is configured as TPM0_CH0 */ PORT_SetPinConfig(PORTA, 19U, &porta19_pin14_config); - - init_tpm(); } -void init_tpm() +void LedDimmer::Init(uint8_t index, bool inverted) { tpm_config_t tpmInfo; tpm_chnl_pwm_signal_param_t tpmParam[3]; + initConfig(); + /* TPM 0 Clock Gate Control: Clock enabled */ CLOCK_EnableClock(kCLOCK_Tpm0); /* Set the source for the LPIT module */ @@ -157,10 +159,12 @@ void init_tpm() TPM_StartTimer(BOARD_TPM_BASEADDR, kTPM_SystemClock); } -void move_to_level(uint8_t level) +void LedDimmer::Set(uint8_t level) { uint8_t control; + mState = level != 0; + updatedDutycycle = static_cast(level * 90) / 255; control = TPM_GetChannelContorlBits(BOARD_TPM_BASEADDR, (tpm_chnl_t) BOARD_FIRST_TPM_CHANNEL); @@ -191,3 +195,5 @@ void move_to_level(uint8_t level) 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); } + +} // namespace chip::NXP::App diff --git a/examples/platform/nxp/k32w/k32w1/util/LEDWidget.cpp b/examples/platform/nxp/k32w1/util/LedOnOff.cpp similarity index 53% rename from examples/platform/nxp/k32w/k32w1/util/LEDWidget.cpp rename to examples/platform/nxp/k32w1/util/LedOnOff.cpp index 695da50e3dae32..92b1f41ebfba4f 100644 --- a/examples/platform/nxp/k32w/k32w1/util/LEDWidget.cpp +++ b/examples/platform/nxp/k32w1/util/LedOnOff.cpp @@ -17,93 +17,69 @@ * limitations under the License. */ -#include "LEDWidget.h" +#include "LedOnOff.h" +#include "app.h" #include -#include "app.h" - -#if CHIP_CONFIG_ENABLE_DIMMABLE_LED -#include "LED_Dimmer.h" -#endif +namespace chip::NXP::App { #if (defined(gAppLedCnt_c) && (gAppLedCnt_c > 0)) -void LEDWidget::Init(uint8_t led, bool inverted) +void LedOnOff::Init(uint8_t index, bool inverted) { mLastChangeTimeMS = 0; - mBlinkOnTimeMS = 0; - mBlinkOffTimeMS = 0; - mGPIONum = led; + mOnTimeMS = 0; + mOffTimeMS = 0; + mIndex = index; mState = false; mOnLogic = !inverted; Set(false); } -void LEDWidget::Invert(void) -{ - Set(!mState); -} - -void LEDWidget::Set(bool state) -{ - mLastChangeTimeMS = mBlinkOnTimeMS = mBlinkOffTimeMS = 0; - DoSet(state); -} - -void LEDWidget::SetLevel(uint8_t level) +void LedOnOff::Set(uint8_t level) { -#if CHIP_CONFIG_ENABLE_DIMMABLE_LED - move_to_level(level); -#endif + mLastChangeTimeMS = mOnTimeMS = mOffTimeMS = 0; + DoSet(level != 0); } -void LEDWidget::Blink(uint32_t changeRateMS) +void LedOnOff::Animate(uint32_t onTimeMS, uint32_t offTimeMS) { - Blink(changeRateMS, changeRateMS); -} - -void LEDWidget::Blink(uint32_t onTimeMS, uint32_t offTimeMS) -{ - mBlinkOnTimeMS = onTimeMS; - mBlinkOffTimeMS = offTimeMS; - Animate(); -} + if (onTimeMS && offTimeMS) + { + mOnTimeMS = onTimeMS; + mOffTimeMS = offTimeMS; + } -void LEDWidget::Animate() -{ - if (mBlinkOnTimeMS != 0 && mBlinkOffTimeMS != 0) + if (mOnTimeMS && mOffTimeMS) { uint64_t nowMS = chip::System::SystemClock().GetMonotonicMilliseconds64().count(); - uint64_t stateDurMS = mState ? mBlinkOnTimeMS : mBlinkOffTimeMS; + uint64_t stateDurMS = mState ? mOnTimeMS : mOffTimeMS; uint64_t nextChangeTimeMS = mLastChangeTimeMS + stateDurMS; if (nextChangeTimeMS < nowMS) { -#if CHIP_CONFIG_ENABLE_DIMMABLE_LED - SetLevel(!mState * 254); - mState = !mState; -#else DoSet(!mState); -#endif mLastChangeTimeMS = nowMS; } } } -void LEDWidget::DoSet(bool state) +void LedOnOff::DoSet(bool state) { mState = state; if (state) { - (void) LED_TurnOnOff((led_handle_t) g_ledHandle[mGPIONum], mOnLogic); + (void) LED_TurnOnOff((led_handle_t) g_ledHandle[mIndex], mOnLogic); } else { - (void) LED_TurnOnOff((led_handle_t) g_ledHandle[mGPIONum], !mOnLogic); + (void) LED_TurnOnOff((led_handle_t) g_ledHandle[mIndex], !mOnLogic); } } #endif /* (defined(gAppLedCnt_c) && (gAppLedCnt_c > 0)) */ + +} // namespace chip::NXP::App diff --git a/examples/platform/nxp/k32w1/util/LightingManagerDimmable.cpp b/examples/platform/nxp/k32w1/util/LightingManagerDimmable.cpp new file mode 100644 index 00000000000000..8476101f5d1a3e --- /dev/null +++ b/examples/platform/nxp/k32w1/util/LightingManagerDimmable.cpp @@ -0,0 +1,79 @@ +/* + * + * 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 "LightingManagerDimmable.h" + +#include "AppConfig.h" +#include "AppTask.h" + +#include +#include +#include +#include +#include + +LightingManagerDimmable LightingManagerDimmable::sLightingManager; + +#if CONFIG_ENABLE_FEEDBACK +UserInterfaceFeedback & FeedbackMgr() +{ + return LightingMgr(); +} +#endif + +void LightingManagerDimmable::ApplyDim(uint8_t value) +{ + ChipLogProgress(DeviceLayer, "Dim action has been initiated"); + LightingManagerDimmable::lightLed.Set(LightingManagerDimmable::lightLed.IsTurnedOff() ? 1 : value); + ChipLogProgress(DeviceLayer, "Move to level %d completed", value); +} + +void LightingManagerDimmable::Init() +{ + /* The parameters will not be used by the dimmer init. */ + lightLed.Init(LIGHTING_MANAGER_LIGHT_LED_INDEX, false); + + RestoreState(); +} + +void LightingManagerDimmable::DisplayInLoop() +{ + lightLed.Animate(); +} + +void LightingManagerDimmable::DisplayOnAction(Action action) +{ + // Do nothing for now. +} + +void LightingManagerDimmable::RestoreState() +{ + /* restore initial state for the LED indicating Lighting state */ + lightLed.Set(false); + + chip::DeviceLayer::PlatformMgr().ScheduleWork([](intptr_t arg) { + chip::app::DataModel::Nullable currentLevel; + chip::app::Clusters::LevelControl::Attributes::CurrentLevel::Get(LIGHTING_MANAGER_APP_DEVICE_TYPE_ENDPOINT, currentLevel); + LightingMgr().ApplyDim(currentLevel.Value()); + }); +} + +void LightingManagerDimmable::UpdateState() +{ + // Do nothing for now. +} diff --git a/examples/platform/nxp/k32w1/util/LightingManagerDimmable.h b/examples/platform/nxp/k32w1/util/LightingManagerDimmable.h new file mode 100644 index 00000000000000..0cd4475ebfb7da --- /dev/null +++ b/examples/platform/nxp/k32w1/util/LightingManagerDimmable.h @@ -0,0 +1,85 @@ +/* + * + * 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 "AppConfig.h" +#include "LedDimmer.h" +#include "LedWidgetInterface.h" +#include "UserInterfaceFeedback.h" + +#include +#include + +using namespace chip::NXP::App; + +/* These flags can be overwritten in AppConfig.h */ +/** + * @brief Specifies the endpoint on which Application Device Type cluster is present. + * + * For example, this should be 1 for Contact Sensor and Lighting App reference apps. + */ +#ifndef LIGHTING_MANAGER_APP_DEVICE_TYPE_ENDPOINT +#define LIGHTING_MANAGER_APP_DEVICE_TYPE_ENDPOINT 1 +#endif + +/** + * @brief Specifies the array index of the light LED. + * + * The light LED is usually used to indicate the state of some cluster + * attribute: e.g OnOff attribute from OnOff cluster. + */ +#ifndef LIGHTING_MANAGER_LIGHT_LED_INDEX +#define LIGHTING_MANAGER_LIGHT_LED_INDEX 1 +#endif + +/** + * @brief Enable dimmable LED instead of a simple on/off LED. + * + */ +#ifndef LIGHTING_MANAGER_ENABLE_DIMMABLE_LED +#define LIGHTING_MANAGER_ENABLE_DIMMABLE_LED 1 +#endif + +/** + * @brief Manager of LedDimmer instance. + * + * It implements the UserInterfaceFeedback abstract interface. + */ +class LightingManagerDimmable : public UserInterfaceFeedback +{ +public: + void Init() override; + void DisplayInLoop() override; + void DisplayOnAction(Action action) override; + void RestoreState() override; + void UpdateState() override; + +private: + void ApplyDim(uint8_t value); + + LedDimmer lightLed; + + friend LightingManagerDimmable & LightingMgr(void); + static LightingManagerDimmable sLightingManager; +}; + +inline LightingManagerDimmable & LightingMgr(void) +{ + return LightingManagerDimmable::sLightingManager; +} diff --git a/examples/platform/nxp/pw_rpc_server.gni b/examples/platform/nxp/pw_rpc_server.gni index 0ec2d3b121b2d5..7133b44bf24aac 100644 --- a/examples/platform/nxp/pw_rpc_server.gni +++ b/examples/platform/nxp/pw_rpc_server.gni @@ -48,6 +48,7 @@ pw_rpc_server = { ] deps = [ + "$dir_pw_hdlc:default_addresses", "$dir_pw_hdlc:rpc_channel_output", "$dir_pw_stream:sys_io_stream", "$dir_pw_trace", diff --git a/scripts/build/builders/nxp.py b/scripts/build/builders/nxp.py index e119a78b5e2cc2..00678e8b0cc246 100644 --- a/scripts/build/builders/nxp.py +++ b/scripts/build/builders/nxp.py @@ -56,7 +56,7 @@ def FolderName(self, os_env): if self == NxpBoard.K32W0: return 'k32w0' elif self == NxpBoard.K32W1: - return 'k32w/k32w1' + return 'k32w1' elif self == NxpBoard.RW61X: if os_env == NxpOsUsed.ZEPHYR: return 'zephyr' @@ -250,7 +250,8 @@ def generate(self): cmd += 'export NXP_K32W0_SDK_ROOT="' + str(p.sdk_storage_location_abspath) + '" \n ' elif p.sdk_name == 'common': cmd += 'export NXP_SDK_ROOT="' + str(p.sdk_storage_location_abspath) + '" \n ' - cmd += 'gn gen --check --fail-on-unused-args --export-compile-commands --root=%s' % self.root + # add empty space at the end to avoid concatenation issue when there is no --args + cmd += 'gn gen --check --fail-on-unused-args --export-compile-commands --root=%s ' % self.root extra_args = [] diff --git a/scripts/tools/nxp/factory_data_generator/generate.py b/scripts/tools/nxp/factory_data_generator/generate.py index 0d905d41faae0b..b3ee98562b6c3a 100755 --- a/scripts/tools/nxp/factory_data_generator/generate.py +++ b/scripts/tools/nxp/factory_data_generator/generate.py @@ -22,6 +22,7 @@ import subprocess import sys +from crc import Calculator, Crc16 from custom import (CertDeclaration, DacCert, DacPKey, Discriminator, HardwareVersion, HardwareVersionStr, IterationCount, ManufacturingDate, PaiCert, PartNumber, ProductFinish, ProductId, ProductLabel, ProductName, ProductPrimaryColor, ProductURL, Salt, SerialNum, SetupPasscode, StrArgument, UniqueId, VendorId, VendorName, @@ -133,6 +134,15 @@ def to_bin(self, klv, out, aes128_key): size = len(fullContent) + if (self.args.hw_params): + calculator = Calculator(Crc16.XMODEM) + crc_sum = calculator.checksum(fullContent) + + fullContent = bytearray(b"APP_FACT_DATA: ") + size.to_bytes(4, 'little') + \ + fullContent + crc_sum.to_bytes(2, 'little') + + size = len(fullContent) + logging.info("Size of final generated binary is: {} bytes".format(size)) file.write(fullContent) else: @@ -235,6 +245,8 @@ def main(): 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") + optional.add_argument("--hw_params", action='store_true', + help="[bool] If present, store factory data in HWParameters APP section") args = parser.parse_args() diff --git a/scripts/tools/nxp/ota/README.md b/scripts/tools/nxp/ota/README.md index d96ab70d63c251..5c3a12adba7cf9 100644 --- a/scripts/tools/nxp/ota/README.md +++ b/scripts/tools/nxp/ota/README.md @@ -14,7 +14,7 @@ thus the `OTAImageProcessorImpl` instance should take this into account. ## Supported platforms - K32W0 - - [K32W OTA README](../../../../src/platform/nxp/k32w/common/K32W_OTA_README.md) + [K32W OTA README](../../../../src/platform/nxp/common/legacy/OTA_README.md) ## Usage diff --git a/src/lib/shell/streamer_nxp.cpp b/src/lib/shell/streamer_nxp.cpp index e46fce84072529..355015ce8f1ddd 100644 --- a/src/lib/shell/streamer_nxp.cpp +++ b/src/lib/shell/streamer_nxp.cpp @@ -66,7 +66,7 @@ #endif // pw RPC uses UART DMA by default -#ifdef PW_RPC_ENABLED +#ifdef CONFIG_ENABLE_PW_RPC #define CONSUMER_TASK_HANDLE RpcTaskHandle #ifndef STREAMER_UART_USE_DMA #define STREAMER_UART_USE_DMA 1 @@ -76,7 +76,7 @@ #ifndef STREAMER_UART_USE_DMA #define STREAMER_UART_USE_DMA 0 #endif -#endif // PW_RPC_ENABLED +#endif // CONFIG_ENABLE_PW_RPC #if STREAMER_UART_USE_DMA typedef serial_port_uart_dma_config_t streamer_serial_port_uart_config_t; diff --git a/src/platform/nxp/BUILD.gn b/src/platform/nxp/BUILD.gn index b60e57af6a4353..0865a1d36dacb6 100644 --- a/src/platform/nxp/BUILD.gn +++ b/src/platform/nxp/BUILD.gn @@ -26,9 +26,24 @@ source_set("logging") { "${chip_root}/src/platform/logging:headers", ] - if (nxp_platform == "k32w/k32w0" || nxp_platform == "k32w/k32w1") { + if (nxp_platform == "k32w/k32w0" || nxp_platform == "k32w1") { sources = [ "${chip_root}/src/platform/nxp/${nxp_platform}/Logging.cpp" ] } else { sources = [ "${chip_root}/src/platform/nxp/common/Logging.cpp" ] } } + +# The application can use this target to integrate the default, platform-specific +# NXP factory data provider. Each platform should define an "nxp_factory_data" source set. +# Usage: deps += [ "${chip_root}/src/platform/nxp:nxp_factory_data" ] +group("nxp_factory_data") { + public_deps = + [ "${chip_root}/src/platform/nxp/${nxp_platform}:nxp_factory_data" ] +} + +# The application can use this target to integrate the default, platform-specific +# NXP OTA implementation. Each platform should define an "nxp_ota" source set. +# Usage: deps += [ "${chip_root}/src/platform/nxp:nxp_ota" ] +group("nxp_ota") { + public_deps = [ "${chip_root}/src/platform/nxp/${nxp_platform}:nxp_ota" ] +} diff --git a/src/platform/nxp/common/NXPConfig.cpp b/src/platform/nxp/common/NXPConfig.cpp index b047d8afebc5ae..029c5e1766385f 100644 --- a/src/platform/nxp/common/NXPConfig.cpp +++ b/src/platform/nxp/common/NXPConfig.cpp @@ -21,8 +21,6 @@ * 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" @@ -30,6 +28,7 @@ #include "FunctionLib.h" #include "board.h" #include +#include #include /* FS Writes in Idle task only - LittleFS only , already enabled by default on NVM */ diff --git a/src/platform/nxp/common/NXPConfig.h b/src/platform/nxp/common/NXPConfig.h index c20dc7e5071d48..432acfa196abbb 100644 --- a/src/platform/nxp/common/NXPConfig.h +++ b/src/platform/nxp/common/NXPConfig.h @@ -23,10 +23,9 @@ #pragma once -#include - #include "FreeRTOS.h" #include +#include #define CHIP_PLAT_NO_NVM 0 #define CHIP_PLAT_NVM_FWK 1 diff --git a/src/platform/nxp/common/NXPConfigKS.cpp b/src/platform/nxp/common/NXPConfigKS.cpp index f7dd6bdc972919..1940a8081cbf7c 100644 --- a/src/platform/nxp/common/NXPConfigKS.cpp +++ b/src/platform/nxp/common/NXPConfigKS.cpp @@ -20,8 +20,6 @@ * 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" @@ -29,6 +27,7 @@ #include "FunctionLib.h" #include "board.h" #include +#include #include #include "fwk_file_cache.h" diff --git a/src/platform/nxp/common/NXPConfigNVS.cpp b/src/platform/nxp/common/NXPConfigNVS.cpp new file mode 100644 index 00000000000000..34d98a36d25002 --- /dev/null +++ b/src/platform/nxp/common/NXPConfigNVS.cpp @@ -0,0 +1,347 @@ +/* + * + * Copyright (c) 2020-2022 Project CHIP Authors + * Copyright 2024 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 "NXPConfig.h" +#include +#include +#include +#include + +/* Only for flash init, to be move to sdk framework */ +#include "port/nvs_port.h" + +// These can be overridden by the application as needed. +#ifndef CHIP_DEVICE_INTEGER_SETTINGS_KEY +/// Key for all integer keys +#define CHIP_DEVICE_INTEGER_SETTINGS_KEY "mt_i" +#endif // CHIP_DEVICE_CONFIG_SETTINGS_KEY +#ifndef CHIP_DEVICE_STRING_SETTINGS_KEY +/// Key for all string keys +#define CHIP_DEVICE_STRING_SETTINGS_KEY "mt_s" +#endif // CHIP_DEVICE_CONFIG_SETTINGS_KEY + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +namespace { + +struct ReadRequest +{ + void * const destination; // NOTE: can be nullptr in which case `configSize` should still be returned + const size_t bufferSize; // size of destination buffer + CHIP_ERROR result; // [out] read result + size_t configSize; // [out] size of configuration value +}; + +struct DeleteSubtreeEntry +{ + int result; +}; + +// Callback for settings_load_subtree_direct() function +int ConfigValueCallback(const char * name, size_t configSize, settings_read_cb readCb, void * cbArg, void * param) +{ + // If requested config key X, process just node X and ignore all its descendants: X/* + if (name != nullptr && *name != '\0') + return 0; + + ReadRequest & request = *reinterpret_cast(param); + + if (!request.destination || configSize > request.bufferSize) + { + request.result = CHIP_ERROR_BUFFER_TOO_SMALL; + request.configSize = configSize; + return 1; + } + + // Found requested key + const ssize_t bytesRead = readCb(cbArg, request.destination, request.bufferSize); + request.result = bytesRead > 0 ? CHIP_NO_ERROR : CHIP_ERROR_PERSISTED_STORAGE_FAILED; + request.configSize = bytesRead > 0 ? bytesRead : 0; + + // Return 1 to stop processing further keys + return 1; +} + +// Read configuration value of maximum size `bufferSize` and store the actual size in `configSize`. +CHIP_ERROR ReadConfigValueImpl(const NXPConfig::Key key, void * const destination, const size_t bufferSize, size_t & configSize) +{ + ReadRequest request{ destination, bufferSize, CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND, 0 }; + char key_name[SETTINGS_MAX_NAME_LEN + 1]; + + sprintf(key_name, CHIP_DEVICE_INTEGER_SETTINGS_KEY "/%04x", key); + settings_load_subtree_direct(key_name, ConfigValueCallback, &request); + configSize = request.configSize; + return request.result; +} + +CHIP_ERROR WriteConfigValueImpl(const NXPConfig::Key key, const void * const source, const size_t length) +{ + char key_name[SETTINGS_MAX_NAME_LEN + 1]; + sprintf(key_name, CHIP_DEVICE_INTEGER_SETTINGS_KEY "/%04x", key); + if (settings_save_one(key_name, source, length) != 0) + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; +#if (DEBUG_NVM > 0) + ChipLogProgress(DeviceLayer, "WriteConfigValue done"); +#endif + return CHIP_NO_ERROR; +} + +template +inline CHIP_ERROR ReadSimpleConfigValue(const NXPConfig::Key key, T & value) +{ + CHIP_ERROR result; + T tempValue; + size_t configSize; + + result = ReadConfigValueImpl(key, &tempValue, sizeof(T), configSize); + SuccessOrExit(result); + + // For simple types require that size of the output variable matches size of the configuration value + VerifyOrExit(configSize == sizeof(T), result = CHIP_ERROR_INVALID_ARGUMENT); + value = tempValue; +exit: + return result; +} + +int DeleteSubtreeCallback(const char * name, size_t /* entrySize */, settings_read_cb /* readCb */, void * /* cbArg */, + void * param) +{ + + DeleteSubtreeEntry & entry = *static_cast(param); + char fullKey[SETTINGS_MAX_NAME_LEN + 1]; + (void) snprintf(fullKey, sizeof(fullKey), CHIP_DEVICE_STRING_SETTINGS_KEY "/%s", StringOrNullMarker(name)); + const int result = settings_delete(fullKey); + + // Return the first error, but continue removing remaining keys anyway. + if (entry.result == 0) + { + entry.result = result; + } + + return 0; +} +} // namespace + +CHIP_ERROR NXPConfig::Init() +{ + /* Only for flash init, to be move to sdk framework */ + /* Initialize flash components */ + const struct flash_area * fa; + + ReturnErrorCodeIf(flash_area_open(SETTINGS_PARTITION, &fa), CHIP_ERROR_PERSISTED_STORAGE_FAILED); + ReturnErrorCodeIf(flash_init(fa->fa_dev), CHIP_ERROR_PERSISTED_STORAGE_FAILED); + /* End flash init */ + + ReturnErrorCodeIf(settings_subsys_init(), CHIP_ERROR_PERSISTED_STORAGE_FAILED); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR NXPConfig::ReadConfigValue(Key key, bool & val) +{ + ReturnErrorCodeIf(!ValidConfigKey(key), CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + return ReadSimpleConfigValue(key, val); +} + +CHIP_ERROR NXPConfig::ReadConfigValue(Key key, uint32_t & val) +{ + ReturnErrorCodeIf(!ValidConfigKey(key), CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + return ReadSimpleConfigValue(key, val); +} + +CHIP_ERROR NXPConfig::ReadConfigValue(Key key, uint64_t & val) +{ + ReturnErrorCodeIf(!ValidConfigKey(key), CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + return ReadSimpleConfigValue(key, val); +} + +CHIP_ERROR NXPConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + ReturnErrorCodeIf(!ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + // Pretend that the buffer is smaller by 1 to secure space for null-character + err = ReadConfigValueImpl(key, buf, bufSize ? bufSize - 1 : 0, outLen); + + if (err == CHIP_NO_ERROR) + { + if (buf[outLen - 1]) // CHIP_NO_ERROR implies outLen > 0 + buf[outLen] = 0; + else + outLen--; + } + return err; +} + +CHIP_ERROR NXPConfig::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) +{ + return ReadConfigValueImpl(key, buf, bufSize, outLen); +} + +CHIP_ERROR NXPConfig::ReadConfigValueBin(const char * keyString, uint8_t * buf, size_t bufSize, size_t & outLen) +{ + ReadRequest request{ buf, bufSize, CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND, 0 }; + char key_name[SETTINGS_MAX_NAME_LEN + 1]; + unsigned key_name_len; + + // to be able to concat CHIP_DEVICE_STRING_SETTINGS_KEY"/" and keyString, + 1 for end char + key_name_len = strlen(keyString) + strlen(CHIP_DEVICE_STRING_SETTINGS_KEY) + 1; + ReturnErrorCodeIf(key_name_len > (SETTINGS_MAX_NAME_LEN + 1), CHIP_ERROR_PERSISTED_STORAGE_FAILED); + + sprintf(key_name, CHIP_DEVICE_STRING_SETTINGS_KEY "/%s", keyString); + settings_load_subtree_direct(key_name, ConfigValueCallback, &request); + outLen = request.configSize; + return request.result; +} + +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) +{ + return WriteConfigValueImpl(key, &val, sizeof(bool)); +} + +CHIP_ERROR NXPConfig::WriteConfigValue(Key key, uint32_t val) +{ + return WriteConfigValueImpl(key, &val, sizeof(uint32_t)); +} + +CHIP_ERROR NXPConfig::WriteConfigValue(Key key, uint64_t val) +{ + return WriteConfigValueImpl(key, &val, sizeof(uint64_t)); +} + +CHIP_ERROR NXPConfig::WriteConfigValueStr(Key key, const char * str) +{ + return WriteConfigValueStr(key, str, str ? strlen(str) : 0); +} + +CHIP_ERROR NXPConfig::WriteConfigValueStr(Key key, const char * str, size_t strLen) +{ + ReturnErrorCodeIf(!ValidConfigKey(key), CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + return WriteConfigValueImpl(key, str, strLen); +} + +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) +{ + char key_name[SETTINGS_MAX_NAME_LEN + 1]; + unsigned key_name_len; + + // to be able to concat CHIP_DEVICE_STRING_SETTINGS_KEY"/" and keyString, + 1 for end char + key_name_len = strlen(keyString) + strlen(CHIP_DEVICE_STRING_SETTINGS_KEY) + 1; + ReturnErrorCodeIf(key_name_len > (SETTINGS_MAX_NAME_LEN + 1), CHIP_ERROR_PERSISTED_STORAGE_FAILED); + + sprintf(key_name, CHIP_DEVICE_STRING_SETTINGS_KEY "/%s", keyString); + if (settings_save_one(key_name, data, dataLen) != 0) + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + + return CHIP_NO_ERROR; +} + +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) +{ + char key_name[SETTINGS_MAX_NAME_LEN + 1]; + sprintf(key_name, CHIP_DEVICE_INTEGER_SETTINGS_KEY "/%04x", key); + return ClearConfigValue(key_name); +} + +CHIP_ERROR NXPConfig::ClearConfigValue(const char * keyString) +{ + char key_name[SETTINGS_MAX_NAME_LEN]; + unsigned key_name_len; + + // to be able to concat CHIP_DEVICE_STRING_SETTINGS_KEY"/" and keyString, + 1 for end char + key_name_len = strlen(keyString) + strlen(CHIP_DEVICE_STRING_SETTINGS_KEY) + 1; + ReturnErrorCodeIf(key_name_len > (SETTINGS_MAX_NAME_LEN + 1), CHIP_ERROR_PERSISTED_STORAGE_FAILED); + + sprintf(key_name, CHIP_DEVICE_STRING_SETTINGS_KEY "/%s", keyString); + if (settings_delete(key_name) != 0) + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + + return CHIP_NO_ERROR; +} + +bool NXPConfig::ConfigValueExists(Key key) +{ + bool err = false; + if (ValidConfigKey(key)) + { + size_t configSize; + err = ReadConfigValueImpl(key, nullptr, 0, configSize) == CHIP_ERROR_BUFFER_TOO_SMALL; + } + return err; +} + +CHIP_ERROR NXPConfig::FactoryResetConfig(void) +{ + DeleteSubtreeEntry entry{ /* success */ 0 }; + // Clear CHIP_DEVICE_STRING_SETTINGS_KEY/* keys + int result = settings_load_subtree_direct(CHIP_DEVICE_STRING_SETTINGS_KEY, DeleteSubtreeCallback, &entry); + + if (result == 0) + { + result = entry.result; + } + + char key_name[SETTINGS_MAX_NAME_LEN + 1]; + for (Key key = kMinConfigKey_ChipConfig; key <= kMaxConfigKey_ChipConfig; key++) + { + sprintf(key_name, CHIP_DEVICE_INTEGER_SETTINGS_KEY "/%04x", key); + if (settings_delete(key_name) != 0) + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + } + + // Clear RebootCount, TotalOperationalHours, UpTime counters during factory reset + for (Key key = kMinConfigKey_ChipCounter; key <= (kMinConfigKey_ChipCounter + 3); key++) + { + sprintf(key_name, CHIP_DEVICE_INTEGER_SETTINGS_KEY "/%04x", key); + if (settings_delete(key_name) != 0) + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + } + return CHIP_NO_ERROR; +} + +bool NXPConfig::ValidConfigKey(Key key) +{ + // Returns true if the key is in the valid CHIP Config PDM key range. + return (key >= kMinConfigKey_ChipFactory) && (key <= kMaxConfigKey_KVS); +} + +void NXPConfig::RunConfigUnitTest(void) {} + +void NXPConfig::RunSystemIdleTask(void) {} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/k32w/common/BLEManagerCommon.cpp b/src/platform/nxp/k32w/common/BLEManagerCommon.cpp deleted file mode 100644 index d9dbde88f3a614..00000000000000 --- a/src/platform/nxp/k32w/common/BLEManagerCommon.cpp +++ /dev/null @@ -1,1435 +0,0 @@ -/* - * - * Copyright (c) 2020-2021 Project CHIP Authors - * Copyright (c) 2020 Nest Labs, Inc. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * Provides an implementation of the BLEManager singleton object - * for the K32W platforms. - */ - -/* this file behaves like a config.h, comes first */ -#include - -#include - -#include - -#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE - -#include - -#include "board.h" -#include "gatt_db_app_interface.h" -#include "gatt_db_handles.h" -#include "stdio.h" -#include "timers.h" - -#if defined(CPU_JN518X) && defined(chip_with_low_power) && (chip_with_low_power == 1) -#include "PWR_Configuration.h" -#endif - -#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING -#include -#include -#endif - -/******************************************************************************* - * Local data types - *******************************************************************************/ -extern "C" bool_t Ble_ConfigureHostStackConfig(void); - -#if defined(chip_with_low_power) && (chip_with_low_power == 1) -extern "C" void PWR_DisallowDeviceToSleep(void); -extern "C" void PWR_AllowDeviceToSleep(void); -#endif - -using namespace ::chip; -using namespace ::chip::Ble; - -namespace chip { -namespace DeviceLayer { -namespace Internal { - -namespace { -/******************************************************************************* - * Macros & Constants definitions - *******************************************************************************/ -/* Timeout of BLE commands */ -#define CHIP_BLE_KW_EVNT_TIMEOUT 1000 / portTICK_PERIOD_MS - -/** BLE advertisement state changed */ -#define CHIP_BLE_KW_EVNT_ADV_CHANGED 0x0001 -/** BLE advertisement command failed */ -#define CHIP_BLE_KW_EVNT_ADV_FAILED 0x0002 -/** BLE advertisement setup failed */ -#define CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED 0x0004 -/** BLE advertisement parameters setup complete */ -#define CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE 0x0008 -/** BLE advertisement data setup complete */ -#define CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE 0x0010 -/** BLE random address set */ -#define CHIP_BLE_KW_EVNT_RND_ADDR_SET 0x0020 -/** BLE Initialization complete */ -#define CHIP_BLE_KW_EVNT_INIT_COMPLETE 0x0040 -/** BLE Received a handle value confirmation from the client */ -#define CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED 0x0080 -/** BLE send indication failed */ -#define CHIP_BLE_KW_EVNT_INDICATION_FAILED 0x0100 -/** TX Power Level Set */ -#define CHIP_BLE_KW_EVNT_POWER_LEVEL_SET 0x0200 -/** Maximal time of connection without activity */ -#define CHIP_BLE_KW_CONN_TIMEOUT 60000 -/** Maximum number of pending BLE events */ -#define CHIP_BLE_EVENT_QUEUE_MAX_ENTRIES 10 - -#define LOOP_EV_BLE (0x08) - -/* controller task configuration */ -#define CONTROLLER_TASK_PRIORITY (6U) -#define CONTROLLER_TASK_STACK_SIZE (gControllerTaskStackSize_c / sizeof(StackType_t)) - -/* host task configuration */ -#define HOST_TASK_PRIORITY (4U) -#define HOST_TASK_STACK_SIZE (gHost_TaskStackSize_c / sizeof(StackType_t)) - -/* advertising configuration */ -#define BLEKW_ADV_MAX_NO (2) -#define BLEKW_SCAN_RSP_MAX_NO (2) -#define BLEKW_MAX_ADV_DATA_LEN (31) -#define CHIP_ADV_SHORT_UUID_LEN (2) - -/* FreeRTOS sw timer */ -TimerHandle_t sbleAdvTimeoutTimer; - -/* Queue used to synchronize asynchronous messages from the KW BLE tasks */ -QueueHandle_t sBleEventQueue; - -/* Used to manage asynchronous events from BLE Stack: e.g.: GAP setup finished */ -EventGroupHandle_t sEventGroup; - -TimerHandle_t connectionTimeout; - -const uint8_t ShortUUID_CHIPoBLEService[] = { 0xF6, 0xFF }; - -#if defined(chip_with_low_power) && (chip_with_low_power == 1) -static bool bleAppStopInProgress; -#endif - -BLEManagerCommon * sImplInstance = nullptr; - -} // namespace - -CHIP_ERROR BLEManagerCommon::_Init() -{ - CHIP_ERROR err = CHIP_NO_ERROR; - EventBits_t eventBits; - uint16_t attChipRxHandle[1] = { (uint16_t) value_chipoble_rx }; - -#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING - uint16_t attChipC3Handle[1] = { (uint16_t) value_chipoble_c3 }; -#endif - - mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled; - - // Check if BLE stack is initialized - VerifyOrExit(!mFlags.Has(Flags::kK32WBLEStackInitialized), err = CHIP_ERROR_INCORRECT_STATE); - - // Initialize the Chip BleLayer. - err = BleLayer::Init(this, this, &DeviceLayer::SystemLayer()); - SuccessOrExit(err); - - /* Initialization of message wait events - - * used for receiving BLE Stack events */ - sEventGroup = xEventGroupCreate(); - VerifyOrExit(sEventGroup != NULL, err = CHIP_ERROR_INCORRECT_STATE); - - /* Prepare callback input queue.*/ - sBleEventQueue = xQueueCreate(CHIP_BLE_EVENT_QUEUE_MAX_ENTRIES, sizeof(blekw_msg_t *)); - VerifyOrExit(sBleEventQueue != NULL, err = CHIP_ERROR_INCORRECT_STATE); - - /* Create the connection timeout timer. */ - connectionTimeout = - xTimerCreate("bleTimeoutTmr", pdMS_TO_TICKS(CHIP_BLE_KW_CONN_TIMEOUT), pdFALSE, (void *) 0, blekw_connection_timeout_cb); - VerifyOrExit(connectionTimeout != NULL, err = CHIP_ERROR_INCORRECT_STATE); - - sImplInstance = GetImplInstance(); - - /* BLE platform code initialization */ - SuccessOrExit(err = InitHostController(&blekw_generic_cb)); - - /* Register the GATT server callback */ - VerifyOrExit(GattServer_RegisterCallback(blekw_gatt_server_cb) == gBleSuccess_c, err = CHIP_ERROR_INCORRECT_STATE); - - /* Wait until BLE Stack is ready */ - eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_INIT_COMPLETE, pdTRUE, pdTRUE, CHIP_BLE_KW_EVNT_TIMEOUT); - VerifyOrExit(eventBits & CHIP_BLE_KW_EVNT_INIT_COMPLETE, err = CHIP_ERROR_INCORRECT_STATE); - -#if BLE_HIGH_TX_POWER - /* Set Adv Power */ - Gap_SetTxPowerLevel(gAdvertisingPowerLeveldBm_c, gTxPowerAdvChannel_c); - eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_POWER_LEVEL_SET, pdTRUE, pdTRUE, CHIP_BLE_KW_EVNT_TIMEOUT); - VerifyOrExit(eventBits & CHIP_BLE_KW_EVNT_POWER_LEVEL_SET, err = CHIP_ERROR_INCORRECT_STATE); - - /* Set Connect Power */ - Gap_SetTxPowerLevel(gConnectPowerLeveldBm_c, gTxPowerConnChannel_c); - eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_POWER_LEVEL_SET, pdTRUE, pdTRUE, CHIP_BLE_KW_EVNT_TIMEOUT); - VerifyOrExit(eventBits & CHIP_BLE_KW_EVNT_POWER_LEVEL_SET, err = CHIP_ERROR_INCORRECT_STATE); -#endif - -#if defined(CPU_JN518X) && defined(chip_with_low_power) && (chip_with_low_power == 1) - PWR_ChangeDeepSleepMode(cPWR_PowerDown_RamRet); -#endif - - GattServer_RegisterHandlesForWriteNotifications(1, attChipRxHandle); -#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING - VerifyOrExit(GattServer_RegisterHandlesForReadNotifications(1, attChipC3Handle) == gBleSuccess_c, - err = CHIP_ERROR_INCORRECT_STATE); -#endif - - mFlags.Set(Flags::kK32WBLEStackInitialized); - mFlags.Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART ? true : false); - mFlags.Set(Flags::kFastAdvertisingEnabled); - - // Create FreeRTOS sw timer for BLE timeouts and interval change. - sbleAdvTimeoutTimer = xTimerCreate("BleAdvTimer", // Just a text name, not used by the RTOS kernel - pdMS_TO_TICKS(100), // == default timer period (mS) - false, // no timer reload (==one-shot) - (void *) this, // init timer id = ble obj context - BleAdvTimeoutHandler // timer callback handler - ); - VerifyOrExit(sbleAdvTimeoutTimer != NULL, err = CHIP_ERROR_INCORRECT_STATE); - -exit: - return err; -} - -uint16_t BLEManagerCommon::_NumConnections(void) -{ - return static_cast(mDeviceConnected == true); -} - -bool BLEManagerCommon::_IsAdvertisingEnabled(void) -{ - return mFlags.Has(Flags::kAdvertisingEnabled); -} - -bool BLEManagerCommon::_IsAdvertising(void) -{ - return mFlags.Has(Flags::kAdvertising); -} - -CHIP_ERROR BLEManagerCommon::_SetAdvertisingEnabled(bool val) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE); - - if (mFlags.Has(Flags::kAdvertisingEnabled) != val) - { - mFlags.Set(Flags::kAdvertisingEnabled, val); - PlatformMgr().ScheduleWork(DriveBLEState, 0); - } - -exit: - return err; -} - -CHIP_ERROR BLEManagerCommon::_SetAdvertisingMode(BLEAdvertisingMode mode) -{ - switch (mode) - { - case BLEAdvertisingMode::kFastAdvertising: - mFlags.Set(Flags::kFastAdvertisingEnabled); - break; - case BLEAdvertisingMode::kSlowAdvertising: { - // We are in FreeRTOS timer service context, which is a default daemon task and has - // the highest priority. Stop advertising should be scheduled to run from Matter task. - mFlags.Clear(Flags::kFastAdvertisingEnabled); - PlatformMgr().ScheduleWork(StopAdvertisingPriorToSwitchingMode, 0); - break; - } - default: - return CHIP_ERROR_INVALID_ARGUMENT; - } - mFlags.Set(Flags::kRestartAdvertising); - PlatformMgr().ScheduleWork(DriveBLEState, 0); - return CHIP_NO_ERROR; -} - -CHIP_ERROR BLEManagerCommon::_GetDeviceName(char * buf, size_t bufSize) -{ - if (strlen(mDeviceName) >= bufSize) - { - return CHIP_ERROR_BUFFER_TOO_SMALL; - } - strcpy(buf, mDeviceName); - return CHIP_NO_ERROR; -} - -CHIP_ERROR BLEManagerCommon::_SetDeviceName(const char * deviceName) -{ - if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_NotSupported) - { - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; - } - if (deviceName != NULL && deviceName[0] != 0) - { - if (strlen(deviceName) >= kMaxDeviceNameLength) - { - return CHIP_ERROR_INVALID_ARGUMENT; - } - memset(mDeviceName, 0, kMaxDeviceNameLength); - strcpy(mDeviceName, deviceName); - mFlags.Set(Flags::kDeviceNameSet); - ChipLogProgress(DeviceLayer, "Setting device name to : \"%s\"", deviceName); - } - else - { - mDeviceName[0] = 0; - mFlags.Clear(Flags::kDeviceNameSet); - } - - return CHIP_NO_ERROR; -} - -void BLEManagerCommon::_OnPlatformEvent(const ChipDeviceEvent * event) -{ - switch (event->Type) - { - case DeviceEventType::kCHIPoBLESubscribe: - ChipDeviceEvent connEstEvent; - - HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &CHIP_BLE_SVC_ID, &Ble::CHIP_BLE_CHAR_2_UUID); - connEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; - PlatformMgr().PostEventOrDie(&connEstEvent); - break; - - case DeviceEventType::kCHIPoBLEUnsubscribe: - HandleUnsubscribeReceived(event->CHIPoBLEUnsubscribe.ConId, &CHIP_BLE_SVC_ID, &Ble::CHIP_BLE_CHAR_2_UUID); - break; - - case DeviceEventType::kCHIPoBLEWriteReceived: - HandleWriteReceived(event->CHIPoBLEWriteReceived.ConId, &CHIP_BLE_SVC_ID, &Ble::CHIP_BLE_CHAR_1_UUID, - PacketBufferHandle::Adopt(event->CHIPoBLEWriteReceived.Data)); - break; - - case DeviceEventType::kCHIPoBLEConnectionError: - HandleConnectionError(event->CHIPoBLEConnectionError.ConId, event->CHIPoBLEConnectionError.Reason); - break; - - case DeviceEventType::kCHIPoBLEIndicateConfirm: - HandleIndicationConfirmation(event->CHIPoBLEIndicateConfirm.ConId, &CHIP_BLE_SVC_ID, &Ble::CHIP_BLE_CHAR_2_UUID); - break; - - default: - break; - } -} - -CHIP_ERROR BLEManagerCommon::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, - const ChipBleUUID * charId) -{ - ChipLogProgress(DeviceLayer, "BLEManagerCommon::SubscribeCharacteristic() not supported"); - return CHIP_ERROR_NOT_IMPLEMENTED; -} - -CHIP_ERROR BLEManagerCommon::UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, - const ChipBleUUID * charId) -{ - ChipLogProgress(DeviceLayer, "BLEManagerCommon::UnsubscribeCharacteristic() not supported"); - return CHIP_ERROR_NOT_IMPLEMENTED; -} - -CHIP_ERROR BLEManagerCommon::CloseConnection(BLE_CONNECTION_OBJECT conId) -{ - return blekw_stop_connection_internal(conId); -} - -uint16_t BLEManagerCommon::GetMTU(BLE_CONNECTION_OBJECT conId) const -{ - uint16_t tempMtu = 0; - (void) Gatt_GetMtu(conId, &tempMtu); - - return tempMtu; -} - -CHIP_ERROR BLEManagerCommon::SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, - PacketBufferHandle pBuf) -{ - ChipLogProgress(DeviceLayer, "BLEManagerCommon::SendWriteRequest() not supported"); - return CHIP_ERROR_NOT_IMPLEMENTED; -} - -void BLEManagerCommon::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) -{ - BLEMgrImpl().CloseConnection(conId); -} - -CHIP_ERROR BLEManagerCommon::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, - PacketBufferHandle data) -{ - VerifyOrReturnError(UUIDsMatch(&Ble::CHIP_BLE_CHAR_2_UUID, charId), BLE_ERROR_GATT_WRITE_FAILED); - - CHIP_ERROR err = CHIP_NO_ERROR; - - if (blekw_send_event(conId, value_chipoble_tx, data->Start(), data->DataLength()) != BLE_OK) - { - err = CHIP_ERROR_SENDING_BLOCKED; - } - else - { - ChipDeviceEvent event; - event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm; - event.CHIPoBLEIndicateConfirm.ConId = conId; - err = PlatformMgr().PostEvent(&event); - } - - return err; -} - -BLEManagerCommon::ble_err_t BLEManagerCommon::blekw_send_event(int8_t connection_handle, uint16_t handle, uint8_t * data, - uint32_t len) -{ - EventBits_t eventBits; - -#if CHIP_DEVICE_CHIP0BLE_DEBUG - ChipLogProgress(DeviceLayer, "Trying to send event."); -#endif - - if (connection_handle < 0 || handle <= 0) - { - ChipLogProgress(DeviceLayer, "BLE Event - Bad Handle"); - return BLE_E_FAIL; - } - - if (len > 0 && data == NULL) - { - ChipLogProgress(DeviceLayer, "BLE Event - Invalid Data"); - return BLE_E_FAIL; - } - - /************* Send the indication *************/ - xEventGroupClearBits(sEventGroup, CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED | CHIP_BLE_KW_EVNT_INDICATION_FAILED); - - if (GattServer_SendInstantValueIndication(connection_handle, handle, len, data) != gBleSuccess_c) - { - ChipLogProgress(DeviceLayer, "BLE Event - Can't sent indication"); - return BLE_E_FAIL; - } - - /* Wait until BLE Stack is ready */ - eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED | CHIP_BLE_KW_EVNT_INDICATION_FAILED, pdTRUE, - pdFALSE, CHIP_BLE_KW_EVNT_TIMEOUT); - - if (eventBits & CHIP_BLE_KW_EVNT_INDICATION_FAILED) - { - ChipLogProgress(DeviceLayer, "BLE Event - Sent Failed"); - return BLE_E_FAIL; - } - -#if CHIP_DEVICE_CHIP0BLE_DEBUG - ChipLogProgress(DeviceLayer, "BLE Event - Sent :-) "); -#endif - - return BLE_OK; -} -/******************************************************************************* - * Private functions - *******************************************************************************/ - -BLEManagerCommon::ble_err_t BLEManagerCommon::blekw_start_advertising(gapAdvertisingParameters_t * adv_params, - gapAdvertisingData_t * adv, gapScanResponseData_t * scnrsp) -{ - EventBits_t eventBits; - - /************* Set the advertising parameters *************/ - xEventGroupClearBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED | CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE); - - /* Set the advertising parameters */ - if (Gap_SetAdvertisingParameters(adv_params) != gBleSuccess_c) - { - vTaskDelay(1); - - /* Retry, just to make sure before giving up and sending an error. */ - if (Gap_SetAdvertisingParameters(adv_params) != gBleSuccess_c) - { - return BLE_E_SET_ADV_PARAMS; - } - } - - eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED | CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE, - pdTRUE, pdFALSE, CHIP_BLE_KW_EVNT_TIMEOUT); - - if (!(eventBits & CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE)) - { - return BLE_E_ADV_PARAMS_FAILED; - } - - /************* Set the advertising data *************/ - xEventGroupClearBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED | CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE); - - /* Set the advertising data */ - if (Gap_SetAdvertisingData(adv, scnrsp) != gBleSuccess_c) - { - return BLE_E_SET_ADV_DATA; - } - - eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED | CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE, - pdTRUE, pdFALSE, CHIP_BLE_KW_EVNT_TIMEOUT); - - if (!(eventBits & CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE)) - { - return BLE_E_ADV_SETUP_FAILED; - } - - /************* Start the advertising *************/ - xEventGroupClearBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED); - - if (gBleSuccess_c != Gap_CreateRandomDeviceAddress(NULL, NULL)) - { - return BLE_E_SET_ADV_PARAMS; - } - - eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_RND_ADDR_SET, pdTRUE, pdTRUE, CHIP_BLE_KW_EVNT_TIMEOUT); - - if (!(eventBits & CHIP_BLE_KW_EVNT_RND_ADDR_SET)) - { - return BLE_E_ADV_PARAMS_FAILED; - } - - /* Start the advertising */ - if (Gap_StartAdvertising(blekw_gap_advertising_cb, blekw_gap_connection_cb) != gBleSuccess_c) - { - return BLE_E_START_ADV; - } - -#if defined(chip_with_low_power) && (chip_with_low_power == 1) - PWR_DisallowDeviceToSleep(); -#endif - - eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED, pdTRUE, pdFALSE, - CHIP_BLE_KW_EVNT_TIMEOUT); - if (!(eventBits & CHIP_BLE_KW_EVNT_ADV_CHANGED)) - { -#if defined(chip_with_low_power) && (chip_with_low_power == 1) - PWR_AllowDeviceToSleep(); -#endif - return BLE_E_START_ADV_FAILED; - } - -#if defined(chip_with_low_power) && (chip_with_low_power == 1) - PWR_AllowDeviceToSleep(); -#endif - - return BLE_OK; -} - -BLEManagerCommon::ble_err_t BLEManagerCommon::blekw_stop_advertising(void) -{ - EventBits_t eventBits; - bleResult_t res; - - xEventGroupClearBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED); - - /* Stop the advertising data */ - res = Gap_StopAdvertising(); - if (res != gBleSuccess_c) - { - ChipLogProgress(DeviceLayer, "Failed to stop advertising %d", res); - return BLE_E_STOP; - } - - eventBits = xEventGroupWaitBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_CHANGED | CHIP_BLE_KW_EVNT_ADV_FAILED, pdTRUE, pdFALSE, - CHIP_BLE_KW_EVNT_TIMEOUT); - - if (eventBits & CHIP_BLE_KW_EVNT_ADV_FAILED) - { - ChipLogProgress(DeviceLayer, "Stop advertising flat out failed."); - return BLE_E_ADV_FAILED; - } - else if (!(eventBits & CHIP_BLE_KW_EVNT_ADV_CHANGED)) - { - ChipLogProgress(DeviceLayer, "Stop advertising event timeout."); - return BLE_E_ADV_CHANGED; - } - - return BLE_OK; -} - -CHIP_ERROR BLEManagerCommon::ConfigureAdvertisingData(void) -{ - ble_err_t err; - CHIP_ERROR chipErr; - uint16_t discriminator; - uint16_t advInterval = 0; - gapAdvertisingData_t adv = { 0 }; - gapAdStructure_t adv_data[BLEKW_ADV_MAX_NO] = { { 0 } }; - gapAdStructure_t scan_rsp_data[BLEKW_SCAN_RSP_MAX_NO] = { { 0 } }; - uint8_t advPayload[BLEKW_MAX_ADV_DATA_LEN] = { 0 }; - gapScanResponseData_t scanRsp = { 0 }; - gapAdvertisingParameters_t adv_params = { 0 }; - uint8_t chipAdvDataFlags = (gLeGeneralDiscoverableMode_c | gBrEdrNotSupported_c); - uint8_t chipOverBleService[2]; - ChipBLEDeviceIdentificationInfo mDeviceIdInfo = { 0 }; - uint8_t mDeviceIdInfoLength = 0; - - chipErr = GetCommissionableDataProvider()->GetSetupDiscriminator(discriminator); - if (chipErr != CHIP_NO_ERROR) - { - return chipErr; - } - - if (!mFlags.Has(Flags::kDeviceNameSet)) - { - memset(mDeviceName, 0, kMaxDeviceNameLength); - snprintf(mDeviceName, kMaxDeviceNameLength, "%s%04u", CHIP_DEVICE_CONFIG_BLE_DEVICE_NAME_PREFIX, discriminator); - } - - /**************** Prepare advertising data *******************************************/ - adv.cNumAdStructures = BLEKW_ADV_MAX_NO; - - chipErr = ConfigurationMgr().GetBLEDeviceIdentificationInfo(mDeviceIdInfo); - SuccessOrExit(chipErr); - mDeviceIdInfoLength = sizeof(mDeviceIdInfo); - - if ((mDeviceIdInfoLength + CHIP_ADV_SHORT_UUID_LEN + 1) > BLEKW_MAX_ADV_DATA_LEN) - { - return CHIP_ERROR_INCORRECT_STATE; - } - - adv_data[0].length = 0x02; - adv_data[0].adType = gAdFlags_c; - adv_data[0].aData = (uint8_t *) (&chipAdvDataFlags); - - adv_data[1].length = static_cast(mDeviceIdInfoLength + CHIP_ADV_SHORT_UUID_LEN + 1); - adv_data[1].adType = gAdServiceData16bit_c; - memcpy(advPayload, ShortUUID_CHIPoBLEService, CHIP_ADV_SHORT_UUID_LEN); - memcpy(&advPayload[CHIP_ADV_SHORT_UUID_LEN], (void *) &mDeviceIdInfo, mDeviceIdInfoLength); - adv_data[1].aData = advPayload; - - adv.aAdStructures = adv_data; - -#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING - ReturnErrorOnFailure(EncodeAdditionalDataTlv()); -#endif - - /**************** Prepare scan response data *******************************************/ - scanRsp.cNumAdStructures = BLEKW_SCAN_RSP_MAX_NO; - - scan_rsp_data[0].length = static_cast(strlen(mDeviceName) + 1); - scan_rsp_data[0].adType = gAdCompleteLocalName_c; - scan_rsp_data[0].aData = (uint8_t *) mDeviceName; - - scan_rsp_data[1].length = sizeof(chipOverBleService) + 1; - scan_rsp_data[1].adType = gAdComplete16bitServiceList_c; - chipOverBleService[0] = ShortUUID_CHIPoBLEService[0]; - chipOverBleService[1] = ShortUUID_CHIPoBLEService[1]; - scan_rsp_data[1].aData = (uint8_t *) chipOverBleService; - - scanRsp.aAdStructures = scan_rsp_data; - - /**************** Prepare advertising parameters *************************************/ - if (mFlags.Has(Flags::kFastAdvertisingEnabled)) - { - advInterval = CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MAX; - } - else - { - advInterval = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX; - } - advInterval = (uint16_t) (advInterval * 0.625F); - - adv_params.minInterval = adv_params.maxInterval = advInterval; - adv_params.advertisingType = gAdvConnectableUndirected_c; - adv_params.ownAddressType = gBleAddrTypeRandom_c; - adv_params.peerAddressType = gBleAddrTypePublic_c; - memset(adv_params.peerAddress, 0, gcBleDeviceAddressSize_c); - adv_params.channelMap = (gapAdvertisingChannelMapFlags_t) (gAdvChanMapFlag37_c | gAdvChanMapFlag38_c | gAdvChanMapFlag39_c); - adv_params.filterPolicy = gProcessAll_c; - - err = blekw_start_advertising(&adv_params, &adv, &scanRsp); - if (err == BLE_OK) - { - ChipLogProgress(DeviceLayer, "Started Advertising at %d ms", advInterval); - } - else - { - ChipLogProgress(DeviceLayer, "Advertising error 0x%x!", err); - mFlags.Clear(Flags::kAdvertising); - return CHIP_ERROR_INCORRECT_STATE; - } - -exit: - return chipErr; -} - -#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING -CHIP_ERROR BLEManagerCommon::EncodeAdditionalDataTlv() -{ - CHIP_ERROR err = CHIP_NO_ERROR; - BitFlags dataFields; - AdditionalDataPayloadGeneratorParams params; - -#if CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID) - uint8_t rotatingDeviceIdUniqueId[ConfigurationManager::kRotatingDeviceIDUniqueIDLength] = {}; - MutableByteSpan rotatingDeviceIdUniqueIdSpan(rotatingDeviceIdUniqueId); - - err = DeviceLayer::GetDeviceInstanceInfoProvider()->GetRotatingDeviceIdUniqueId(rotatingDeviceIdUniqueIdSpan); - SuccessOrExit(err); - err = ConfigurationMgr().GetLifetimeCounter(params.rotatingDeviceIdLifetimeCounter); - SuccessOrExit(err); - params.rotatingDeviceIdUniqueId = rotatingDeviceIdUniqueIdSpan; - dataFields.Set(AdditionalDataFields::RotatingDeviceId); -#endif /* CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID) */ - err = AdditionalDataPayloadGenerator().generateAdditionalDataPayload(params, sImplInstance->c3AdditionalDataBufferHandle, - dataFields); - -exit: - if (err != CHIP_NO_ERROR) - { - ChipLogError(DeviceLayer, "Failed to generate TLV encoded Additional Data (%s)", __func__); - } - - return err; -} - -void BLEManagerCommon::HandleC3ReadRequest(blekw_msg_t * msg) -{ - bleResult_t result; - blekw_att_read_data_t * att_rd_data = (blekw_att_read_data_t *) msg->data.data; - deviceId_t deviceId = att_rd_data->device_id; - uint16_t handle = att_rd_data->handle; - uint16_t length = sImplInstance->c3AdditionalDataBufferHandle->DataLength(); - const uint8_t * data = (const uint8_t *) sImplInstance->c3AdditionalDataBufferHandle->Start(); - - result = GattDb_WriteAttribute(handle, length, data); - if (result != gBleSuccess_c) - { - ChipLogError(DeviceLayer, "Failed to write C3 characteristic: %d", result); - } - - result = GattServer_SendAttributeReadStatus(deviceId, handle, gAttErrCodeNoError_c); - if (result != gBleSuccess_c) - { - ChipLogError(DeviceLayer, "Failed to send response to C3 read request: %d", result); - } -} -#endif /* CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING */ - -CHIP_ERROR BLEManagerCommon::StartAdvertising(void) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - mFlags.Set(Flags::kAdvertising); - mFlags.Clear(Flags::kRestartAdvertising); - - if (mFlags.Has(Flags::kFastAdvertisingEnabled)) - { - StartBleAdvTimeoutTimer(CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_TIMEOUT); - } - - err = ConfigureAdvertisingData(); - - if (err == CHIP_NO_ERROR) - /* schedule NFC emulation stop */ - { - ChipDeviceEvent advChange; - advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; - advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Started; - err = PlatformMgr().PostEvent(&advChange); - } - - return err; -} - -CHIP_ERROR BLEManagerCommon::StopAdvertising(void) -{ - CHIP_ERROR error = CHIP_NO_ERROR; - - if (mFlags.Has(Flags::kAdvertising)) - { - mFlags.Clear(Flags::kAdvertising); - mFlags.Clear(Flags::kRestartAdvertising); - - if (!mDeviceConnected) - { - ble_err_t err = blekw_stop_advertising(); - VerifyOrReturnError(err == BLE_OK, CHIP_ERROR_INCORRECT_STATE); - CancelBleAdvTimeoutTimer(); - } - -#if CONFIG_CHIP_NFC_COMMISSIONING - /* schedule NFC emulation stop */ - ChipDeviceEvent advChange; - advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; - advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Stopped; - error = PlatformMgr().PostEvent(&advChange); -#endif - } - - return error; -} - -void BLEManagerCommon::DriveBLEState(void) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - // Check if BLE stack is initialized - VerifyOrExit(mFlags.Has(Flags::kK32WBLEStackInitialized), err = CHIP_ERROR_INCORRECT_STATE); - - // Start advertising if needed... - if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled && mFlags.Has(Flags::kAdvertisingEnabled)) - { - // Start/re-start advertising if not already started, or if there is a pending change - // to the advertising configuration. - if (!mFlags.Has(Flags::kAdvertising) || mFlags.Has(Flags::kRestartAdvertising)) - { - err = StartAdvertising(); - SuccessOrExit(err); - } - } - // Otherwise, stop advertising if it is enabled. - else if (mFlags.Has(Flags::kAdvertising)) - { - err = StopAdvertising(); - SuccessOrExit(err); - // Reset to fast advertising mode only if SetBLEAdvertisingEnabled(false) was called (usually from app). - mFlags.Set(Flags::kFastAdvertisingEnabled); - } - -exit: - if (err != CHIP_NO_ERROR) - { - ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %s", ErrorStr(err)); - mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled; - } -} - -void BLEManagerCommon::DriveBLEState(intptr_t arg) -{ - sImplInstance->DriveBLEState(); -} - -void BLEManagerCommon::StopAdvertisingPriorToSwitchingMode(intptr_t arg) -{ - if (CHIP_NO_ERROR != sImplInstance->StopAdvertising()) - { - ChipLogProgress(DeviceLayer, "Failed to stop advertising"); - } -} - -void BLEManagerCommon::DoBleProcessing(void) -{ - blekw_msg_t * msg = NULL; - - while ((xQueueReceive(sBleEventQueue, &msg, 0) == pdTRUE) && msg) - { - if (msg->type == BLE_KW_MSG_ERROR) - { - if (msg->data.u8 == BLE_KW_MSG_2M_UPGRADE_ERROR) - { - ChipLogProgress(DeviceLayer, - "Warning. BLE is using 1Mbps. Couldn't upgrade to 2Mbps, " - "maybe the peer is missing 2Mbps support."); - } - else - { - ChipLogProgress(DeviceLayer, "BLE Error: %d.\n", msg->data.u8); - } - } - else if (msg->type == BLE_KW_MSG_CONNECTED) - { - sImplInstance->HandleConnectEvent(msg); - } - else if (msg->type == BLE_KW_MSG_DISCONNECTED) - { - sImplInstance->HandleConnectionCloseEvent(msg); - } - else if (msg->type == BLE_KW_MSG_MTU_CHANGED) - { - blekw_start_connection_timeout(); - ChipLogProgress(DeviceLayer, "BLE MTU size has been changed to %d.", msg->data.u16); - } - else if (msg->type == BLE_KW_MSG_ATT_WRITTEN || msg->type == BLE_KW_MSG_ATT_LONG_WRITTEN || - msg->type == BLE_KW_MSG_ATT_CCCD_WRITTEN) - { - sImplInstance->HandleWriteEvent(msg); - } - else if (msg->type == BLE_KW_MSG_ATT_READ) - { -#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING - blekw_att_read_data_t * att_rd_data = (blekw_att_read_data_t *) msg->data.data; - if (value_chipoble_c3 == att_rd_data->handle) - sImplInstance->HandleC3ReadRequest(msg); -#endif - } - else if (msg->type == BLE_KW_MSG_FORCE_DISCONNECT) - { - sImplInstance->HandleForceDisconnect(); - } - - /* Free the message from the queue */ - free(msg); - msg = NULL; - } -} - -void BLEManagerCommon::RegisterAppCallbacks(BLECallbackDelegate::GapGenericCallback gapCallback, - BLECallbackDelegate::GattServerCallback gattCallback) -{ - callbackDelegate.gapCallback = gapCallback; - callbackDelegate.gattCallback = gattCallback; -} - -void BLEManagerCommon::HandleConnectEvent(blekw_msg_t * msg) -{ - uint8_t deviceId = msg->data.u8; - ChipLogProgress(DeviceLayer, "BLE is connected with device: %d.\n", deviceId); - -#if gClkUseFro32K && defined(chip_with_low_power) && (chip_with_low_power == 1) - PWR_DisallowDeviceToSleep(); -#endif - - mDeviceId = deviceId; - mDeviceConnected = true; - - blekw_start_connection_timeout(); - PlatformMgr().ScheduleWork(DriveBLEState, 0); -} - -void BLEManagerCommon::HandleConnectionCloseEvent(blekw_msg_t * msg) -{ - uint8_t deviceId = msg->data.u8; - ChipLogProgress(DeviceLayer, "BLE is disconnected with device: %d.\n", deviceId); - -#if gClkUseFro32K && defined(chip_with_low_power) && (chip_with_low_power == 1) - PWR_AllowDeviceToSleep(); -#endif - - mDeviceConnected = false; - - ChipDeviceEvent event; - event.Type = DeviceEventType::kCHIPoBLEConnectionClosed; - event.CHIPoBLEConnectionError.ConId = deviceId; - event.CHIPoBLEConnectionError.Reason = BLE_ERROR_REMOTE_DEVICE_DISCONNECTED; - - CancelBleAdvTimeoutTimer(); - - PlatformMgr().PostEventOrDie(&event); - mFlags.Set(Flags::kRestartAdvertising); - mFlags.Set(Flags::kFastAdvertisingEnabled); - PlatformMgr().ScheduleWork(DriveBLEState, 0); -} - -void BLEManagerCommon::HandleWriteEvent(blekw_msg_t * msg) -{ - blekw_att_written_data_t * att_wr_data = (blekw_att_written_data_t *) msg->data.data; - attErrorCode_t status = gAttErrCodeNoError_c; - -#if CHIP_DEVICE_CHIP0BLE_DEBUG - ChipLogProgress(DeviceLayer, "Attribute write request(device: %d,handle: %d).", att_wr_data->device_id, att_wr_data->handle); -#endif - - blekw_start_connection_timeout(); - - if (value_chipoble_rx == att_wr_data->handle) - { - sImplInstance->HandleRXCharWrite(msg); - } - else if (cccd_chipoble_tx == att_wr_data->handle) - { - sImplInstance->HandleTXCharCCCDWrite(msg); - } - - /* TODO: do we need to send the status also for CCCD_WRITTEN? */ - if (msg->type != BLE_KW_MSG_ATT_CCCD_WRITTEN) - { - bleResult_t res = GattServer_SendAttributeWrittenStatus(att_wr_data->device_id, att_wr_data->handle, status); - - if (res != gBleSuccess_c) - { - ChipLogProgress(DeviceLayer, "GattServer_SendAttributeWrittenStatus returned %d", res); - } - } -} - -void BLEManagerCommon::HandleTXCharCCCDWrite(blekw_msg_t * msg) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - blekw_att_written_data_t * att_wr_data = (blekw_att_written_data_t *) msg->data.data; - ChipDeviceEvent event; - - VerifyOrExit(att_wr_data->length != 0, err = CHIP_ERROR_INCORRECT_STATE); - VerifyOrExit(att_wr_data->data != nullptr, err = CHIP_ERROR_INCORRECT_STATE); - -#if CHIP_DEVICE_CHIP0BLE_DEBUG - ChipLogProgress(DeviceLayer, "CHIPoBLE %s received", *att_wr_data->data ? "subscribe" : "unsubscribe"); -#endif - - if (*att_wr_data->data) - { - if (!mDeviceSubscribed) - { - mDeviceSubscribed = true; - event.Type = DeviceEventType::kCHIPoBLESubscribe; - event.CHIPoBLESubscribe.ConId = att_wr_data->device_id; - err = PlatformMgr().PostEvent(&event); - } - } - else - { - mDeviceSubscribed = false; - event.Type = DeviceEventType::kCHIPoBLEUnsubscribe; - event.CHIPoBLESubscribe.ConId = att_wr_data->device_id; - err = PlatformMgr().PostEvent(&event); - } - -exit: - if (err != CHIP_NO_ERROR) - { - ChipLogError(DeviceLayer, "HandleTXCharCCCDWrite() failed: %s", ErrorStr(err)); - } -} - -void BLEManagerCommon::HandleRXCharWrite(blekw_msg_t * msg) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - System::PacketBufferHandle buf; - blekw_att_written_data_t * att_wr_data = (blekw_att_written_data_t *) msg->data.data; - - VerifyOrExit(att_wr_data->length != 0, err = CHIP_ERROR_INCORRECT_STATE); - VerifyOrExit(att_wr_data->data != nullptr, err = CHIP_ERROR_INCORRECT_STATE); - - // Copy the data to a PacketBuffer. - buf = System::PacketBufferHandle::NewWithData(att_wr_data->data, att_wr_data->length); - VerifyOrExit(!buf.IsNull(), err = CHIP_ERROR_NO_MEMORY); - -#if CHIP_DEVICE_CHIP0BLE_DEBUG - ChipLogDetail(DeviceLayer, - "Write request/command received for" - "CHIPoBLE RX characteristic (con %u, len %u)", - att_wr_data->device_id, buf->DataLength()); -#endif - - // Post an event to the CHIP queue to deliver the data into the CHIP stack. - { - ChipDeviceEvent event; - event.Type = DeviceEventType::kCHIPoBLEWriteReceived; - event.CHIPoBLEWriteReceived.ConId = att_wr_data->device_id; - event.CHIPoBLEWriteReceived.Data = std::move(buf).UnsafeRelease(); - err = PlatformMgr().PostEvent(&event); - } -exit: - if (err != CHIP_NO_ERROR) - { - ChipLogError(DeviceLayer, "HandleRXCharWrite() failed: %s", ErrorStr(err)); - } -} - -void BLEManagerCommon::HandleForceDisconnect() -{ - ChipLogProgress(DeviceLayer, "BLE connection timeout: Forcing disconnection."); - - /* Set the advertising parameters */ - if (Gap_Disconnect(mDeviceId) != gBleSuccess_c) - { - ChipLogProgress(DeviceLayer, "Gap_Disconnect() failed."); - } - -#if defined(chip_with_low_power) && (chip_with_low_power == 1) - PWR_AllowDeviceToSleep(); -#endif -} - -/******************************************************************************* - * BLE stack callbacks - *******************************************************************************/ -void BLEManagerCommon::blekw_generic_cb(gapGenericEvent_t * pGenericEvent) -{ - /* Call BLE Conn Manager */ - BleConnManager_GenericEvent(pGenericEvent); - - if (sImplInstance && sImplInstance->callbackDelegate.gapCallback) - { - sImplInstance->callbackDelegate.gapCallback(pGenericEvent); - } - - switch (pGenericEvent->eventType) - { - case gInternalError_c: - /* Notify the CHIP that the BLE hardware report fail */ - ChipLogProgress(DeviceLayer, "BLE Internal Error: Code 0x%04X, Source 0x%08X, HCI OpCode %d.\n", - pGenericEvent->eventData.internalError.errorCode, pGenericEvent->eventData.internalError.errorSource, - pGenericEvent->eventData.internalError.hciCommandOpcode); - if ((gHciUnsupportedRemoteFeature_c == pGenericEvent->eventData.internalError.errorCode) && - (gLeSetPhy_c == pGenericEvent->eventData.internalError.errorSource)) - { - (void) blekw_msg_add_u8(BLE_KW_MSG_ERROR, BLE_KW_MSG_2M_UPGRADE_ERROR); - } - else - { - (void) blekw_msg_add_u8(BLE_KW_MSG_ERROR, BLE_INTERNAL_ERROR); - } - break; - - case gAdvertisingSetupFailed_c: - xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_SETUP_FAILED); - break; - - case gAdvertisingParametersSetupComplete_c: - xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_PAR_SETUP_COMPLETE); - break; - - case gAdvertisingDataSetupComplete_c: - xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_DAT_SETUP_COMPLETE); - break; - - case gRandomAddressReady_c: - Gap_SetRandomAddress(pGenericEvent->eventData.addrReady.aAddress); - break; - - case gRandomAddressSet_c: - xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_RND_ADDR_SET); - break; - -#if BLE_HIGH_TX_POWER - case gTxPowerLevelSetComplete_c: - if (gBleSuccess_c == pGenericEvent->eventData.txPowerLevelSetStatus) - { - xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_POWER_LEVEL_SET); - } - break; -#endif - - case gInitializationComplete_c: - /* Common GAP configuration */ - BleConnManager_GapCommonConfig(); - - /* Set the local synchronization event */ - xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_INIT_COMPLETE); - break; - default: - break; - } -} - -void BLEManagerCommon::blekw_gap_advertising_cb(gapAdvertisingEvent_t * pAdvertisingEvent) -{ - if (pAdvertisingEvent->eventType == gAdvertisingStateChanged_c) - { - /* Set the local synchronization event */ - xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_CHANGED); - } - else - { - /* The advertisement start failed */ - ChipLogProgress(DeviceLayer, "Advertising failed: event=%d reason=0x%04X\n", pAdvertisingEvent->eventType, - pAdvertisingEvent->eventData.failReason); - - /* Set the local synchronization event */ - xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_ADV_FAILED); - } -} - -void BLEManagerCommon::blekw_gap_connection_cb(deviceId_t deviceId, gapConnectionEvent_t * pConnectionEvent) -{ - /* Call BLE Conn Manager */ - BleConnManager_GapPeripheralEvent(deviceId, pConnectionEvent); - - if (pConnectionEvent->eventType == gConnEvtConnected_c) - { -#if CHIP_DEVICE_K32W1 -#if defined(chip_with_low_power) && (chip_with_low_power == 1) - /* Disallow must be called here for K32W1, otherwise an assert will be reached. - * Disclaimer: this is a workaround until a better cross platform solution is found. */ - PWR_DisallowDeviceToSleep(); -#endif -#endif - -#if CHIP_DEVICE_CONFIG_BLE_SET_PHY_2M_REQ - ChipLogProgress(DeviceLayer, "BLE K32W: Trying to set the PHY to 2M"); - - (void) Gap_LeSetPhy(FALSE, deviceId, 0, gConnPhyUpdateReqTxPhySettings_c, gConnPhyUpdateReqRxPhySettings_c, - (uint16_t) gConnPhyUpdateReqPhyOptions_c); -#endif - - /* Notify App Task that the BLE is connected now */ - (void) blekw_msg_add_u8(BLE_KW_MSG_CONNECTED, (uint8_t) deviceId); -#if defined(chip_with_low_power) && (chip_with_low_power == 1) - PWR_AllowDeviceToSleep(); -#endif - } - else if (pConnectionEvent->eventType == gConnEvtDisconnected_c) - { - blekw_stop_connection_timeout(); - - /* Notify App Task that the BLE is disconnected now */ - (void) blekw_msg_add_u8(BLE_KW_MSG_DISCONNECTED, (uint8_t) deviceId); - -#if defined(chip_with_low_power) && (chip_with_low_power == 1) - if (bleAppStopInProgress == TRUE) - { - bleAppStopInProgress = FALSE; - PWR_AllowDeviceToSleep(); - } -#endif - } - else if (pConnectionEvent->eventType == gConnEvtPairingRequest_c) - { - /* Reject request for pairing */ - Gap_RejectPairing(deviceId, gPairingNotSupported_c); - } - else if (pConnectionEvent->eventType == gConnEvtAuthenticationRejected_c) - { - ChipLogProgress(DeviceLayer, "BLE Authentication rejected (reason:%d).\n", - pConnectionEvent->eventData.authenticationRejectedEvent.rejectReason); - } -} - -void BLEManagerCommon::blekw_connection_timeout_cb(TimerHandle_t timer) -{ - (void) blekw_msg_add_u8(BLE_KW_MSG_FORCE_DISCONNECT, 0); -} - -void BLEManagerCommon::blekw_start_connection_timeout(void) -{ - xTimerReset(connectionTimeout, 0); -} - -void BLEManagerCommon::blekw_stop_connection_timeout(void) -{ - ChipLogProgress(DeviceLayer, "Stopped connectionTimeout timer."); - xTimerStop(connectionTimeout, 0); -} - -void BLEManagerCommon::blekw_gatt_server_cb(deviceId_t deviceId, gattServerEvent_t * pServerEvent) -{ - if (sImplInstance && sImplInstance->callbackDelegate.gattCallback) - { - sImplInstance->callbackDelegate.gattCallback(deviceId, pServerEvent); - } - - switch (pServerEvent->eventType) - { - case gEvtMtuChanged_c: { - uint16_t tempMtu = 0; - - (void) Gatt_GetMtu(deviceId, &tempMtu); - blekw_msg_add_u16(BLE_KW_MSG_MTU_CHANGED, tempMtu); - break; - } - - case gEvtAttributeWritten_c: - blekw_msg_add_att_written(BLE_KW_MSG_ATT_WRITTEN, deviceId, pServerEvent->eventData.attributeWrittenEvent.handle, - pServerEvent->eventData.attributeWrittenEvent.aValue, - pServerEvent->eventData.attributeWrittenEvent.cValueLength); - break; - - case gEvtLongCharacteristicWritten_c: - blekw_msg_add_att_written(BLE_KW_MSG_ATT_LONG_WRITTEN, deviceId, pServerEvent->eventData.longCharWrittenEvent.handle, - pServerEvent->eventData.longCharWrittenEvent.aValue, - pServerEvent->eventData.longCharWrittenEvent.cValueLength); - break; - - case gEvtAttributeRead_c: - blekw_msg_add_att_read(BLE_KW_MSG_ATT_READ, deviceId, pServerEvent->eventData.attributeReadEvent.handle); - break; - - case gEvtCharacteristicCccdWritten_c: { - uint16_t cccd_val = pServerEvent->eventData.charCccdWrittenEvent.newCccd; - - blekw_msg_add_att_written(BLE_KW_MSG_ATT_CCCD_WRITTEN, deviceId, pServerEvent->eventData.charCccdWrittenEvent.handle, - (uint8_t *) &cccd_val, 2); - break; - } - - case gEvtHandleValueConfirmation_c: - /* Set the local synchronization event */ - xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_INDICATION_CONFIRMED); - break; - - case gEvtError_c: - if (pServerEvent->eventData.procedureError.procedureType == gSendIndication_c) - { - /* Set the local synchronization event */ - xEventGroupSetBits(sEventGroup, CHIP_BLE_KW_EVNT_INDICATION_FAILED); - } - else - { - ChipLogProgress(DeviceLayer, "BLE Gatt Server Error: Code 0x%04X, Source %d.\n", - pServerEvent->eventData.procedureError.error, pServerEvent->eventData.procedureError.procedureType); - - /* Notify CHIP BLE App Task that the BLE hardware report fail */ - (void) blekw_msg_add_u8(BLE_KW_MSG_ERROR, BLE_INTERNAL_GATT_ERROR); - } - break; - - default: - break; - } -} -/******************************************************************************* - * Add to message queue functions - *******************************************************************************/ -CHIP_ERROR BLEManagerCommon::blekw_msg_add_att_written(blekw_msg_type_t type, uint8_t device_id, uint16_t handle, uint8_t * data, - uint16_t length) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - blekw_msg_t * msg = NULL; - blekw_att_written_data_t * att_wr_data; - - /* Allocate a buffer with enough space to store the packet */ - msg = (blekw_msg_t *) malloc(sizeof(blekw_msg_t) + sizeof(blekw_att_written_data_t) + length); - VerifyOrExit(msg, err = CHIP_ERROR_NO_MEMORY); - - msg->type = type; - msg->length = sizeof(blekw_att_written_data_t) + length; - att_wr_data = (blekw_att_written_data_t *) msg->data.data; - att_wr_data->device_id = device_id; - att_wr_data->handle = handle; - att_wr_data->length = length; - FLib_MemCpy(att_wr_data->data, data, length); - - VerifyOrExit(xQueueSend(sBleEventQueue, &msg, 0) == pdTRUE, err = CHIP_ERROR_NO_MEMORY); - otTaskletsSignalPending(NULL); - -exit: - return err; -} - -CHIP_ERROR BLEManagerCommon::blekw_msg_add_att_read(blekw_msg_type_t type, uint8_t device_id, uint16_t handle) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - blekw_msg_t * msg = NULL; - blekw_att_read_data_t * att_rd_data; - - /* Allocate a buffer with enough space to store the packet */ - msg = (blekw_msg_t *) malloc(sizeof(blekw_msg_t) + sizeof(blekw_att_read_data_t)); - VerifyOrExit(msg, err = CHIP_ERROR_NO_MEMORY); - - msg->type = type; - msg->length = sizeof(blekw_att_read_data_t); - att_rd_data = (blekw_att_read_data_t *) msg->data.data; - att_rd_data->device_id = device_id; - att_rd_data->handle = handle; - - VerifyOrExit(xQueueSend(sBleEventQueue, &msg, 0) == pdTRUE, err = CHIP_ERROR_NO_MEMORY); - otTaskletsSignalPending(NULL); - -exit: - return err; -} - -CHIP_ERROR BLEManagerCommon::blekw_msg_add_u8(blekw_msg_type_t type, uint8_t data) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - blekw_msg_t * msg = NULL; - - /* Allocate a buffer with enough space to store the packet */ - msg = (blekw_msg_t *) malloc(sizeof(blekw_msg_t)); - VerifyOrExit(msg, err = CHIP_ERROR_NO_MEMORY); - - msg->type = type; - msg->length = 0; - msg->data.u8 = data; - - VerifyOrExit(xQueueSend(sBleEventQueue, &msg, 0) == pdTRUE, err = CHIP_ERROR_NO_MEMORY); - otTaskletsSignalPending(NULL); - -exit: - return err; -} - -CHIP_ERROR BLEManagerCommon::blekw_msg_add_u16(blekw_msg_type_t type, uint16_t data) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - blekw_msg_t * msg = NULL; - - /* Allocate a buffer with enough space to store the packet */ - msg = (blekw_msg_t *) malloc(sizeof(blekw_msg_t)); - VerifyOrExit(msg, err = CHIP_ERROR_NO_MEMORY); - - msg->type = type; - msg->length = 0; - msg->data.u16 = data; - - VerifyOrExit(xQueueSend(sBleEventQueue, &msg, 0) == pdTRUE, err = CHIP_ERROR_NO_MEMORY); - otTaskletsSignalPending(NULL); - -exit: - return err; -} - -void BLEManagerCommon::BleAdvTimeoutHandler(TimerHandle_t xTimer) -{ - if (BLEMgrImpl().mFlags.Has(Flags::kFastAdvertisingEnabled)) - { - ChipLogDetail(DeviceLayer, "Start slow advertisement"); - BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kSlowAdvertising); - } -} - -void BLEManagerCommon::CancelBleAdvTimeoutTimer(void) -{ - if (xTimerStop(sbleAdvTimeoutTimer, 0) == pdFAIL) - { - ChipLogError(DeviceLayer, "Failed to stop BledAdv timeout timer"); - } -} - -void BLEManagerCommon::StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs) -{ - if (xTimerIsTimerActive(sbleAdvTimeoutTimer)) - { - CancelBleAdvTimeoutTimer(); - } - - // timer is not active, change its period to required value (== restart). - // FreeRTOS- Block for a maximum of 100 ticks if the change period command - // cannot immediately be sent to the timer command queue. - if (xTimerChangePeriod(sbleAdvTimeoutTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) != pdPASS) - { - ChipLogError(DeviceLayer, "Failed to start BledAdv timeout timer"); - } -} - -CHIP_ERROR BLEManagerCommon::blekw_stop_connection_internal(BLE_CONNECTION_OBJECT conId) -{ - ChipLogProgress(DeviceLayer, "Closing BLE GATT connection (con %u)", conId); - - if (Gap_Disconnect(conId) != gBleSuccess_c) - { - ChipLogProgress(DeviceLayer, "Gap_Disconnect() failed."); - return CHIP_ERROR_INTERNAL; - } -#if defined(chip_with_low_power) && (chip_with_low_power == 1) - else - { - bleAppStopInProgress = TRUE; - PWR_DisallowDeviceToSleep(); - } -#endif - - return CHIP_NO_ERROR; -} - -} // namespace Internal -} // namespace DeviceLayer -} // namespace chip -#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE diff --git a/src/platform/nxp/k32w/common/BLEManagerCommon.h b/src/platform/nxp/k32w/common/BLEManagerCommon.h deleted file mode 100644 index b7fc1275d2501f..00000000000000 --- a/src/platform/nxp/k32w/common/BLEManagerCommon.h +++ /dev/null @@ -1,249 +0,0 @@ -/* - * - * Copyright (c) 2020-2021 Project CHIP Authors - * Copyright (c) 2020 Nest Labs, Inc. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * Provides an implementation of the BLEManager singleton object - * for the K32W platforms. - */ - -#pragma once - -#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE - -#include "fsl_os_abstraction.h" - -#include "ble_conn_manager.h" -#include "ble_general.h" -#include "ble_host_task_config.h" -#include "ble_host_tasks.h" -#include "gap_interface.h" -#include "gatt_db_dynamic.h" -#include "gatt_server_interface.h" - -#include "FreeRTOS.h" -#include "event_groups.h" -#include "timers.h" - -namespace chip { -namespace DeviceLayer { -namespace Internal { - -using namespace chip::Ble; - -/** - * A delegate class that can be used by the application to subscribe to BLE events. - */ -struct BLECallbackDelegate -{ - using GapGenericCallback = void (*)(gapGenericEvent_t * event); - using GattServerCallback = void (*)(deviceId_t id, gattServerEvent_t * event); - - GapGenericCallback gapCallback = nullptr; - GattServerCallback gattCallback = nullptr; -}; - -/** - * Base class for different platform implementations (K32W0 and K32W1 for now). - */ -class BLEManagerCommon : public BLEManager, protected BleLayer, private BlePlatformDelegate, private BleApplicationDelegate -{ -protected: - // ===== Members that implement the BLEManager internal interface. - - CHIP_ERROR _Init(void); - CHIP_ERROR _Shutdown() { return CHIP_NO_ERROR; } - CHIPoBLEServiceMode _GetCHIPoBLEServiceMode(void); - CHIP_ERROR _SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val); - bool _IsAdvertisingEnabled(void); - CHIP_ERROR _SetAdvertisingEnabled(bool val); - bool _IsAdvertising(void); - CHIP_ERROR _SetAdvertisingMode(BLEAdvertisingMode mode); - CHIP_ERROR _GetDeviceName(char * buf, size_t bufSize); - CHIP_ERROR _SetDeviceName(const char * deviceName); - uint16_t _NumConnections(void); - void _OnPlatformEvent(const ChipDeviceEvent * event); - - // ===== Members that implement virtual methods on BlePlatformDelegate. - - CHIP_ERROR SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, - const Ble::ChipBleUUID * charId) override; - CHIP_ERROR UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, - const Ble::ChipBleUUID * charId) override; - CHIP_ERROR CloseConnection(BLE_CONNECTION_OBJECT conId) override; - uint16_t GetMTU(BLE_CONNECTION_OBJECT conId) const override; - CHIP_ERROR SendIndication(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId, - System::PacketBufferHandle pBuf) override; - CHIP_ERROR SendWriteRequest(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId, - System::PacketBufferHandle pBuf) override; - - // ===== Members that implement virtual methods on BleApplicationDelegate. - - void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) override; - - // ===== Private members reserved for use by this class only. - - enum class Flags : uint8_t - { - kAdvertisingEnabled = 0x0001, - kFastAdvertisingEnabled = 0x0002, - kAdvertising = 0x0004, - kRestartAdvertising = 0x0008, - kK32WBLEStackInitialized = 0x0010, - kDeviceNameSet = 0x0020, - }; - BitFlags mFlags; - - enum - { - kMaxDeviceNameLength = 16, - kUnusedIndex = 0xFF, - }; - - typedef enum - { - BLE_KW_MSG_ERROR = 0x01, - BLE_KW_MSG_CONNECTED, - BLE_KW_MSG_DISCONNECTED, - BLE_KW_MSG_MTU_CHANGED, - BLE_KW_MSG_ATT_WRITTEN, - BLE_KW_MSG_ATT_LONG_WRITTEN, - BLE_KW_MSG_ATT_READ, - BLE_KW_MSG_ATT_CCCD_WRITTEN, - BLE_KW_MSG_FORCE_DISCONNECT, - } blekw_msg_type_t; - - typedef struct hk_ble_kw_msg_s - { - blekw_msg_type_t type; - uint16_t length; - union - { - uint8_t u8; - uint16_t u16; - uint32_t u32; - uint8_t data[1]; - char * str; - } data; - } blekw_msg_t; - - typedef enum ble_err_t - { - BLE_OK = 0, - BLE_INTERNAL_GATT_ERROR, - BLE_E_SET_ADV_PARAMS, - BLE_E_ADV_PARAMS_FAILED, - BLE_E_SET_ADV_DATA, - BLE_E_ADV_CHANGED, - BLE_E_ADV_FAILED, - BLE_E_ADV_SETUP_FAILED, - BLE_E_START_ADV, - BLE_E_STOP, - BLE_E_FAIL, - BLE_E_START_ADV_FAILED, - BLE_KW_MSG_2M_UPGRADE_ERROR, - BLE_INTERNAL_ERROR, - } ble_err_t; - - typedef struct ble_att_written_data_s - { - uint8_t device_id; - uint16_t handle; - uint16_t length; - uint8_t data[1]; - } blekw_att_written_data_t; - - typedef struct hk_ble_att_read_data_s - { - uint8_t device_id; - uint16_t handle; - } blekw_att_read_data_t; - - CHIPoBLEServiceMode mServiceMode; - char mDeviceName[kMaxDeviceNameLength + 1]; -#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING - chip::System::PacketBufferHandle c3AdditionalDataBufferHandle; -#endif - uint8_t mDeviceId; - bool mDeviceSubscribed = false; - bool mDeviceConnected = false; - - void DriveBLEState(void); - CHIP_ERROR ConfigureAdvertising(void); - CHIP_ERROR ConfigureAdvertisingData(void); - CHIP_ERROR StartAdvertising(void); - CHIP_ERROR StopAdvertising(void); - - void HandleConnectEvent(blekw_msg_t * msg); - void HandleConnectionCloseEvent(blekw_msg_t * msg); - void HandleWriteEvent(blekw_msg_t * msg); - void HandleRXCharWrite(blekw_msg_t * msg); - void HandleTXCharCCCDWrite(blekw_msg_t * msg); - void HandleForceDisconnect(); - -#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING - CHIP_ERROR EncodeAdditionalDataTlv(); - void HandleC3ReadRequest(blekw_msg_t * msg); -#endif - BLEManagerCommon::ble_err_t blekw_send_event(int8_t connection_handle, uint16_t handle, uint8_t * data, uint32_t len); - - static void DriveBLEState(intptr_t arg); - static void StopAdvertisingPriorToSwitchingMode(intptr_t arg); - static void BleAdvTimeoutHandler(TimerHandle_t xTimer); - static void CancelBleAdvTimeoutTimer(void); - static void StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs); - - static void blekw_connection_timeout_cb(TimerHandle_t timer); - static void blekw_generic_cb(gapGenericEvent_t * pGenericEvent); - static void blekw_gatt_server_cb(deviceId_t deviceId, gattServerEvent_t * pServerEvent); - static CHIP_ERROR blekw_msg_add_u8(blekw_msg_type_t type, uint8_t data); - static CHIP_ERROR blekw_msg_add_u16(blekw_msg_type_t type, uint16_t data); - static CHIP_ERROR blekw_msg_add_att_written(blekw_msg_type_t type, uint8_t device_id, uint16_t handle, uint8_t * data, - uint16_t length); - static CHIP_ERROR blekw_msg_add_att_read(blekw_msg_type_t type, uint8_t device_id, uint16_t handle); - static BLEManagerCommon::ble_err_t blekw_start_advertising(gapAdvertisingParameters_t * adv_params, gapAdvertisingData_t * adv, - gapScanResponseData_t * scnrsp); - static BLEManagerCommon::ble_err_t blekw_stop_advertising(void); - static void blekw_gap_advertising_cb(gapAdvertisingEvent_t * pAdvertisingEvent); - static void blekw_gap_connection_cb(deviceId_t deviceId, gapConnectionEvent_t * pConnectionEvent); - static void blekw_start_connection_timeout(void); - static void blekw_stop_connection_timeout(void); - static CHIP_ERROR blekw_stop_connection_internal(BLE_CONNECTION_OBJECT conId); - -public: - virtual CHIP_ERROR InitHostController(BLECallbackDelegate::GapGenericCallback cb_fp) = 0; - virtual BLEManagerCommon * GetImplInstance() = 0; - virtual CHIP_ERROR ResetController() { return CHIP_NO_ERROR; } - void DoBleProcessing(void); - - BLECallbackDelegate callbackDelegate; - void RegisterAppCallbacks(BLECallbackDelegate::GapGenericCallback gapCallback, - BLECallbackDelegate::GattServerCallback gattCallback); -}; - -inline BLEManager::CHIPoBLEServiceMode BLEManagerCommon::_GetCHIPoBLEServiceMode(void) -{ - return mServiceMode; -} - -} // namespace Internal -} // namespace DeviceLayer -} // namespace chip - -#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE diff --git a/src/platform/nxp/k32w/common/CHIPDevicePlatformRamStorageConfig.h b/src/platform/nxp/k32w/common/CHIPDevicePlatformRamStorageConfig.h deleted file mode 100644 index bcb9ecdd82d58c..00000000000000 --- a/src/platform/nxp/k32w/common/CHIPDevicePlatformRamStorageConfig.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * - * Copyright (c) 2022 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * Configuration of RAM storage metadata: key IDs and NVM IDs. - */ - -#pragma once - -/* Base key IDs used when creating new keys for RAM storage instances. */ -/** - * @def kKeyId_Factory - * - * Base key id used for factory RAM storage. - */ -#ifndef kKeyId_Factory -#define kKeyId_Factory (uint8_t) 0x01 -#endif - -/** - * @def kKeyId_Config - * - * Base key id used for config RAM storage. - */ -#ifndef kKeyId_Config -#define kKeyId_Config (uint8_t) 0x02 -#endif - -/** - * @def kKeyId_Counter - * - * Base key id used for counter RAM storage. - */ -#ifndef kKeyId_Counter -#define kKeyId_Counter (uint8_t) 0x03 -#endif - -/** - * @def kKeyId_KvsKeys - * - * Base key id used for KVS keys RAM storage. - */ -#ifndef kKeyId_KvsKeys -#define kKeyId_KvsKeys (uint8_t) 0x04 -#endif - -/** - * @def kKeyId_KvsValues - * - * Base key id used for KVS values RAM storage. - */ -#ifndef kKeyId_KvsValues -#define kKeyId_KvsValues (uint8_t) 0x05 -#endif - -/* PDM IDs used when defining RAM storage instances or RAM buffers (OT). */ -/** - * @def kNvmId_Factory - * - * PDM ID used for factory RAM storage. - */ -#ifndef kNvmId_Factory -#define kNvmId_Factory (uint16_t) 0x5001 -#endif - -/** - * @def kNvmId_Config - * - * PDM ID used for config RAM storage. - */ -#ifndef kNvmId_Config -#define kNvmId_Config (uint16_t) 0x5002 -#endif - -/** - * @def kNvmId_Counter - * - * PDM ID used for counter RAM storage. - */ -#ifndef kNvmId_Counter -#define kNvmId_Counter (uint16_t) 0x5003 -#endif - -/** - * @def kNvmId_KvsKeys - * - * PDM ID used for KVS keys RAM storage. - */ -#ifndef kNvmId_KvsKeys -#define kNvmId_KvsKeys (uint16_t) 0x6000 -#endif - -/** - * @def kNvmId_KvsValues - * - * PDM ID used for KVS values RAM storage. - * KVS buffer can become quite big, so this PDM - * id is used as base id for subsequent PDM ids - * used to store data in chunks of PDM page size. - * This will use the extended search feature, so - * subsequent PDM ids should not be used. - */ -#ifndef kNvmId_KvsValues -#define kNvmId_KvsValues (uint16_t) 0x6001 -#endif - -/** - * @def kNvmId_KvsSubscription - * - * PDM ID used for KVS subscription RAM storage. - * It will store both keys and values for those keys. - */ -#ifndef kNvmId_KvsSubscription -#define kNvmId_KvsSubscription (uint16_t) 0x6100 -#endif - -/** - * @def kNvmId_KvsGroups - * - * PDM ID used for KVS groups RAM storage. - * It will store both keys and values for those keys. - * This will use the extended search feature, so - * subsequent PDM ids should not be used. - */ -#ifndef kNvmId_KvsGroups -#define kNvmId_KvsGroups (uint16_t) 0x6200 -#endif - -/** - * @def kNvmId_OTConfigData - * - * PDM ID used for OT RAM buffer. - */ -#ifndef kNvmId_OTConfigData -#define kNvmId_OTConfigData (uint16_t) 0x4F00 -#endif - -/** - * @def kNvmId_ApplicationBase - * - * Base PDM ID to be used by applications to define their own - * PDM IDs by using an offset. - */ -#ifndef kNvmId_ApplicationBase -#define kNvmId_ApplicationBase (uint16_t) 0xA000 -#endif - -#if CONFIG_CHIP_LOAD_REAL_FACTORY_DATA -/** - * @def kNvmId_FactoryDataBackup - * - * PDM ID used for factory data backup in FactoryDataProvider. - */ -#ifndef kNvmId_FactoryDataBackup -#define kNvmId_FactoryDataBackup (uint16_t) 0x7000 -#endif -#endif // CONFIG_CHIP_LOAD_REAL_FACTORY_DATA diff --git a/src/platform/nxp/k32w/common/FactoryDataProvider.cpp b/src/platform/nxp/k32w/common/FactoryDataProvider.cpp deleted file mode 100644 index dd79b020c881ea..00000000000000 --- a/src/platform/nxp/k32w/common/FactoryDataProvider.cpp +++ /dev/null @@ -1,368 +0,0 @@ -/* - * - * Copyright (c) 2022 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if (!CONFIG_CHIP_LOAD_REAL_FACTORY_DATA || !(defined CONFIG_CHIP_LOAD_REAL_FACTORY_DATA)) -#include -#include -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace chip { -namespace DeviceLayer { - -static constexpr size_t kSpake2pSerializedVerifier_MaxBase64Len = - BASE64_ENCODED_LEN(chip::Crypto::kSpake2p_VerifierSerialized_Length) + 1; -static constexpr size_t kSpake2pSalt_MaxBase64Len = BASE64_ENCODED_LEN(chip::Crypto::kSpake2p_Max_PBKDF_Salt_Length) + 1; -/* Secure subsystem private key blob size is 32 + 24 = 56. - * DAC private key may be used to store an SSS exported blob instead of the private key. - */ -static constexpr size_t kDacPrivateKey_MaxLen = Crypto::kP256_PrivateKey_Length + 24; - -uint32_t FactoryDataProvider::kFactoryDataStart = (uint32_t) __MATTER_FACTORY_DATA_START; -uint32_t FactoryDataProvider::kFactoryDataSize = (uint32_t) __MATTER_FACTORY_DATA_SIZE; -uint32_t FactoryDataProvider::kFactoryDataPayloadStart = kFactoryDataStart + sizeof(FactoryDataProvider::Header); - -FactoryDataProvider::~FactoryDataProvider() {} - -CHIP_ERROR FactoryDataProvider::Validate() -{ - uint8_t output[Crypto::kSHA256_Hash_Length] = { 0 }; - - memcpy(&mHeader, (void *) kFactoryDataStart, sizeof(Header)); - ReturnErrorCodeIf(mHeader.hashId != kHashId, CHIP_FACTORY_DATA_HASH_ID); - - ReturnErrorOnFailure(Crypto::Hash_SHA256((uint8_t *) kFactoryDataPayloadStart, mHeader.size, output)); - ReturnErrorCodeIf(memcmp(output, mHeader.hash, kHashLen) != 0, CHIP_FACTORY_DATA_SHA_CHECK); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR FactoryDataProvider::SearchForId(uint8_t searchedType, uint8_t * pBuf, size_t bufLength, uint16_t & length, - uint32_t * offset) -{ - uint32_t addr = kFactoryDataPayloadStart; - uint8_t type = 0; - - while (addr < (kFactoryDataPayloadStart + mHeader.size)) - { - memcpy(&type, (void *) addr, sizeof(type)); - memcpy(&length, (void *) (addr + 1), sizeof(length)); - - if (searchedType == type) - { - ReturnErrorCodeIf(bufLength < length, CHIP_ERROR_BUFFER_TOO_SMALL); - memcpy(pBuf, (void *) (addr + kValueOffset), length); - - if (offset) - *offset = (addr - kFactoryDataPayloadStart); - - return CHIP_NO_ERROR; - } - else - { - /* Jump past 3 bytes of length and then use length to jump to next data */ - addr = addr + kValueOffset + length; - } - } - - return CHIP_ERROR_NOT_FOUND; -} - -CHIP_ERROR FactoryDataProvider::GetCertificationDeclaration(MutableByteSpan & outBuffer) -{ -#if CHIP_USE_DEVICE_CONFIG_CERTIFICATION_DECLARATION - constexpr uint8_t kCdForAllExamples[] = CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION; - - return CopySpanToMutableSpan(ByteSpan{ kCdForAllExamples }, outBuffer); -#else - uint16_t declarationSize = 0; - ReturnErrorOnFailure(SearchForId(FactoryDataId::kCertDeclarationId, outBuffer.data(), outBuffer.size(), declarationSize)); - outBuffer.reduce_size(declarationSize); - - return CHIP_NO_ERROR; -#endif -} - -CHIP_ERROR FactoryDataProvider::GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) -{ - return CHIP_NO_ERROR; -} - -CHIP_ERROR FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & outBuffer) -{ - uint16_t certificateSize = 0; - ReturnErrorOnFailure(SearchForId(FactoryDataId::kDacCertificateId, outBuffer.data(), outBuffer.size(), certificateSize)); - outBuffer.reduce_size(certificateSize); - return CHIP_NO_ERROR; -} - -CHIP_ERROR FactoryDataProvider::GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) -{ - uint16_t certificateSize = 0; - ReturnErrorOnFailure(SearchForId(FactoryDataId::kPaiCertificateId, outBuffer.data(), outBuffer.size(), certificateSize)); - outBuffer.reduce_size(certificateSize); - return CHIP_NO_ERROR; -} - -CHIP_ERROR FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) -{ - return SignWithDacKey(messageToSign, outSignBuffer); -} - -CHIP_ERROR FactoryDataProvider::GetSetupDiscriminator(uint16_t & setupDiscriminator) -{ - uint32_t discriminator = 0; - uint16_t temp = 0; - - ReturnErrorOnFailure(SearchForId(FactoryDataId::kDiscriminatorId, (uint8_t *) &discriminator, sizeof(discriminator), temp)); - setupDiscriminator = (uint16_t) (discriminator & 0x0000FFFF); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR FactoryDataProvider::SetSetupDiscriminator(uint16_t setupDiscriminator) -{ - return CHIP_ERROR_NOT_IMPLEMENTED; -} - -CHIP_ERROR FactoryDataProvider::GetSpake2pIterationCount(uint32_t & iterationCount) -{ - uint16_t temp = 0; - ReturnErrorOnFailure(SearchForId(FactoryDataId::kIcId, (uint8_t *) &iterationCount, sizeof(iterationCount), temp)); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) -{ - char saltB64[kSpake2pSalt_MaxBase64Len] = { 0 }; - uint16_t saltB64Len = 0; - - ReturnErrorOnFailure(SearchForId(FactoryDataId::kSaltId, (uint8_t *) (&saltB64[0]), sizeof(saltB64), saltB64Len)); - size_t saltLen = chip::Base64Decode32(saltB64, saltB64Len, reinterpret_cast(saltB64)); - - ReturnErrorCodeIf(saltLen > saltBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); - memcpy(saltBuf.data(), saltB64, saltLen); - saltBuf.reduce_size(saltLen); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) -{ - char verifierB64[kSpake2pSerializedVerifier_MaxBase64Len] = { 0 }; - uint16_t verifierB64Len = 0; - ReturnErrorOnFailure(SearchForId(FactoryDataId::kVerifierId, (uint8_t *) &verifierB64[0], sizeof(verifierB64), verifierB64Len)); - - verifierLen = chip::Base64Decode32(verifierB64, verifierB64Len, reinterpret_cast(verifierB64)); - ReturnErrorCodeIf(verifierLen > verifierBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); - memcpy(verifierBuf.data(), verifierB64, verifierLen); - verifierBuf.reduce_size(verifierLen); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR FactoryDataProvider::GetSetupPasscode(uint32_t & setupPasscode) -{ - uint16_t length = 0; - ReturnErrorOnFailure(SearchForId(FactoryDataId::kSetupPasscodeId, (uint8_t *) &setupPasscode, sizeof(setupPasscode), length)); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR FactoryDataProvider::SetSetupPasscode(uint32_t setupPasscode) -{ - return CHIP_ERROR_NOT_IMPLEMENTED; -} - -CHIP_ERROR FactoryDataProvider::GetVendorName(char * buf, size_t bufSize) -{ - uint16_t length = 0; - ReturnErrorOnFailure(SearchForId(FactoryDataId::kVendorNameId, (uint8_t *) buf, bufSize, length)); - buf[length] = '\0'; - - return CHIP_NO_ERROR; -} - -CHIP_ERROR FactoryDataProvider::GetVendorId(uint16_t & vendorId) -{ - uint16_t length = 0; - ReturnErrorOnFailure(SearchForId(FactoryDataId::kVidId, (uint8_t *) &vendorId, sizeof(vendorId), length)); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR FactoryDataProvider::GetProductName(char * buf, size_t bufSize) -{ - uint16_t length = 0; - ReturnErrorOnFailure(SearchForId(FactoryDataId::kProductNameId, (uint8_t *) buf, bufSize, length)); - buf[length] = '\0'; - - return CHIP_NO_ERROR; -} - -CHIP_ERROR FactoryDataProvider::GetProductId(uint16_t & productId) -{ - uint16_t length = 0; - ReturnErrorOnFailure(SearchForId(FactoryDataId::kPidId, (uint8_t *) &productId, sizeof(productId), length)); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR FactoryDataProvider::GetPartNumber(char * buf, size_t bufSize) -{ - uint16_t length = 0; - ReturnErrorOnFailure(SearchForId(FactoryDataId::kPartNumber, (uint8_t *) buf, bufSize, length)); - buf[length] = '\0'; - - return CHIP_NO_ERROR; -} - -CHIP_ERROR FactoryDataProvider::GetProductURL(char * buf, size_t bufSize) -{ - uint16_t length = 0; - ReturnErrorOnFailure(SearchForId(FactoryDataId::kProductURL, (uint8_t *) buf, bufSize, length)); - buf[length] = '\0'; - - return CHIP_NO_ERROR; -} - -CHIP_ERROR FactoryDataProvider::GetProductLabel(char * buf, size_t bufSize) -{ - uint16_t length = 0; - ReturnErrorOnFailure(SearchForId(FactoryDataId::kProductLabel, (uint8_t *) buf, bufSize, length)); - buf[length] = '\0'; - - return CHIP_NO_ERROR; -} - -CHIP_ERROR FactoryDataProvider::GetSerialNumber(char * buf, size_t bufSize) -{ - uint16_t length = 0; - ReturnErrorOnFailure(SearchForId(FactoryDataId::kSerialNumberId, (uint8_t *) buf, bufSize, length)); - buf[length] = '\0'; - - return CHIP_NO_ERROR; -} - -CHIP_ERROR FactoryDataProvider::GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) -{ - uint16_t length = 0; - uint8_t date[ConfigurationManager::kMaxManufacturingDateLength]; - - ReturnErrorOnFailure( - SearchForId(FactoryDataId::kManufacturingDateId, date, ConfigurationManager::kMaxManufacturingDateLength, length)); - date[length] = '\0'; - - if (length == 10 && isdigit(date[0]) && isdigit(date[1]) && isdigit(date[2]) && isdigit(date[3]) && date[4] == '-' && - isdigit(date[5]) && isdigit(date[6]) && date[7] == '-' && isdigit(date[8]) && isdigit(date[9])) - { - year = 1000 * (date[0] - '0') + 100 * (date[1] - '0') + 10 * (date[2] - '0') + date[3] - '0'; - month = 10 * (date[5] - '0') + date[6] - '0'; - day = 10 * (date[8] - '0') + date[9] - '0'; - } - else - { - ChipLogError(DeviceLayer, "Manufacturing date is not formatted correctly: YYYY-MM-DD."); - return CHIP_ERROR_INVALID_ARGUMENT; - } - - return CHIP_NO_ERROR; -} - -CHIP_ERROR FactoryDataProvider::GetHardwareVersion(uint16_t & hardwareVersion) -{ - uint16_t length = 0; - ReturnErrorOnFailure( - SearchForId(FactoryDataId::kHardwareVersionId, (uint8_t *) &hardwareVersion, sizeof(hardwareVersion), length)); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR FactoryDataProvider::GetHardwareVersionString(char * buf, size_t bufSize) -{ - uint16_t length = 0; - ReturnErrorOnFailure(SearchForId(FactoryDataId::kHardwareVersionStrId, (uint8_t *) buf, bufSize, length)); - buf[length] = '\0'; - - return CHIP_NO_ERROR; -} - -CHIP_ERROR FactoryDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) -{ - CHIP_ERROR err = CHIP_ERROR_NOT_IMPLEMENTED; -#if CHIP_ENABLE_ROTATING_DEVICE_ID - static_assert(ConfigurationManager::kRotatingDeviceIDUniqueIDLength >= ConfigurationManager::kMinRotatingDeviceIDUniqueIDLength, - "Length of unique ID for rotating device ID is smaller than minimum."); - uint16_t uniqueIdLen = 0; - err = SearchForId(FactoryDataId::kUniqueId, (uint8_t *) uniqueIdSpan.data(), uniqueIdSpan.size(), uniqueIdLen); -#if defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID) - if (err != CHIP_NO_ERROR) - { - constexpr uint8_t uniqueId[] = CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID; - - ReturnErrorCodeIf(sizeof(uniqueId) > uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); - memcpy(uniqueIdSpan.data(), uniqueId, sizeof(uniqueId)); - uniqueIdLen = sizeof(uniqueId); - err = CHIP_NO_ERROR; - } -#endif // CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID - ReturnErrorOnFailure(err); - uniqueIdSpan.reduce_size(uniqueIdLen); -#endif - - return err; -} - -CHIP_ERROR FactoryDataProvider::GetProductFinish(app::Clusters::BasicInformation::ProductFinishEnum * finish) -{ - uint8_t productFinish; - uint16_t length = 0; - auto err = SearchForId(FactoryDataId::kProductFinish, &productFinish, sizeof(productFinish), length); - ReturnErrorCodeIf(err != CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); - - *finish = static_cast(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 -} // namespace chip diff --git a/src/platform/nxp/k32w/common/FactoryDataProvider.h b/src/platform/nxp/k32w/common/FactoryDataProvider.h deleted file mode 100644 index 03ccf370f7641c..00000000000000 --- a/src/platform/nxp/k32w/common/FactoryDataProvider.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * - * Copyright (c) 2022 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include -#include -#include -#include - -#include - -#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[]; - -namespace chip { -namespace DeviceLayer { - -#define CHIP_FACTORY_DATA_ERROR(e) \ - ChipError(ChipError::Range::kLastRange, ((uint8_t) ChipError::Range::kLastRange << 2) | e, __FILE__, __LINE__) - -#define CHIP_FACTORY_DATA_SHA_CHECK CHIP_FACTORY_DATA_ERROR(0x01) -#define CHIP_FACTORY_DATA_HEADER_READ CHIP_FACTORY_DATA_ERROR(0x02) -#define CHIP_FACTORY_DATA_HASH_ID CHIP_FACTORY_DATA_ERROR(0x03) -#define CHIP_FACTORY_DATA_PDM_RESTORE CHIP_FACTORY_DATA_ERROR(0x04) -#define CHIP_FACTORY_DATA_NULL CHIP_FACTORY_DATA_ERROR(0x05) -#define CHIP_FACTORY_DATA_FLASH_ERASE CHIP_FACTORY_DATA_ERROR(0x06) -#define CHIP_FACTORY_DATA_FLASH_PROGRAM CHIP_FACTORY_DATA_ERROR(0x07) -#define CHIP_FACTORY_DATA_INTERNAL_FLASH_READ CHIP_FACTORY_DATA_ERROR(0x08) -#define CHIP_FACTORY_DATA_PDM_SAVE_RECORD CHIP_FACTORY_DATA_ERROR(0x09) -#define CHIP_FACTORY_DATA_PDM_READ_RECORD CHIP_FACTORY_DATA_ERROR(0x0A) -#define CHIP_FACTORY_DATA_RESTORE_MECHANISM CHIP_FACTORY_DATA_ERROR(0x0B) - -/** - * @brief This class provides Commissionable data, Device Attestation Credentials, - * and Device Instance Info. - */ - -class FactoryDataProvider : public DeviceInstanceInfoProvider, - public CommissionableDataProvider, - public Credentials::DeviceAttestationCredentialsProvider -{ -public: - struct Header - { - uint32_t hashId; - uint32_t size; - uint8_t hash[4]; - }; - - // Default factory data IDs - enum FactoryDataId - { - kVerifierId = 1, - kSaltId, - kIcId, - kDacPrivateKeyId, - kDacCertificateId, - kPaiCertificateId, - kDiscriminatorId, - kSetupPasscodeId, - kVidId, - kPidId, - kCertDeclarationId, - kVendorNameId, - kProductNameId, - kSerialNumberId, - kManufacturingDateId, - kHardwareVersionId, - kHardwareVersionStrId, - kUniqueId, - kPartNumber, - kProductURL, - kProductLabel, - kProductFinish, - kProductPrimaryColor, - kMaxId - }; - - static uint32_t kFactoryDataStart; - static uint32_t kFactoryDataSize; - static uint32_t kFactoryDataPayloadStart; - static constexpr uint32_t kLengthOffset = 1; - static constexpr uint32_t kValueOffset = 3; - static constexpr uint32_t kHashLen = 4; - static constexpr size_t kHashId = 0xCE47BA5E; - - virtual ~FactoryDataProvider(); - - virtual CHIP_ERROR Init() = 0; - virtual CHIP_ERROR SignWithDacKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) = 0; - CHIP_ERROR Validate(); - - CHIP_ERROR SearchForId(uint8_t searchedType, uint8_t * pBuf, size_t bufLength, uint16_t & length, uint32_t * offset = nullptr); - - // ===== Members functions that implement the CommissionableDataProvider - CHIP_ERROR GetSetupDiscriminator(uint16_t & setupDiscriminator) override; - CHIP_ERROR SetSetupDiscriminator(uint16_t setupDiscriminator) override; - CHIP_ERROR GetSpake2pIterationCount(uint32_t & iterationCount) override; - CHIP_ERROR GetSpake2pSalt(MutableByteSpan & saltBuf) override; - CHIP_ERROR GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) override; - CHIP_ERROR GetSetupPasscode(uint32_t & setupPasscode) override; - CHIP_ERROR SetSetupPasscode(uint32_t setupPasscode) override; - - // ===== Members functions that implement the DeviceAttestationCredentialsProvider - CHIP_ERROR GetCertificationDeclaration(MutableByteSpan & outBuffer) override; - CHIP_ERROR GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) override; - CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & outBuffer) override; - CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) override; - CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) override; - - // ===== Members functions that implement the GenericDeviceInstanceInfoProvider - CHIP_ERROR GetVendorName(char * buf, size_t bufSize) override; - CHIP_ERROR GetVendorId(uint16_t & vendorId) override; - CHIP_ERROR GetProductName(char * buf, size_t bufSize) override; - CHIP_ERROR GetProductId(uint16_t & productId) override; - CHIP_ERROR GetPartNumber(char * buf, size_t bufSize) override; - CHIP_ERROR GetProductURL(char * buf, size_t bufSize) override; - CHIP_ERROR GetProductLabel(char * buf, size_t bufSize) override; - CHIP_ERROR GetHardwareVersionString(char * buf, size_t bufSize) override; - CHIP_ERROR GetSerialNumber(char * buf, size_t bufSize) override; - CHIP_ERROR GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) override; - CHIP_ERROR GetHardwareVersion(uint16_t & hardwareVersion) override; - CHIP_ERROR GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) override; - CHIP_ERROR GetProductFinish(app::Clusters::BasicInformation::ProductFinishEnum * finish) override; - CHIP_ERROR GetProductPrimaryColor(app::Clusters::BasicInformation::ColorEnum * primaryColor) override; - -protected: - Header mHeader; -}; - -} // namespace DeviceLayer -} // namespace chip diff --git a/src/platform/nxp/k32w/common/K32W_OTA_README.md b/src/platform/nxp/k32w/common/K32W_OTA_README.md deleted file mode 100644 index 0c9715b4610ff8..00000000000000 --- a/src/platform/nxp/k32w/common/K32W_OTA_README.md +++ /dev/null @@ -1,149 +0,0 @@ -# K32W OTA - -The OTA processing is now delegated to instances of `OTATlvProcessor` derived -classes. These instances are registered with the `OTAImageProcessorImpl` -instance, which manages the selection of processors that should process the next -blocks, until a full TLV block was transferred. - -The application is able to define its own processors, thus extending the default -OTA functionality. The application can also opt to disable the default -processors (application, SSBL and factory data). - -Please note that if an OTA image containing multiple TLV is transferred, then -the action for each TLV is applied sequentially, If one of the actions fails, -the remaining actions will not be applied and OTA abort is called. TBD: should -all actions be applied only if there is no error? Or should each action be -applied separately? - -## Default processors - -The default processors for K32W0 are already implemented in: - -- `OTAFirmwareProcessor` for application/SSBL update. Enabled by default. -- `OTAFactoryDataProcessor` for factory data update. Disabled by default, user - has to specify `chip_ota_enable_factory_data_processor=1` in the build args. - -Some SDK OTA module flags are defined to support additional features: - -- `gOTAAllowCustomStartAddress=1` - enable `EEPROM` offset value. Used - internally by SDK OTA module. -- `gOTAUseCustomOtaEntry=1` - support custom OTA entry for multi-image. -- `gOTACustomOtaEntryMemory=1` - K32W0 uses `OTACustomStorage_ExtFlash` (1) by - default. - -## Implementing custom processors - -A custom processor should implement the abstract interface defined in -`OTATlvProcessor.h`. Below is a compact version: - -``` -class OTATlvProcessor -{ -public: - virtual CHIP_ERROR Init() = 0; - virtual CHIP_ERROR Clear() = 0; - virtual CHIP_ERROR ApplyAction() = 0; - virtual CHIP_ERROR AbortAction() = 0; - virtual CHIP_ERROR ExitAction(); - - CHIP_ERROR Process(ByteSpan & block); - void RegisterDescriptorCallback(ProcessDescriptor callback); -protected: - virtual CHIP_ERROR ProcessInternal(ByteSpan & block) = 0; -}; - -``` - -Some details regarding the interface: - -- `Init` will be called whenever the processor is selected. -- `Clear` will be called when abort occurs or after the apply action takes - place. -- `ApplyAction` will be called in `OTAImageProcessorImpl::HandleApply`, before - the board is reset. -- `AbortAction` will be called in `OTAImageProcessorImpl::HandleAbort`. - Processors should reset state here. -- `ExitAction` is optional and should be implemented by the processors that - want to execute an action after all data has been transferred, but before - `HandleApply` is called. It's called before the new processor selection - takes place. This is useful in the context of multiple TLV transferred in a - single OTA process. -- `Process` is the public API used inside `OTAImageProcessorImpl` for data - processing. This is a wrapper over `ProcessInternal`, which can return - `CHIP_OTA_CHANGE_PROCESSOR` to notify a new processor should be selected for - the remaining data. -- `RegisterDescriptorCallback` can be used to register a callback for - processing the descriptor. It's optional. -- `ProcessInternal` should return: _ `CHIP_NO_ERROR` if block was processed - successfully. _ `CHIP_ERROR_BUFFER_TOO_SMALL` if current block doesn't - contain all necessary data. This can happen when a TLV value field has a - header, but it is split across two blocks. \* - `CHIP_OTA_FETCH_ALREADY_SCHEDULED` if block was processed successfully and - the fetching is already scheduled by the processor. This happens in the - default application processor, because the next data fetching is scheduled - through a callback (called when enough external flash was erased). - -Furthermore, a processor can use an instance of `OTADataAccumulator` to -accumulate data until a given threshold. This is useful when a custom payload -contains metadata that need parsing: accumulate data until the threshold is -reached or return `CHIP_ERROR_BUFFER_TOO_SMALL` to signal -`OTAImageProcessorImpl` more data is needed. - -``` -/** - * This class can be used to accumulate data until a given threshold. - * Should be used by OTATlvProcessor derived classes if they need - * metadata accumulation (e.g. for custom header decoding). - */ -class OTADataAccumulator -{ -public: - void Init(uint32_t threshold); - void Clear(); - CHIP_ERROR Accumulate(ByteSpan & block); - - inline uint8_t* data() { return mBuffer.Get(); } - -private: - uint32_t mThreshold; - uint32_t mBufferOffset; - Platform::ScopedMemoryBuffer mBuffer; -}; -``` - -## SSBL max entries example - -`CONFIG_CHIP_K32W0_MAX_ENTRIES_TEST` can be set to 1 to enable max entries test. -There will be 8 additional processors registered in default `OtaHooks` -implementation. The OTA image should be generated with the -`create_ota_images.sh` script from `./scripts/tools/nxp/ota/examples`. - -## Factory data restore mechanism - -Prior to factory data update, the old factory data is backed up in external -flash. If anything interrupts the update (e.g. power loss), there is a slight -chance the internal flash factory data section is erased and has to be restored -at next boot. The `FactoryDataProvider` offers a default restore mechanism and -support for registering additional restore mechanisms or overwriting the default -one. - -Prior to factory data update, the old factory data is backed up in external -flash. If anything interrupts the update (e.g. power loss), there is a slight -chance the internal flash factory data section is erased and has to be restored -at next boot. The `FactoryDataProvider` offers a default restore mechanism and -support for registering additional restore mechanisms or overwriting the default -one. - -Restore mechanisms are just functions that have this signature: -`CHIP_ERROR (*)(void)`. Any such function can be registered through -`FactoryDataProvider::RegisterRestoreMechanism`. - -The default restore mechanism is implemented as a weak function: -`FactoryDataDefaultRestoreMechanism`. It is registered in -`FactoryDataProvider::Init`, before factory data validation, and it can be -overwritten at application level. When doing the actual restore, the mechanisms -are called in the order they were registered. - -Please note that the restore mechanisms registration order matters. Once a -restore mechanism is successful (`CHIP_NO_ERROR` is returned), the restore -process has finished and subsequent restore mechanisms will not be called. diff --git a/src/platform/nxp/k32w/common/OTAImageProcessorImpl.cpp b/src/platform/nxp/k32w/common/OTAImageProcessorImpl.cpp deleted file mode 100644 index e972550c536d58..00000000000000 --- a/src/platform/nxp/k32w/common/OTAImageProcessorImpl.cpp +++ /dev/null @@ -1,424 +0,0 @@ -/* - * - * 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 -#include -#include -#include -#include - -#include - -using namespace chip::DeviceLayer; -using namespace ::chip::DeviceLayer::Internal; - -#if USE_SMU2_STATIC -// The attribute specifier should not be changed. -static chip::OTAImageProcessorImpl gImageProcessor __attribute__((section(".smu2"))); -#else -static chip::OTAImageProcessorImpl gImageProcessor; -#endif - -namespace chip { - -CHIP_ERROR OTAImageProcessorImpl::Init(OTADownloader * downloader) -{ - ReturnErrorCodeIf(downloader == nullptr, CHIP_ERROR_INVALID_ARGUMENT); - mDownloader = downloader; - - OtaHookInit(); - - return CHIP_NO_ERROR; -} - -void OTAImageProcessorImpl::Clear() -{ - mHeaderParser.Clear(); - mAccumulator.Clear(); - mParams.totalFileBytes = 0; - mParams.downloadedBytes = 0; - mCurrentProcessor = nullptr; - - ReleaseBlock(); -} - -CHIP_ERROR OTAImageProcessorImpl::PrepareDownload() -{ - DeviceLayer::PlatformMgr().ScheduleWork(HandlePrepareDownload, reinterpret_cast(this)); - return CHIP_NO_ERROR; -} - -CHIP_ERROR OTAImageProcessorImpl::Finalize() -{ - DeviceLayer::PlatformMgr().ScheduleWork(HandleFinalize, reinterpret_cast(this)); - return CHIP_NO_ERROR; -} - -CHIP_ERROR OTAImageProcessorImpl::Apply() -{ - DeviceLayer::PlatformMgr().ScheduleWork(HandleApply, reinterpret_cast(this)); - return CHIP_NO_ERROR; -} - -CHIP_ERROR OTAImageProcessorImpl::Abort() -{ - DeviceLayer::PlatformMgr().ScheduleWork(HandleAbort, reinterpret_cast(this)); - return CHIP_NO_ERROR; -} - -CHIP_ERROR OTAImageProcessorImpl::ProcessBlock(ByteSpan & block) -{ - if ((block.data() == nullptr) || block.empty()) - { - return CHIP_ERROR_INVALID_ARGUMENT; - } - - // Store block data for HandleProcessBlock to access - CHIP_ERROR err = SetBlock(block); - if (err != CHIP_NO_ERROR) - { - ChipLogError(SoftwareUpdate, "Cannot set block data: %" CHIP_ERROR_FORMAT, err.Format()); - } - - DeviceLayer::PlatformMgr().ScheduleWork(HandleProcessBlock, reinterpret_cast(this)); - return CHIP_NO_ERROR; -} - -void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context) -{ - auto * imageProcessor = reinterpret_cast(context); - - VerifyOrReturn(imageProcessor != nullptr, ChipLogError(SoftwareUpdate, "ImageProcessor context is null")); - - VerifyOrReturn(imageProcessor->mDownloader != nullptr, ChipLogError(SoftwareUpdate, "mDownloader is null")); - - GetRequestorInstance()->GetProviderLocation(imageProcessor->mBackupProviderLocation); - - imageProcessor->mHeaderParser.Init(); - imageProcessor->mAccumulator.Init(sizeof(OTATlvHeader)); - imageProcessor->mDownloader->OnPreparedForDownload(CHIP_NO_ERROR); -} - -CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block) -{ - OTAImageHeader header; - ReturnErrorOnFailure(mHeaderParser.AccumulateAndDecode(block, header)); - - mParams.totalFileBytes = header.mPayloadSize; - mHeaderParser.Clear(); - ChipLogError(SoftwareUpdate, "Processed header successfully"); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR OTAImageProcessorImpl::ProcessPayload(ByteSpan & block) -{ - CHIP_ERROR status = CHIP_NO_ERROR; - - while (true) - { - if (!mCurrentProcessor) - { - ReturnErrorOnFailure(mAccumulator.Accumulate(block)); - ByteSpan tlvHeader{ mAccumulator.data(), sizeof(OTATlvHeader) }; - ReturnErrorOnFailure(SelectProcessor(tlvHeader)); - ReturnErrorOnFailure(mCurrentProcessor->Init()); - } - - status = mCurrentProcessor->Process(block); - if (status == CHIP_ERROR_OTA_CHANGE_PROCESSOR) - { - mAccumulator.Clear(); - mAccumulator.Init(sizeof(OTATlvHeader)); - - mCurrentProcessor = nullptr; - - // If the block size is 0, it means that the processed data was a multiple of - // received BDX block size (e.g. 8 blocks of 1024 bytes were transferred). - // After state for selecting next processor is reset, a request for fetching next - // data must be sent. - if (block.size() == 0) - { - status = CHIP_NO_ERROR; - break; - } - } - else - { - break; - } - } - - return status; -} - -CHIP_ERROR OTAImageProcessorImpl::SelectProcessor(ByteSpan & block) -{ - OTATlvHeader header; - Encoding::LittleEndian::Reader reader(block.data(), sizeof(header)); - - ReturnErrorOnFailure(reader.Read32(&header.tag).StatusCode()); - ReturnErrorOnFailure(reader.Read32(&header.length).StatusCode()); - - auto pair = mProcessorMap.find(header.tag); - if (pair == mProcessorMap.end()) - { - ChipLogError(SoftwareUpdate, "There is no registered processor for tag: %" PRIu32, header.tag); - return CHIP_ERROR_OTA_PROCESSOR_NOT_REGISTERED; - } - - ChipLogDetail(SoftwareUpdate, "Selected processor with tag: %ld", pair->first); - mCurrentProcessor = pair->second; - mCurrentProcessor->SetLength(header.length); - mCurrentProcessor->SetWasSelected(true); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR OTAImageProcessorImpl::RegisterProcessor(uint32_t tag, OTATlvProcessor * processor) -{ - auto pair = mProcessorMap.find(tag); - if (pair != mProcessorMap.end()) - { - ChipLogError(SoftwareUpdate, "A processor for tag %" PRIu32 " is already registered.", tag); - return CHIP_ERROR_OTA_PROCESSOR_ALREADY_REGISTERED; - } - - mProcessorMap.insert({ tag, processor }); - - return CHIP_NO_ERROR; -} - -void OTAImageProcessorImpl::HandleAbort(intptr_t context) -{ - ChipLogError(SoftwareUpdate, "OTA was aborted"); - auto * imageProcessor = reinterpret_cast(context); - if (imageProcessor != nullptr) - { - imageProcessor->AbortAllProcessors(); - } - imageProcessor->Clear(); - - OtaHookAbort(); -} - -void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context) -{ - auto * imageProcessor = reinterpret_cast(context); - - VerifyOrReturn(imageProcessor != nullptr, ChipLogError(SoftwareUpdate, "ImageProcessor context is null")); - - VerifyOrReturn(imageProcessor->mDownloader != nullptr, ChipLogError(SoftwareUpdate, "mDownloader is null")); - - CHIP_ERROR status; - auto block = ByteSpan(imageProcessor->mBlock.data(), imageProcessor->mBlock.size()); - - if (imageProcessor->mHeaderParser.IsInitialized()) - { - status = imageProcessor->ProcessHeader(block); - if (status != CHIP_NO_ERROR) - { - imageProcessor->HandleStatus(status); - } - } - - status = imageProcessor->ProcessPayload(block); - imageProcessor->HandleStatus(status); -} - -void OTAImageProcessorImpl::HandleStatus(CHIP_ERROR status) -{ - if (status == CHIP_NO_ERROR || status == CHIP_ERROR_BUFFER_TOO_SMALL) - { - mParams.downloadedBytes += mBlock.size(); - FetchNextData(0); - } - else if (status == CHIP_ERROR_OTA_FETCH_ALREADY_SCHEDULED) - { - mParams.downloadedBytes += mBlock.size(); - } - else - { - ChipLogError(SoftwareUpdate, "Image update canceled. Failed to process OTA block: %s", ErrorStr(status)); - GetRequestorInstance()->CancelImageUpdate(); - } -} - -void OTAImageProcessorImpl::AbortAllProcessors() -{ - ChipLogError(SoftwareUpdate, "All selected processors will call abort action"); - - for (auto const & pair : mProcessorMap) - { - if (pair.second->WasSelected()) - { - pair.second->AbortAction(); - pair.second->Clear(); - pair.second->SetWasSelected(false); - } - } -} - -bool OTAImageProcessorImpl::IsFirstImageRun() -{ - OTARequestorInterface * requestor = chip::GetRequestorInstance(); - if (requestor == nullptr) - { - return false; - } - - return requestor->GetCurrentUpdateState() == OTARequestorInterface::OTAUpdateStateEnum::kApplying; -} - -CHIP_ERROR OTAImageProcessorImpl::ConfirmCurrentImage() -{ - uint32_t currentVersion; - uint32_t targetVersion; - - OTARequestorInterface * requestor = chip::GetRequestorInstance(); - ReturnErrorCodeIf(requestor == nullptr, CHIP_ERROR_INTERNAL); - - targetVersion = requestor->GetTargetVersion(); - ReturnErrorOnFailure(DeviceLayer::ConfigurationMgr().GetSoftwareVersion(currentVersion)); - if (currentVersion != targetVersion) - { - ChipLogError(SoftwareUpdate, "Current sw version %" PRIu32 " is different than the expected sw version = %" PRIu32, - currentVersion, targetVersion); - return CHIP_ERROR_INCORRECT_STATE; - } - - return CHIP_NO_ERROR; -} - -CHIP_ERROR OTAImageProcessorImpl::SetBlock(ByteSpan & block) -{ - if (!IsSpanUsable(block)) - { - return CHIP_NO_ERROR; - } - - if (mBlock.size() < block.size()) - { - if (!mBlock.empty()) - { - ReleaseBlock(); - } - uint8_t * mBlock_ptr = static_cast(chip::Platform::MemoryAlloc(block.size())); - if (mBlock_ptr == nullptr) - { - return CHIP_ERROR_NO_MEMORY; - } - mBlock = MutableByteSpan(mBlock_ptr, block.size()); - } - - CHIP_ERROR err = CopySpanToMutableSpan(block, mBlock); - if (err != CHIP_NO_ERROR) - { - ChipLogError(SoftwareUpdate, "Cannot copy block data: %" CHIP_ERROR_FORMAT, err.Format()); - return err; - } - return CHIP_NO_ERROR; -} - -void OTAImageProcessorImpl::HandleFinalize(intptr_t context) -{ - auto * imageProcessor = reinterpret_cast(context); - if (imageProcessor == nullptr) - { - return; - } - - imageProcessor->ReleaseBlock(); -} - -void OTAImageProcessorImpl::HandleApply(intptr_t context) -{ - CHIP_ERROR error = CHIP_NO_ERROR; - auto * imageProcessor = reinterpret_cast(context); - if (imageProcessor == nullptr) - { - return; - } - - for (auto const & pair : imageProcessor->mProcessorMap) - { - if (pair.second->WasSelected()) - { - error = pair.second->ApplyAction(); - if (error != CHIP_NO_ERROR) - { - ChipLogError(SoftwareUpdate, "Apply action for tag %d processor failed.", (uint8_t) pair.first); - // Revert all previously applied actions if current apply action fails. - // Reset image processor and requestor states. - imageProcessor->AbortAllProcessors(); - imageProcessor->Clear(); - GetRequestorInstance()->Reset(); - - return; - } - } - } - - for (auto const & pair : imageProcessor->mProcessorMap) - { - pair.second->Clear(); - pair.second->SetWasSelected(false); - } - - imageProcessor->mAccumulator.Clear(); - - ConfigurationManagerImpl().StoreSoftwareUpdateCompleted(); - PlatformMgr().HandleServerShuttingDown(); - - // Set the necessary information to inform the SSBL that a new image is available - // and trigger the actual device reboot after some time, to take into account - // queued actions, e.g. sending events to a subscription - SystemLayer().StartTimer( - chip::System::Clock::Milliseconds32(CHIP_DEVICE_LAYER_OTA_REBOOT_DELAY), - [](chip::System::Layer *, void *) { OtaHookReset(); }, nullptr); -} - -CHIP_ERROR OTAImageProcessorImpl::ReleaseBlock() -{ - if (mBlock.data() != nullptr) - { - chip::Platform::MemoryFree(mBlock.data()); - } - - mBlock = MutableByteSpan(); - return CHIP_NO_ERROR; -} - -void OTAImageProcessorImpl::FetchNextData(uint32_t context) -{ - auto * imageProcessor = &OTAImageProcessorImpl::GetDefaultInstance(); - SystemLayer().ScheduleLambda([imageProcessor] { - if (imageProcessor->mDownloader) - { - imageProcessor->mDownloader->FetchNextData(); - } - }); -} - -OTAImageProcessorImpl & OTAImageProcessorImpl::GetDefaultInstance() -{ - return gImageProcessor; -} - -} // namespace chip diff --git a/src/platform/nxp/k32w/common/OTAImageProcessorImpl.h b/src/platform/nxp/k32w/common/OTAImageProcessorImpl.h deleted file mode 100644 index 4eea088891109f..00000000000000 --- a/src/platform/nxp/k32w/common/OTAImageProcessorImpl.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * - * Copyright (c) 2021-2023 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -/* - * OTA hooks that can be overwritten by application. - * Default behavior is implemented as WEAK symbols in platform OtaHooks.cpp. - */ - -/* - * This hook is called at the end of OTAImageProcessorImpl::Init. - * It should generally register the OTATlvProcessor instances. - */ -extern "C" CHIP_ERROR OtaHookInit(); - -/* - * This hook is called at the end of OTAImageProcessorImpl::HandleApply. - * The default implementation saves the internal OTA entry structure and resets the device. - */ -extern "C" void OtaHookReset(); - -/* - * This hook is called at the end of OTAImageProcessorImpl::HandleAbort. - * For example, it can be used to schedule a retry. - */ -extern "C" void OtaHookAbort(); - -namespace chip { - -class OTAImageProcessorImpl : public OTAImageProcessorInterface -{ -public: - using ProviderLocation = chip::OTARequestorInterface::ProviderLocationType; - - CHIP_ERROR Init(OTADownloader * downloader); - void Clear(); - - //////////// OTAImageProcessorInterface Implementation /////////////// - CHIP_ERROR PrepareDownload() override; - CHIP_ERROR Finalize() override; - CHIP_ERROR Apply() override; - CHIP_ERROR Abort() override; - CHIP_ERROR ProcessBlock(ByteSpan & block) override; - bool IsFirstImageRun() override; - CHIP_ERROR ConfirmCurrentImage() override; - - CHIP_ERROR ProcessHeader(ByteSpan & block); - CHIP_ERROR ProcessPayload(ByteSpan & block); - CHIP_ERROR SelectProcessor(ByteSpan & block); - CHIP_ERROR RegisterProcessor(uint32_t tag, OTATlvProcessor * processor); - Optional & GetBackupProvider() { return mBackupProviderLocation; } - - static void FetchNextData(uint32_t context); - static OTAImageProcessorImpl & GetDefaultInstance(); - -private: - //////////// Actual handlers for the OTAImageProcessorInterface /////////////// - static void HandlePrepareDownload(intptr_t context); - static void HandleFinalize(intptr_t context); - static void HandleApply(intptr_t context); - static void HandleAbort(intptr_t context); - static void HandleProcessBlock(intptr_t context); - - void HandleStatus(CHIP_ERROR status); - - /** - * Called to allocate memory for mBlock if necessary and set it to block - */ - CHIP_ERROR SetBlock(ByteSpan & block); - - /** - * Called to release allocated memory for mBlock - */ - CHIP_ERROR ReleaseBlock(); - - /** - * Call AbortAction for all processors that were used - */ - void AbortAllProcessors(); - - MutableByteSpan mBlock; - OTADownloader * mDownloader; - OTAImageHeaderParser mHeaderParser; - OTATlvProcessor * mCurrentProcessor = nullptr; - OTADataAccumulator mAccumulator; - std::map mProcessorMap; - Optional mBackupProviderLocation; -}; - -} // namespace chip diff --git a/src/platform/nxp/k32w/common/OTATlvProcessor.cpp b/src/platform/nxp/k32w/common/OTATlvProcessor.cpp deleted file mode 100644 index 5dc0eaebd83627..00000000000000 --- a/src/platform/nxp/k32w/common/OTATlvProcessor.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/* - * - * 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 -#include -#include - -#include -#include -#if OTA_ENCRYPTION_ENABLE -#include "OtaUtils.h" -#include "rom_aes.h" -#endif -namespace chip { - -#if OTA_ENCRYPTION_ENABLE -constexpr uint8_t au8Iv[] = { 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x00, 0x00, 0x00, 0x00 }; -#endif - -CHIP_ERROR OTATlvProcessor::ApplyAction() -{ - return mApplyState == ApplyState::kApply ? CHIP_NO_ERROR : CHIP_ERROR_OTA_PROCESSOR_DO_NOT_APPLY; -} - -CHIP_ERROR OTATlvProcessor::Process(ByteSpan & block) -{ - CHIP_ERROR status = CHIP_NO_ERROR; - uint32_t bytes = chip::min(mLength - mProcessedLength, static_cast(block.size())); - ByteSpan relevantData = block.SubSpan(0, bytes); - - status = ProcessInternal(relevantData); - if (!IsError(status)) - { - mProcessedLength += bytes; - block = block.SubSpan(bytes); - if (mProcessedLength == mLength) - { - status = ExitAction(); - if (!IsError(status)) - { - // If current block was processed fully and the block still contains data, it - // means that the block contains another TLV's data and the current processor - // should be changed by OTAImageProcessorImpl. - return CHIP_ERROR_OTA_CHANGE_PROCESSOR; - } - } - } - - return status; -} - -void OTATlvProcessor::ClearInternal() -{ - mLength = 0; - mProcessedLength = 0; - mWasSelected = false; - mApplyState = ApplyState::kApply; -#if OTA_ENCRYPTION_ENABLE - mIVOffset = 0; -#endif -} - -bool OTATlvProcessor::IsError(CHIP_ERROR & status) -{ - return status != CHIP_NO_ERROR && status != CHIP_ERROR_BUFFER_TOO_SMALL && status != CHIP_ERROR_OTA_FETCH_ALREADY_SCHEDULED; -} - -void OTADataAccumulator::Init(uint32_t threshold) -{ - mThreshold = threshold; - mBufferOffset = 0; - mBuffer.Alloc(mThreshold); -} - -void OTADataAccumulator::Clear() -{ - mThreshold = 0; - mBufferOffset = 0; - mBuffer.Free(); -} - -CHIP_ERROR OTADataAccumulator::Accumulate(ByteSpan & block) -{ - uint32_t numBytes = chip::min(mThreshold - mBufferOffset, static_cast(block.size())); - memcpy(&mBuffer[mBufferOffset], block.data(), numBytes); - mBufferOffset += numBytes; - block = block.SubSpan(numBytes); - - if (mBufferOffset < mThreshold) - { - return CHIP_ERROR_BUFFER_TOO_SMALL; - } - - return CHIP_NO_ERROR; -} - -#if OTA_ENCRYPTION_ENABLE -CHIP_ERROR OTATlvProcessor::vOtaProcessInternalEncryption(MutableByteSpan & block) -{ - uint8_t iv[16]; - uint8_t key[kOTAEncryptionKeyLength]; - uint8_t dataOut[16] = { 0 }; - uint32_t u32IVCount; - uint32_t Offset = 0; - uint8_t data; - tsReg128 sKey; - aesContext_t Context; - - memcpy(iv, au8Iv, sizeof(au8Iv)); - - u32IVCount = (((uint32_t) iv[12]) << 24) | (((uint32_t) iv[13]) << 16) | (((uint32_t) iv[14]) << 8) | (iv[15]); - u32IVCount += (mIVOffset >> 4); - - iv[12] = (uint8_t) ((u32IVCount >> 24) & 0xff); - iv[13] = (uint8_t) ((u32IVCount >> 16) & 0xff); - iv[14] = (uint8_t) ((u32IVCount >> 8) & 0xff); - iv[15] = (uint8_t) (u32IVCount & 0xff); - - if (Encoding::HexToBytes(OTA_ENCRYPTION_KEY, strlen(OTA_ENCRYPTION_KEY), key, kOTAEncryptionKeyLength) != - kOTAEncryptionKeyLength) - { - // Failed to convert the OTAEncryptionKey string to octstr type value - return CHIP_ERROR_INVALID_STRING_LENGTH; - } - - ByteSpan KEY = ByteSpan(key); - Encoding::LittleEndian::Reader reader_key(KEY.data(), KEY.size()); - ReturnErrorOnFailure(reader_key.Read32(&sKey.u32register0) - .Read32(&sKey.u32register1) - .Read32(&sKey.u32register2) - .Read32(&sKey.u32register3) - .StatusCode()); - - while (Offset + 16 <= block.size()) - { - /*Encrypt the IV*/ - Context.mode = AES_MODE_ECB_ENCRYPT; - Context.pSoftwareKey = (uint32_t *) &sKey; - AES_128_ProcessBlocks(&Context, (uint32_t *) &iv[0], (uint32_t *) &dataOut[0], 1); - - /* Decrypt a block of the buffer */ - for (uint8_t i = 0; i < 16; i++) - { - data = block[Offset + i] ^ dataOut[i]; - memcpy(&block[Offset + i], &data, sizeof(uint8_t)); - } - - /* increment the IV for the next block */ - u32IVCount++; - - iv[12] = (uint8_t) ((u32IVCount >> 24) & 0xff); - iv[13] = (uint8_t) ((u32IVCount >> 16) & 0xff); - iv[14] = (uint8_t) ((u32IVCount >> 8) & 0xff); - iv[15] = (uint8_t) (u32IVCount & 0xff); - - Offset += 16; /* increment the buffer offset */ - mIVOffset += 16; - } - - return CHIP_NO_ERROR; -} -#endif -} // namespace chip diff --git a/src/platform/nxp/k32w/common/OTATlvProcessor.h b/src/platform/nxp/k32w/common/OTATlvProcessor.h deleted file mode 100644 index f1faef7e8eecf9..00000000000000 --- a/src/platform/nxp/k32w/common/OTATlvProcessor.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * - * 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 { - -#define CHIP_ERROR_TLV_PROCESSOR(e) \ - ChipError(ChipError::Range::kLastRange, ((uint8_t) ChipError::Range::kLastRange << 3) | e, __FILE__, __LINE__) - -#define CHIP_ERROR_OTA_CHANGE_PROCESSOR CHIP_ERROR_TLV_PROCESSOR(0x02) -#define CHIP_ERROR_OTA_PROCESSOR_NOT_REGISTERED CHIP_ERROR_TLV_PROCESSOR(0x03) -#define CHIP_ERROR_OTA_PROCESSOR_ALREADY_REGISTERED CHIP_ERROR_TLV_PROCESSOR(0x04) -#define CHIP_ERROR_OTA_PROCESSOR_CLIENT_INIT CHIP_ERROR_TLV_PROCESSOR(0x05) -#define CHIP_ERROR_OTA_PROCESSOR_MAKE_ROOM CHIP_ERROR_TLV_PROCESSOR(0x06) -#define CHIP_ERROR_OTA_PROCESSOR_PUSH_CHUNK CHIP_ERROR_TLV_PROCESSOR(0x07) -#define CHIP_ERROR_OTA_PROCESSOR_IMG_AUTH CHIP_ERROR_TLV_PROCESSOR(0x08) -#define CHIP_ERROR_OTA_FETCH_ALREADY_SCHEDULED CHIP_ERROR_TLV_PROCESSOR(0x09) -#define CHIP_ERROR_OTA_PROCESSOR_IMG_COMMIT CHIP_ERROR_TLV_PROCESSOR(0x0A) -#define CHIP_ERROR_OTA_PROCESSOR_CB_NOT_REGISTERED CHIP_ERROR_TLV_PROCESSOR(0x0B) -#define CHIP_ERROR_OTA_PROCESSOR_EEPROM_OFFSET CHIP_ERROR_TLV_PROCESSOR(0x0C) -#define CHIP_ERROR_OTA_PROCESSOR_EXTERNAL_STORAGE CHIP_ERROR_TLV_PROCESSOR(0x0D) -#define CHIP_ERROR_OTA_PROCESSOR_START_IMAGE CHIP_ERROR_TLV_PROCESSOR(0x0E) -#define CHIP_ERROR_OTA_PROCESSOR_DO_NOT_APPLY CHIP_ERROR_TLV_PROCESSOR(0x0F) - -// Descriptor constants -constexpr size_t kVersionStringSize = 64; -constexpr size_t kBuildDateSize = 64; - -constexpr uint16_t requestedOtaMaxBlockSize = 1024; - -/** - * Used alongside RegisterDescriptorCallback to register - * a custom descriptor processing function with a certain - * TLV processor. - */ -typedef CHIP_ERROR (*ProcessDescriptor)(void * descriptor); - -struct OTATlvHeader -{ - uint32_t tag; - uint32_t length; -}; - -/** - * This class defines an interface for a Matter TLV processor. - * Instances of derived classes can be registered as processors - * in OTAImageProcessorImpl. Based on the TLV type, a certain - * processor is used to process subsequent blocks until the number - * of bytes found in the metadata is processed. In case a block contains - * data from two different TLVs, the processor should ensure the remaining - * data is returned in the block passed as input. - * The default processors: application, SSBL and factory data are registered - * in OTAImageProcessorImpl::Init through OtaHookInit. - * Applications should use OTAImageProcessorImpl::RegisterProcessor - * to register additional processors. - */ -class OTATlvProcessor -{ -public: - enum class ApplyState : uint8_t - { - kApply = 0, - kDoNotApply - }; - - virtual ~OTATlvProcessor() {} - - virtual CHIP_ERROR Init() = 0; - virtual CHIP_ERROR Clear() = 0; - virtual CHIP_ERROR AbortAction() = 0; - virtual CHIP_ERROR ExitAction() { return CHIP_NO_ERROR; } - virtual CHIP_ERROR ApplyAction(); - - CHIP_ERROR Process(ByteSpan & block); - void RegisterDescriptorCallback(ProcessDescriptor callback) { mCallbackProcessDescriptor = callback; } - void SetLength(uint32_t length) { mLength = length; } - void SetWasSelected(bool selected) { mWasSelected = selected; } - bool WasSelected() { return mWasSelected; } -#if OTA_ENCRYPTION_ENABLE - CHIP_ERROR vOtaProcessInternalEncryption(MutableByteSpan & block); -#endif - -protected: - /** - * @brief Process custom TLV payload - * - * The method takes subsequent chunks of the Matter OTA image file and processes them. - * If more image chunks are needed, CHIP_ERROR_BUFFER_TOO_SMALL error is returned. - * Other error codes indicate that an error occurred during processing. Fetching - * next data is scheduled automatically by OTAImageProcessorImpl if the return value - * is neither an error code, nor CHIP_ERROR_OTA_FETCH_ALREADY_SCHEDULED (which implies the - * scheduling is done inside ProcessInternal or will be done in the future, through a - * callback). - * - * @param block Byte span containing a subsequent Matter OTA image chunk. When the method - * returns CHIP_NO_ERROR, the byte span is used to return a remaining part - * of the chunk, not used by current TLV processor. - * - * @retval CHIP_NO_ERROR Block was processed successfully. - * @retval CHIP_ERROR_BUFFER_TOO_SMALL Provided buffers are insufficient to decode some - * metadata (e.g. a descriptor). - * @retval CHIP_ERROR_OTA_FETCH_ALREADY_SCHEDULED Should be returned if ProcessInternal schedules - * fetching next data (e.g. through a callback). - * @retval Error code Something went wrong. Current OTA process will be - * canceled. - */ - virtual CHIP_ERROR ProcessInternal(ByteSpan & block) = 0; - - void ClearInternal(); - - bool IsError(CHIP_ERROR & status); - -#if OTA_ENCRYPTION_ENABLE - /*ota decryption*/ - uint32_t mIVOffset = 0; - /* Expected byte size of the OTAEncryptionKeyLength */ - static constexpr size_t kOTAEncryptionKeyLength = 16; -#endif - uint32_t mLength = 0; - uint32_t mProcessedLength = 0; - bool mWasSelected = false; - - /** - * @brief A flag to account for corner cases during OTA apply - * - * Used by the default ApplyAction implementation. - * - * If something goes wrong during ExitAction of the TLV processor, - * then mApplyState should be set to kDoNotApply and the image processor - * should abort. In this case, the BDX transfer was already finished - * and calling CancelImageUpdate will not abort the transfer, hence - * the device will reboot even though it should not have. If ApplyAction - * fails during HandleApply, then the process will be aborted. - */ - ApplyState mApplyState = ApplyState::kApply; - ProcessDescriptor mCallbackProcessDescriptor = nullptr; -}; - -/** - * This class can be used to accumulate data until a given threshold. - * Should be used by OTATlvProcessor derived classes if they need - * metadata accumulation (e.g. for custom header decoding). - */ -class OTADataAccumulator -{ -public: - void Init(uint32_t threshold); - void Clear(); - CHIP_ERROR Accumulate(ByteSpan & block); - - inline uint8_t * data() { return mBuffer.Get(); } - inline uint32_t GetThreshold() { return mThreshold; } - -private: - uint32_t mThreshold; - uint32_t mBufferOffset; - Platform::ScopedMemoryBuffer mBuffer; -}; - -} // namespace chip diff --git a/src/platform/nxp/k32w/k32w1/BUILD.gn b/src/platform/nxp/k32w/k32w1/BUILD.gn deleted file mode 100644 index 028bd2a1cde4a1..00000000000000 --- a/src/platform/nxp/k32w/k32w1/BUILD.gn +++ /dev/null @@ -1,153 +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/nxp_sdk.gni") -import("${chip_root}/src/crypto/crypto.gni") -import("${chip_root}/src/platform/device.gni") -import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") - -assert(chip_device_platform == "nxp") -assert(nxp_platform == "k32w/k32w1") - -if (chip_enable_openthread) { - import("//build_overrides/openthread.gni") -} - -if (chip_crypto == "platform") { - import("//build_overrides/mbedtls.gni") -} - -static_library("nxp_platform") { - defines = [ "CHIP_DEVICE_K32W1=1" ] - - sources = [ - "../../../SingletonConfigurationManager.cpp", - "../common/BLEManagerCommon.cpp", - "../common/BLEManagerCommon.h", - "BLEManagerImpl.cpp", - "BLEManagerImpl.h", - "CHIPDevicePlatformConfig.h", - "CHIPDevicePlatformEvent.h", - "ConfigurationManagerImpl.cpp", - "ConfigurationManagerImpl.h", - "ConnectivityManagerImpl.cpp", - "ConnectivityManagerImpl.h", - "DefaultTestEventTriggerDelegate.cpp", - "DefaultTestEventTriggerDelegate.h", - "DiagnosticDataProviderImpl.cpp", - "DiagnosticDataProviderImpl.h", - "K32W1Config.cpp", - "K32W1Config.h", - "KeyValueStoreManagerImpl.cpp", - "KeyValueStoreManagerImpl.h", - "PlatformManagerImpl.cpp", - "PlatformManagerImpl.h", - "SystemTimeSupport.cpp", - "ble_function_mux.c", - "ram_storage.c", - "ram_storage.h", - ] - - if (chip_use_plain_dac_key) { - defines += [ "CHIP_USE_PLAIN_DAC_KEY=1" ] - } else { - defines += [ "CHIP_USE_PLAIN_DAC_KEY=0" ] - } - - public = [ - "${chip_root}/src/credentials/DeviceAttestationCredsProvider.h", - "${chip_root}/src/credentials/examples/DeviceAttestationCredsExample.h", - "${chip_root}/src/credentials/examples/ExampleDACs.h", - "${chip_root}/src/credentials/examples/ExamplePAI.h", - "${chip_root}/src/platform/nxp/k32w/k32w1/BLEManagerImpl.h", - "${chip_root}/src/platform/nxp/k32w/k32w1/DefaultTestEventTriggerDelegate.h", - "${chip_root}/src/platform/nxp/k32w/k32w1/SMU2Manager.h", - ] - - public_deps = [ - "${chip_root}/src/app:test-event-trigger", - "${chip_root}/src/platform:platform_base", - ] - - if (chip_with_low_power != 0) { - sources += [ "LowPowerHooks.cpp" ] - } - - if (chip_enable_ota_requestor) { - public += [ "../common/OTAImageProcessorImpl.h" ] - - sources += [ - "../common/OTAImageProcessorImpl.cpp", - "../common/OTAImageProcessorImpl.h", - "../common/OTATlvProcessor.cpp", - "../common/OTATlvProcessor.h", - "OTAFirmwareProcessor.cpp", - "OTAFirmwareProcessor.h", - "OTAHooks.cpp", - ] - } - - if (chip_crypto == "platform") { - sources += [ - "CHIPCryptoPalK32W1.cpp", - "K32W1PersistentStorageOpKeystore.cpp", - "K32W1PersistentStorageOpKeystore.h", - ] - - if (chip_with_factory_data == 1) { - sources += [ - "../common/FactoryDataProvider.cpp", - "FactoryDataProviderImpl.cpp", - ] - public += [ - "${chip_root}/src/credentials/CHIPCert.h", - "${chip_root}/src/credentials/CertificationDeclaration.h", - ] - } - - public_deps += [ "${mbedtls_root}:mbedtls" ] - } - - deps = [] - - if (chip_enable_openthread) { - sources += [ - "../../../OpenThread/OpenThreadUtils.cpp", - "ThreadStackManagerImpl.cpp", - "ThreadStackManagerImpl.h", - ] - - if (chip_mdns == "platform") { - sources += [ - "../../../OpenThread/DnssdImpl.cpp", - "../../../OpenThread/OpenThreadDnssdImpl.cpp", - "../../../OpenThread/OpenThreadDnssdImpl.h", - ] - deps += [ "${chip_root}/src/lib/dnssd:platform_header" ] - } - - if (use_smu2_dynamic) { - sources += [ - "SMU2Manager.cpp", - "SMU2Manager.h", - ] - } - } - - public_deps += [ - "${chip_root}/src/crypto", - "${chip_root}/src/platform/logging:headers", - ] -} diff --git a/src/platform/nxp/k32w/k32w1/SoftwareUpdateManagerImpl.cpp b/src/platform/nxp/k32w/k32w1/SoftwareUpdateManagerImpl.cpp deleted file mode 100644 index c464bb327c24a6..00000000000000 --- a/src/platform/nxp/k32w/k32w1/SoftwareUpdateManagerImpl.cpp +++ /dev/null @@ -1,46 +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. - */ -/* this file behaves like a config.h, comes first */ -#include - -#if CHIP_DEVICE_CONFIG_ENABLE_SOFTWARE_UPDATE_MANAGER - -#include -#include - -#include -#include - -namespace chip { -namespace DeviceLayer { - -SoftwareUpdateManagerImpl SoftwareUpdateManagerImpl::sInstance; - -CHIP_ERROR SoftwareUpdateManagerImpl::_Init(void) -{ - Internal::GenericSoftwareUpdateManagerImpl_BDX::DoInit(); - Internal::GenericSoftwareUpdateManagerImpl::DoInit(); - - return CHIP_NO_ERROR; -} - -} // namespace DeviceLayer -} // namespace chip - -#endif // CHIP_DEVICE_CONFIG_ENABLE_SOFTWARE_UPDATE_MANAGER diff --git a/src/platform/nxp/k32w/k32w1/SoftwareUpdateManagerImpl.h b/src/platform/nxp/k32w/k32w1/SoftwareUpdateManagerImpl.h deleted file mode 100644 index f04025435928d5..00000000000000 --- a/src/platform/nxp/k32w/k32w1/SoftwareUpdateManagerImpl.h +++ /dev/null @@ -1,89 +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. - */ - -#pragma once - -#if CHIP_DEVICE_CONFIG_ENABLE_SOFTWARE_UPDATE_MANAGER - -#include -#include - -namespace chip { -namespace DeviceLayer { - -/** - * Concrete implementation of the SoftwareUpdateManager singleton object for the - * NXP K32W platforms. - */ -class SoftwareUpdateManagerImpl final : public SoftwareUpdateManager, - public Internal::GenericSoftwareUpdateManagerImpl, - public Internal::GenericSoftwareUpdateManagerImpl_BDX -{ - // Allow the SoftwareUpdateManager interface class to delegate method calls to - // the implementation methods provided by this class. - friend class SoftwareUpdateManager; - - // Allow the GenericSoftwareUpdateManagerImpl base class to access helper methods - // and types defined on this class. - friend class Internal::GenericSoftwareUpdateManagerImpl; - - // Allow the GenericSoftwareUpdateManagerImpl_BDX base class to access helper methods - // and types defined on this class. - friend class Internal::GenericSoftwareUpdateManagerImpl_BDX; - -public: - // ===== Members for internal use by the following friends. - - friend ::chip::DeviceLayer::SoftwareUpdateManager & SoftwareUpdateMgr(void); - friend SoftwareUpdateManagerImpl & SoftwareUpdateMgrImpl(void); - - static SoftwareUpdateManagerImpl sInstance; - -private: - // ===== Members that implement the SoftwareUpdateManager abstract interface. - - CHIP_ERROR _Init(void); -}; - -/** - * Returns a reference to the public interface of the SoftwareUpdateManager singleton object. - * - * Internal components should use this to access features of the SoftwareUpdateManager object - * that are common to all platforms. - */ -inline SoftwareUpdateManager & SoftwareUpdateMgr(void) -{ - return SoftwareUpdateManagerImpl::sInstance; -} - -/** - * Returns the platform-specific implementation of the SoftwareUpdateManager singleton object. - * - * Internal components can use this to gain access to features of the SoftwareUpdateManager - * that are specific to the K32W platform. - */ -inline SoftwareUpdateManagerImpl & SoftwareUpdateMgrImpl(void) -{ - return SoftwareUpdateManagerImpl::sInstance; -} - -} // namespace DeviceLayer -} // namespace chip - -#endif // CHIP_DEVICE_CONFIG_ENABLE_SOFTWARE_UPDATE_MANAGER diff --git a/src/platform/nxp/k32w0/BUILD.gn b/src/platform/nxp/k32w0/BUILD.gn index 41a80a77a7aa53..a1b40506d6cd6a 100644 --- a/src/platform/nxp/k32w0/BUILD.gn +++ b/src/platform/nxp/k32w0/BUILD.gn @@ -25,6 +25,11 @@ if (chip_enable_openthread) { import("//build_overrides/openthread.gni") } +source_set("nxp_factory_data") { +} +source_set("nxp_ota") { +} + static_library("nxp_platform") { defines = [] sources = [ diff --git a/src/platform/nxp/k32w/k32w1/BLEManagerImpl.cpp b/src/platform/nxp/k32w1/BLEManagerImpl.cpp similarity index 97% rename from src/platform/nxp/k32w/k32w1/BLEManagerImpl.cpp rename to src/platform/nxp/k32w1/BLEManagerImpl.cpp index 88d5c00400193c..fe3ebd0c0b5027 100644 --- a/src/platform/nxp/k32w/k32w1/BLEManagerImpl.cpp +++ b/src/platform/nxp/k32w1/BLEManagerImpl.cpp @@ -28,7 +28,7 @@ messaging_t gHci2Host_TaskQueue; /*! Event for the Host Task Queue */ OSA_EVENT_HANDLE_DEFINE(gHost_TaskEvent); -#include +#include extern "C" bleResult_t Hci_Reset(void); @@ -52,7 +52,6 @@ CHIP_ERROR BLEManagerImpl::InitHostController(BLECallbackDelegate::GapGenericCal PLATFORM_InitBle(); (void) RNG_Init(); - RNG_SetPseudoRandomNoSeed(NULL); /* Has to be called after RNG_Init(), once seed is generated. */ (void) Controller_SetRandomSeed(); diff --git a/src/platform/nxp/k32w/k32w1/BLEManagerImpl.h b/src/platform/nxp/k32w1/BLEManagerImpl.h similarity index 97% rename from src/platform/nxp/k32w/k32w1/BLEManagerImpl.h rename to src/platform/nxp/k32w1/BLEManagerImpl.h index 59bda33db0051f..d2b38cdeda1619 100644 --- a/src/platform/nxp/k32w/k32w1/BLEManagerImpl.h +++ b/src/platform/nxp/k32w1/BLEManagerImpl.h @@ -31,7 +31,7 @@ #include "controller_api.h" #include "controller_interface.h" -#include +#include /* host task configuration */ #define HOST_TASK_PRIORITY (4U) diff --git a/src/platform/nxp/k32w1/BUILD.gn b/src/platform/nxp/k32w1/BUILD.gn new file mode 100644 index 00000000000000..89e9ad06e918f4 --- /dev/null +++ b/src/platform/nxp/k32w1/BUILD.gn @@ -0,0 +1,211 @@ +# 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/nxp_sdk.gni") +import("//build_overrides/openthread.gni") + +import("${chip_root}/src/crypto/crypto.gni") +import("${chip_root}/src/platform/device.gni") + +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") + +assert(chip_device_platform == "nxp") +assert(nxp_platform == "k32w1") + +assert(chip_with_low_power == 0 || + (chip_with_low_power == 1 && chip_with_ot_cli == 0), + "Please disable low power if openthread CLI is needed!") + +source_set("nxp_factory_data") { + sources = [ + "../common/legacy/FactoryDataDriver.cpp", + "../common/legacy/FactoryDataProvider.cpp", + "FactoryDataDriverImpl.cpp", + "FactoryDataProviderImpl.cpp", + ] + + public = [ + "${chip_root}/src/credentials/CHIPCert.h", + "${chip_root}/src/credentials/CertificationDeclaration.h", + ] + + defines = [ "PLATFORM_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/k32w1/FactoryDataProviderImpl.h\"" ] + + deps = [ + ":nxp_platform", + "${chip_root}/src/credentials:credentials", + ] +} + +source_set("nxp_ota") { + public = [ "../common/legacy/OTAImageProcessorImpl.h" ] + + sources = [ + "../common/legacy/OTAImageProcessorImpl.cpp", + "../common/legacy/OTAImageProcessorImpl.h", + "../common/legacy/OTATlvProcessor.cpp", + "../common/legacy/OTATlvProcessor.h", + "OTAFirmwareProcessor.cpp", + "OTAFirmwareProcessor.h", + "OTAHooks.cpp", + ] + + if (chip_with_factory_data == 1 && + chip_enable_ota_factory_data_processor == 1) { + sources += [ + "../common/legacy/OTAFactoryDataProcessor.cpp", + "../common/legacy/OTAFactoryDataProcessor.h", + ] + } + + deps = [ + ":nxp_platform", + "${chip_root}/src/platform:platform", + ] +} + +static_library("nxp_platform") { + deps = [] + defines = [ "CHIP_DEVICE_K32W1=1" ] + + sources = [ + "../../SingletonConfigurationManager.cpp", + "../common/legacy/BLEManagerCommon.cpp", + "../common/legacy/BLEManagerCommon.h", + "BLEManagerImpl.cpp", + "BLEManagerImpl.h", + "CHIPDevicePlatformConfig.h", + "CHIPDevicePlatformEvent.h", + "ConfigurationManagerImpl.cpp", + "ConfigurationManagerImpl.h", + "ConnectivityManagerImpl.cpp", + "ConnectivityManagerImpl.h", + "DiagnosticDataProviderImpl.cpp", + "DiagnosticDataProviderImpl.h", + "PlatformManagerImpl.cpp", + "PlatformManagerImpl.h", + "SystemTimeSupport.cpp", + "ble_function_mux.c", + ] + + if (chip_key_storage == "fwk_nvm") { + defines += [ "CHIP_PLAT_NVM_SUPPORT=1" ] + + sources += [ + "K32W1Config.cpp", + "K32W1Config.h", + "KeyValueStoreManagerImpl.cpp", + "KeyValueStoreManagerImpl.h", + "ram_storage.c", + "ram_storage.h", + ] + } else if (chip_key_storage == "littlefs") { + defines += [ + "CHIP_PLAT_NVM_SUPPORT=3", + "EXTERNAL_KEYVALUESTOREMANAGERIMPL_HEADER=\"platform/nxp/common/KeyValueStoreManagerImpl.h\"", + ] + + sources += [ + "../common/KeyValueStoreManagerImpl.cpp", + "../common/KeyValueStoreManagerImpl.h", + "../common/NXPConfig.h", + "../common/NXPConfigKS.cpp", + ] + } else if (chip_key_storage == "nvs") { + defines += [ + "gAppNvsExternalFlash_c=0", + "gAppNvsInternalFlash_c=1", + "CONFIG_SETTINGS_RUNTIME=1", + ] + + sources += [ + "../common/KeyValueStoreManagerImpl.cpp", + "../common/KeyValueStoreManagerImpl.h", + "../common/NXPConfig.h", + "../common/NXPConfigNVS.cpp", + ] + } + + if (chip_use_plain_dac_key) { + defines += [ "CHIP_USE_PLAIN_DAC_KEY=1" ] + } else { + defines += [ "CHIP_USE_PLAIN_DAC_KEY=0" ] + } + + public = [ + "${chip_root}/src/credentials/DeviceAttestationCredsProvider.h", + "${chip_root}/src/credentials/examples/DeviceAttestationCredsExample.h", + "${chip_root}/src/credentials/examples/ExampleDACs.h", + "${chip_root}/src/credentials/examples/ExamplePAI.h", + "${chip_root}/src/platform/nxp/k32w1/BLEManagerImpl.h", + "${chip_root}/src/platform/nxp/k32w1/SMU2Manager.h", + ] + + public_deps = [ "${chip_root}/src/platform:platform_base" ] + + if (chip_with_low_power != 0) { + sources += [ "LowPowerHooks.cpp" ] + } + + if (chip_crypto == "platform") { + sources += [ + "CHIPCryptoPalK32W1.cpp", + "K32W1PersistentStorageOpKeystore.cpp", + "K32W1PersistentStorageOpKeystore.h", + ] + + if (chip_with_ot_cli == 1) { + defines += [ "CHIP_DEVICE_CONFIG_THREAD_ENABLE_CLI=1" ] + } + } + + if (chip_enable_openthread) { + sources += [ + "../../OpenThread/OpenThreadUtils.cpp", + "ThreadStackManagerImpl.cpp", + "ThreadStackManagerImpl.h", + ] + + 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", + ] + deps += [ "${chip_root}/src/lib/dnssd:platform_header" ] + } + + if (use_smu2_dynamic) { + sources += [ + "SMU2Manager.cpp", + "SMU2Manager.h", + ] + } + } + + deps += [ "${nxp_sdk_build_root}:nxp_sdk" ] + + public_deps += [ + "${chip_root}/examples/platform/nxp/${nxp_platform}/app/support:freertos_memory_utils", + "${chip_root}/src/crypto", + "${chip_root}/src/platform:syscalls_stub", + "${chip_root}/src/platform/logging:headers", + ] +} diff --git a/src/platform/nxp/k32w/k32w1/BlePlatformConfig.h b/src/platform/nxp/k32w1/BlePlatformConfig.h similarity index 100% rename from src/platform/nxp/k32w/k32w1/BlePlatformConfig.h rename to src/platform/nxp/k32w1/BlePlatformConfig.h diff --git a/src/platform/nxp/k32w/k32w1/CHIPCryptoPalK32W1.cpp b/src/platform/nxp/k32w1/CHIPCryptoPalK32W1.cpp similarity index 100% rename from src/platform/nxp/k32w/k32w1/CHIPCryptoPalK32W1.cpp rename to src/platform/nxp/k32w1/CHIPCryptoPalK32W1.cpp diff --git a/src/platform/nxp/k32w/k32w1/CHIPDevicePlatformConfig.h b/src/platform/nxp/k32w1/CHIPDevicePlatformConfig.h similarity index 94% rename from src/platform/nxp/k32w/k32w1/CHIPDevicePlatformConfig.h rename to src/platform/nxp/k32w1/CHIPDevicePlatformConfig.h index 52dec0809f618d..13dbd99290ea68 100644 --- a/src/platform/nxp/k32w/k32w1/CHIPDevicePlatformConfig.h +++ b/src/platform/nxp/k32w1/CHIPDevicePlatformConfig.h @@ -61,6 +61,16 @@ // These are configuration options that are unique to the K32W platform. // These can be overridden by the application as needed. +/** + * @def CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR + * + * Enables default OTA TLV factory data processor. + * Disabled by default. + */ +#ifndef CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR +#define CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR 0 +#endif // CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR + /** * @def CHIP_DEVICE_LAYER_BLE_OBSERVER_PRIORITY * diff --git a/src/platform/nxp/k32w/k32w1/CHIPDevicePlatformEvent.h b/src/platform/nxp/k32w1/CHIPDevicePlatformEvent.h similarity index 100% rename from src/platform/nxp/k32w/k32w1/CHIPDevicePlatformEvent.h rename to src/platform/nxp/k32w1/CHIPDevicePlatformEvent.h diff --git a/src/platform/nxp/k32w/k32w1/CHIPPlatformConfig.h b/src/platform/nxp/k32w1/CHIPPlatformConfig.h similarity index 100% rename from src/platform/nxp/k32w/k32w1/CHIPPlatformConfig.h rename to src/platform/nxp/k32w1/CHIPPlatformConfig.h diff --git a/src/platform/nxp/k32w/k32w1/ConfigurationManagerImpl.cpp b/src/platform/nxp/k32w1/ConfigurationManagerImpl.cpp similarity index 80% rename from src/platform/nxp/k32w/k32w1/ConfigurationManagerImpl.cpp rename to src/platform/nxp/k32w1/ConfigurationManagerImpl.cpp index 68a1a4196ed39c..fc6815d20fd157 100644 --- a/src/platform/nxp/k32w/k32w1/ConfigurationManagerImpl.cpp +++ b/src/platform/nxp/k32w1/ConfigurationManagerImpl.cpp @@ -29,9 +29,8 @@ #include #include #include -#include #if defined(USE_SMU2_DYNAMIC) -#include +#include #endif // #include @@ -56,7 +55,7 @@ CHIP_ERROR ConfigurationManagerImpl::Init() CHIP_ERROR err; uint32_t rebootCount = 0; - if (K32WConfig::ConfigValueExists(K32WConfig::kCounterKey_RebootCount)) + if (NXPConfig::ConfigValueExists(NXPConfig::kCounterKey_RebootCount)) { err = GetRebootCount(rebootCount); SuccessOrExit(err); @@ -71,20 +70,20 @@ CHIP_ERROR ConfigurationManagerImpl::Init() SuccessOrExit(err); } - if (!K32WConfig::ConfigValueExists(K32WConfig::kCounterKey_TotalOperationalHours)) + if (!NXPConfig::ConfigValueExists(NXPConfig::kCounterKey_TotalOperationalHours)) { err = StoreTotalOperationalHours(0); SuccessOrExit(err); } - if (!K32WConfig::ConfigValueExists(K32WConfig::kCounterKey_BootReason)) + if (!NXPConfig::ConfigValueExists(NXPConfig::kCounterKey_BootReason)) { err = StoreBootReason(to_underlying(BootReasonType::kUnspecified)); SuccessOrExit(err); } // Initialize the generic implementation base class. - err = Internal::GenericConfigurationManagerImpl::Init(); + err = Internal::GenericConfigurationManagerImpl::Init(); SuccessOrExit(err); // TODO: Initialize the global GroupKeyStore object here @@ -103,22 +102,22 @@ CHIP_ERROR ConfigurationManagerImpl::StoreSoftwareUpdateCompleted() CHIP_ERROR ConfigurationManagerImpl::GetRebootCount(uint32_t & rebootCount) { - return ReadConfigValue(K32WConfig::kCounterKey_RebootCount, rebootCount); + return ReadConfigValue(NXPConfig::kCounterKey_RebootCount, rebootCount); } CHIP_ERROR ConfigurationManagerImpl::StoreRebootCount(uint32_t rebootCount) { - return WriteConfigValue(K32WConfig::kCounterKey_RebootCount, rebootCount); + return WriteConfigValue(NXPConfig::kCounterKey_RebootCount, rebootCount); } CHIP_ERROR ConfigurationManagerImpl::GetTotalOperationalHours(uint32_t & totalOperationalHours) { - return ReadConfigValue(K32WConfig::kCounterKey_TotalOperationalHours, totalOperationalHours); + return ReadConfigValue(NXPConfig::kCounterKey_TotalOperationalHours, totalOperationalHours); } CHIP_ERROR ConfigurationManagerImpl::StoreTotalOperationalHours(uint32_t totalOperationalHours) { - return WriteConfigValue(K32WConfig::kCounterKey_TotalOperationalHours, totalOperationalHours); + return WriteConfigValue(NXPConfig::kCounterKey_TotalOperationalHours, totalOperationalHours); } CHIP_ERROR ConfigurationManagerImpl::GetBootReason(uint32_t & bootReason) @@ -149,7 +148,7 @@ CHIP_ERROR ConfigurationManagerImpl::GetBootReason(uint32_t & bootReason) CHIP_ERROR ConfigurationManagerImpl::StoreBootReason(uint32_t bootReason) { - return WriteConfigValue(K32WConfig::kCounterKey_BootReason, bootReason); + return WriteConfigValue(NXPConfig::kCounterKey_BootReason, bootReason); } bool ConfigurationManagerImpl::CanFactoryReset() @@ -168,7 +167,7 @@ CHIP_ERROR ConfigurationManagerImpl::ReadPersistedStorageValue(::chip::Platform: { CHIP_ERROR err; - err = K32WConfig::ReadConfigValueCounter(persistedStorageKey, value); + err = NXPConfig::ReadConfigValueCounter(persistedStorageKey, value); if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) { err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; @@ -186,7 +185,7 @@ CHIP_ERROR ConfigurationManagerImpl::WritePersistedStorageValue(::chip::Platform // (where persistedStorageKey represents an index to the counter). CHIP_ERROR err; - err = K32WConfig::WriteConfigValueCounter(persistedStorageKey, value); + err = NXPConfig::WriteConfigValueCounter(persistedStorageKey, value); if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) { err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; @@ -199,62 +198,62 @@ CHIP_ERROR ConfigurationManagerImpl::WritePersistedStorageValue(::chip::Platform CHIP_ERROR ConfigurationManagerImpl::ReadConfigValue(Key key, bool & val) { - return K32WConfig::ReadConfigValue(key, val); + return NXPConfig::ReadConfigValue(key, val); } CHIP_ERROR ConfigurationManagerImpl::ReadConfigValue(Key key, uint32_t & val) { - return K32WConfig::ReadConfigValue(key, val); + return NXPConfig::ReadConfigValue(key, val); } CHIP_ERROR ConfigurationManagerImpl::ReadConfigValue(Key key, uint64_t & val) { - return K32WConfig::ReadConfigValue(key, val); + return NXPConfig::ReadConfigValue(key, val); } CHIP_ERROR ConfigurationManagerImpl::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) { - return K32WConfig::ReadConfigValueStr(key, buf, bufSize, outLen); + return NXPConfig::ReadConfigValueStr(key, buf, bufSize, outLen); } CHIP_ERROR ConfigurationManagerImpl::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) { - return K32WConfig::ReadConfigValueBin(key, buf, bufSize, outLen); + return NXPConfig::ReadConfigValueBin(key, buf, bufSize, outLen); } CHIP_ERROR ConfigurationManagerImpl::WriteConfigValue(Key key, bool val) { - return K32WConfig::WriteConfigValue(key, val); + return NXPConfig::WriteConfigValue(key, val); } CHIP_ERROR ConfigurationManagerImpl::WriteConfigValue(Key key, uint32_t val) { - return K32WConfig::WriteConfigValue(key, val); + return NXPConfig::WriteConfigValue(key, val); } CHIP_ERROR ConfigurationManagerImpl::WriteConfigValue(Key key, uint64_t val) { - return K32WConfig::WriteConfigValue(key, val); + return NXPConfig::WriteConfigValue(key, val); } CHIP_ERROR ConfigurationManagerImpl::WriteConfigValueStr(Key key, const char * str) { - return K32WConfig::WriteConfigValueStr(key, str); + return NXPConfig::WriteConfigValueStr(key, str); } CHIP_ERROR ConfigurationManagerImpl::WriteConfigValueStr(Key key, const char * str, size_t strLen) { - return K32WConfig::WriteConfigValueStr(key, str, strLen); + return NXPConfig::WriteConfigValueStr(key, str, strLen); } CHIP_ERROR ConfigurationManagerImpl::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) { - return K32WConfig::WriteConfigValueBin(key, data, dataLen); + return NXPConfig::WriteConfigValueBin(key, data, dataLen); } void ConfigurationManagerImpl::RunConfigUnitTest(void) { - K32WConfig::RunConfigUnitTest(); + NXPConfig::RunConfigUnitTest(); } void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg) @@ -263,7 +262,7 @@ void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg) ChipLogProgress(DeviceLayer, "Performing factory reset"); - err = K32WConfig::FactoryResetConfig(); + err = NXPConfig::FactoryResetConfig(); if (err != CHIP_NO_ERROR) { ChipLogError(DeviceLayer, "FactoryResetConfig() failed: %s", ErrorStr(err)); diff --git a/src/platform/nxp/k32w/k32w1/ConfigurationManagerImpl.h b/src/platform/nxp/k32w1/ConfigurationManagerImpl.h similarity index 95% rename from src/platform/nxp/k32w/k32w1/ConfigurationManagerImpl.h rename to src/platform/nxp/k32w1/ConfigurationManagerImpl.h index 26201d85f58a52..ba6dd2e721340b 100644 --- a/src/platform/nxp/k32w/k32w1/ConfigurationManagerImpl.h +++ b/src/platform/nxp/k32w1/ConfigurationManagerImpl.h @@ -25,7 +25,11 @@ #pragma once -#include "K32W1Config.h" +#if (CHIP_PLAT_NVM_SUPPORT == 1) +#include +#else +#include +#endif #include namespace chip { @@ -34,7 +38,7 @@ namespace DeviceLayer { /** * Concrete implementation of the ConfigurationManager singleton object for the K32W platform. */ -class ConfigurationManagerImpl final : public Internal::GenericConfigurationManagerImpl +class ConfigurationManagerImpl final : public Internal::GenericConfigurationManagerImpl { public: // This returns an instance of this class. diff --git a/src/platform/nxp/k32w/k32w1/ConnectivityManagerImpl.cpp b/src/platform/nxp/k32w1/ConnectivityManagerImpl.cpp similarity index 100% rename from src/platform/nxp/k32w/k32w1/ConnectivityManagerImpl.cpp rename to src/platform/nxp/k32w1/ConnectivityManagerImpl.cpp diff --git a/src/platform/nxp/k32w/k32w1/ConnectivityManagerImpl.h b/src/platform/nxp/k32w1/ConnectivityManagerImpl.h similarity index 100% rename from src/platform/nxp/k32w/k32w1/ConnectivityManagerImpl.h rename to src/platform/nxp/k32w1/ConnectivityManagerImpl.h diff --git a/src/platform/nxp/k32w/k32w1/DiagnosticDataProviderImpl.cpp b/src/platform/nxp/k32w1/DiagnosticDataProviderImpl.cpp similarity index 99% rename from src/platform/nxp/k32w/k32w1/DiagnosticDataProviderImpl.cpp rename to src/platform/nxp/k32w1/DiagnosticDataProviderImpl.cpp index 3a3412eb031d36..090feb53adde4a 100644 --- a/src/platform/nxp/k32w/k32w1/DiagnosticDataProviderImpl.cpp +++ b/src/platform/nxp/k32w1/DiagnosticDataProviderImpl.cpp @@ -25,7 +25,7 @@ #include #include -#include +#include #if CHIP_SYSTEM_CONFIG_USE_LWIP #include diff --git a/src/platform/nxp/k32w/k32w1/DiagnosticDataProviderImpl.h b/src/platform/nxp/k32w1/DiagnosticDataProviderImpl.h similarity index 100% rename from src/platform/nxp/k32w/k32w1/DiagnosticDataProviderImpl.h rename to src/platform/nxp/k32w1/DiagnosticDataProviderImpl.h diff --git a/src/platform/nxp/k32w1/FactoryDataDriverImpl.cpp b/src/platform/nxp/k32w1/FactoryDataDriverImpl.cpp new file mode 100644 index 00000000000000..ae50e2361b8257 --- /dev/null +++ b/src/platform/nxp/k32w1/FactoryDataDriverImpl.cpp @@ -0,0 +1,147 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +using namespace chip::DeviceLayer::PersistedStorage; + +namespace chip { +namespace DeviceLayer { + +FactoryDataDriverImpl FactoryDataDriverImpl::sInstance; + +FactoryDataDriver & FactoryDataDrv() +{ + return FactoryDataDriverImpl::sInstance; +} + +FactoryDataDriverImpl & FactoryDataDrvImpl() +{ + return FactoryDataDriverImpl::sInstance; +} + +CHIP_ERROR FactoryDataDriverImpl::Init(void) +{ + mFactoryData = Nv_GetAppFactoryData(); + VerifyOrReturnError(mFactoryData != nullptr, CHIP_ERROR_INTERNAL); + + mSize = mFactoryData->extendedDataLength; + mMaxSize = FactoryDataProvider::kFactoryDataMaxSize; + + return CHIP_NO_ERROR; +} + +bool FactoryDataDriverImpl::DoesBackupExist(uint16_t * size) +{ + return false; +} + +CHIP_ERROR FactoryDataDriverImpl::DeleteBackup() +{ + CHIP_ERROR error = CHIP_NO_ERROR; + + error = KeyValueStoreMgr().Delete(FactoryDataDriverImpl::GetFactoryBackupKey().KeyName()); + ReturnErrorOnFailure(error); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataDriverImpl::InitRamBackup(void) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + + VerifyOrReturnError(mFactoryData != nullptr, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(mFactoryDataRamBuff == nullptr, CHIP_ERROR_INTERNAL); + + mFactoryDataRamBuff = static_cast(chip::Platform::MemoryAlloc(mMaxSize)); + ReturnErrorCodeIf(mFactoryDataRamBuff == nullptr, CHIP_ERROR_INTERNAL); + + memset(mFactoryDataRamBuff, 0, mMaxSize); + memcpy(mFactoryDataRamBuff, (void *) &mFactoryData->app_factory_data[0], mSize); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataDriverImpl::ClearRamBackup() +{ + VerifyOrReturnError(mFactoryDataRamBuff != nullptr, CHIP_ERROR_NO_MEMORY); + memset(mFactoryDataRamBuff, 0, mMaxSize); + chip::Platform::MemoryFree(mFactoryDataRamBuff); + + mFactoryDataRamBuff = nullptr; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataDriverImpl::ReadBackupInRam() +{ + CHIP_ERROR error = CHIP_NO_ERROR; + size_t bytesRead = 0; + + if (mFactoryDataRamBuff == nullptr) + { + mFactoryDataRamBuff = static_cast(chip::Platform::MemoryAlloc(mMaxSize)); + ReturnErrorCodeIf(mFactoryDataRamBuff == nullptr, CHIP_ERROR_NO_MEMORY); + memset(mFactoryDataRamBuff, 0, mMaxSize); + } + + error = + KeyValueStoreMgr().Get(FactoryDataDriverImpl::GetFactoryBackupKey().KeyName(), mFactoryDataRamBuff, mMaxSize, &bytesRead); + ReturnErrorOnFailure(error); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataDriverImpl::BackupFactoryData() +{ + CHIP_ERROR error = CHIP_NO_ERROR; + ReturnErrorCodeIf(mFactoryData == nullptr, CHIP_ERROR_INTERNAL); + + error = KeyValueStoreMgr().Put(FactoryDataDriverImpl::GetFactoryBackupKey().KeyName(), &mFactoryData->app_factory_data[0], + mMaxSize); + ReturnErrorOnFailure(error); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataDriverImpl::UpdateFactoryData(void) +{ + FactoryDataProvider::Header * header; + extendedAppFactoryData_t * data; + VerifyOrReturnError(mFactoryDataRamBuff != nullptr, CHIP_ERROR_INTERNAL); + + header = (FactoryDataProvider::Header *) mFactoryDataRamBuff; + size_t size = offsetof(extendedAppFactoryData_t, app_factory_data) + sizeof(FactoryDataProvider::Header) + header->size; + data = static_cast(chip::Platform::MemoryAlloc(size)); + + memcpy(data->identificationWord, "APP_FACT_DATA: ", APP_FACTORY_DATA_ID_STRING_SZ); + + data->extendedDataLength = sizeof(FactoryDataProvider::Header) + header->size; + mSize = data->extendedDataLength; + memcpy(&data->app_factory_data[0], mFactoryDataRamBuff, mSize); + uint8_t status = Nv_WriteAppFactoryData(data, mSize); + VerifyOrReturnError(status == 0, CHIP_ERROR_INTERNAL); + + chip::Platform::MemoryFree(data); + + return CHIP_NO_ERROR; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/k32w1/FactoryDataDriverImpl.h b/src/platform/nxp/k32w1/FactoryDataDriverImpl.h new file mode 100644 index 00000000000000..8b3e77358c6d47 --- /dev/null +++ b/src/platform/nxp/k32w1/FactoryDataDriverImpl.h @@ -0,0 +1,59 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include +#include +#include +#include + +extern "C" { +#include "HWParameter.h" +} + +namespace chip { +namespace DeviceLayer { + +/** + * This class implements the FactoryDataDriver with K32W1 specific functions + */ + +class FactoryDataDriverImpl : public FactoryDataDriver +{ +public: + static FactoryDataDriverImpl sInstance; + + FactoryDataDriverImpl() = default; + ~FactoryDataDriverImpl() = default; + + bool DoesBackupExist(uint16_t *) override; + CHIP_ERROR Init() override; + CHIP_ERROR DeleteBackup(void) override; + CHIP_ERROR InitRamBackup(void) override; + CHIP_ERROR ClearRamBackup(void) override; + CHIP_ERROR ReadBackupInRam(void) override; + CHIP_ERROR BackupFactoryData(void) override; + CHIP_ERROR UpdateFactoryData(void) override; + + static StorageKeyName GetFactoryBackupKey() { return StorageKeyName::FromConst("nxp/fact-bkp"); } + +private: + extendedAppFactoryData_t * mFactoryData = nullptr; +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/k32w/k32w1/FactoryDataProviderImpl.cpp b/src/platform/nxp/k32w1/FactoryDataProviderImpl.cpp similarity index 70% rename from src/platform/nxp/k32w/k32w1/FactoryDataProviderImpl.cpp rename to src/platform/nxp/k32w1/FactoryDataProviderImpl.cpp index 764e3f6ac48300..f3af97803b13d0 100644 --- a/src/platform/nxp/k32w/k32w1/FactoryDataProviderImpl.cpp +++ b/src/platform/nxp/k32w1/FactoryDataProviderImpl.cpp @@ -14,9 +14,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include +#include +#include #include "fsl_adapter_flash.h" -#include + +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR +extern "C" WEAK CHIP_ERROR FactoryDataDefaultRestoreMechanism(); +#endif + +using namespace chip::DeviceLayer::PersistedStorage; namespace chip { namespace DeviceLayer { @@ -27,6 +35,27 @@ static constexpr size_t kSssBlobMetadataLength = 24; static constexpr size_t kPrivateKeyBlobLength = Crypto::kP256_PrivateKey_Length + kSssBlobMetadataLength; #endif +uint32_t FactoryDataProvider::kFactoryDataMaxSize = 0x800; + +FactoryDataProviderImpl FactoryDataProviderImpl::sInstance; + +FactoryDataProvider & FactoryDataPrvd() +{ + return FactoryDataProviderImpl::sInstance; +} + +FactoryDataProviderImpl & FactoryDataPrvdImpl() +{ + return FactoryDataProviderImpl::sInstance; +} + +FactoryDataProviderImpl::FactoryDataProviderImpl() +{ +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR + RegisterRestoreMechanism(FactoryDataDefaultRestoreMechanism); +#endif +} + FactoryDataProviderImpl::~FactoryDataProviderImpl() { #if !CHIP_USE_PLAIN_DAC_KEY @@ -38,11 +67,27 @@ CHIP_ERROR FactoryDataProviderImpl::Init() { CHIP_ERROR error = CHIP_NO_ERROR; + mFactoryData = Nv_GetAppFactoryData(); + VerifyOrReturnError(mFactoryData != nullptr, CHIP_ERROR_INTERNAL); + + mConfig.start = (uint32_t) &mFactoryData->app_factory_data[0]; + mConfig.size = mFactoryData->extendedDataLength; + mConfig.payload = mConfig.start + sizeof(FactoryDataProvider::Header); + +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR + mFactoryDataDriver = &FactoryDataDrv(); + ReturnErrorOnFailure(PostResetCheck()); +#endif + #if CHIP_DEVICE_CONFIG_ENABLE_SSS_API_TEST && !CHIP_USE_PLAIN_DAC_KEY SSS_RunApiTest(); #endif +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR + error = ValidateWithRestore(); +#else error = Validate(); +#endif if (error != CHIP_NO_ERROR) { ChipLogError(DeviceLayer, "Factory data init failed with: %s", ErrorStr(error)); @@ -60,41 +105,7 @@ CHIP_ERROR FactoryDataProviderImpl::Init() #if CHIP_USE_PLAIN_DAC_KEY CHIP_ERROR FactoryDataProviderImpl::SignWithDacKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) { - CHIP_ERROR error = CHIP_NO_ERROR; - Crypto::P256ECDSASignature signature; - Crypto::P256Keypair keypair; - Crypto::P256SerializedKeypair serializedKeypair; - uint8_t keyBuf[Crypto::kP256_PrivateKey_Length]; - MutableByteSpan dacPrivateKeySpan(keyBuf); - uint16_t keySize = 0; - - VerifyOrExit(!outSignBuffer.empty(), error = CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrExit(!messageToSign.empty(), error = CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrExit(outSignBuffer.size() >= signature.Capacity(), error = CHIP_ERROR_BUFFER_TOO_SMALL); - - /* Get private key of DAC certificate from reserved section */ - error = SearchForId(FactoryDataId::kDacPrivateKeyId, dacPrivateKeySpan.data(), dacPrivateKeySpan.size(), keySize); - SuccessOrExit(error); - dacPrivateKeySpan.reduce_size(keySize); - VerifyOrExit(keySize == Crypto::kP256_PrivateKey_Length, error = CHIP_ERROR_WRONG_KEY_TYPE); - - /* Only the private key is used when signing */ - error = serializedKeypair.SetLength(Crypto::kP256_PublicKey_Length + dacPrivateKeySpan.size()); - SuccessOrExit(error); - memcpy(serializedKeypair.Bytes() + Crypto::kP256_PublicKey_Length, dacPrivateKeySpan.data(), dacPrivateKeySpan.size()); - - error = keypair.Deserialize(serializedKeypair); - SuccessOrExit(error); - - error = keypair.ECDSA_sign_msg(messageToSign.data(), messageToSign.size(), signature); - SuccessOrExit(error); - - error = CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, outSignBuffer); - -exit: - /* Sanitize temporary buffer */ - memset(keyBuf, 0, Crypto::kP256_PrivateKey_Length); - return error; + return FactoryDataProvider::SignWithDacKey(messageToSign, outSignBuffer); } #else @@ -164,11 +175,14 @@ CHIP_ERROR FactoryDataProviderImpl::SSS_ConvertDacKey() size_t blobSize = kPrivateKeyBlobLength; size_t newSize = sizeof(FactoryDataProvider::Header) + mHeader.size + kSssBlobMetadataLength; uint8_t blob[kPrivateKeyBlobLength] = { 0 }; - uint8_t * data = static_cast(chip::Platform::MemoryAlloc(newSize)); - uint32_t offset = 0; - bool convNeeded = true; + extendedAppFactoryData_t * data = static_cast( + chip::Platform::MemoryAlloc(offsetof(extendedAppFactoryData_t, app_factory_data) + newSize)); + uint32_t offset = 0; + bool convNeeded = true; + uint8_t status = 0; VerifyOrReturnError(data != nullptr, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(mFactoryData != nullptr, CHIP_ERROR_INTERNAL); ReturnErrorOnFailure(SSS_ExportBlob(blob, &blobSize, offset, convNeeded)); if (!convNeeded) @@ -177,20 +191,17 @@ CHIP_ERROR FactoryDataProviderImpl::SSS_ConvertDacKey() chip::Platform::MemoryFree(data); return CHIP_NO_ERROR; } - ChipLogError(DeviceLayer, "SSS: extracted blob from DAC private key"); - hal_flash_status_t status = HAL_FlashRead(kFactoryDataStart, newSize - kSssBlobMetadataLength, data); - VerifyOrReturnError(status == kStatus_HAL_Flash_Success, CHIP_ERROR_INTERNAL); + memcpy(data, mFactoryData, offsetof(extendedAppFactoryData_t, app_factory_data) + mFactoryData->extendedDataLength); ChipLogError(DeviceLayer, "SSS: cached factory data in RAM"); - ReturnErrorOnFailure(ReplaceWithBlob(data, blob, blobSize, offset)); + ReturnErrorOnFailure(ReplaceWithBlob(&data->app_factory_data[0], blob, blobSize, offset)); ChipLogError(DeviceLayer, "SSS: replaced DAC private key with secured blob"); - status = HAL_FlashEraseSector(kFactoryDataStart, kFactoryDataSize); - VerifyOrReturnError(status == kStatus_HAL_Flash_Success, CHIP_ERROR_INTERNAL); - status = HAL_FlashProgramUnaligned(kFactoryDataStart, newSize, data); - VerifyOrReturnError(status == kStatus_HAL_Flash_Success, CHIP_ERROR_INTERNAL); + data->extendedDataLength = newSize; + status = Nv_WriteAppFactoryData(data, newSize); + VerifyOrReturnError(status == 0, CHIP_ERROR_INTERNAL); ChipLogError(DeviceLayer, "SSS: updated factory data"); memset(data, 0, newSize); @@ -255,6 +266,107 @@ CHIP_ERROR FactoryDataProviderImpl::ReplaceWithBlob(uint8_t * data, uint8_t * bl return CHIP_NO_ERROR; } +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR + +extern "C" WEAK CHIP_ERROR FactoryDataDefaultRestoreMechanism() +{ + CHIP_ERROR error = CHIP_NO_ERROR; + FactoryDataDriver * driver = &FactoryDataDrv(); + + ReturnErrorCodeIf(driver == nullptr, CHIP_ERROR_INTERNAL); + + // Check if key related to factory data backup exists. + // If it does, it means an external event (such as a power loss) + // interrupted the factory data update process and the section + // from internal flash is most likely erased and should be restored. + error = driver->ReadBackupInRam(); + + if (error == CHIP_NO_ERROR) + { + error = driver->UpdateFactoryData(); + if (error == CHIP_NO_ERROR) + { + ChipLogProgress(DeviceLayer, "Factory data was restored successfully"); + } + } + + ReturnErrorOnFailure(driver->ClearRamBackup()); + + if (error == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND) + return CHIP_NO_ERROR; + + return error; +} + +CHIP_ERROR FactoryDataProviderImpl::PreResetCheck() +{ + OTARequestorInterface * requestor = nullptr; + uint32_t targetVersion; + /* Check integrity of freshly copied data. If validation fails, OTA will be aborted + * and factory data will be restored to the previous version. Use device instance info + * provider getter to access the factory data provider instance. The instance is created + * by the application, so it's easier to access it this way.*/ + ReturnErrorOnFailure(Validate()); + + requestor = GetRequestorInstance(); + VerifyOrReturnError(requestor != nullptr, CHIP_ERROR_INVALID_ADDRESS); + + targetVersion = requestor->GetTargetVersion(); + ReturnErrorOnFailure(FactoryDataProviderImpl::SaveTargetVersion(targetVersion)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProviderImpl::PostResetCheck() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + uint32_t targetVersion, currentVersion; + + err = FactoryDataProviderImpl::GetTargetVersion(targetVersion); + if (err != CHIP_NO_ERROR) + ChipLogProgress(DeviceLayer, "Could not get target version"); + + err = DeviceLayer::ConfigurationMgr().GetSoftwareVersion(currentVersion); + if (err != CHIP_NO_ERROR) + ChipLogProgress(DeviceLayer, "Could not get current version"); + + if (targetVersion == currentVersion) + { + ChipLogProgress(DeviceLayer, "OTA successfully applied"); + // If this point is reached, it means the new image successfully booted. + // Delete the factory data backup to stop doing a restore. + // This ensures that both the factory data and app were updated, otherwise + // revert to the backed up factory data. + mFactoryDataDriver->DeleteBackup(); + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProviderImpl::GetTargetVersion(uint32_t & version) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + uint16_t len = sizeof(uint32_t); + size_t bytesRead = 0; + + error = KeyValueStoreMgr().Get(FactoryDataProviderImpl::GetTargetVersionKey().KeyName(), (uint8_t *) &version, len, &bytesRead); + ReturnErrorOnFailure(error); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProviderImpl::SaveTargetVersion(uint32_t & version) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + + error = + KeyValueStoreMgr().Put(FactoryDataProviderImpl::GetTargetVersionKey().KeyName(), (uint8_t *) &version, sizeof(uint32_t)); + ReturnErrorOnFailure(error); + + return CHIP_NO_ERROR; +} +#endif // CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR + #if CHIP_DEVICE_CONFIG_ENABLE_SSS_API_TEST #define _assert(condition) \ diff --git a/src/platform/nxp/k32w/k32w1/FactoryDataProviderImpl.h b/src/platform/nxp/k32w1/FactoryDataProviderImpl.h similarity index 81% rename from src/platform/nxp/k32w/k32w1/FactoryDataProviderImpl.h rename to src/platform/nxp/k32w1/FactoryDataProviderImpl.h index f81b5d141837df..d7f15bba4ed422 100644 --- a/src/platform/nxp/k32w/k32w1/FactoryDataProviderImpl.h +++ b/src/platform/nxp/k32w1/FactoryDataProviderImpl.h @@ -17,12 +17,18 @@ #pragma once #include -#include +#include +#include +#include #if !CHIP_USE_PLAIN_DAC_KEY #include "sss_crypto.h" #endif +extern "C" { +#include "HWParameter.h" +} + /* This flag should be defined to run SSS_RunApiTest tests. */ #ifndef CHIP_DEVICE_CONFIG_ENABLE_SSS_API_TEST @@ -35,16 +41,31 @@ namespace DeviceLayer { /** * This class extends the default FactoryDataProvider functionality * by leveraging the secure subsystem for signing messages. + * CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR - enables factory data OTA */ class FactoryDataProviderImpl : public FactoryDataProvider { public: + static FactoryDataProviderImpl sInstance; + + FactoryDataProviderImpl(); ~FactoryDataProviderImpl(); CHIP_ERROR Init() override; CHIP_ERROR SignWithDacKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) override; +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR + + CHIP_ERROR PreResetCheck() override; + CHIP_ERROR PostResetCheck() override; + + static StorageKeyName GetTargetVersionKey() { return StorageKeyName::FromConst("nxp/tgt-sw-ver"); } + + static CHIP_ERROR GetTargetVersion(uint32_t & version); + static CHIP_ERROR SaveTargetVersion(uint32_t & version); +#endif + private: #if !CHIP_USE_PLAIN_DAC_KEY @@ -90,9 +111,13 @@ class FactoryDataProviderImpl : public FactoryDataProvider #if CHIP_DEVICE_CONFIG_ENABLE_SSS_API_TEST void SSS_RunApiTest(); #endif +#endif // CHIP_USE_PLAIN_DAC_KEY +private: + extendedAppFactoryData_t * mFactoryData = nullptr; +#if !CHIP_USE_PLAIN_DAC_KEY sss_sscp_object_t mContext; -#endif // CHIP_USE_PLAIN_DAC_KEY +#endif }; } // namespace DeviceLayer diff --git a/src/platform/nxp/k32w/k32w1/InetPlatformConfig.h b/src/platform/nxp/k32w1/InetPlatformConfig.h similarity index 100% rename from src/platform/nxp/k32w/k32w1/InetPlatformConfig.h rename to src/platform/nxp/k32w1/InetPlatformConfig.h diff --git a/src/platform/nxp/k32w/k32w1/K32W1Config.cpp b/src/platform/nxp/k32w1/K32W1Config.cpp similarity index 87% rename from src/platform/nxp/k32w/k32w1/K32W1Config.cpp rename to src/platform/nxp/k32w1/K32W1Config.cpp index 2019fce5811eba..6f578f8ed01624 100644 --- a/src/platform/nxp/k32w/k32w1/K32W1Config.cpp +++ b/src/platform/nxp/k32w1/K32W1Config.cpp @@ -25,7 +25,7 @@ /* this file behaves like a config.h, comes first */ #include -#include +#include #include #include @@ -110,7 +110,7 @@ static rsError AddToRamStorage(ramBufferDescriptor * pBuffer, uint16_t aKey, con return err; } -CHIP_ERROR K32WConfig::Init() +CHIP_ERROR NXPConfig::Init() { CHIP_ERROR err = CHIP_NO_ERROR; bool bLoadDataFromNvm = true; @@ -148,7 +148,7 @@ CHIP_ERROR K32WConfig::Init() return err; } -CHIP_ERROR K32WConfig::ReadConfigValue(Key key, bool & val) +CHIP_ERROR NXPConfig::ReadConfigValue(Key key, bool & val) { CHIP_ERROR err; bool tempVal; @@ -164,7 +164,7 @@ CHIP_ERROR K32WConfig::ReadConfigValue(Key key, bool & val) return err; } -CHIP_ERROR K32WConfig::ReadConfigValue(Key key, uint32_t & val) +CHIP_ERROR NXPConfig::ReadConfigValue(Key key, uint32_t & val) { CHIP_ERROR err; uint32_t tempVal; @@ -180,7 +180,7 @@ CHIP_ERROR K32WConfig::ReadConfigValue(Key key, uint32_t & val) return err; } -CHIP_ERROR K32WConfig::ReadConfigValue(Key key, uint64_t & val) +CHIP_ERROR NXPConfig::ReadConfigValue(Key key, uint64_t & val) { CHIP_ERROR err; uint32_t tempVal; @@ -196,7 +196,7 @@ CHIP_ERROR K32WConfig::ReadConfigValue(Key key, uint64_t & val) return err; } -CHIP_ERROR K32WConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) +CHIP_ERROR NXPConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) { CHIP_ERROR err; rsError status; @@ -213,18 +213,18 @@ CHIP_ERROR K32WConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize, s return err; } -CHIP_ERROR K32WConfig::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) +CHIP_ERROR NXPConfig::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) { return ReadConfigValueStr(key, (char *) buf, bufSize, outLen); } -CHIP_ERROR K32WConfig::ReadConfigValueCounter(uint8_t counterIdx, uint32_t & val) +CHIP_ERROR NXPConfig::ReadConfigValueCounter(uint8_t counterIdx, uint32_t & val) { Key key = kMinConfigKey_ChipCounter + counterIdx; return ReadConfigValue(key, val); } -CHIP_ERROR K32WConfig::WriteConfigValue(Key key, bool val) +CHIP_ERROR NXPConfig::WriteConfigValue(Key key, bool val) { CHIP_ERROR err; rsError status; @@ -242,7 +242,7 @@ CHIP_ERROR K32WConfig::WriteConfigValue(Key key, bool val) return err; } -CHIP_ERROR K32WConfig::WriteConfigValueSync(Key key, bool val) +CHIP_ERROR NXPConfig::WriteConfigValueSync(Key key, bool val) { CHIP_ERROR err; rsError status; @@ -260,7 +260,7 @@ CHIP_ERROR K32WConfig::WriteConfigValueSync(Key key, bool val) return err; } -CHIP_ERROR K32WConfig::WriteConfigValue(Key key, uint32_t val) +CHIP_ERROR NXPConfig::WriteConfigValue(Key key, uint32_t val) { CHIP_ERROR err; rsError status; @@ -278,7 +278,7 @@ CHIP_ERROR K32WConfig::WriteConfigValue(Key key, uint32_t val) return err; } -CHIP_ERROR K32WConfig::WriteConfigValue(Key key, uint64_t val) +CHIP_ERROR NXPConfig::WriteConfigValue(Key key, uint64_t val) { CHIP_ERROR err; rsError status; @@ -296,12 +296,12 @@ CHIP_ERROR K32WConfig::WriteConfigValue(Key key, uint64_t val) return err; } -CHIP_ERROR K32WConfig::WriteConfigValueStr(Key key, const char * str) +CHIP_ERROR NXPConfig::WriteConfigValueStr(Key key, const char * str) { return WriteConfigValueStr(key, str, (str != NULL) ? strlen(str) : 0); } -CHIP_ERROR K32WConfig::WriteConfigValueStr(Key key, const char * str, size_t strLen) +CHIP_ERROR NXPConfig::WriteConfigValueStr(Key key, const char * str, size_t strLen) { CHIP_ERROR err; rsError status; @@ -327,18 +327,18 @@ CHIP_ERROR K32WConfig::WriteConfigValueStr(Key key, const char * str, size_t str return err; } -CHIP_ERROR K32WConfig::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) +CHIP_ERROR NXPConfig::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) { return WriteConfigValueStr(key, (char *) data, dataLen); } -CHIP_ERROR K32WConfig::WriteConfigValueCounter(uint8_t counterIdx, uint32_t val) +CHIP_ERROR NXPConfig::WriteConfigValueCounter(uint8_t counterIdx, uint32_t val) { Key key = kMinConfigKey_ChipCounter + counterIdx; return WriteConfigValue(key, val); } -CHIP_ERROR K32WConfig::ClearConfigValue(Key key) +CHIP_ERROR NXPConfig::ClearConfigValue(Key key) { CHIP_ERROR err = CHIP_NO_ERROR; rsError status; @@ -355,7 +355,7 @@ CHIP_ERROR K32WConfig::ClearConfigValue(Key key) return err; } -bool K32WConfig::ConfigValueExists(Key key) +bool NXPConfig::ConfigValueExists(Key key) { rsError status; uint16_t sizeToRead; @@ -369,7 +369,7 @@ bool K32WConfig::ConfigValueExists(Key key) return found; } -CHIP_ERROR K32WConfig::FactoryResetConfig(void) +CHIP_ERROR NXPConfig::FactoryResetConfig(void) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -386,7 +386,7 @@ CHIP_ERROR K32WConfig::FactoryResetConfig(void) return err; } -void K32WConfig::FactoryResetConfigInternal(Key firstKey, Key lastKey) +void NXPConfig::FactoryResetConfigInternal(Key firstKey, Key lastKey) { for (Key key = firstKey; key <= lastKey; key++) { @@ -394,7 +394,7 @@ void K32WConfig::FactoryResetConfigInternal(Key firstKey, Key lastKey) } } -CHIP_ERROR K32WConfig::MapRamStorageStatus(rsError rsStatus) +CHIP_ERROR NXPConfig::MapRamStorageStatus(rsError rsStatus) { CHIP_ERROR err; @@ -414,7 +414,7 @@ CHIP_ERROR K32WConfig::MapRamStorageStatus(rsError rsStatus) return err; } -bool K32WConfig::ValidConfigKey(Key key) +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_KVSValue)) @@ -425,7 +425,7 @@ bool K32WConfig::ValidConfigKey(Key key) return false; } -void K32WConfig::RunConfigUnitTest() {} +void NXPConfig::RunConfigUnitTest() {} } // namespace Internal } // namespace DeviceLayer diff --git a/src/platform/nxp/k32w/k32w1/K32W1Config.h b/src/platform/nxp/k32w1/K32W1Config.h similarity index 99% rename from src/platform/nxp/k32w/k32w1/K32W1Config.h rename to src/platform/nxp/k32w1/K32W1Config.h index a14b4d5cd10fdd..ceeae82a8dc273 100644 --- a/src/platform/nxp/k32w/k32w1/K32W1Config.h +++ b/src/platform/nxp/k32w1/K32W1Config.h @@ -49,7 +49,7 @@ constexpr inline uint16_t K32WConfigKey(uint8_t chipId, uint8_t nvmId) * naturally provides implementations for the delegated members referenced by * the template class (e.g. the ReadConfigValue() method). */ -class K32WConfig +class NXPConfig { public: // Category ids used by the CHIP Device Layer diff --git a/src/platform/nxp/k32w/k32w1/K32W1PersistentStorageOpKeystore.cpp b/src/platform/nxp/k32w1/K32W1PersistentStorageOpKeystore.cpp similarity index 100% rename from src/platform/nxp/k32w/k32w1/K32W1PersistentStorageOpKeystore.cpp rename to src/platform/nxp/k32w1/K32W1PersistentStorageOpKeystore.cpp diff --git a/src/platform/nxp/k32w/k32w1/K32W1PersistentStorageOpKeystore.h b/src/platform/nxp/k32w1/K32W1PersistentStorageOpKeystore.h similarity index 100% rename from src/platform/nxp/k32w/k32w1/K32W1PersistentStorageOpKeystore.h rename to src/platform/nxp/k32w1/K32W1PersistentStorageOpKeystore.h diff --git a/src/platform/nxp/k32w/k32w1/KeyValueStoreManagerImpl.cpp b/src/platform/nxp/k32w1/KeyValueStoreManagerImpl.cpp similarity index 85% rename from src/platform/nxp/k32w/k32w1/KeyValueStoreManagerImpl.cpp rename to src/platform/nxp/k32w1/KeyValueStoreManagerImpl.cpp index 6af22df6781d3b..f70c6abb6c9e83 100644 --- a/src/platform/nxp/k32w/k32w1/KeyValueStoreManagerImpl.cpp +++ b/src/platform/nxp/k32w1/KeyValueStoreManagerImpl.cpp @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include @@ -45,7 +45,7 @@ uint16_t GetStringKeyId(const char * key, uint16_t * freeId) { CHIP_ERROR err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; uint8_t keyId = 0; - uint8_t nvmIdKvsKey = chip::DeviceLayer::Internal::K32WConfig::kFileId_KVSKey; + uint8_t nvmIdKvsKey = chip::DeviceLayer::Internal::NXPConfig::kFileId_KVSKey; bool bFreeIdxFound = false; char keyString[kMaxKeyValueBytes] = { 0 }; size_t keyStringSize = 0; @@ -55,7 +55,7 @@ uint16_t GetStringKeyId(const char * key, uint16_t * freeId) { nvmInternalId = chip::DeviceLayer::Internal::K32WConfigKey(nvmIdKvsKey, keyId); err = - chip::DeviceLayer::Internal::K32WConfig::ReadConfigValueStr(nvmInternalId, keyString, kMaxKeyValueBytes, keyStringSize); + chip::DeviceLayer::Internal::NXPConfig::ReadConfigValueStr(nvmInternalId, keyString, kMaxKeyValueBytes, keyStringSize); if (err == CHIP_NO_ERROR) { @@ -78,7 +78,7 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t size_t offset_bytes) { CHIP_ERROR err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; - uint8_t nvmIdKvsValue = chip::DeviceLayer::Internal::K32WConfig::kFileId_KVSValue; + uint8_t nvmIdKvsValue = chip::DeviceLayer::Internal::NXPConfig::kFileId_KVSValue; size_t read_bytes = 0; uint8_t keyId = 0; uint16_t nvmInternalId = 0; @@ -92,7 +92,7 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t // This is the ID of the actual data nvmInternalId = chip::DeviceLayer::Internal::K32WConfigKey(nvmIdKvsValue, keyId); ChipLogProgress(DeviceLayer, "KVS, get the value of Matter key [%s] with NVM id: %i", key, nvmInternalId); - err = chip::DeviceLayer::Internal::K32WConfig::ReadConfigValueBin(nvmInternalId, (uint8_t *) value, value_size, read_bytes); + err = chip::DeviceLayer::Internal::NXPConfig::ReadConfigValueBin(nvmInternalId, (uint8_t *) value, value_size, read_bytes); // According to Get api read_bytes_size can be null if (read_bytes_size) @@ -115,8 +115,8 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, { CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; bool_t putKey = false; - uint8_t nvmIdKvsKey = chip::DeviceLayer::Internal::K32WConfig::kFileId_KVSKey; - uint8_t nvmIdKvsValue = chip::DeviceLayer::Internal::K32WConfig::kFileId_KVSValue; + uint8_t nvmIdKvsKey = chip::DeviceLayer::Internal::NXPConfig::kFileId_KVSKey; + uint8_t nvmIdKvsValue = chip::DeviceLayer::Internal::NXPConfig::kFileId_KVSValue; uint16_t nvmInternalId = 0; uint16_t freeKeyId; uint8_t keyId; @@ -135,7 +135,7 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, nvmInternalId = chip::DeviceLayer::Internal::K32WConfigKey(nvmIdKvsValue, keyId); ChipLogProgress(DeviceLayer, "KVS, save in flash the value of the Matter key [%s] with NVM id: %i", key, nvmInternalId); - err = chip::DeviceLayer::Internal::K32WConfig::WriteConfigValueBin(nvmInternalId, (uint8_t *) value, value_size); + err = chip::DeviceLayer::Internal::NXPConfig::WriteConfigValueBin(nvmInternalId, (uint8_t *) value, value_size); /* save the 'key' in flash such that it can be retrieved later on */ if (err == CHIP_NO_ERROR) @@ -145,7 +145,7 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, nvmInternalId = chip::DeviceLayer::Internal::K32WConfigKey(nvmIdKvsKey, keyId); ChipLogProgress(DeviceLayer, "KVS, save in flash the Matter key [%s] with NVM id: %i", key, nvmInternalId); - err = chip::DeviceLayer::Internal::K32WConfig::WriteConfigValueStr(nvmInternalId, key, strlen(key) + 1); + err = chip::DeviceLayer::Internal::NXPConfig::WriteConfigValueStr(nvmInternalId, key, strlen(key) + 1); if (err != CHIP_NO_ERROR) { @@ -168,8 +168,8 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key) { CHIP_ERROR err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; - uint8_t nvmIdKvsKey = chip::DeviceLayer::Internal::K32WConfig::kFileId_KVSKey; - uint8_t nvmIdKvsValue = chip::DeviceLayer::Internal::K32WConfig::kFileId_KVSValue; + uint8_t nvmIdKvsKey = chip::DeviceLayer::Internal::NXPConfig::kFileId_KVSKey; + uint8_t nvmIdKvsValue = chip::DeviceLayer::Internal::NXPConfig::kFileId_KVSValue; uint8_t keyId = 0; uint16_t nvmInternalId = 0; @@ -183,7 +183,7 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key) nvmInternalId = chip::DeviceLayer::Internal::K32WConfigKey(nvmIdKvsKey, keyId); ChipLogProgress(DeviceLayer, "KVS, delete from flash the Matter key [%s] with NVM id: %i", key, nvmInternalId); - err = chip::DeviceLayer::Internal::K32WConfig::ClearConfigValue(nvmInternalId); + err = chip::DeviceLayer::Internal::NXPConfig::ClearConfigValue(nvmInternalId); /* also delete the 'key string' from flash */ if (err == CHIP_NO_ERROR) @@ -192,7 +192,7 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key) ChipLogProgress(DeviceLayer, "KVS, delete from flash the value of the Matter key [%s] with NVM id: %i", key, nvmInternalId); - err = chip::DeviceLayer::Internal::K32WConfig::ClearConfigValue(nvmInternalId); + err = chip::DeviceLayer::Internal::NXPConfig::ClearConfigValue(nvmInternalId); if (err != CHIP_NO_ERROR) { diff --git a/src/platform/nxp/k32w/k32w1/KeyValueStoreManagerImpl.h b/src/platform/nxp/k32w1/KeyValueStoreManagerImpl.h similarity index 100% rename from src/platform/nxp/k32w/k32w1/KeyValueStoreManagerImpl.h rename to src/platform/nxp/k32w1/KeyValueStoreManagerImpl.h diff --git a/src/platform/nxp/k32w/k32w1/Logging.cpp b/src/platform/nxp/k32w1/Logging.cpp similarity index 98% rename from src/platform/nxp/k32w/k32w1/Logging.cpp rename to src/platform/nxp/k32w1/Logging.cpp index 8f8aedd66741f8..8efa4539fdaa84 100644 --- a/src/platform/nxp/k32w/k32w1/Logging.cpp +++ b/src/platform/nxp/k32w1/Logging.cpp @@ -12,7 +12,7 @@ #include "fsl_debug_console.h" #include -#ifdef PW_RPC_ENABLED +#ifdef CONFIG_ENABLE_PW_RPC #include #endif @@ -113,7 +113,7 @@ void ENFORCE_FORMAT(1, 0) GenericLog(const char * format, va_list arg, const cha if (!isLogInitialized) { isLogInitialized = true; -#ifndef PW_RPC_ENABLED +#ifndef CONFIG_ENABLE_PW_RPC otPlatUartEnable(); #endif } @@ -127,7 +127,7 @@ void ENFORCE_FORMAT(1, 0) GenericLog(const char * format, va_list arg, const cha VerifyOrDie(writtenLen > 0); memcpy(formattedMsg + prefixLen + writtenLen, EOL_CHARS, EOL_CHARS_LEN); -#ifndef PW_RPC_ENABLED +#ifndef CONFIG_ENABLE_PW_RPC otPlatUartSendBlocking((const uint8_t *) formattedMsg, strlen(formattedMsg)); #else PigweedLogger::PutString((const char *) formattedMsg, strlen(formattedMsg)); diff --git a/src/platform/nxp/k32w/k32w1/LowPowerHooks.cpp b/src/platform/nxp/k32w1/LowPowerHooks.cpp similarity index 100% rename from src/platform/nxp/k32w/k32w1/LowPowerHooks.cpp rename to src/platform/nxp/k32w1/LowPowerHooks.cpp diff --git a/src/platform/nxp/k32w/k32w1/OTAFirmwareProcessor.cpp b/src/platform/nxp/k32w1/OTAFirmwareProcessor.cpp similarity index 96% rename from src/platform/nxp/k32w/k32w1/OTAFirmwareProcessor.cpp rename to src/platform/nxp/k32w1/OTAFirmwareProcessor.cpp index ee3ff9b655c504..33eed513ba033c 100644 --- a/src/platform/nxp/k32w/k32w1/OTAFirmwareProcessor.cpp +++ b/src/platform/nxp/k32w1/OTAFirmwareProcessor.cpp @@ -17,8 +17,8 @@ */ #include -#include -#include +#include +#include #include "OtaSupport.h" diff --git a/src/platform/nxp/k32w/k32w1/OTAFirmwareProcessor.h b/src/platform/nxp/k32w1/OTAFirmwareProcessor.h similarity index 96% rename from src/platform/nxp/k32w/k32w1/OTAFirmwareProcessor.h rename to src/platform/nxp/k32w1/OTAFirmwareProcessor.h index c06a2342ba08d6..b8bb3abd008e7a 100644 --- a/src/platform/nxp/k32w/k32w1/OTAFirmwareProcessor.h +++ b/src/platform/nxp/k32w1/OTAFirmwareProcessor.h @@ -20,7 +20,7 @@ #include "OtaPrivate.h" #include -#include +#include /* Posted Operations Size Info */ #define NB_PENDING_TRANSACTIONS 12 diff --git a/src/platform/nxp/k32w/k32w1/OTAHooks.cpp b/src/platform/nxp/k32w1/OTAHooks.cpp similarity index 82% rename from src/platform/nxp/k32w/k32w1/OTAHooks.cpp rename to src/platform/nxp/k32w1/OTAHooks.cpp index c045a111618e49..3bbabaa274fba4 100644 --- a/src/platform/nxp/k32w/k32w1/OTAHooks.cpp +++ b/src/platform/nxp/k32w1/OTAHooks.cpp @@ -16,12 +16,16 @@ * limitations under the License. */ -#include +#include #include #include -#include +#include +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR +#include +#include +#endif // CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR #include "OtaSupport.h" @@ -34,6 +38,7 @@ #endif #define APPLICATION_PROCESSOR_TAG 1 +#define FACTORY_DATA_PROCESSOR_TAG 3 extern "C" void HAL_ResetMCU(void); @@ -60,10 +65,17 @@ extern "C" WEAK CHIP_ERROR OtaHookInit() static chip::OTAFirmwareProcessor processors[8]; #endif +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR + static chip::OTAFactoryDataProcessor sFactoryDataProcessor; +#endif // CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR + gApplicationProcessor.RegisterDescriptorCallback(ProcessDescriptor); auto & imageProcessor = chip::OTAImageProcessorImpl::GetDefaultInstance(); ReturnErrorOnFailure(imageProcessor.RegisterProcessor(APPLICATION_PROCESSOR_TAG, &gApplicationProcessor)); +#if CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR + ReturnErrorOnFailure(imageProcessor.RegisterProcessor(FACTORY_DATA_PROCESSOR_TAG, &sFactoryDataProcessor)); +#endif // CONFIG_CHIP_OTA_FACTORY_DATA_PROCESSOR #if CONFIG_CHIP_K32W1_MAX_ENTRIES_TEST for (auto i = 0; i < 8; i++) @@ -78,8 +90,11 @@ extern "C" WEAK CHIP_ERROR OtaHookInit() extern "C" WEAK void OtaHookReset() { +#if (CHIP_PLAT_NVM_SUPPORT == 1) // Process all idle saves NvShutdown(); +#endif + // Set the bootloader flags OTA_SetNewImageFlag(); ResetMCU(); diff --git a/src/platform/nxp/k32w/k32w1/PlatformManagerImpl.cpp b/src/platform/nxp/k32w1/PlatformManagerImpl.cpp similarity index 80% rename from src/platform/nxp/k32w/k32w1/PlatformManagerImpl.cpp rename to src/platform/nxp/k32w1/PlatformManagerImpl.cpp index 40d747fc8a21d5..964884e77523c6 100644 --- a/src/platform/nxp/k32w/k32w1/PlatformManagerImpl.cpp +++ b/src/platform/nxp/k32w1/PlatformManagerImpl.cpp @@ -26,11 +26,17 @@ #include #include +#include #include #include #include -#include -#include +#ifdef EXTERNAL_CONFIGURATIONMANAGERIMPL_HEADER +#include EXTERNAL_CONFIGURATIONMANAGERIMPL_HEADER +#else +#include +#endif +#include +#include #if CHIP_SYSTEM_CONFIG_USE_LWIP #include @@ -40,7 +46,10 @@ #include "fwk_platform.h" #include +#include + extern "C" void HAL_ResetMCU(void); +extern "C" void freertos_mbedtls_mutex_init(void); extern uint8_t __data_end__[], m_data0_end[]; memAreaCfg_t data0Heap = { .start_address = (void *) __data_end__, .end_address = (void *) m_data0_end }; @@ -60,7 +69,19 @@ namespace DeviceLayer { PlatformManagerImpl PlatformManagerImpl::sInstance; -CHIP_ERROR PlatformManagerImpl::InitBoardFwk(void) +void PlatformManagerImpl::HardwareInit(void) +{ + mbedtls_platform_set_calloc_free(CHIPPlatformMemoryCalloc, CHIPPlatformMemoryFree); + + /* Used for HW initializations */ + otSysInit(0, NULL); + + /* Mbedtls Threading support is needed because both + * Thread and Matter tasks are using it */ + freertos_mbedtls_mutex_init(); +} + +CHIP_ERROR PlatformManagerImpl::ServiceInit(void) { mem_status_t memSt = kStatus_MemSuccess; @@ -71,11 +92,12 @@ CHIP_ERROR PlatformManagerImpl::InitBoardFwk(void) return CHIP_NO_ERROR; } + void PlatformManagerImpl::CleanReset() { StopEventLoopTask(); Shutdown(); -#if CHIP_PLAT_NVM_SUPPORT +#if (CHIP_PLAT_NVM_SUPPORT == 1) NvCompletePendingOperations(); #endif HAL_ResetMCU(); @@ -99,7 +121,10 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) CHIP_ERROR err = CHIP_NO_ERROR; // Initialize the configuration system. - err = Internal::K32WConfig::Init(); + err = Internal::NXPConfig::Init(); + SuccessOrExit(err); + + err = ServiceInit(); SuccessOrExit(err); SetConfigurationMgr(&ConfigurationManagerImpl::GetDefaultInstance()); @@ -119,6 +144,10 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) err = Internal::GenericPlatformManagerImpl_FreeRTOS::_InitChipStack(); SuccessOrExit(err); +#if USE_SMU2_DYNAMIC + ReturnErrorOnFailure(SMU2::Init()); +#endif + exit: return err; } diff --git a/src/platform/nxp/k32w/k32w1/PlatformManagerImpl.h b/src/platform/nxp/k32w1/PlatformManagerImpl.h similarity index 96% rename from src/platform/nxp/k32w/k32w1/PlatformManagerImpl.h rename to src/platform/nxp/k32w1/PlatformManagerImpl.h index 6798cb911ee377..ae1ef0ad3eb25f 100644 --- a/src/platform/nxp/k32w/k32w1/PlatformManagerImpl.h +++ b/src/platform/nxp/k32w1/PlatformManagerImpl.h @@ -49,8 +49,10 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener // ===== Platform-specific members that may be accessed directly by the application. System::Clock::Timestamp GetStartTime() { return mStartTime; } - CHIP_ERROR InitBoardFwk(void); + void HardwareInit(void); + CHIP_ERROR ServiceInit(void); void CleanReset(); + void StopBLEConnectivity() {} private: // ===== Methods that implement the PlatformManager abstract interface. diff --git a/src/platform/nxp/k32w/k32w1/SMU2Manager.cpp b/src/platform/nxp/k32w1/SMU2Manager.cpp similarity index 99% rename from src/platform/nxp/k32w/k32w1/SMU2Manager.cpp rename to src/platform/nxp/k32w1/SMU2Manager.cpp index f7c54ea7c796b7..6f941b3f10d28b 100644 --- a/src/platform/nxp/k32w/k32w1/SMU2Manager.cpp +++ b/src/platform/nxp/k32w1/SMU2Manager.cpp @@ -123,6 +123,7 @@ CHIP_ERROR Init() if (mUseAllocator) { + ResetBLEController(); RegisterArea(); } diff --git a/src/platform/nxp/k32w/k32w1/SMU2Manager.h b/src/platform/nxp/k32w1/SMU2Manager.h similarity index 100% rename from src/platform/nxp/k32w/k32w1/SMU2Manager.h rename to src/platform/nxp/k32w1/SMU2Manager.h diff --git a/src/platform/nxp/k32w/k32w1/SystemPlatformConfig.h b/src/platform/nxp/k32w1/SystemPlatformConfig.h similarity index 100% rename from src/platform/nxp/k32w/k32w1/SystemPlatformConfig.h rename to src/platform/nxp/k32w1/SystemPlatformConfig.h diff --git a/src/platform/nxp/k32w/k32w1/SystemTimeSupport.cpp b/src/platform/nxp/k32w1/SystemTimeSupport.cpp similarity index 100% rename from src/platform/nxp/k32w/k32w1/SystemTimeSupport.cpp rename to src/platform/nxp/k32w1/SystemTimeSupport.cpp diff --git a/src/platform/nxp/k32w/k32w1/ThreadStackManagerImpl.cpp b/src/platform/nxp/k32w1/ThreadStackManagerImpl.cpp similarity index 90% rename from src/platform/nxp/k32w/k32w1/ThreadStackManagerImpl.cpp rename to src/platform/nxp/k32w1/ThreadStackManagerImpl.cpp index 89c63694fed168..c7b16ffd3e5c6a 100644 --- a/src/platform/nxp/k32w/k32w1/ThreadStackManagerImpl.cpp +++ b/src/platform/nxp/k32w1/ThreadStackManagerImpl.cpp @@ -35,7 +35,7 @@ #include #if defined(USE_SMU2_DYNAMIC) -#include +#include #endif #include @@ -89,6 +89,18 @@ bool ThreadStackManagerImpl::IsInitialized() using namespace ::chip; using namespace ::chip::DeviceLayer; +/** + * Glue function called directly by the OpenThread stack + * when system event processing work is pending. + */ +extern "C" void otSysEventSignalPending(void) +{ + { + BaseType_t yieldRequired = chip::DeviceLayer::ThreadStackMgrImpl().SignalThreadActivityPendingFromISR(); + portYIELD_FROM_ISR(yieldRequired); + } +} + /** * Glue function called directly by the OpenThread stack when tasklet processing work * is pending. diff --git a/src/platform/nxp/k32w/k32w1/ThreadStackManagerImpl.h b/src/platform/nxp/k32w1/ThreadStackManagerImpl.h similarity index 100% rename from src/platform/nxp/k32w/k32w1/ThreadStackManagerImpl.h rename to src/platform/nxp/k32w1/ThreadStackManagerImpl.h diff --git a/src/platform/nxp/k32w/k32w1/args.gni b/src/platform/nxp/k32w1/args.gni similarity index 72% rename from src/platform/nxp/k32w/k32w1/args.gni rename to src/platform/nxp/k32w1/args.gni index 8b90982be93ca3..1c984c386ea086 100644 --- a/src/platform/nxp/k32w/k32w1/args.gni +++ b/src/platform/nxp/k32w1/args.gni @@ -19,15 +19,28 @@ import("//build_overrides/openthread.gni") declare_args() { chip_with_ot_cli = 0 chip_with_low_power = 0 - sdk_release = 1 + sdk_release = false + k32w1_sdk_root = "" + + # The key storage solution. Developers can select between "littlefs", "nvs" + # and the older "fwk_nvm". + chip_key_storage = "nvs" + chip_use_plain_dac_key = false + + k32w1_sdk_root = "${nxp_sdk_matter_support_root}/github_sdk/common_sdk/repo" +} + +if (sdk_release || getenv("NXP_SDK_ROOT") != "") { + k32w1_sdk_root = getenv("NXP_SDK_ROOT") } -nxp_platform = "k32w/k32w1" +openthread_root = + "//third_party/connectedhomeip/third_party/openthread/ot-nxp/openthread" +nxp_platform = "k32w1" nxp_sdk_name = "k32w1_sdk" nxp_device_layer = "nxp/${nxp_platform}" nxp_use_lwip = false -nxp_use_mbedtls_port = false # ARM architecture flags will be set based on NXP board. arm_platform_config = "${nxp_sdk_build_root}/${nxp_sdk_name}/nxp_arm.gni" @@ -39,8 +52,6 @@ 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 @@ -57,12 +68,12 @@ chip_mdns = "platform" chip_system_config_use_open_thread_inet_endpoints = true chip_with_lwip = false -mbedtls_target = "${nxp_sdk_build_root}/${nxp_sdk_name}:mbedtls" +mbedtls_target = "${nxp_sdk_build_root}:nxp_mbedtls" openthread_external_mbedtls = mbedtls_target openthread_project_core_config_file = "OpenThreadConfig.h" openthread_core_config_platform_check_file = "openthread-core-k32w1-config-check.h" -openthread_core_config_deps = [ "${chip_root}/examples/platform/nxp/k32w/k32w1:openthread_core_config_k32w1_chip_examples" ] +openthread_core_config_deps = [ "${chip_root}/third_party/openthread/platforms/nxp/${nxp_platform}:openthread_core_config_k32w1" ] -openthread_external_platform = "${chip_root}/third_party/openthread/platforms/nxp/k32w/k32w1:libopenthread-k32w1" +openthread_external_platform = "${chip_root}/third_party/openthread/platforms/nxp/${nxp_platform}:libopenthread-k32w1" diff --git a/src/platform/nxp/k32w/k32w1/ble_function_mux.c b/src/platform/nxp/k32w1/ble_function_mux.c similarity index 100% rename from src/platform/nxp/k32w/k32w1/ble_function_mux.c rename to src/platform/nxp/k32w1/ble_function_mux.c diff --git a/src/platform/nxp/k32w/k32w1/ble_function_mux.h b/src/platform/nxp/k32w1/ble_function_mux.h similarity index 100% rename from src/platform/nxp/k32w/k32w1/ble_function_mux.h rename to src/platform/nxp/k32w1/ble_function_mux.h diff --git a/src/platform/nxp/k32w/k32w1/gatt_db.h b/src/platform/nxp/k32w1/gatt_db.h similarity index 100% rename from src/platform/nxp/k32w/k32w1/gatt_db.h rename to src/platform/nxp/k32w1/gatt_db.h diff --git a/src/platform/nxp/k32w/k32w1/gatt_uuid128.h b/src/platform/nxp/k32w1/gatt_uuid128.h similarity index 100% rename from src/platform/nxp/k32w/k32w1/gatt_uuid128.h rename to src/platform/nxp/k32w1/gatt_uuid128.h diff --git a/src/platform/nxp/k32w/k32w1/k32w1-chip-mbedtls-config.h b/src/platform/nxp/k32w1/k32w1-chip-mbedtls-config.h similarity index 100% rename from src/platform/nxp/k32w/k32w1/k32w1-chip-mbedtls-config.h rename to src/platform/nxp/k32w1/k32w1-chip-mbedtls-config.h diff --git a/src/platform/nxp/k32w/k32w1/ram_storage.c b/src/platform/nxp/k32w1/ram_storage.c similarity index 100% rename from src/platform/nxp/k32w/k32w1/ram_storage.c rename to src/platform/nxp/k32w1/ram_storage.c diff --git a/src/platform/nxp/k32w/k32w1/ram_storage.h b/src/platform/nxp/k32w1/ram_storage.h similarity index 100% rename from src/platform/nxp/k32w/k32w1/ram_storage.h rename to src/platform/nxp/k32w1/ram_storage.h diff --git a/src/platform/nxp/rt/rw61x/BUILD.gn b/src/platform/nxp/rt/rw61x/BUILD.gn index 7337f896c8ddcc..1793b50884dd30 100644 --- a/src/platform/nxp/rt/rw61x/BUILD.gn +++ b/src/platform/nxp/rt/rw61x/BUILD.gn @@ -22,6 +22,11 @@ import("${nxp_sdk_build_root}/nxp_sdk.gni") assert(chip_device_platform == "nxp") +source_set("nxp_factory_data") { +} +source_set("nxp_ota") { +} + config("nxp_platform_config") { defines = [ "EXTERNAL_BLEMANAGERIMPL_HEADER=\"platform/nxp/common/ble_zephyr/BLEManagerImpl.h\"" ] include_dirs = [ diff --git a/third_party/nxp/nxp_matter_support b/third_party/nxp/nxp_matter_support index e6deaf56001387..2aad9239944047 160000 --- a/third_party/nxp/nxp_matter_support +++ b/third_party/nxp/nxp_matter_support @@ -1 +1 @@ -Subproject commit e6deaf5600138763ea68418e34bc62a02d1aef0d +Subproject commit 2aad9239944047012e525caf52119a5c84b704d3 diff --git a/third_party/openthread/platforms/nxp/k32w/k32w1/BUILD.gn b/third_party/openthread/platforms/nxp/k32w1/BUILD.gn similarity index 73% rename from third_party/openthread/platforms/nxp/k32w/k32w1/BUILD.gn rename to third_party/openthread/platforms/nxp/k32w1/BUILD.gn index b004389a09fa64..38a2f231cb811c 100644 --- a/third_party/openthread/platforms/nxp/k32w/k32w1/BUILD.gn +++ b/third_party/openthread/platforms/nxp/k32w1/BUILD.gn @@ -24,7 +24,6 @@ openthread_nxp_root = "${chip_root}/third_party/openthread/ot-nxp" config("openthread_k32w1_config") { include_dirs = [ "${openthread_nxp_root}/src/k32w1/k32w1" ] - include_dirs += [ "${chip_root}/examples/platform/nxp/k32w/k32w1" ] defines = [ "OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE=1", @@ -34,12 +33,27 @@ config("openthread_k32w1_config") { "MBEDTLS_THREADING_ALT=1", ] + if (chip_mdns == "platform") { + defines += [ + "OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE=1", + "OPENTHREAD_CONFIG_ECDSA_ENABLE=1", + "OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE=1", + "OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE=1", + ] + } + if (use_smu2_dynamic) { defines += [ "OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE=1", "OPENTHREAD_CONFIG_ENABLE_BUILTIN_MBEDTLS_MANAGEMENT=0", ] } + + if (chip_key_storage == "littlefs") { + defines += [ "OT_PLAT_SAVE_NVM_DATA_ON_IDLE=0" ] + } else if (chip_key_storage == "nvs") { + defines += [ "CONFIG_SETTINGS_RUNTIME=1" ] + } } source_set("openthread_core_config_k32w1") { @@ -49,16 +63,12 @@ source_set("openthread_core_config_k32w1") { ] public_configs = [ ":openthread_k32w1_config" ] -} - -source_set("openthread_mbedtls_config_k32w1") { - sources = [ "${openthread_nxp_root}/src/k32w1/k32w1/k32w1-mbedtls-config.h" ] + public_deps = [ nxp_sdk_target ] } source_set("libopenthread-k32w1") { sources = [ "${openthread_nxp_root}/src/common/crypto.c", - "${openthread_nxp_root}/src/common/flash_nvm.c", "${openthread_nxp_root}/src/k32w1/k32w1/alarm.c", "${openthread_nxp_root}/src/k32w1/k32w1/diag.c", "${openthread_nxp_root}/src/k32w1/k32w1/entropy.c", @@ -79,6 +89,14 @@ source_set("libopenthread-k32w1") { if (use_hw_aes) { sources += [ "${openthread_nxp_root}/src/k32w1/k32w1/aes_sss.cpp" ] } + + if (chip_key_storage == "fwk_nvm") { + sources += [ "${openthread_nxp_root}/src/common/flash_nvm.c" ] + } else if (chip_key_storage == "littlefs") { + sources += [ "${openthread_nxp_root}/src/common/flash_fsa.c" ] + } else if (chip_key_storage == "nvs") { + sources += [ "${openthread_nxp_root}/src/common/flash_nvs.c" ] + } } if (chip_with_ot_cli == 1) { @@ -86,10 +104,9 @@ source_set("libopenthread-k32w1") { } public_deps = [ - ":openthread_core_config_k32w1", - "${nxp_sdk_build_root}:nxp_sdk", - "${openthread_root}/src/core:libopenthread_core_headers", - "../../..:libopenthread-platform", - "../../..:libopenthread-platform-utils", + "${nxp_sdk_build_root}:nxp_mbedtls", + "../..:libopenthread-platform", + "../..:libopenthread-platform-utils", + nxp_sdk_target, ] }