From 2800013c06ad54c96d00224c3f59f04357a5d0a9 Mon Sep 17 00:00:00 2001 From: Artur Tynecki <77382963+ATmobica@users.noreply.github.com> Date: Wed, 12 Jul 2023 12:17:46 +0200 Subject: [PATCH] [OIS] Add all-clusters-app Matter example (#27836) Add all-clusters-app implementation for OIS. Create all-clusters-app integration tests. Extend build script, Vscode tasks, CI with all-clusters-app. Signed-off-by: ATmobica Co-authored-by: Chris Swinchatt --- .github/workflows/examples-openiotsdk.yaml | 19 ++ docs/guides/openiotsdk_examples.md | 1 + .../all-clusters-app/openiotsdk/.gitignore | 1 + .../openiotsdk/CMakeLists.txt | 68 +++++ .../all-clusters-app/openiotsdk/README.md | 100 +++++++ .../openiotsdk/cmsis-config/RTE_Components.h | 22 ++ .../freertos-config/FreeRTOSConfig.h | 257 ++++++++++++++++++ .../main/include/CHIPProjectConfig.h | 33 +++ .../openiotsdk/main/main_ns.cpp | 72 +++++ .../openiotsdk/tf-m-config/TfmProjectConfig.h | 165 +++++++++++ .../openiotsdk/supported_examples.txt | 1 + .../all-clusters-app/__init__.py | 0 .../all-clusters-app/test_app.py | 156 +++++++++++ 13 files changed, 895 insertions(+) create mode 100644 examples/all-clusters-app/openiotsdk/.gitignore create mode 100644 examples/all-clusters-app/openiotsdk/CMakeLists.txt create mode 100644 examples/all-clusters-app/openiotsdk/README.md create mode 100644 examples/all-clusters-app/openiotsdk/cmsis-config/RTE_Components.h create mode 100644 examples/all-clusters-app/openiotsdk/freertos-config/FreeRTOSConfig.h create mode 100644 examples/all-clusters-app/openiotsdk/main/include/CHIPProjectConfig.h create mode 100644 examples/all-clusters-app/openiotsdk/main/main_ns.cpp create mode 100644 examples/all-clusters-app/openiotsdk/tf-m-config/TfmProjectConfig.h create mode 100644 src/test_driver/openiotsdk/integration-tests/all-clusters-app/__init__.py create mode 100644 src/test_driver/openiotsdk/integration-tests/all-clusters-app/test_app.py diff --git a/.github/workflows/examples-openiotsdk.yaml b/.github/workflows/examples-openiotsdk.yaml index 2b46e34e7d8310..888904a5eb9338 100644 --- a/.github/workflows/examples-openiotsdk.yaml +++ b/.github/workflows/examples-openiotsdk.yaml @@ -91,6 +91,16 @@ jobs: examples/tv-app/openiotsdk/build/chip-openiotsdk-tv-app-example.elf \ /tmp/bloat_reports/ + - name: Build all-clusters-app example + id: build_all_clusters_app + timeout-minutes: 10 + run: | + scripts/examples/openiotsdk_example.sh all-clusters-app + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + openiotsdk release all-clusters-app \ + examples/all-clusters-app/openiotsdk/build/chip-openiotsdk-all-clusters-app-example.elf \ + /tmp/bloat_reports/ + - name: Build unit tests (mbedtls) id: build_unit_tests_mbedtls run: | @@ -119,6 +129,15 @@ jobs: 'scripts/run_in_ns.sh ${TEST_NETWORK_NAME}ns scripts/examples/openiotsdk_example.sh --no-activate -C test -n ${TEST_NETWORK_NAME}tap tv-app' scripts/setup/openiotsdk/network_setup.sh -n $TEST_NETWORK_NAME down + - name: "Test: all-clusters-app example" + if: steps.build_all_clusters_app.outcome == 'success' + timeout-minutes: 5 + run: | + scripts/setup/openiotsdk/network_setup.sh -n $TEST_NETWORK_NAME up + scripts/run_in_python_env.sh out/venv \ + 'scripts/run_in_ns.sh ${TEST_NETWORK_NAME}ns scripts/examples/openiotsdk_example.sh --no-activate -C test -n ${TEST_NETWORK_NAME}tap all-clusters-app' + scripts/setup/openiotsdk/network_setup.sh -n $TEST_NETWORK_NAME down + - name: "Test: unit-tests (mbedtls)" if: steps.build_unit_tests_mbedtls.outcome == 'success' run: | diff --git a/docs/guides/openiotsdk_examples.md b/docs/guides/openiotsdk_examples.md index b5cdd0fc026287..d779f34b6c5358 100644 --- a/docs/guides/openiotsdk_examples.md +++ b/docs/guides/openiotsdk_examples.md @@ -11,6 +11,7 @@ The list of currently supported Matter examples: shell lock-app tv-app +all-clusters-app ``` You can use these examples as a reference for creating your own applications. diff --git a/examples/all-clusters-app/openiotsdk/.gitignore b/examples/all-clusters-app/openiotsdk/.gitignore new file mode 100644 index 00000000000000..567609b1234a9b --- /dev/null +++ b/examples/all-clusters-app/openiotsdk/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/examples/all-clusters-app/openiotsdk/CMakeLists.txt b/examples/all-clusters-app/openiotsdk/CMakeLists.txt new file mode 100644 index 00000000000000..85a53464e64601 --- /dev/null +++ b/examples/all-clusters-app/openiotsdk/CMakeLists.txt @@ -0,0 +1,68 @@ +# +# 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. +# + +cmake_minimum_required(VERSION 3.21) + +get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../.. REALPATH) +get_filename_component(OPEN_IOT_SDK_CONFIG ${CHIP_ROOT}/config/openiotsdk REALPATH) +get_filename_component(OPEN_IOT_SDK_EXAMPLE_COMMON ${CHIP_ROOT}/examples/platform/openiotsdk REALPATH) +get_filename_component(ALL_CLUSTERS_COMMON ${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common REALPATH) + +list(APPEND CMAKE_MODULE_PATH ${OPEN_IOT_SDK_CONFIG}/cmake) + +set(APP_TARGET chip-openiotsdk-all-clusters-app-example_ns) + +set(TFM_PROJECT_CONFIG_HEADER_FILE "${CMAKE_CURRENT_SOURCE_DIR}/tf-m-config/TfmProjectConfig.h") + +# Toolchain files need to exist before first call to project +include(toolchain) + +project(${APP_TARGET} LANGUAGES C CXX ASM) + +include(sdk) + +add_executable(${APP_TARGET}) + +# Application CHIP build configuration +include(chip) + +add_subdirectory(${OPEN_IOT_SDK_EXAMPLE_COMMON}/app ./app_build) + +chip_add_data_model(openiotsdk-app PUBLIC all-clusters) + +target_include_directories(${APP_TARGET} + PRIVATE + main/include + ${ALL_CLUSTERS_COMMON}/include +) + +target_sources(${APP_TARGET} + PRIVATE + main/main_ns.cpp + ${ALL_CLUSTERS_COMMON}/src/bridged-actions-stub.cpp + ${ALL_CLUSTERS_COMMON}/src/static-supported-modes-manager.cpp + ${ALL_CLUSTERS_COMMON}/src/binding-handler.cpp +) + +target_link_libraries(${APP_TARGET} + openiotsdk-startup + openiotsdk-app +) + +include(linker) +set_target_link(${APP_TARGET}) + +sdk_post_build(${APP_TARGET}) diff --git a/examples/all-clusters-app/openiotsdk/README.md b/examples/all-clusters-app/openiotsdk/README.md new file mode 100644 index 00000000000000..269411f9f59bf9 --- /dev/null +++ b/examples/all-clusters-app/openiotsdk/README.md @@ -0,0 +1,100 @@ +# Matter Open IoT SDK All-Clusters-App Example Application + +The Open IoT SDK All Clusters Example demonstrates various ZCL clusters control. + +The example behaves as a Matter accessory, device that can be paired into an +existing Matter network and can be controlled by it. + +You can use this example as a reference for creating your own application. + +## Build-run-test-debug + +For information on how to build, run, test and debug this example and further +information about the platform it is run on see +[Open IoT SDK examples](../../../docs/guides/openiotsdk_examples.md). + +The example name to use in the scripts is `all-clusters-app`. + +## Example output + +When the example runs, these lines should be visible: + +``` +[INF] [-] Open IoT SDK all-clusters-app example application start +... +[INF] [-] Open IoT SDK all-clusters-app example application run +``` + +This means the all-clusters-app application launched correctly and you can +follow traces in the terminal. + +### Commissioning + +Read the +[Open IoT SDK commissioning guide](../../../docs/guides/openiotsdk_commissioning.md) +to see how to use the Matter controller to commission and control the +application. + +### AccessControl cluster usage + +The application fully supports the AccessControl cluster. For more details about +access control please visit +[Access Control Guide](../../../docs/guides/access-control-guide.md). Use +cluster commands to trigger actions on the device. You can issue commands +through the same Matter controller you used to perform the commissioning step +above. + +Example command: + +``` +chip-tool accesscontrol read acl 123 0 +``` + +The numeric arguments are: device node ID and device endpoint ID, respectively. + +The device sent a response and you should see this line in the controller +output: + +``` +CHIP:TOO: Endpoint: 0 Cluster: 0x0000_001F Attribute 0x0000_0000 DataVersion: 3442030892 +CHIP:TOO: ACL: 1 entries +CHIP:TOO: [1]: { +CHIP:TOO: Privilege: 5 +CHIP:TOO: AuthMode: 2 +CHIP:TOO: Subjects: 1 entries +CHIP:TOO: [1]: 112233 +CHIP:TOO: Targets: null +CHIP:TOO: FabricIndex: 1 +CHIP:TOO: } +``` + +These are automatically installed ACL entries after commissioning. + +### BasicInformation cluster usage + +One of the fully supported clusters by this example is BasicInformation cluster. +Use cluster commands to trigger actions on the device. You can issue commands +through the same Matter controller you used to perform the commissioning step +above. + +Example command: + +``` +chip-tool basicinformation read vendor-id 123 0 +``` + +The numeric arguments are: device node ID and device endpoint ID, respectively. + +The device send a response with its vendor ID number and you should see this +line in the controller output: + +``` +CHIP:TOO: VendorID: 65521 +``` + +The `65521` value is the default `vendor ID` for Matter examples. + +**NOTE** + +More details about the `chip-tool` controller can be found +[here](../../chip-tool/README.md). diff --git a/examples/all-clusters-app/openiotsdk/cmsis-config/RTE_Components.h b/examples/all-clusters-app/openiotsdk/cmsis-config/RTE_Components.h new file mode 100644 index 00000000000000..e86df2b4e44e06 --- /dev/null +++ b/examples/all-clusters-app/openiotsdk/cmsis-config/RTE_Components.h @@ -0,0 +1,22 @@ +/* + * + * 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. + */ + +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + +#endif // RTE_COMPONENTS_H diff --git a/examples/all-clusters-app/openiotsdk/freertos-config/FreeRTOSConfig.h b/examples/all-clusters-app/openiotsdk/freertos-config/FreeRTOSConfig.h new file mode 100644 index 00000000000000..9efedc9f133712 --- /dev/null +++ b/examples/all-clusters-app/openiotsdk/freertos-config/FreeRTOSConfig.h @@ -0,0 +1,257 @@ +/* + * + * 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. + */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * 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 + *----------------------------------------------------------*/ + +#if (defined(__ARMCC_VERSION) || defined(__GNUC__) || defined(__ICCARM__)) +#include + +extern uint32_t SystemCoreClock; +#endif + +// Minimal stack size [words] <0-65535> +// Stack for idle task and default task stack in words. +// Default: 4kB +#define configMINIMAL_STACK_SIZE ((uint16_t)(4 * 1024)) + +// Total heap size [bytes] <0-0xFFFFFFFF> +// Heap memory size in bytes. +// Default: 32kB +#define configTOTAL_HEAP_SIZE ((size_t)(32 * 1024)) + +// Kernel tick frequency [Hz] <0-0xFFFFFFFF> +// Kernel tick rate in Hz. +// Default: 1000 +#define configTICK_RATE_HZ ((TickType_t) 1000) + +// Timer task stack depth [words] <0-65535> +// Stack for timer task in words. +// Default: 80 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +// Timer task priority <0-56> +// Timer task priority. +// Default: 40 (High) +#define configTIMER_TASK_PRIORITY 40 + +// Timer queue length <0-1024> +// Timer command queue length. +// Default: 5 +#define configTIMER_QUEUE_LENGTH 5 + +// Preemption interrupt priority +// Maximum priority of interrupts that are safe to call FreeRTOS API. +// Default: 16 +#define configMAX_SYSCALL_INTERRUPT_PRIORITY (5 << (8 - configPRIO_BITS)) + +// Use time slicing +// Enable setting to use timeslicing. +// Default: 1 +#define configUSE_TIME_SLICING 1 + +// Idle should yield +// Control Yield behaviour of the idle task. +// Default: 1 +#define configIDLE_SHOULD_YIELD 1 + +// Check for stack overflow +// <0=>Disable <1=>Method one <2=>Method two +// Enable or disable stack overflow checking. +// Callback function vApplicationStackOverflowHook implementation is required when stack checking is enabled. +// Default: 0 +#define configCHECK_FOR_STACK_OVERFLOW 2 + +// Use idle hook +// Enable callback function call on each idle task iteration. +// Callback function vApplicationIdleHook implementation is required when idle hook is enabled. +// Default: 0 +#define configUSE_IDLE_HOOK 0 + +// Use tick hook +// Enable callback function call during each tick interrupt. +// Callback function vApplicationTickHook implementation is required when tick hook is enabled. +// Default: 0 +#define configUSE_TICK_HOOK 0 + +// Use deamon task startup hook +// Enable callback function call when timer service starts. +// Callback function vApplicationDaemonTaskStartupHook implementation is required when deamon task startup hook is +// enabled. Default: 0 +#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 + +// Use malloc failed hook +// Enable callback function call when out of dynamic memory. +// Callback function vApplicationMallocFailedHook implementation is required when malloc failed hook is enabled. +// Default: 0 +#define configUSE_MALLOC_FAILED_HOOK 0 + +// Queue registry size +// Define maximum number of queue objects registered for debug purposes. +// The queue registry is used by kernel aware debuggers to locate queue and semaphore structures and display +// associated text names. Default: 0 +#define configQUEUE_REGISTRY_SIZE 0 + +// Event Recorder configuration +// Initialize and setup Event Recorder level filtering. +// Settings have no effect when Event Recorder is not present. + +// Initialize Event Recorder +// Initialize Event Recorder before FreeRTOS kernel start. +// Default: 1 +#define configEVR_INITIALIZE 1 + +// Setup recording level filter +// Enable configuration of FreeRTOS events recording level +// Default: 1 +#define configEVR_SETUP_LEVEL 1 + +// Tasks functions +// Define event recording level bitmask for events generated from Tasks functions. +// Default: 0x05 +// <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All +#define configEVR_LEVEL_TASKS 0x05 + +// Queue functions +// Define event recording level bitmask for events generated from Queue functions. +// Default: 0x05 +// <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All +#define configEVR_LEVEL_QUEUE 0x05 + +// Timer functions +// Define event recording level bitmask for events generated from Timer functions. +// Default: 0x05 +// <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All +#define configEVR_LEVEL_TIMERS 0x05 + +// Event Groups functions +// Define event recording level bitmask for events generated from Event Groups functions. +// Default: 0x05 +// <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All +#define configEVR_LEVEL_EVENTGROUPS 0x05 + +// Heap functions +// Define event recording level bitmask for events generated from Heap functions. +// Default: 0x05 +// <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All +#define configEVR_LEVEL_HEAP 0x05 + +// Stream Buffer functions +// Define event recording level bitmask for events generated from Stream Buffer functions. +// Default: 0x05 +// <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All +#define configEVR_LEVEL_STREAMBUFFER 0x05 +// +// + +// Port Specific Features +// Enable and configure port specific features. +// Check FreeRTOS documentation for definitions that apply for the used port. + +// Use Floating Point Unit +// Using Floating Point Unit (FPU) affects context handling. +// Enable FPU when application uses floating point operations. +// Default: 1 +#define configENABLE_FPU 1 + +// Use Memory Protection Unit +// Using Memory Protection Unit (MPU) requires detailed memory map definition. +// This setting is only releavant for MPU enabled ports. +// Default: 0 +#define configENABLE_MPU 0 + +// Use TrustZone Secure Side Only +// This settings prevents FreeRTOS contex switch to Non-Secure side. +// Enable this setting when FreeRTOS runs on the Secure side only. +#define configRUN_FREERTOS_SECURE_ONLY 0 + +// Use TrustZone Security Extension +// Using TrustZone affects context handling. +// Enable TrustZone when FreeRTOS runs on the Non-Secure side and calls functions from the Secure side. +// Default: 1 +#define configENABLE_TRUSTZONE 0 + +// Minimal secure stack size [words] <0-65535> +// Stack for idle task Secure side context in words. +// This setting is only relevant when TrustZone extension is enabled. +// Default: 128 +#define configMINIMAL_SECURE_STACK_SIZE ((uint32_t) 128) +// + +#ifdef __NVIC_PRIO_BITS +#define configPRIO_BITS __NVIC_PRIO_BITS +#else +#define configPRIO_BITS 4 +#endif + +//------------- <<< end of configuration section >>> --------------------------- + +/* Defines needed by FreeRTOS to implement CMSIS RTOS2 API. Do not change! */ +#define configCPU_CLOCK_HZ (SystemCoreClock) +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configUSE_PREEMPTION 1 +#define configUSE_TIMERS 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_TASK_NOTIFICATIONS 1 +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configMAX_PRIORITIES 56 +#define configKERNEL_INTERRUPT_PRIORITY (0x07 << (8 - configPRIO_BITS)) + +/* Defines that include FreeRTOS functions which implement CMSIS RTOS2 API. Do not change! */ +#define INCLUDE_xEventGroupSetBitsFromISR 1 +#define INCLUDE_xSemaphoreGetMutexHolder 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskDelayUntil 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_xTimerPendFunctionCall 1 + +/* Map the FreeRTOS port interrupt handlers to their CMSIS standard names. */ +#define xPortPendSVHandler PendSV_Handler +#define vPortSVCHandler SVC_Handler + +/* Ensure Cortex-M port compatibility. */ +#define SysTick_Handler xPortSysTickHandler + +#include "RTE_Components.h" +#include CMSIS_device_header + +#endif /* FREERTOS_CONFIG_H */ diff --git a/examples/all-clusters-app/openiotsdk/main/include/CHIPProjectConfig.h b/examples/all-clusters-app/openiotsdk/main/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..03c4ba727b64d4 --- /dev/null +++ b/examples/all-clusters-app/openiotsdk/main/include/CHIPProjectConfig.h @@ -0,0 +1,33 @@ +/* + * + * 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 + +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION 0 +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP 0 + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 + +// Lock Manager settings +#define CHIP_LOCK_MANAGER_USER_NUMBER 10 +#define CHIP_LOCK_MANAGER_CREDENTIALS_NUMBER 10 +#define CHIP_LOCK_MANAGER_CREDENTIALS_PER_USER_NUMBER 5 +#define CHIP_LOCK_MANAGER_WEEK_DAY_SCHEDULES_PER_USER_NUMBER 10 +#define CHIP_LOCK_MANAGER_YEAR_DAY_SCHEDULES_PER_USER_NUMBER 10 diff --git a/examples/all-clusters-app/openiotsdk/main/main_ns.cpp b/examples/all-clusters-app/openiotsdk/main/main_ns.cpp new file mode 100644 index 00000000000000..63239975e89cc9 --- /dev/null +++ b/examples/all-clusters-app/openiotsdk/main/main_ns.cpp @@ -0,0 +1,72 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +#include + +#include "openiotsdk_platform.h" + +int main() +{ + if (openiotsdk_platform_init()) + { + ChipLogError(NotSpecified, "Open IoT SDK platform initialization failed"); + return EXIT_FAILURE; + } + + if (openiotsdk_chip_init()) + { + ChipLogError(NotSpecified, "Open IoT SDK CHIP stack initialization failed"); + return EXIT_FAILURE; + } + + ChipLogProgress(NotSpecified, "Open IoT SDK all-clusters-app example application start"); + + if (openiotsdk_network_init(true)) + { + ChipLogError(NotSpecified, "Network initialization failed"); + return EXIT_FAILURE; + } + + if (openiotsdk_chip_run()) + { + ChipLogError(NotSpecified, "CHIP stack run failed"); + return EXIT_FAILURE; + } + + if (InitBindingHandlers() != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "InitBindingHandlers failed"); + return EXIT_FAILURE; + } + + ChipLogProgress(NotSpecified, "Open IoT SDK all-clusters-app example application run"); + + while (true) + { + // Add forever delay to ensure proper workload for this thread + osDelay(osWaitForever); + } + + openiotsdk_chip_shutdown(); + + return EXIT_SUCCESS; +} diff --git a/examples/all-clusters-app/openiotsdk/tf-m-config/TfmProjectConfig.h b/examples/all-clusters-app/openiotsdk/tf-m-config/TfmProjectConfig.h new file mode 100644 index 00000000000000..a792f400bd2660 --- /dev/null +++ b/examples/all-clusters-app/openiotsdk/tf-m-config/TfmProjectConfig.h @@ -0,0 +1,165 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TFM_PROJECT_CONFIG_H +#define TFM_PROJECT_CONFIG_H + +/* Platform Partition Configs */ + +/* Size of input buffer in platform service */ +#define PLATFORM_SERVICE_INPUT_BUFFER_SIZE 64 + +/* Size of output buffer in platform service */ +#define PLATFORM_SERVICE_OUTPUT_BUFFER_SIZE 64 + +/* The stack size of the Platform Secure Partition */ +#define PLATFORM_SP_STACK_SIZE 0x500 + +/* Disable Non-volatile counter module */ +#define PLATFORM_NV_COUNTER_MODULE_DISABLED 0 + +/* Crypto Partition Configs */ + +/* + * Heap size for the crypto backend + * CRYPTO_ENGINE_BUF_SIZE needs to be >8KB for EC signing by attest module. + */ +#define CRYPTO_ENGINE_BUF_SIZE 0x2080 + +/* The max number of concurrent operations that can be active (allocated) at any time in Crypto */ +#define CRYPTO_CONC_OPER_NUM 8 + +/* Enable PSA Crypto random number generator module */ +#define CRYPTO_RNG_MODULE_ENABLED 1 + +/* Enable PSA Crypto Key module */ +#define CRYPTO_KEY_MODULE_ENABLED 1 + +/* Enable PSA Crypto AEAD module */ +#define CRYPTO_AEAD_MODULE_ENABLED 1 + +/* Enable PSA Crypto MAC module */ +#define CRYPTO_MAC_MODULE_ENABLED 1 + +/* Enable PSA Crypto Hash module */ +#define CRYPTO_HASH_MODULE_ENABLED 1 + +/* Enable PSA Crypto Cipher module */ +#define CRYPTO_CIPHER_MODULE_ENABLED 1 + +/* Enable PSA Crypto asymmetric key signature module */ +#define CRYPTO_ASYM_SIGN_MODULE_ENABLED 1 + +/* Enable PSA Crypto asymmetric key encryption module */ +#define CRYPTO_ASYM_ENCRYPT_MODULE_ENABLED 0 + +/* Enable PSA Crypto key derivation module */ +#define CRYPTO_KEY_DERIVATION_MODULE_ENABLED 1 + +/* Default size of the internal scratch buffer used for PSA FF IOVec allocations */ +#define CRYPTO_IOVEC_BUFFER_SIZE 5120 + +/* Use stored NV seed to provide entropy */ +#define CRYPTO_NV_SEED 1 + +/* + * Only enable multi-part operations in Hash, MAC, AEAD and symmetric ciphers, + * to optimize memory footprint in resource-constrained devices. + */ +#define CRYPTO_SINGLE_PART_FUNCS_DISABLED 0 + +/* The stack size of the Crypto Secure Partition */ +#define CRYPTO_STACK_SIZE 0x1B00 + +/* FWU Partition Configs */ + +/* Size of the FWU internal data transfer buffer */ +#define TFM_FWU_BUF_SIZE PSA_FWU_MAX_WRITE_SIZE + +/* The stack size of the Firmware Update Secure Partition */ +#define FWU_STACK_SIZE 0x600 + +/* Attest Partition Configs */ + +/* Include optional claims in initial attestation token */ +#define ATTEST_INCLUDE_OPTIONAL_CLAIMS 1 + +/* Include COSE key-id in initial attestation token */ +#define ATTEST_INCLUDE_COSE_KEY_ID 0 + +/* The stack size of the Initial Attestation Secure Partition */ +#define ATTEST_STACK_SIZE 0x700 + +/* Set the initial attestation token profile */ +#define ATTEST_TOKEN_PROFILE_PSA_IOT_1 1 + +/* ITS Partition Configs */ + +/* Create flash FS if it doesn't exist for Internal Trusted Storage partition */ +#define ITS_CREATE_FLASH_LAYOUT 1 + +/* Enable emulated RAM FS for platforms that don't have flash for Internal Trusted Storage partition */ +#define ITS_RAM_FS 0 + +/* Validate filesystem metadata every time it is read from flash */ +#define ITS_VALIDATE_METADATA_FROM_FLASH 1 + +/* The maximum asset size to be stored in the Internal Trusted Storage */ +#define ITS_MAX_ASSET_SIZE 512 + +/* Size of the ITS internal data transfer buffer */ +#define ITS_BUF_SIZE 32 + +/* The maximum number of assets to be stored in the Internal Trusted Storage */ +#define ITS_NUM_ASSETS 10 + +/* The stack size of the Internal Trusted Storage Secure Partition */ +#define ITS_STACK_SIZE 0x720 + +/* PS Partition Configs */ + +/* Create flash FS if it doesn't exist for Protected Storage partition */ +#define PS_CREATE_FLASH_LAYOUT 1 + +/* Enable emulated RAM FS for platforms that don't have flash for Protected Storage partition */ +#define PS_RAM_FS 0 + +/* Enable rollback protection for Protected Storage partition */ +#define PS_ROLLBACK_PROTECTION 1 + +/* Validate filesystem metadata every time it is read from flash */ +#define PS_VALIDATE_METADATA_FROM_FLASH 1 + +/* The maximum asset size to be stored in the Protected Storage */ +#define PS_MAX_ASSET_SIZE 2048 + +/* The maximum number of assets to be stored in the Protected Storage */ +#define PS_NUM_ASSETS 30 + +/* The stack size of the Protected Storage Secure Partition */ +#define PS_STACK_SIZE 0x700 + +/* SPM Partition Configs */ + +/* The maximal number of secure services that are connected or requested at the same time */ +#define CONFIG_TFM_CONN_HANDLE_MAX_NUM 8 + +/* Enable the doorbell APIs */ +#define CONFIG_TFM_DOORBELL_API 1 + +#endif /* TFM_PROJECT_CONFIG_H */ diff --git a/examples/platform/openiotsdk/supported_examples.txt b/examples/platform/openiotsdk/supported_examples.txt index bbe7b8f70550f2..b7d7f985fb87bf 100644 --- a/examples/platform/openiotsdk/supported_examples.txt +++ b/examples/platform/openiotsdk/supported_examples.txt @@ -1,3 +1,4 @@ shell lock-app tv-app +all-clusters-app diff --git a/src/test_driver/openiotsdk/integration-tests/all-clusters-app/__init__.py b/src/test_driver/openiotsdk/integration-tests/all-clusters-app/__init__.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/src/test_driver/openiotsdk/integration-tests/all-clusters-app/test_app.py b/src/test_driver/openiotsdk/integration-tests/all-clusters-app/test_app.py new file mode 100644 index 00000000000000..fd3aa815c3bb6a --- /dev/null +++ b/src/test_driver/openiotsdk/integration-tests/all-clusters-app/test_app.py @@ -0,0 +1,156 @@ +# +# 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. +# + +import logging +import os +import re + +import chip.interaction_model +import pytest +from chip.clusters.Objects import AccessControl +from chip.clusters.Types import NullValue +from common.utils import (connect_device, disconnect_device, discover_device, get_setup_payload, read_zcl_attribute, + write_zcl_attribute) + +log = logging.getLogger(__name__) + + +@pytest.fixture(scope="session") +def binaryPath(request, rootDir): + if request.config.getoption('binaryPath'): + return request.config.getoption('binaryPath') + else: + return os.path.join(rootDir, 'examples/all-clusters-app/openiotsdk/build/chip-openiotsdk-all-clusters-app-example.elf') + + +@pytest.fixture(scope="session") +def controllerConfig(request): + config = { + 'vendorId': 0xFFF1, + 'fabricId': 1, + 'persistentStoragePath': '/tmp/openiotsdk-test-storage.json' + } + return config + + +@pytest.mark.smoketest +def test_smoke_test(device): + ret = device.wait_for_output("Open IoT SDK all-clusters-app example application start") + assert ret is not None and len(ret) > 0 + ret = device.wait_for_output("Open IoT SDK all-clusters-app example application run") + assert ret is not None and len(ret) > 0 + + +@pytest.mark.commissioningtest +def test_commissioning(device, controller): + assert controller is not None + devCtrl = controller + + ret = device.wait_for_output("Open IoT SDK all-clusters-app example application start") + assert ret is not None and len(ret) > 0 + + setupPayload = get_setup_payload(device) + assert setupPayload is not None + + commissionable_device = discover_device(devCtrl, setupPayload) + assert commissionable_device is not None + + assert commissionable_device.vendorId == int(setupPayload.attributes['VendorID']) + assert commissionable_device.productId == int(setupPayload.attributes['ProductID']) + assert commissionable_device.addresses[0] is not None + + nodeId = connect_device(devCtrl, setupPayload, commissionable_device) + assert nodeId is not None + log.info("Device {} connected".format(commissionable_device.addresses[0])) + + ret = device.wait_for_output("Commissioning completed successfully") + assert ret is not None and len(ret) > 0 + + assert disconnect_device(devCtrl, nodeId) + + +ALL_CLUSTERS_CTRL_TEST_ENDPOINT_ID = 0 + + +@pytest.mark.ctrltest +def test_clusters_ctrl(device, controller): + assert controller is not None + devCtrl = controller + + ret = device.wait_for_output("Open IoT SDK all-clusters-app example application start") + assert ret is not None and len(ret) > 0 + + setupPayload = get_setup_payload(device) + assert setupPayload is not None + + ret = device.wait_for_output("Current software version") + assert ret is not None and len(ret) > 1 + + version_app = ret[-1].split()[-2:] + + commissionable_device = discover_device(devCtrl, setupPayload) + assert commissionable_device is not None + + nodeId = connect_device(devCtrl, setupPayload, commissionable_device) + assert nodeId is not None + + ret = device.wait_for_output("Commissioning completed successfully") + assert ret is not None and len(ret) > 0 + + acs = AccessControl.Structs() + ace = AccessControl.Enums() + + # AccessControl cluster test - write entires + entry0 = acs.AccessControlEntryStruct(privilege=ace.AccessControlEntryPrivilegeEnum.kAdminister, authMode=ace.AccessControlEntryAuthModeEnum.kCase, subjects=NullValue, targets=[acs.AccessControlTargetStruct( + cluster=NullValue, endpoint=0, deviceType=NullValue), acs.AccessControlTargetStruct(cluster=1, endpoint=NullValue, deviceType=NullValue), acs.AccessControlTargetStruct(cluster=2, endpoint=3, deviceType=NullValue)], fabricIndex=1) + entry1 = acs.AccessControlEntryStruct(privilege=ace.AccessControlEntryPrivilegeEnum.kView, authMode=ace.AccessControlEntryAuthModeEnum.kCase, subjects=[4, 5, 6, 7], targets=[acs.AccessControlTargetStruct( + cluster=NullValue, endpoint=8, deviceType=NullValue), acs.AccessControlTargetStruct(cluster=9, endpoint=NullValue, deviceType=NullValue), acs.AccessControlTargetStruct(cluster=10, endpoint=11, deviceType=NullValue)], fabricIndex=1) + entry2 = acs.AccessControlEntryStruct(privilege=ace.AccessControlEntryPrivilegeEnum.kOperate, authMode=ace.AccessControlEntryAuthModeEnum.kGroup, subjects=[12, 13, 14, 15], targets=[acs.AccessControlTargetStruct( + cluster=NullValue, endpoint=16, deviceType=NullValue), acs.AccessControlTargetStruct(cluster=17, endpoint=NullValue, deviceType=NullValue), acs.AccessControlTargetStruct(cluster=18, endpoint=19, deviceType=NullValue)], fabricIndex=1) + entry3 = acs.AccessControlEntryStruct(privilege=ace.AccessControlEntryPrivilegeEnum.kOperate, authMode=ace.AccessControlEntryAuthModeEnum.kCase, subjects=[20, 21, 22, 23], targets=[acs.AccessControlTargetStruct( + cluster=NullValue, endpoint=24, deviceType=NullValue), acs.AccessControlTargetStruct(cluster=25, endpoint=NullValue, deviceType=NullValue), acs.AccessControlTargetStruct(cluster=26, endpoint=27, deviceType=NullValue)], fabricIndex=1) + err, res = write_zcl_attribute(devCtrl, "AccessControl", "Acl", nodeId, ALL_CLUSTERS_CTRL_TEST_ENDPOINT_ID, + [entry0, entry1, entry2, entry3]) + assert err == 0 + assert res[0].Status == chip.interaction_model.Status.Success + + err, res = read_zcl_attribute(devCtrl, "AccessControl", "Acl", nodeId, ALL_CLUSTERS_CTRL_TEST_ENDPOINT_ID) + assert err == 0 + assert res.value[0] == entry0 + assert res.value[1] == entry1 + assert res.value[2] == entry2 + assert res.value[3] == entry3 + + # BasicInformation cluster test - check vendor ID + err, res = read_zcl_attribute(devCtrl, "BasicInformation", "VendorID", nodeId, ALL_CLUSTERS_CTRL_TEST_ENDPOINT_ID) + assert err == 0 + assert res.value == int(setupPayload.attributes['VendorID']) + + # BasicInformation cluster test - check product ID + err, res = read_zcl_attribute(devCtrl, "BasicInformation", "ProductID", nodeId, ALL_CLUSTERS_CTRL_TEST_ENDPOINT_ID) + assert err == 0 + assert res.value == int(setupPayload.attributes['ProductID']) + + # BasicInformation cluster test - check software version + err, res = read_zcl_attribute(devCtrl, "BasicInformation", "SoftwareVersion", nodeId, ALL_CLUSTERS_CTRL_TEST_ENDPOINT_ID) + assert err == 0 + assert res.value == int(re.sub(r"[\[\]]", "", version_app[0])) + + # BasicInformation cluster test - check software version string + err, res = read_zcl_attribute(devCtrl, "BasicInformation", "SoftwareVersionString", nodeId, ALL_CLUSTERS_CTRL_TEST_ENDPOINT_ID) + assert err == 0 + assert res.value == version_app[1]