diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt index ca364bc513ae9c..34c4a0bf8932c4 100644 --- a/.github/.wordlist.txt +++ b/.github/.wordlist.txt @@ -301,6 +301,7 @@ contrib controllee conv CopperConcentrationMeasurement +Corstone cortexa cp cpio @@ -886,6 +887,7 @@ MyPASSWORD MySSID NAMESERVER NAMESPACE +namespaces namespacing nano natively @@ -1144,11 +1146,13 @@ rsn RSSI RST rsync +RTC rtd RTL rtld RTOS RTT +RTX RUNAS RunMain runtime @@ -1254,6 +1258,7 @@ subdirectory subfolder submodule submodules +subnet subprocess SubscribeResponse SubscriptionId @@ -1326,6 +1331,7 @@ Tizen TKIP tlsr TLV +TLS tmp tngvndl TODO diff --git a/.github/workflows/examples-openiotsdk.yaml b/.github/workflows/examples-openiotsdk.yaml new file mode 100644 index 00000000000000..65c7b69b18bd14 --- /dev/null +++ b/.github/workflows/examples-openiotsdk.yaml @@ -0,0 +1,114 @@ +# 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. + +name: Build example - Open IoT SDK + +on: + push: + pull_request: + workflow_dispatch: + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }}-${{ (github.event_name == 'pull_request' && github.event.number) || (github.event_name == 'workflow_dispatch' && github.run_number) || github.sha }} + cancel-in-progress: true + +jobs: + openiotsdk: + name: Open IoT SDK examples building + timeout-minutes: 140 + + env: + TEST_NETWORK_NAME: OIStest + + runs-on: ubuntu-latest + if: github.actor != 'restyled-io[bot]' + + container: + image: connectedhomeip/chip-build-openiotsdk:0.6.06 + volumes: + - "/tmp/bloat_reports:/tmp/bloat_reports" + options: --privileged + + steps: + - uses: Wandalen/wretry.action@v1.0.36 + name: Checkout + with: + action: actions/checkout@v3 + with: | + token: ${{ github.token }} + attempt_limit: 3 + attempt_delay: 2000 + - name: Checkout submodules + run: scripts/checkout_submodules.py --shallow --recursive --platform openiotsdk + + - name: Set up environment for size reports + if: ${{ !env.ACT }} + env: + GH_CONTEXT: ${{ toJson(github) }} + run: scripts/tools/memory/gh_sizes_environment.py "${GH_CONTEXT}" + + - name: Bootstrap + timeout-minutes: 10 + run: scripts/build/gn_bootstrap.sh + + - name: Build and install Python controller + timeout-minutes: 10 + run: | + scripts/run_in_build_env.sh './scripts/build_python.sh --install_wheel build-env' + + - name: Build shell example + id: build_shell + timeout-minutes: 10 + run: | + scripts/examples/openiotsdk_example.sh shell + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + openiotsdk release shell \ + examples/shell/openiotsdk/build/chip-openiotsdk-shell-example.elf \ + /tmp/bloat_reports/ + + - name: Build lock-app example + id: build_lock_app + timeout-minutes: 10 + run: | + scripts/examples/openiotsdk_example.sh lock-app + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + openiotsdk release lock-app \ + examples/lock-app/openiotsdk/build/chip-openiotsdk-lock-app-example.elf \ + /tmp/bloat_reports/ + + - name: Build unit tests + id: build_unit_tests + timeout-minutes: 10 + run: | + scripts/examples/openiotsdk_example.sh unit-tests + + - name: Test shell example + if: steps.build_shell.outcome == 'success' + timeout-minutes: 5 + run: | + scripts/examples/openiotsdk_example.sh -C test shell + + - name: Test lock-app example + if: steps.build_lock_app.outcome == 'success' + timeout-minutes: 5 + run: | + scripts/setup/openiotsdk/network_setup.sh -n $TEST_NETWORK_NAME up + scripts/run_in_ns.sh ${TEST_NETWORK_NAME}ns scripts/examples/openiotsdk_example.sh -C test -n ${TEST_NETWORK_NAME}tap lock-app + scripts/setup/openiotsdk/network_setup.sh -n $TEST_NETWORK_NAME down + + - name: Run unit tests + if: steps.build_unit_tests.outcome == 'success' && github.event_name == 'pull_request' + timeout-minutes: 90 + run: | + scripts/examples/openiotsdk_example.sh -C run unit-tests diff --git a/.vscode/launch.json b/.vscode/launch.json index aca86897789a1c..bf83cc0d85d6e4 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -424,6 +424,35 @@ "/tmp/ota-image.bin" ], "cwd": "${workspaceFolder}" + }, + + { + "name": "Debug Open IoT SDK example application", + "type": "cortex-debug", + "request": "launch", + "cwd": "${workspaceRoot}/examples/${input:openiotsdkApp}/openiotsdk", + "executable": "./build/chip-openiotsdk-${input:openiotsdkApp}-example.elf", + "armToolchainPath": "${env:ARM_GCC_TOOLCHAIN_PATH}/bin", + "servertype": "external", + "gdbTarget": "${input:openiotsdkRemoteHost}:31627", //GDBserver port on FVP + "overrideLaunchCommands": ["-enable-pretty-printing"], + "runToEntryPoint": "main", + "preLaunchTask": "Debug Open IoT SDK example", + "showDevDebugOutput": "parsed" + }, + { + "name": "Debug Open IoT SDK unit-tests application", + "type": "cortex-debug", + "request": "launch", + "cwd": "${workspaceRoot}/src/test_driver/openiotsdk/unit-tests", + "executable": "./build/${input:openiotsdkUnittest}.elf", + "armToolchainPath": "${env:ARM_GCC_TOOLCHAIN_PATH}/bin", + "servertype": "external", + "gdbTarget": ":31627", //GDBserver port on FVP + "overrideLaunchCommands": ["-enable-pretty-printing"], + "runToEntryPoint": "main", + "preLaunchTask": "Debug Open IoT SDK unit-tests", + "showDevDebugOutput": "parsed" } ], "inputs": [ @@ -479,6 +508,52 @@ "description": "What mbed target do you want to use?", "options": ["CY8CPROTO_062_4343W"], "default": "CY8CPROTO_062_4343W" + }, + { + "type": "pickString", + "id": "openiotsdkApp", + "description": "What Open IoT SDK example do you want to use?", + "options": ["shell", "lock-app"], + "default": "shell" + }, + { + "type": "promptString", + "id": "openiotsdkRemoteHost", + "description": "Type the hostname/IP address of external GDB target that you want to connect to. Leave blank for internal GDB server", + "default": "" + }, + { + "type": "pickString", + "id": "openiotsdkUnittest", + "description": "What Open IoT SDK unit test do you want to use?", + "options": [ + "accesstest", + "AppTests", + "ASN1Tests", + "BDXTests", + "ChipCryptoTests", + "ControllerTests", + "CoreTests", + "CredentialsTest", + "DataModelTests", + "InetLayerTests", + "MdnsTests", + "MessagingLayerTests", + "MinimalMdnsCoreTests", + "MinimalMdnsRecordsTests", + "MinimalMdnsRespondersTests", + "PlatformTests", + "RawTransportTests", + "RetransmitTests", + "SecureChannelTests", + "SetupPayloadTests", + "SupportTests", + "SystemLayerTests", + "TestShell", + "TransportLayerTests", + "UserDirectedCommissioningTests" + ], + "default": "accesstest" } ] } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index f8cf998bd15e2a..fd815494affee7 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -242,6 +242,151 @@ "showReuseMessage": true, "clear": true } + }, + { + "label": "Build Open IoT SDK example", + "type": "shell", + "command": "scripts/examples/openiotsdk_example.sh", + "args": [ + "-Cbuild", + "-d${input:openiotsdkDebugMode}", + "${input:openiotsdkExample}" + ], + "group": "build", + "problemMatcher": { + "pattern": { + "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", + "file": 1, + "line": 2, + "message": 5 + } + } + }, + { + "label": "Build Open IoT SDK unit-tests", + "type": "shell", + "command": "scripts/examples/openiotsdk_example.sh", + "args": ["-Cbuild", "-d${input:openiotsdkDebugMode}", "unit-tests"], + "group": "build", + "problemMatcher": { + "pattern": { + "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", + "file": 1, + "line": 2, + "message": 5 + } + } + }, + { + "label": "Run Open IoT SDK example", + "type": "shell", + "command": "scripts/run_in_ns.sh", + "args": [ + "${input:openiotsdkNetworkNamespace}", + "scripts/examples/openiotsdk_example.sh", + "-Crun", + "-n${input:openiotsdkNetworkInterface}", + "${input:openiotsdkExample}" + ], + "group": "test", + "problemMatcher": { + "pattern": { + "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", + "file": 1, + "line": 2, + "message": 5 + } + } + }, + { + "label": "Run Open IoT SDK unit-tests", + "type": "shell", + "command": "scripts/examples/openiotsdk_example.sh", + "args": ["-Crun", "unit-tests", "${input:openiotsdkUnitTest}"], + "group": "test", + "problemMatcher": { + "pattern": { + "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", + "file": 1, + "line": 2, + "message": 5 + } + } + }, + { + "label": "Test Open IoT SDK example", + "type": "shell", + "command": "scripts/run_in_ns.sh", + "args": [ + "${input:openiotsdkNetworkNamespace}", + "scripts/examples/openiotsdk_example.sh", + "-Ctest", + "-n${input:openiotsdkNetworkInterface}", + "${input:openiotsdkExample}" + ], + "group": "test", + "problemMatcher": { + "pattern": { + "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", + "file": 1, + "line": 2, + "message": 5 + } + } + }, + { + "label": "Debug Open IoT SDK example", + "type": "shell", + "command": "scripts/run_in_ns.sh", + "args": [ + "${input:openiotsdkNetworkNamespace}", + "scripts/examples/openiotsdk_example.sh", + "-Crun", + "-n${input:openiotsdkNetworkInterface}", + "-dtrue", + "${input:openiotsdkExample}" + ], + "group": "none", + "isBackground": true, + "problemMatcher": { + "pattern": { + "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", + "file": 1, + "line": 2, + "message": 5 + }, + "background": { + "activeOnStart": true, + "beginsPattern": "^.*Trying*", + "endsPattern": "^.*Connected to localhost*" + } + } + }, + { + "label": "Debug Open IoT SDK unit-tests", + "type": "shell", + "command": "scripts/examples/openiotsdk_example.sh", + "args": [ + "-Crun", + "-dtrue", + "unit-tests", + "${input:openiotsdkUnitTest}" + ], + "group": "none", + "isBackground": true, + "problemMatcher": { + "pattern": { + "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", + "file": 1, + "line": 2, + "message": 5 + }, + "background": { + "activeOnStart": true, + "beginsPattern": "^.*Trying*", + "endsPattern": "^.*Connected to localhost*" + } + } } ], "inputs": [ @@ -287,6 +432,66 @@ "options": ["simple", "boot", "upgrade"], "default": "simple" }, + { + "type": "pickString", + "id": "openiotsdkDebugMode", + "description": "Do you want to use debug mode?", + "options": ["false", "true"], + "default": "false" + }, + { + "type": "pickString", + "id": "openiotsdkExample", + "description": "What Open IoT SDK example application do you want to use?", + "options": ["shell", "lock-app"], + "default": "shell" + }, + { + "type": "pickString", + "id": "openiotsdkUnitTest", + "description": "What unit test do you want to use?", + "options": [ + "all", + "accesstest", + "AppTests", + "ASN1Tests", + "BDXTests", + "ChipCryptoTests", + "ControllerTests", + "CoreTests", + "CredentialsTest", + "DataModelTests", + "InetLayerTests", + "MdnsTests", + "MessagingLayerTests", + "MinimalMdnsCoreTests", + "MinimalMdnsRecordsTests", + "MinimalMdnsRespondersTests", + "PlatformTests", + "RawTransportTests", + "RetransmitTests", + "SecureChannelTests", + "SetupPayloadTests", + "SupportTests", + "SystemLayerTests", + "TestShell", + "TransportLayerTests", + "UserDirectedCommissioningTests" + ], + "default": "all" + }, + { + "type": "promptString", + "id": "openiotsdkNetworkNamespace", + "description": "Type the network namespace that you want to use. \"default\" means host default network namespace", + "default": "default" + }, + { + "type": "promptString", + "id": "openiotsdkNetworkInterface", + "description": "Type the network interface name that you want to use. \"user\" means user network mode", + "default": "user" + }, { "type": "promptString", "id": "exampleGlob", @@ -428,6 +633,8 @@ "nrf-nrf5340-pump", "nrf-nrf5340-pump-controller", "nrf-nrf5340-shell", + "openiotsdk-lock", + "openiotsdk-shell", "qpg-qpg6100-lock", "telink-tlsr9518adk80d-all-clusters", "telink-tlsr9518adk80d-all-clusters-minimal", diff --git a/build/chip/tools.gni b/build/chip/tools.gni index 374a69b26fdad9..efb25d3fa4a43a 100644 --- a/build/chip/tools.gni +++ b/build/chip/tools.gni @@ -23,5 +23,5 @@ declare_args() { (chip_crypto == "" && (current_os != "android" && current_os != "freertos" && current_os != "zephyr" && current_os != "mbed" && - current_os != "webos")) + current_os != "webos" && current_os != "cmsis-rtos")) } diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 96cdcd00256e3f..93276a4666fa27 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn @@ -225,7 +225,8 @@ config("warnings_common") { } if (current_os != "mac" && current_os != "ios" && current_os != "linux" && - current_os != "win" && current_os != "tizen" && current_os != "webos") { + current_os != "win" && current_os != "tizen" && current_os != "webos" && + current_os != "cmsis-rtos") { cflags += [ "-Wstack-usage=8192" ] } } diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni index 842500c73f5c0c..d97ea02cc4b674 100644 --- a/build/config/compiler/compiler.gni +++ b/build/config/compiler/compiler.gni @@ -20,8 +20,8 @@ declare_args() { optimize_for_size = true # Optimize debug builds with -Og. - optimize_debug = - current_os == "freertos" || current_os == "zephyr" || current_os == "mbed" + optimize_debug = current_os == "freertos" || current_os == "zephyr" || + current_os == "mbed" || current_os == "cmsis-rtos" # Optimization level for debug. Only has an effect if optimize_debug is true. optimize_debug_level = "g" diff --git a/config/openiotsdk/CMakeLists.txt b/config/openiotsdk/CMakeLists.txt new file mode 100644 index 00000000000000..414f591095f1dc --- /dev/null +++ b/config/openiotsdk/CMakeLists.txt @@ -0,0 +1,272 @@ +# +# 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. +# + +# +# @file +# CMake sub-project defining 'chip' target which represents CHIP library +# and other optional libraries like unit tests, built with 'open-iot-sdk' +# platform. +# Since CHIP doesn't provide native CMake support, ExternalProject +# module is used to build the required artifacts with GN meta-build +# system. +# + +include(ExternalProject) +include(util.cmake) + +# ============================================================================== +# Declare configuration variables and define constants +# ============================================================================== +# C/C++ compiler flags passed to CHIP build system +list(APPEND CHIP_CFLAGS \"-Wno-unused-function\") + +# C compiler flags passed to CHIP build system +list(APPEND CHIP_CFLAGS_C ${CMAKE_C_FLAGS}) + +# C++ compiler flags passed to CHIP build system +list(APPEND CHIP_CFLAGS_CC ${CMAKE_CXX_FLAGS}) + +# GN meta-build system arguments in the form of 'key1 = value1\nkey2 = value2...' string +string(APPEND CHIP_GN_ARGS) + +# ============================================================================== +# Helper macros +# ============================================================================== +macro(chip_gn_arg_import FILE) + string(APPEND CHIP_GN_ARGS "--module\n${FILE}\n") +endmacro() + +macro(chip_gn_arg_string ARG STRING) + string(APPEND CHIP_GN_ARGS "--arg-string\n${ARG}\n${STRING}\n") +endmacro() + +macro(chip_gn_arg_bool ARG) + if (${ARGN}) + string(APPEND CHIP_GN_ARGS "--arg\n${ARG}\ntrue\n") + else() + string(APPEND CHIP_GN_ARGS "--arg\n${ARG}\nfalse\n") + endif() +endmacro() + +macro(chip_gn_arg_cflags ARG CFLAGS) + string(APPEND CHIP_GN_ARGS "--arg-cflags\n${ARG}\n${CFLAGS}\n") +endmacro() + +macro(chip_gn_arg_cflags_lang ARG CFLAGS) + string(APPEND CHIP_GN_ARGS "--arg-cflags-lang\n${ARG}\n${CFLAGS}\n") +endmacro() + +macro(chip_gn_arg ARG VALUE) + string(APPEND CHIP_GN_ARGS "--arg\n${ARG}\n${VALUE}\n") +endmacro() + +# Select gnu++ standard based on project configuration +macro(get_gnu_cpp_standard VAR) + if (CONFIG_STD_CPP11) + list(APPEND ${VAR} -std=gnu++11) + elseif (CONFIG_STD_CPP14) + list(APPEND ${VAR} -std=gnu++14) + elseif (CONFIG_STD_CPP17) + list(APPEND ${VAR} -std=gnu++17) + elseif (CONFIG_STD_CPP2A) + list(APPEND ${VAR} -std=gnu++20) + endif() +endmacro() + +# ============================================================================== +# Prepare CHIP configuration based on the project configuration +# ============================================================================== +# Set paths +if (NOT CHIP_ROOT) + get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../.. REALPATH) +endif() + +set(GN_ROOT_TARGET ${CHIP_ROOT}/config/openiotsdk/chip-gn) + +# Prepare compiler flags +# All Open IoT SDK targets +list(APPEND ALL_SDK_TARGETS) + +foreach(source_dir ${SDK_SOURCES_BINARY_DIRS}) + get_all_cmake_targets(SDK_TARGETS ${source_dir}) + list(APPEND ALL_SDK_TARGETS ${SDK_TARGETS}) +endforeach() + +# Exclude unnecessary targets +list(FILTER ALL_SDK_TARGETS EXCLUDE REGEX "^.*linker.*|.*example.*|.*apps.*|.*doc.*|dist|lib$") + +foreach(target ${ALL_SDK_TARGETS}) + get_target_common_compile_flags(SDK_TARGET_CFLAGS ${target}) + list(APPEND CHIP_CFLAGS ${SDK_TARGET_CFLAGS}) +endforeach() + +# Remove duplicated flags +list(REMOVE_DUPLICATES CHIP_CFLAGS) + +get_gnu_cpp_standard(CHIP_CFLAGS_CC) + +# CFLAGS are put in random order, sort them before converting them to a string +list(SORT CHIP_CFLAGS) +list(SORT CHIP_CFLAGS_C) +list(SORT CHIP_CFLAGS_CC) + +set(SEPARATOR ",") +convert_list_of_flags_to_string_of_flags(CHIP_CFLAGS CHIP_CFLAGS ${SEPARATOR}) +set(SEPARATOR " ") +convert_list_of_flags_to_string_of_flags(CHIP_CFLAGS_C CHIP_CFLAGS_C ${SEPARATOR}) +convert_list_of_flags_to_string_of_flags(CHIP_CFLAGS_CC CHIP_CFLAGS_CC ${SEPARATOR}) + +# Prepare CHIP libraries that the application should be linked with +set(CHIP_LIBRARIES "${CMAKE_CURRENT_BINARY_DIR}/lib/libCHIP.a") + +if (CONFIG_CHIP_LIB_SHELL) + list(APPEND CHIP_LIBRARIES "${CMAKE_CURRENT_BINARY_DIR}/lib/libCHIPShell.a") +endif() + +# Set up CHIP project configuration file + +if (CONFIG_CHIP_PROJECT_CONFIG) + get_filename_component(CHIP_PROJECT_CONFIG + ${CONFIG_CHIP_PROJECT_CONFIG} + REALPATH + BASE_DIR ${CMAKE_SOURCE_DIR} + ) + set(CHIP_PROJECT_CONFIG "<${CHIP_PROJECT_CONFIG}>") +else() + set(CHIP_PROJECT_CONFIG "") +endif() + +if (${CMAKE_BUILD_TYPE} STREQUAL "Debug") + set(CONFIG_DEBUG YES) +endif() + +# Find required programs + +find_program(GN_EXECUTABLE gn) +if (${GN_EXECUTABLE} STREQUAL GN_EXECUTABLE-NOTFOUND) + message(FATAL_ERROR "The 'gn' command was not found. Make sure you have GN installed.") +else() + # Parse the 'gn --version' output to find the installed version. + set(MIN_GN_VERSION 1851) + execute_process( + COMMAND + ${GN_EXECUTABLE} --version + OUTPUT_VARIABLE gn_version_output + ERROR_VARIABLE gn_error_output + RESULT_VARIABLE gn_status + ) + + if(${gn_status} EQUAL 0) + if(gn_version_output VERSION_LESS ${MIN_GN_VERSION}) + message(FATAL_ERROR "Found unsuitable version of 'gn'. Required is at least ${MIN_GN_VERSION}") + endif() + else() + message(FATAL_ERROR "Could NOT find working gn: Found gn (${GN_EXECUTABLE}), but failed to load with:\n ${gn_error_output}") + endif() +endif() + +find_package(Python3 REQUIRED) + +# ============================================================================== +# Generate configuration for CHIP GN build system +# ============================================================================== +chip_gn_arg_string("target_cpu" "${CMAKE_SYSTEM_PROCESSOR}") +chip_gn_arg_cflags("target_cflags" ${CHIP_CFLAGS}) +chip_gn_arg_cflags_lang("target_cflags_c" ${CHIP_CFLAGS_C}) +chip_gn_arg_cflags_lang("target_cflags_cc" ${CHIP_CFLAGS_CC}) +chip_gn_arg_string("openiotsdk_ar" ${CMAKE_AR}) +chip_gn_arg_string("openiotsdk_cc" ${CMAKE_C_COMPILER}) +chip_gn_arg_string("openiotsdk_cxx" ${CMAKE_CXX_COMPILER}) +chip_gn_arg_string("chip_project_config_include" "${CHIP_PROJECT_CONFIG}") +chip_gn_arg_string("chip_system_project_config_include" "${CHIP_PROJECT_CONFIG}") +chip_gn_arg_bool ("is_debug" CONFIG_DEBUG) +chip_gn_arg_bool ("chip_build_tests" CONFIG_CHIP_LIB_TESTS) +chip_gn_arg_bool ("chip_monolithic_tests" CONFIG_CHIP_LIB_TESTS) +chip_gn_arg_bool ("chip_build_libshell" CONFIG_CHIP_LIB_SHELL) +chip_gn_arg_bool ("chip_detail_logging" CONFIG_CHIP_DETAIL_LOGGING) +chip_gn_arg_bool ("chip_progress_logging" CONFIG_CHIP_PROGRESS_LOGGING) +chip_gn_arg_bool ("chip_automation_logging" CONFIG_CHIP_AUTOMATION_LOGGING) +chip_gn_arg_bool ("chip_error_logging" CONFIG_CHIP_ERROR_LOGGING) +if (TARGET cmsis-rtos-api) + chip_gn_arg_string("target_os" "cmsis-rtos") +endif() +chip_gn_arg_string("optimize_debug_level" "s") + +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/args.tmp" CONTENT ${CHIP_GN_ARGS}) + +# ============================================================================== +# Define 'chip-gn' target that builds CHIP library(ies) with GN build system +# ============================================================================== +ExternalProject_Add( + chip-gn + PREFIX ${CMAKE_CURRENT_BINARY_DIR} + SOURCE_DIR ${CHIP_ROOT} + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} + CONFIGURE_COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/make_gn_args.py + @args.tmp > args.gn && + ${GN_EXECUTABLE} + --root=${CHIP_ROOT} + --root-target=${GN_ROOT_TARGET} + --dotfile=${GN_ROOT_TARGET}/.gn + --script-executable=${Python3_EXECUTABLE} + gen --check --fail-on-unused-args ${CMAKE_CURRENT_BINARY_DIR} + BUILD_COMMAND ninja + INSTALL_COMMAND "" + BUILD_BYPRODUCTS ${CHIP_LIBRARIES} + BUILD_ALWAYS TRUE + USES_TERMINAL_CONFIGURE TRUE + USES_TERMINAL_BUILD TRUE +) + +# ============================================================================== +# Define 'openiotsdk-chip' target that exposes CHIP and Open IoT SDK +# headers & libraries to the application +# ============================================================================== +add_library(openiotsdk-chip INTERFACE) +target_compile_definitions(openiotsdk-chip INTERFACE CHIP_HAVE_CONFIG_H) +target_include_directories(openiotsdk-chip INTERFACE + ${CHIP_ROOT}/src + ${CHIP_ROOT}/src/include + ${CHIP_ROOT}/src/lib + ${CHIP_ROOT}/third_party/nlassert/repo/include + ${CHIP_ROOT}/third_party/nlio/repo/include + ${CHIP_ROOT}/zzz_generated/app-common + ${CMAKE_CURRENT_BINARY_DIR}/gen/include +) +target_link_directories(openiotsdk-chip INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/lib) +target_link_libraries(openiotsdk-chip INTERFACE -Wl,--start-group ${CHIP_LIBRARIES} -Wl,--end-group) +target_link_libraries(openiotsdk-chip INTERFACE + $<$:mcu-driver-hal> + $<$:mcu-driver-bootstrap> + $<$:mdh-reference-platforms-for-arm> + $<$:mbedtls> + $<$:lwipcore> + $<$:iotsdk-ip-network-api> + $<$:iotsdk-tdbstore> + $<$:iotsdk-blockdevice> + $<$:$> +) +add_dependencies(openiotsdk-chip chip-gn) + +target_include_directories(openiotsdk-chip INTERFACE + ${CHIP_ROOT}/config/openiotsdk/mbedtls +) + +if (NOT ${CMAKE_BUILD_TYPE} STREQUAL "Debug") + target_compile_definitions(openiotsdk-chip INTERFACE + NDEBUG + ) +endif() diff --git a/config/openiotsdk/chip-gn/.gn b/config/openiotsdk/chip-gn/.gn new file mode 100644 index 00000000000000..4b9894b0f943ac --- /dev/null +++ b/config/openiotsdk/chip-gn/.gn @@ -0,0 +1,29 @@ +# 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. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +# The location of the build configuration file. +buildconfig = "//build/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + target_cpu = "arm" + target_os = "cmsis-rtos" + + import("${chip_root}/config/openiotsdk/chip-gn/args.gni") +} diff --git a/config/openiotsdk/chip-gn/BUILD.gn b/config/openiotsdk/chip-gn/BUILD.gn new file mode 100644 index 00000000000000..6e6fb51d404bb1 --- /dev/null +++ b/config/openiotsdk/chip-gn/BUILD.gn @@ -0,0 +1,28 @@ +# 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. + +import("//build_overrides/chip.gni") +import("${chip_root}/build/chip/tests.gni") + +group("openiotsdk") { + deps = [ "${chip_root}/src/lib" ] + + if (chip_build_tests) { + deps += [ "${chip_root}/src:tests" ] + } +} + +group("default") { + deps = [ ":openiotsdk" ] +} diff --git a/config/openiotsdk/chip-gn/args.gni b/config/openiotsdk/chip-gn/args.gni new file mode 100644 index 00000000000000..87c43e7a343dc2 --- /dev/null +++ b/config/openiotsdk/chip-gn/args.gni @@ -0,0 +1,38 @@ +# 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. + +import("//build_overrides/chip.gni") + +import("${chip_root}/src/crypto/crypto.gni") + +chip_device_platform = "openiotsdk" + +chip_build_tests = false + +chip_project_config_include = "" +chip_system_project_config_include = "" +chip_device_project_config_include = "" +chip_ble_project_config_include = "" + +chip_config_network_layer_ble = false +chip_system_config_use_lwip = true +lwip_platform = "external" +chip_system_config_use_sockets = false + +chip_crypto = "mbedtls" +chip_external_mbedtls = true + +custom_toolchain = "${chip_root}/config/openiotsdk/chip-gn/toolchain:openiotsdk" + +pw_build_PIP_CONSTRAINTS = [ "${chip_root}/scripts/constraints.txt" ] diff --git a/config/openiotsdk/chip-gn/toolchain/BUILD.gn b/config/openiotsdk/chip-gn/toolchain/BUILD.gn new file mode 100644 index 00000000000000..024a993aad6b43 --- /dev/null +++ b/config/openiotsdk/chip-gn/toolchain/BUILD.gn @@ -0,0 +1,32 @@ +# 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. + +import("//build/toolchain/arm_gcc/arm_toolchain.gni") + +declare_args() { + openiotsdk_ar = "" + openiotsdk_cc = "" + openiotsdk_cxx = "" +} + +gcc_toolchain("openiotsdk") { + ar = openiotsdk_ar + cc = openiotsdk_cc + cxx = openiotsdk_cxx + + toolchain_args = { + current_os = target_os + is_clang = false + } +} diff --git a/config/openiotsdk/cmake/chip.cmake b/config/openiotsdk/cmake/chip.cmake new file mode 100644 index 00000000000000..985d7f05bf74db --- /dev/null +++ b/config/openiotsdk/cmake/chip.cmake @@ -0,0 +1,33 @@ +# +# 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. +# + +# +# @file +# CMake for CHIP library configuration +# + +# Default CHIP build configuration +set(CONFIG_CHIP_PROJECT_CONFIG "main/include/CHIPProjectConfig.h" CACHE STRING "") +set(CONFIG_CHIP_LIB_TESTS NO CACHE BOOL "") +set(CONFIG_CHIP_LIB_SHELL NO CACHE BOOL "") + +set(CONFIG_CHIP_DETAIL_LOGGING YES CACHE BOOL "Enable logging at detail level") +set(CONFIG_CHIP_PROGRESS_LOGGING YES CACHE BOOL "Enable logging at progress level") +set(CONFIG_CHIP_AUTOMATION_LOGGING YES CACHE BOOL "Enable logging at automation level") +set(CONFIG_CHIP_ERROR_LOGGING YES CACHE BOOL "Enable logging at error level") + +# Add CHIP sources +add_subdirectory(${OPEN_IOT_SDK_CONFIG} ./chip_build) diff --git a/config/openiotsdk/cmake/linker.cmake b/config/openiotsdk/cmake/linker.cmake new file mode 100644 index 00000000000000..032b95f54afd60 --- /dev/null +++ b/config/openiotsdk/cmake/linker.cmake @@ -0,0 +1,39 @@ +# +# 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. +# + +# +# @file +# CMake linker configuration for target +# + +function(set_target_link target) + target_link_libraries(${target} + mdh-arm-corstone-300-startup + ) + + if (NOT LINKER_SCRIPT) + set(LINKER_SCRIPT ${OPEN_IOT_SDK_CONFIG}/ld/cs300_gcc.ld) + endif() + target_link_options(${APP_TARGET} PRIVATE -T ${LINKER_SCRIPT}) + set_target_properties(${APP_TARGET} PROPERTIES LINK_DEPENDS ${LINKER_SCRIPT}) + + target_link_options(${target} + PRIVATE + "-Wl,-Map=${APP_TARGET}.map" + ) +endfunction() + +set(CMAKE_EXECUTABLE_SUFFIX_CXX .elf) diff --git a/config/openiotsdk/cmake/sdk.cmake b/config/openiotsdk/cmake/sdk.cmake new file mode 100644 index 00000000000000..c87dad8412579d --- /dev/null +++ b/config/openiotsdk/cmake/sdk.cmake @@ -0,0 +1,144 @@ +# +# 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. +# + +# +# @file +# CMake for Open IoT SDK configuration +# + +include(FetchContent) + +get_filename_component(OPEN_IOT_SDK_SOURCE ${CHIP_ROOT}/third_party/open-iot-sdk/sdk REALPATH) +get_filename_component(OPEN_IOT_SDK_STORAGE_SOURCE ${CHIP_ROOT}/third_party/open-iot-sdk/storage REALPATH) + +# List of binary directories to Open IoT SDK sources +list(APPEND SDK_SOURCES_BINARY_DIRS) + +# Open IoT SDK configuration +set(IOTSDK_MDH_ARM ON) +set(MDH_PLATFORM "ARM_AN552_MPS3") +set(MDH_ARM_BUILD_EXAMPLES OFF) +set(IOTSDK_CMSIS_RTOS_API ON) +set(IOTSDK_FREERTOS ON) +set(IOTSDK_MBEDTLS ON) +set(IOTSDK_LWIP ON) +set(FETCHCONTENT_QUIET OFF) +set(IOTSDK_EXAMPLES OFF) +set(BUILD_TESTING NO) +set(VARIANT "FVP") + +# Add Open IoT SDK source +add_subdirectory(${OPEN_IOT_SDK_SOURCE} ./sdk_build) +list(APPEND SDK_SOURCES_BINARY_DIRS ${CMAKE_CURRENT_BINARY_DIR}/sdk_build) + +# Add Open IoT SDK modules to path +list(APPEND CMAKE_MODULE_PATH ${open-iot-sdk_SOURCE_DIR}/cmake) + +# CMSIS-RTOS configuration +# CMSIS 5 require projects to provide configuration macros via RTE_Components.h +# and CMSIS_device_header. The macro CMSIS_device_header is not automatically set +# based on CMAKE_SYSTEM_PROCESSOR in the place where cmsis-core is first defined, +# because a project may want to provide its own device header. +if(TARGET cmsis-rtos-api) + target_include_directories(cmsis-rtos-api + PUBLIC + cmsis-config + ) +endif() + +if(TARGET cmsis-core) + target_compile_definitions(cmsis-core + INTERFACE + $<$:CMSIS_device_header="ARMCM55.h"> + ) +endif() + +# LwIP configuration +if(TARGET lwip-cmsis-port) + # lwipcore requires the config defined by lwip-cmsis-port + target_link_libraries(lwipcore + PUBLIC + lwip-cmsis-port + ) + + # provide method to use for tracing by the lwip port (optional) + target_compile_definitions(lwipopts + INTERFACE + DEBUG_PRINT=printf + ) + + if(TARGET lwip-cmsis-port) + # Link the emac factory to LwIP port + target_link_libraries(lwip-cmsis-port PUBLIC iotsdk-emac-factory) + endif() +endif() + +# MDH configuration +if(TARGET ethernet-lan91c111) + target_compile_definitions(ethernet-lan91c111 + INTERFACE + LAN91C111_RFS_MULTICAST_SUPPORT + ) +endif() + +# Mbedtls config +if(TARGET mbedtls-config) + target_include_directories(mbedtls-config + INTERFACE + ${OPEN_IOT_SDK_CONFIG}/mbedtls + ) + + target_sources(mbedtls-config + INTERFACE + ${OPEN_IOT_SDK_CONFIG}/mbedtls/platform_alt.cpp + ) + + target_compile_definitions(mbedtls-config + INTERFACE + MBEDTLS_CONFIG_FILE="mbedtls_config.h" + ) + + target_link_libraries(mbedtls-config + INTERFACE + mbedtls-threading-cmsis-rtos + ) +endif() + +# Declare RTOS interface target +add_library(cmsis-rtos-implementation INTERFACE) + +if(TARGET freertos-kernel) + target_link_libraries(cmsis-rtos-implementation + INTERFACE + freertos-cmsis-rtos + freertos-kernel-heap-3 + ) + target_include_directories(cmsis-rtos-implementation + INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR}/freertos-config + ) +elseif(TARGET cmsis-rtx) + target_link_libraries(cmsis-rtos-implementation + INTERFACE + cmsis-rtx + cmsis-rtos-api + cmsis-rtx-freertos-alloc-wrapper + ) +endif() + +# Add Open IoT SDK storage source +add_subdirectory(${OPEN_IOT_SDK_STORAGE_SOURCE} ./sdk_storage_build) +list(APPEND SDK_SOURCES_BINARY_DIRS ${CMAKE_CURRENT_BINARY_DIR}/sdk_storage_build) diff --git a/config/openiotsdk/cmake/toolchain.cmake b/config/openiotsdk/cmake/toolchain.cmake new file mode 100644 index 00000000000000..ef0a8d1a3995a9 --- /dev/null +++ b/config/openiotsdk/cmake/toolchain.cmake @@ -0,0 +1,29 @@ +# +# 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. +# + +# +# @file +# CMake for toolchain configuration +# + +include(FetchContent) + +FetchContent_Declare(iotsdk-toolchains + GIT_REPOSITORY https://git.gitlab.arm.com/iot/open-iot-sdk/toolchain.git + GIT_TAG v2022.09 + SOURCE_DIR ${CMAKE_BINARY_DIR}/toolchains +) +FetchContent_MakeAvailable(iotsdk-toolchains) diff --git a/config/openiotsdk/fvp/cs300.conf b/config/openiotsdk/fvp/cs300.conf new file mode 100644 index 00000000000000..5fc302cef68d2b --- /dev/null +++ b/config/openiotsdk/fvp/cs300.conf @@ -0,0 +1,25 @@ +## Turn off terminal1 terminal2 and termimal5, keep terminal0 open +mps3_board.telnetterminal1.quiet=1 +mps3_board.telnetterminal2.quiet=1 +mps3_board.telnetterminal5.quiet=1 + +## Suppress the telnet/xterm to be launched, so that model agent can talk to the port +mps3_board.telnetterminal0.start_telnet=0 + +## Turn the rate limite off, make FVP runs as fast as possiable +mps3_board.visualisation.rate_limit-enable=0 + +## Enable SMSC_91C111 controller +mps3_board.smsc_91c111.enabled=1 + +## Turn off GUI windows +mps3_board.visualisation.disable-visualisation=1 + +## Enable semihosting SVC traps +cpu0.semihosting-enable=1 + +## Disable Memory gating logic +mps3_board.DISABLE_GATING=1 + +## Set Clock Rate Multiplier +core_clk.mul=100000000 diff --git a/config/openiotsdk/ld/cs300_gcc.ld b/config/openiotsdk/ld/cs300_gcc.ld new file mode 100644 index 00000000000000..850e91200bc0d5 --- /dev/null +++ b/config/openiotsdk/ld/cs300_gcc.ld @@ -0,0 +1,161 @@ +; +MEMORY +{ + ITCM (rx) : ORIGIN = 0x00000000, LENGTH = 32K + /* Vector table is copied to RAM, so RAM address needs to be adjusted */ + DTCM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K + DATA_SRAM (rwx) : ORIGIN = 0x21000000, LENGTH = 2M + QSPI_RAM (rx) : ORIGIN = 0x28000000, LENGTH = 8M +} + +__stack_size__ = 0x1000; + +/* Library configurations */ +GROUP(libgcc.a libc.a libm.a libnosys.a) + +SECTIONS +{ + .vectors : + { + KEEP(*(.vectors)) + __Vectors_End = .; + __Vectors_Size = __Vectors_End - __Vectors; + __end__ = .; + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + } > ITCM + + .text : + { + *(.text*) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > QSPI_RAM + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > QSPI_RAM + + __exidx_start = .; + + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > QSPI_RAM + + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * define etext2/data2_start/data2_end */ + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (DEFINED(__etext2) ? __etext2 : 0) + LONG (DEFINED(__data2_start__) ? __data2_start__ : 0) + LONG (DEFINED(__data2_start__) ? __data2_end__ - __data2_start__ : 0) + __copy_table_end__ = .; + } > QSPI_RAM + + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (DEFINED(__bss2_start__) ? __bss2_start__ : 0) + LONG (DEFINED(__bss2_start__) ? __bss2_end__ - __bss2_start__ : 0) + __zero_table_end__ = .; + } > QSPI_RAM + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + } > DATA_SRAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > DATA_SRAM + + bss_size = __bss_end__ - __bss_start__; + + .stack : + { + . = ALIGN(8); + __StackLimit = .; + KEEP(*(.stack*)) + . += __stack_size__; + __StackTop = .; + } > DTCM + PROVIDE(__stack = __StackTop); + + .heap (COPY): + { + . = ALIGN(8); + __HeapBase = .; + __end__ = .; + end = __end__; + KEEP(*(.heap*)) + . += (ORIGIN(DATA_SRAM) + LENGTH(DATA_SRAM) - .); + __HeapLimit = .; + __heap_limit = .; + } > DATA_SRAM + + ASSERT(__StackTop <= (ORIGIN(DTCM) + LENGTH(DTCM)), "RAM region overflowed") +} diff --git a/config/openiotsdk/lwip/user_lwipopts.h b/config/openiotsdk/lwip/user_lwipopts.h new file mode 100644 index 00000000000000..8bf38b1129fc56 --- /dev/null +++ b/config/openiotsdk/lwip/user_lwipopts.h @@ -0,0 +1,51 @@ +/* + * + * 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 USER_LWIPOPTS_H +#define USER_LWIPOPTS_H + +#define LWIP_STATS (0) +#define LWIP_IGMP (1) +#define LWIP_RAW (1) + +#define MEM_LIBC_MALLOC (1) +#define MEM_USE_POOLS (0) + +#ifdef LWIP_DEBUG + +// Debug Options +#define NETIF_DEBUG LWIP_DBG_ON +#define IP_DEBUG LWIP_DBG_ON +#define TCP_DEBUG LWIP_DBG_ON +#define UDP_DEBUG LWIP_DBG_ON +#define IP6_DEBUG LWIP_DBG_ON + +#define LWIP_DBG_TYPES_ON LWIP_DBG_ON +#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL +#endif + +#ifndef LWIP_PLATFORM_DIAG +#define LWIP_PLATFORM_DIAG(x) \ + do \ + { \ + DEBUG_PRINT x; \ + DEBUG_PRINT("\r"); \ + } while (0) +#endif + +#endif /* USER_LWIPOPTS_H */ diff --git a/config/openiotsdk/make_gn_args.py b/config/openiotsdk/make_gn_args.py new file mode 100755 index 00000000000000..074645140deeb0 --- /dev/null +++ b/config/openiotsdk/make_gn_args.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 + +# +# 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. +# + +import argparse +import re +import sys + +GN_SPECIAL_CHARACTERS = r'(["$\\])' +GN_CFLAG_EXCLUDES = [ + '-fno-asynchronous-unwind-tables', + '-fno-common', + '-fno-defer-pop', + '-fno-reorder-functions', + '-ffunction-sections', + '-fdata-sections', + '-g*', + '-O*', + '-W*', +] + + +def escape_strings(gn_args): + return [[key, re.sub(GN_SPECIAL_CHARACTERS, r'\\\1', value)] for key, value in gn_args] + + +def write_gn_args(args): + if args.module: + sys.stdout.write('import("{}")\n'.format(args.module)) + + for key, value in args.arg: + sys.stdout.write('{} = {}\n'.format(key, value)) + + for key, value in args.arg_string: + sys.stdout.write('{} = "{}"\n'.format(key, value)) + + for key, value in args.arg_cflags: + # Remove empty include paths - fix generator expressions issue + filtered_value = [x for x in value.split(",") if x != '"-isystem"'] + sys.stdout.write('{} = [{}]\n'.format( + key, ",".join(filtered_value))) + + cflag_excludes = ', '.join(['"{}"'.format(exclude) + for exclude in GN_CFLAG_EXCLUDES]) + + for key, value in args.arg_cflags_lang: + sys.stdout.write('{} = filter_exclude(string_split("{}"), [{}])\n'.format( + key, value, cflag_excludes)) + + +def main(): + parser = argparse.ArgumentParser(fromfile_prefix_chars='@') + parser.add_argument('--module', action='store') + parser.add_argument('--arg', action='append', nargs=2, default=[]) + parser.add_argument('--arg-string', action='append', nargs=2, default=[]) + parser.add_argument('--arg-cflags', action='append', nargs=2, default=[]) + parser.add_argument('--arg-cflags-lang', action='append', nargs=2, default=[]) + args = parser.parse_args() + write_gn_args(args) + + +if __name__ == "__main__": + main() diff --git a/config/openiotsdk/mbedtls/mbedtls_config.h b/config/openiotsdk/mbedtls/mbedtls_config.h new file mode 100644 index 00000000000000..e12878adf14986 --- /dev/null +++ b/config/openiotsdk/mbedtls/mbedtls_config.h @@ -0,0 +1,3960 @@ +/** + * \file mbedtls_config.h + * + * \brief Configuration options (set of defines) + * + * This set of compile-time options may be used to enable + * or disable features selectively, and reduce the global + * memory footprint. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * 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 MBEDTLS_CONFIG_H +#define MBEDTLS_CONFIG_H + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif + +/** + * \name SECTION: System support + * + * This section sets system specific settings. + * \{ + */ + +/** + * \def MBEDTLS_HAVE_ASM + * + * The compiler has support for asm(). + * + * Requires support for asm() in compiler. + * + * Used in: + * library/aria.c + * library/timing.c + * include/mbedtls/bn_mul.h + * + * Required by: + * MBEDTLS_AESNI_C + * MBEDTLS_PADLOCK_C + * + * Comment to disable the use of assembly code. + */ +#define MBEDTLS_HAVE_ASM + +/** + * \def MBEDTLS_NO_UDBL_DIVISION + * + * The platform lacks support for double-width integer division (64-bit + * division on a 32-bit platform, 128-bit division on a 64-bit platform). + * + * Used in: + * include/mbedtls/bignum.h + * library/bignum.c + * + * The bignum code uses double-width division to speed up some operations. + * Double-width division is often implemented in software that needs to + * be linked with the program. The presence of a double-width integer + * type is usually detected automatically through preprocessor macros, + * but the automatic detection cannot know whether the code needs to + * and can be linked with an implementation of division for that type. + * By default division is assumed to be usable if the type is present. + * Uncomment this option to prevent the use of double-width division. + * + * Note that division for the native integer type is always required. + * Furthermore, a 64-bit type is always required even on a 32-bit + * platform, but it need not support multiplication or division. In some + * cases it is also desirable to disable some double-width operations. For + * example, if double-width division is implemented in software, disabling + * it can reduce code size in some embedded targets. + */ +//#define MBEDTLS_NO_UDBL_DIVISION + +/** + * \def MBEDTLS_NO_64BIT_MULTIPLICATION + * + * The platform lacks support for 32x32 -> 64-bit multiplication. + * + * Used in: + * library/poly1305.c + * + * Some parts of the library may use multiplication of two unsigned 32-bit + * operands with a 64-bit result in order to speed up computations. On some + * platforms, this is not available in hardware and has to be implemented in + * software, usually in a library provided by the toolchain. + * + * Sometimes it is not desirable to have to link to that library. This option + * removes the dependency of that library on platforms that lack a hardware + * 64-bit multiplier by embedding a software implementation in Mbed TLS. + * + * Note that depending on the compiler, this may decrease performance compared + * to using the library function provided by the toolchain. + */ +//#define MBEDTLS_NO_64BIT_MULTIPLICATION + +/** + * \def MBEDTLS_HAVE_SSE2 + * + * CPU supports SSE2 instruction set. + * + * Uncomment if the CPU supports SSE2 (IA-32 specific). + */ +//#define MBEDTLS_HAVE_SSE2 + +/** + * \def MBEDTLS_HAVE_TIME + * + * System has time.h and time(). + * The time does not need to be correct, only time differences are used, + * by contrast with MBEDTLS_HAVE_TIME_DATE + * + * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT, + * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and + * MBEDTLS_PLATFORM_STD_TIME. + * + * Comment if your system does not support time functions + */ +#define MBEDTLS_HAVE_TIME + +/** + * \def MBEDTLS_HAVE_TIME_DATE + * + * System has time.h, time(), and an implementation for + * mbedtls_platform_gmtime_r() (see below). + * The time needs to be correct (not necessarily very accurate, but at least + * the date should be correct). This is used to verify the validity period of + * X.509 certificates. + * + * Comment if your system does not have a correct clock. + * + * \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that + * behaves similarly to the gmtime_r() function from the C standard. Refer to + * the documentation for mbedtls_platform_gmtime_r() for more information. + * + * \note It is possible to configure an implementation for + * mbedtls_platform_gmtime_r() at compile-time by using the macro + * MBEDTLS_PLATFORM_GMTIME_R_ALT. + */ +//#define MBEDTLS_HAVE_TIME_DATE + +/** + * \def MBEDTLS_PLATFORM_MEMORY + * + * Enable the memory allocation layer. + * + * By default mbed TLS uses the system-provided calloc() and free(). + * This allows different allocators (self-implemented or provided) to be + * provided to the platform abstraction layer. + * + * Enabling MBEDTLS_PLATFORM_MEMORY without the + * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide + * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and + * free() function pointer at runtime. + * + * Enabling MBEDTLS_PLATFORM_MEMORY and specifying + * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the + * alternate function at compile time. + * + * Requires: MBEDTLS_PLATFORM_C + * + * Enable this layer to allow use of alternative memory allocators. + */ +//#define MBEDTLS_PLATFORM_MEMORY + +/** + * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + * + * Do not assign standard functions in the platform layer (e.g. calloc() to + * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF) + * + * This makes sure there are no linking errors on platforms that do not support + * these functions. You will HAVE to provide alternatives, either at runtime + * via the platform_set_xxx() functions or at compile time by setting + * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a + * MBEDTLS_PLATFORM_XXX_MACRO. + * + * Requires: MBEDTLS_PLATFORM_C + * + * Uncomment to prevent default assignment of standard functions in the + * platform layer. + */ +//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + +/** + * \def MBEDTLS_PLATFORM_EXIT_ALT + * + * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let mbed TLS support the + * function in the platform abstraction layer. + * + * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, mbed TLS will + * provide a function "mbedtls_platform_set_printf()" that allows you to set an + * alternative printf function pointer. + * + * All these define require MBEDTLS_PLATFORM_C to be defined! + * + * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows; + * it will be enabled automatically by check_config.h + * + * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as + * MBEDTLS_PLATFORM_XXX_MACRO! + * + * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME + * + * Uncomment a macro to enable alternate implementation of specific base + * platform function + */ +//#define MBEDTLS_PLATFORM_EXIT_ALT +//#define MBEDTLS_PLATFORM_TIME_ALT +//#define MBEDTLS_PLATFORM_FPRINTF_ALT +//#define MBEDTLS_PLATFORM_PRINTF_ALT +//#define MBEDTLS_PLATFORM_SNPRINTF_ALT +//#define MBEDTLS_PLATFORM_VSNPRINTF_ALT +#define MBEDTLS_PLATFORM_NV_SEED_ALT +#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT + +/** + * \def MBEDTLS_DEPRECATED_WARNING + * + * Mark deprecated functions and features so that they generate a warning if + * used. Functionality deprecated in one version will usually be removed in the + * next version. You can enable this to help you prepare the transition to a + * new major version by making sure your code is not using this functionality. + * + * This only works with GCC and Clang. With other compilers, you may want to + * use MBEDTLS_DEPRECATED_REMOVED + * + * Uncomment to get warnings on using deprecated functions and features. + */ +//#define MBEDTLS_DEPRECATED_WARNING + +/** + * \def MBEDTLS_DEPRECATED_REMOVED + * + * Remove deprecated functions and features so that they generate an error if + * used. Functionality deprecated in one version will usually be removed in the + * next version. You can enable this to help you prepare the transition to a + * new major version by making sure your code is not using this functionality. + * + * Uncomment to get errors on using deprecated functions and features. + */ +//#define MBEDTLS_DEPRECATED_REMOVED + +/** + * \def MBEDTLS_CHECK_PARAMS + * + * This configuration option controls whether the library validates more of + * the parameters passed to it. + * + * When this flag is not defined, the library only attempts to validate an + * input parameter if: (1) they may come from the outside world (such as the + * network, the filesystem, etc.) or (2) not validating them could result in + * internal memory errors such as overflowing a buffer controlled by the + * library. On the other hand, it doesn't attempt to validate parameters whose + * values are fully controlled by the application (such as pointers). + * + * When this flag is defined, the library additionally attempts to validate + * parameters that are fully controlled by the application, and should always + * be valid if the application code is fully correct and trusted. + * + * For example, when a function accepts as input a pointer to a buffer that may + * contain untrusted data, and its documentation mentions that this pointer + * must not be NULL: + * - The pointer is checked to be non-NULL only if this option is enabled. + * - The content of the buffer is always validated. + * + * When this flag is defined, if a library function receives a parameter that + * is invalid: + * 1. The function will invoke the macro MBEDTLS_PARAM_FAILED(). + * 2. If MBEDTLS_PARAM_FAILED() did not terminate the program, the function + * will immediately return. If the function returns an Mbed TLS error code, + * the error code in this case is MBEDTLS_ERR_xxx_BAD_INPUT_DATA. + * + * When defining this flag, you also need to arrange a definition for + * MBEDTLS_PARAM_FAILED(). You can do this by any of the following methods: + * - By default, the library defines MBEDTLS_PARAM_FAILED() to call a + * function mbedtls_param_failed(), but the library does not define this + * function. If you do not make any other arrangements, you must provide + * the function mbedtls_param_failed() in your application. + * See `platform_util.h` for its prototype. + * - If you enable the macro #MBEDTLS_CHECK_PARAMS_ASSERT, then the + * library defines MBEDTLS_PARAM_FAILED(\c cond) to be `assert(cond)`. + * You can still supply an alternative definition of + * MBEDTLS_PARAM_FAILED(), which may call `assert`. + * - If you define a macro MBEDTLS_PARAM_FAILED() before including `config.h` + * or you uncomment the definition of MBEDTLS_PARAM_FAILED() in `config.h`, + * the library will call the macro that you defined and will not supply + * its own version. Note that if MBEDTLS_PARAM_FAILED() calls `assert`, + * you need to enable #MBEDTLS_CHECK_PARAMS_ASSERT so that library source + * files include ``. + * + * Uncomment to enable validation of application-controlled parameters. + */ +//#define MBEDTLS_CHECK_PARAMS + +/** + * \def MBEDTLS_CHECK_PARAMS_ASSERT + * + * Allow MBEDTLS_PARAM_FAILED() to call `assert`, and make it default to + * `assert`. This macro is only used if #MBEDTLS_CHECK_PARAMS is defined. + * + * If this macro is not defined, then MBEDTLS_PARAM_FAILED() defaults to + * calling a function mbedtls_param_failed(). See the documentation of + * #MBEDTLS_CHECK_PARAMS for details. + * + * Uncomment to allow MBEDTLS_PARAM_FAILED() to call `assert`. + */ +//#define MBEDTLS_CHECK_PARAMS_ASSERT + +/* \} name SECTION: System support */ + +/** + * \name SECTION: mbed TLS feature support + * + * This section sets support for features that are or are not needed + * within the modules that are enabled. + * \{ + */ + +/** + * \def MBEDTLS_TIMING_ALT + * + * Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(), + * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay() + * + * Only works if you have MBEDTLS_TIMING_C enabled. + * + * You will need to provide a header "timing_alt.h" and an implementation at + * compile time. + */ +//#define MBEDTLS_TIMING_ALT + +/** + * \def MBEDTLS_AES_ALT + * + * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your + * alternate core implementation of a symmetric crypto, an arithmetic or hash + * module (e.g. platform specific assembly optimized implementations). Keep + * in mind that the function prototypes should remain the same. + * + * This replaces the whole module. If you only want to replace one of the + * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags. + * + * Example: In case you uncomment MBEDTLS_AES_ALT, mbed TLS will no longer + * provide the "struct mbedtls_aes_context" definition and omit the base + * function declarations and implementations. "aes_alt.h" will be included from + * "aes.h" to include the new function definitions. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * module. + * + * \warning MD2, MD4, MD5, ARC4, DES and SHA-1 are considered weak and their + * use constitutes a security risk. If possible, we recommend + * avoiding dependencies on them, and considering stronger message + * digests and ciphers instead. + * + */ +//#define MBEDTLS_AES_ALT +//#define MBEDTLS_ARC4_ALT +//#define MBEDTLS_ARIA_ALT +//#define MBEDTLS_BLOWFISH_ALT +//#define MBEDTLS_CAMELLIA_ALT +//#define MBEDTLS_CCM_ALT +//#define MBEDTLS_CHACHA20_ALT +//#define MBEDTLS_CHACHAPOLY_ALT +//#define MBEDTLS_CMAC_ALT +//#define MBEDTLS_DES_ALT +//#define MBEDTLS_DHM_ALT +//#define MBEDTLS_ECJPAKE_ALT +//#define MBEDTLS_GCM_ALT +//#define MBEDTLS_NIST_KW_ALT +//#define MBEDTLS_MD2_ALT +//#define MBEDTLS_MD4_ALT +//#define MBEDTLS_MD5_ALT +//#define MBEDTLS_POLY1305_ALT +//#define MBEDTLS_RIPEMD160_ALT +//#define MBEDTLS_RSA_ALT +//#define MBEDTLS_SHA1_ALT +//#define MBEDTLS_SHA256_ALT +//#define MBEDTLS_SHA512_ALT +//#define MBEDTLS_XTEA_ALT + +/* + * When replacing the elliptic curve module, pleace consider, that it is + * implemented with two .c files: + * - ecp.c + * - ecp_curves.c + * You can replace them very much like all the other MBEDTLS__MODULE_NAME__ALT + * macros as described above. The only difference is that you have to make sure + * that you provide functionality for both .c files. + */ +//#define MBEDTLS_ECP_ALT + +/** + * \def MBEDTLS_MD2_PROCESS_ALT + * + * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you + * alternate core implementation of symmetric crypto or hash function. Keep in + * mind that function prototypes should remain the same. + * + * This replaces only one function. The header file from mbed TLS is still + * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags. + * + * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will + * no longer provide the mbedtls_sha1_process() function, but it will still provide + * the other function (using your mbedtls_sha1_process() function) and the definition + * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible + * with this definition. + * + * \note Because of a signature change, the core AES encryption and decryption routines are + * currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt, + * respectively. When setting up alternative implementations, these functions should + * be overridden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt + * must stay untouched. + * + * \note If you use the AES_xxx_ALT macros, then is is recommended to also set + * MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES + * tables. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * function. + * + * \warning MD2, MD4, MD5, DES and SHA-1 are considered weak and their use + * constitutes a security risk. If possible, we recommend avoiding + * dependencies on them, and considering stronger message digests + * and ciphers instead. + * + * \warning If both MBEDTLS_ECDSA_SIGN_ALT and MBEDTLS_ECDSA_DETERMINISTIC are + * enabled, then the deterministic ECDH signature functions pass the + * the static HMAC-DRBG as RNG to mbedtls_ecdsa_sign(). Therefore + * alternative implementations should use the RNG only for generating + * the ephemeral key and nothing else. If this is not possible, then + * MBEDTLS_ECDSA_DETERMINISTIC should be disabled and an alternative + * implementation should be provided for mbedtls_ecdsa_sign_det_ext() + * (and for mbedtls_ecdsa_sign_det() too if backward compatibility is + * desirable). + * + */ +//#define MBEDTLS_MD2_PROCESS_ALT +//#define MBEDTLS_MD4_PROCESS_ALT +//#define MBEDTLS_MD5_PROCESS_ALT +//#define MBEDTLS_RIPEMD160_PROCESS_ALT +//#define MBEDTLS_SHA1_PROCESS_ALT +//#define MBEDTLS_SHA256_PROCESS_ALT +//#define MBEDTLS_SHA512_PROCESS_ALT +//#define MBEDTLS_DES_SETKEY_ALT +//#define MBEDTLS_DES_CRYPT_ECB_ALT +//#define MBEDTLS_DES3_CRYPT_ECB_ALT +//#define MBEDTLS_AES_SETKEY_ENC_ALT +//#define MBEDTLS_AES_SETKEY_DEC_ALT +//#define MBEDTLS_AES_ENCRYPT_ALT +//#define MBEDTLS_AES_DECRYPT_ALT +//#define MBEDTLS_ECDH_GEN_PUBLIC_ALT +//#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT +//#define MBEDTLS_ECDSA_VERIFY_ALT +//#define MBEDTLS_ECDSA_SIGN_ALT +//#define MBEDTLS_ECDSA_GENKEY_ALT + +/** + * \def MBEDTLS_ECP_INTERNAL_ALT + * + * Expose a part of the internal interface of the Elliptic Curve Point module. + * + * MBEDTLS_ECP__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use your + * alternative core implementation of elliptic curve arithmetic. Keep in mind + * that function prototypes should remain the same. + * + * This partially replaces one function. The header file from mbed TLS is still + * used, in contrast to the MBEDTLS_ECP_ALT flag. The original implementation + * is still present and it is used for group structures not supported by the + * alternative. + * + * The original implementation can in addition be removed by setting the + * MBEDTLS_ECP_NO_FALLBACK option, in which case any function for which the + * corresponding MBEDTLS_ECP__FUNCTION_NAME__ALT macro is defined will not be + * able to fallback to curves not supported by the alternative implementation. + * + * Any of these options become available by defining MBEDTLS_ECP_INTERNAL_ALT + * and implementing the following functions: + * unsigned char mbedtls_internal_ecp_grp_capable( + * const mbedtls_ecp_group *grp ) + * int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp ) + * void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp ) + * The mbedtls_internal_ecp_grp_capable function should return 1 if the + * replacement functions implement arithmetic for the given group and 0 + * otherwise. + * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_free are + * called before and after each point operation and provide an opportunity to + * implement optimized set up and tear down instructions. + * + * Example: In case you set MBEDTLS_ECP_INTERNAL_ALT and + * MBEDTLS_ECP_DOUBLE_JAC_ALT, mbed TLS will still provide the ecp_double_jac() + * function, but will use your mbedtls_internal_ecp_double_jac() if the group + * for the operation is supported by your implementation (i.e. your + * mbedtls_internal_ecp_grp_capable() function returns 1 for this group). If the + * group is not supported by your implementation, then the original mbed TLS + * implementation of ecp_double_jac() is used instead, unless this fallback + * behaviour is disabled by setting MBEDTLS_ECP_NO_FALLBACK (in which case + * ecp_double_jac() will return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE). + * + * The function prototypes and the definition of mbedtls_ecp_group and + * mbedtls_ecp_point will not change based on MBEDTLS_ECP_INTERNAL_ALT, so your + * implementation of mbedtls_internal_ecp__function_name__ must be compatible + * with their definitions. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * function. + */ +/* Required for all the functions in this section */ +//#define MBEDTLS_ECP_INTERNAL_ALT +/* Turn off software fallback for curves not supported in hardware */ +//#define MBEDTLS_ECP_NO_FALLBACK +/* Support for Weierstrass curves with Jacobi representation */ +//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT +//#define MBEDTLS_ECP_ADD_MIXED_ALT +//#define MBEDTLS_ECP_DOUBLE_JAC_ALT +//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT +//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT +/* Support for curves with Montgomery arithmetic */ +//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT +//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT +//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT + +/** + * \def MBEDTLS_TEST_NULL_ENTROPY + * + * Enables testing and use of mbed TLS without any configured entropy sources. + * This permits use of the library on platforms before an entropy source has + * been integrated (see for example the MBEDTLS_ENTROPY_HARDWARE_ALT or the + * MBEDTLS_ENTROPY_NV_SEED switches). + * + * WARNING! This switch MUST be disabled in production builds, and is suitable + * only for development. + * Enabling the switch negates any security provided by the library. + * + * Requires MBEDTLS_ENTROPY_C, MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + * + */ +//#define MBEDTLS_TEST_NULL_ENTROPY + +/** + * \def MBEDTLS_ENTROPY_HARDWARE_ALT + * + * Uncomment this macro to let mbed TLS use your own implementation of a + * hardware entropy collector. + * + * Your function must be called \c mbedtls_hardware_poll(), have the same + * prototype as declared in entropy_poll.h, and accept NULL as first argument. + * + * Uncomment to use your own hardware entropy collector. + */ +//#define MBEDTLS_ENTROPY_HARDWARE_ALT + +/** + * \def MBEDTLS_AES_ROM_TABLES + * + * Use precomputed AES tables stored in ROM. + * + * Uncomment this macro to use precomputed AES tables stored in ROM. + * Comment this macro to generate AES tables in RAM at runtime. + * + * Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb + * (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the + * initialization time before the first AES operation can be performed. + * It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c + * MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded + * performance if ROM access is slower than RAM access. + * + * This option is independent of \c MBEDTLS_AES_FEWER_TABLES. + * + */ +#define MBEDTLS_AES_ROM_TABLES + +/** + * \def MBEDTLS_AES_FEWER_TABLES + * + * Use less ROM/RAM for AES tables. + * + * Uncommenting this macro omits 75% of the AES tables from + * ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES) + * by computing their values on the fly during operations + * (the tables are entry-wise rotations of one another). + * + * Tradeoff: Uncommenting this reduces the RAM / ROM footprint + * by ~6kb but at the cost of more arithmetic operations during + * runtime. Specifically, one has to compare 4 accesses within + * different tables to 4 accesses with additional arithmetic + * operations within the same table. The performance gain/loss + * depends on the system and memory details. + * + * This option is independent of \c MBEDTLS_AES_ROM_TABLES. + * + */ +//#define MBEDTLS_AES_FEWER_TABLES + +/** + * \def MBEDTLS_CAMELLIA_SMALL_MEMORY + * + * Use less ROM for the Camellia implementation (saves about 768 bytes). + * + * Uncomment this macro to use less memory for Camellia. + */ +//#define MBEDTLS_CAMELLIA_SMALL_MEMORY + +/** + * \def MBEDTLS_CIPHER_MODE_CBC + * + * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. + */ +#define MBEDTLS_CIPHER_MODE_CBC + +/** + * \def MBEDTLS_CIPHER_MODE_CFB + * + * Enable Cipher Feedback mode (CFB) for symmetric ciphers. + */ +#define MBEDTLS_CIPHER_MODE_CFB + +/** + * \def MBEDTLS_CIPHER_MODE_CTR + * + * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. + */ +#define MBEDTLS_CIPHER_MODE_CTR + +/** + * \def MBEDTLS_CIPHER_MODE_OFB + * + * Enable Output Feedback mode (OFB) for symmetric ciphers. + */ +//#define MBEDTLS_CIPHER_MODE_OFB + +/** + * \def MBEDTLS_CIPHER_MODE_XTS + * + * Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES. + */ +//#define MBEDTLS_CIPHER_MODE_XTS + +/** + * \def MBEDTLS_CIPHER_NULL_CIPHER + * + * Enable NULL cipher. + * Warning: Only do so when you know what you are doing. This allows for + * encryption or channels without any security! + * + * Requires MBEDTLS_ENABLE_WEAK_CIPHERSUITES as well to enable + * the following ciphersuites: + * MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA + * MBEDTLS_TLS_RSA_WITH_NULL_SHA256 + * MBEDTLS_TLS_RSA_WITH_NULL_SHA + * MBEDTLS_TLS_RSA_WITH_NULL_MD5 + * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA + * MBEDTLS_TLS_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_PSK_WITH_NULL_SHA + * + * Uncomment this macro to enable the NULL cipher and ciphersuites + */ +//#define MBEDTLS_CIPHER_NULL_CIPHER + +/** + * \def MBEDTLS_CIPHER_PADDING_PKCS7 + * + * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for + * specific padding modes in the cipher layer with cipher modes that support + * padding (e.g. CBC) + * + * If you disable all padding modes, only full blocks can be used with CBC. + * + * Enable padding modes in the cipher layer. + */ +#define MBEDTLS_CIPHER_PADDING_PKCS7 +#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS +#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN +#define MBEDTLS_CIPHER_PADDING_ZEROS + +/** \def MBEDTLS_CTR_DRBG_USE_128_BIT_KEY + * + * Uncomment this macro to use a 128-bit key in the CTR_DRBG module. + * By default, CTR_DRBG uses a 256-bit key. + */ +//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY + +/** + * \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES + * + * Enable weak ciphersuites in SSL / TLS. + * Warning: Only do so when you know what you are doing. This allows for + * channels with virtually no security at all! + * + * This enables the following ciphersuites: + * MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA + * + * Uncomment this macro to enable weak ciphersuites + * + * \warning DES is considered a weak cipher and its use constitutes a + * security risk. We recommend considering stronger ciphers instead. + */ +//#define MBEDTLS_ENABLE_WEAK_CIPHERSUITES + +/** + * \def MBEDTLS_REMOVE_ARC4_CIPHERSUITES + * + * Remove RC4 ciphersuites by default in SSL / TLS. + * This flag removes the ciphersuites based on RC4 from the default list as + * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible to + * enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including them + * explicitly. + * + * Uncomment this macro to remove RC4 ciphersuites by default. + */ +#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES + +/** + * \def MBEDTLS_REMOVE_3DES_CIPHERSUITES + * + * Remove 3DES ciphersuites by default in SSL / TLS. + * This flag removes the ciphersuites based on 3DES from the default list as + * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible + * to enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including + * them explicitly. + * + * A man-in-the-browser attacker can recover authentication tokens sent through + * a TLS connection using a 3DES based cipher suite (see "On the Practical + * (In-)Security of 64-bit Block Ciphers" by Karthikeyan Bhargavan and Gaëtan + * Leurent, see https://sweet32.info/SWEET32_CCS16.pdf). If this attack falls + * in your threat model or you are unsure, then you should keep this option + * enabled to remove 3DES based cipher suites. + * + * Comment this macro to keep 3DES in the default ciphersuite list. + */ +#define MBEDTLS_REMOVE_3DES_CIPHERSUITES + +/** + * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED + * + * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve + * module. By default all supported curves are enabled. + * + * Comment macros to disable the curve and functions for it + */ +/* Short Weierstrass curves (supporting ECP, ECDH, ECDSA) */ +//#define MBEDTLS_ECP_DP_SECP192R1_ENABLED +//#define MBEDTLS_ECP_DP_SECP224R1_ENABLED +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +//#define MBEDTLS_ECP_DP_SECP384R1_ENABLED +//#define MBEDTLS_ECP_DP_SECP521R1_ENABLED +//#define MBEDTLS_ECP_DP_SECP192K1_ENABLED +//#define MBEDTLS_ECP_DP_SECP224K1_ENABLED +//#define MBEDTLS_ECP_DP_SECP256K1_ENABLED +//#define MBEDTLS_ECP_DP_BP256R1_ENABLED +//#define MBEDTLS_ECP_DP_BP384R1_ENABLED +//#define MBEDTLS_ECP_DP_BP512R1_ENABLED +/* Montgomery curves (supporting ECP) */ +//#define MBEDTLS_ECP_DP_CURVE25519_ENABLED +//#define MBEDTLS_ECP_DP_CURVE448_ENABLED + +/** + * \def MBEDTLS_ECP_NIST_OPTIM + * + * Enable specific 'modulo p' routines for each NIST prime. + * Depending on the prime and architecture, makes operations 4 to 8 times + * faster on the corresponding curve. + * + * Comment this macro to disable NIST curves optimisation. + */ +#define MBEDTLS_ECP_NIST_OPTIM + +/** + * \def MBEDTLS_ECP_NO_INTERNAL_RNG + * + * When this option is disabled, mbedtls_ecp_mul() will make use of an + * internal RNG when called with a NULL \c f_rng argument, in order to protect + * against some side-channel attacks. + * + * This protection introduces a dependency of the ECP module on one of the + * DRBG modules. For very constrained implementations that don't require this + * protection (for example, because you're only doing signature verification, + * so not manipulating any secret, or because local/physical side-channel + * attacks are outside your threat model), it might be desirable to get rid of + * that dependency. + * + * \warning Enabling this option makes some uses of ECP vulnerable to some + * side-channel attacks. Only enable it if you know that's not a problem for + * your use case. + * + * Uncomment this macro to disable some counter-measures in ECP. + */ +//#define MBEDTLS_ECP_NO_INTERNAL_RNG + +/** + * \def MBEDTLS_ECP_RESTARTABLE + * + * Enable "non-blocking" ECC operations that can return early and be resumed. + * + * This allows various functions to pause by returning + * #MBEDTLS_ERR_ECP_IN_PROGRESS (or, for functions in the SSL module, + * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) and then be called later again in + * order to further progress and eventually complete their operation. This is + * controlled through mbedtls_ecp_set_max_ops() which limits the maximum + * number of ECC operations a function may perform before pausing; see + * mbedtls_ecp_set_max_ops() for more information. + * + * This is useful in non-threaded environments if you want to avoid blocking + * for too long on ECC (and, hence, X.509 or SSL/TLS) operations. + * + * Uncomment this macro to enable restartable ECC computations. + * + * \note This option only works with the default software implementation of + * elliptic curve functionality. It is incompatible with + * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT, MBEDTLS_ECDSA_XXX_ALT + * and MBEDTLS_ECDH_LEGACY_CONTEXT. + */ +//#define MBEDTLS_ECP_RESTARTABLE + +/** + * \def MBEDTLS_ECDH_LEGACY_CONTEXT + * + * Use a backward compatible ECDH context. + * + * Mbed TLS supports two formats for ECDH contexts (#mbedtls_ecdh_context + * defined in `ecdh.h`). For most applications, the choice of format makes + * no difference, since all library functions can work with either format, + * except that the new format is incompatible with MBEDTLS_ECP_RESTARTABLE. + + * The new format used when this option is disabled is smaller + * (56 bytes on a 32-bit platform). In future versions of the library, it + * will support alternative implementations of ECDH operations. + * The new format is incompatible with applications that access + * context fields directly and with restartable ECP operations. + * + * Define this macro if you enable MBEDTLS_ECP_RESTARTABLE or if you + * want to access ECDH context fields directly. Otherwise you should + * comment out this macro definition. + * + * This option has no effect if #MBEDTLS_ECDH_C is not enabled. + * + * \note This configuration option is experimental. Future versions of the + * library may modify the way the ECDH context layout is configured + * and may modify the layout of the new context type. + */ +//#define MBEDTLS_ECDH_LEGACY_CONTEXT + +/** + * \def MBEDTLS_ECDSA_DETERMINISTIC + * + * Enable deterministic ECDSA (RFC 6979). + * Standard ECDSA is "fragile" in the sense that lack of entropy when signing + * may result in a compromise of the long-term signing key. This is avoided by + * the deterministic variant. + * + * Requires: MBEDTLS_HMAC_DRBG_C, MBEDTLS_ECDSA_C + * + * Comment this macro to disable deterministic ECDSA. + */ +//#define MBEDTLS_ECDSA_DETERMINISTIC + +/** + * \def MBEDTLS_KEY_EXCHANGE_PSK_ENABLED + * + * Enable the PSK based ciphersuite modes in SSL / TLS. + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA + */ +//#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED + * + * Enable the DHE-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_DHM_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA + * + * \warning Using DHE constitutes a security risk as it + * is not possible to validate custom DH parameters. + * If possible, it is recommended users should consider + * preferring other methods of key exchange. + * See dhm.h for more details. + * + */ +//#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED + * + * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA + */ +//#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED + * + * Enable the RSA-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA + */ +//#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED + * + * Enable the RSA-only based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 + */ +//#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED + * + * Enable the DHE-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_DHM_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + * + * \warning Using DHE constitutes a security risk as it + * is not possible to validate custom DH parameters. + * If possible, it is recommended users should consider + * preferring other methods of key exchange. + * See dhm.h for more details. + * + */ +//#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED + * + * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA + */ +#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + * + * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C, + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA + */ +#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + * + * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +//#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED + * + * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +//#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED + * + * Enable the ECJPAKE based ciphersuite modes in SSL / TLS. + * + * \warning This is currently experimental. EC J-PAKE support is based on the + * Thread v1.0.0 specification; incompatible changes to the specification + * might still happen. For this reason, this is disabled by default. + * + * Requires: MBEDTLS_ECJPAKE_C + * MBEDTLS_SHA256_C + * MBEDTLS_ECP_DP_SECP256R1_ENABLED + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 + */ +//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED + +/** + * \def MBEDTLS_PK_PARSE_EC_EXTENDED + * + * Enhance support for reading EC keys using variants of SEC1 not allowed by + * RFC 5915 and RFC 5480. + * + * Currently this means parsing the SpecifiedECDomain choice of EC + * parameters (only known groups are supported, not arbitrary domains, to + * avoid validation issues). + * + * Disable if you only need to support RFC 5915 + 5480 key formats. + */ +//#define MBEDTLS_PK_PARSE_EC_EXTENDED + +/** + * \def MBEDTLS_ERROR_STRERROR_DUMMY + * + * Enable a dummy error function to make use of mbedtls_strerror() in + * third party libraries easier when MBEDTLS_ERROR_C is disabled + * (no effect when MBEDTLS_ERROR_C is enabled). + * + * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're + * not using mbedtls_strerror() or error_strerror() in your application. + * + * Disable if you run into name conflicts and want to really remove the + * mbedtls_strerror() + */ +//#define MBEDTLS_ERROR_STRERROR_DUMMY + +/** + * \def MBEDTLS_GENPRIME + * + * Enable the prime-number generation code. + * + * Requires: MBEDTLS_BIGNUM_C + */ +#define MBEDTLS_GENPRIME + +/** + * \def MBEDTLS_FS_IO + * + * Enable functions that use the filesystem. + */ +//#define MBEDTLS_FS_IO + +/** + * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + * + * Do not add default entropy sources. These are the platform specific, + * mbedtls_timing_hardclock and HAVEGE based poll functions. + * + * This is useful to have more control over the added entropy sources in an + * application. + * + * Uncomment this macro to prevent loading of default entropy functions. + */ +//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + +/** + * \def MBEDTLS_NO_PLATFORM_ENTROPY + * + * Do not use built-in platform entropy functions. + * This is useful if your platform does not support + * standards like the /dev/urandom or Windows CryptoAPI. + * + * Uncomment this macro to disable the built-in platform entropy functions. + */ +#define MBEDTLS_NO_PLATFORM_ENTROPY + +/** + * \def MBEDTLS_ENTROPY_FORCE_SHA256 + * + * Force the entropy accumulator to use a SHA-256 accumulator instead of the + * default SHA-512 based one (if both are available). + * + * Requires: MBEDTLS_SHA256_C + * + * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option + * if you have performance concerns. + * + * This option is only useful if both MBEDTLS_SHA256_C and + * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used. + */ +#define MBEDTLS_ENTROPY_FORCE_SHA256 + +/** + * \def MBEDTLS_ENTROPY_NV_SEED + * + * Enable the non-volatile (NV) seed file-based entropy source. + * (Also enables the NV seed read/write functions in the platform layer) + * + * This is crucial (if not required) on systems that do not have a + * cryptographic entropy source (in hardware or kernel) available. + * + * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C + * + * \note The read/write functions that are used by the entropy source are + * determined in the platform layer, and can be modified at runtime and/or + * compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used. + * + * \note If you use the default implementation functions that read a seedfile + * with regular fopen(), please make sure you make a seedfile with the + * proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at + * least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from + * and written to or you will get an entropy source error! The default + * implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE + * bytes from the file. + * + * \note The entropy collector will write to the seed file before entropy is + * given to an external source, to update it. + */ +#define MBEDTLS_ENTROPY_NV_SEED + +/* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER + * + * Enable key identifiers that encode a key owner identifier. + * + * The owner of a key is identified by a value of type ::mbedtls_key_owner_id_t + * which is currently hard-coded to be int32_t. + * + * Note that this option is meant for internal use only and may be removed + * without notice. It is incompatible with MBEDTLS_USE_PSA_CRYPTO. + */ +//#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER + +/** + * \def MBEDTLS_MEMORY_DEBUG + * + * Enable debugging of buffer allocator memory issues. Automatically prints + * (to stderr) all (fatal) messages on memory allocation issues. Enables + * function for 'debug output' of allocated memory. + * + * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C + * + * Uncomment this macro to let the buffer allocator print out error messages. + */ +//#define MBEDTLS_MEMORY_DEBUG + +/** + * \def MBEDTLS_MEMORY_BACKTRACE + * + * Include backtrace information with each allocated block. + * + * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C + * GLIBC-compatible backtrace() an backtrace_symbols() support + * + * Uncomment this macro to include backtrace information + */ +//#define MBEDTLS_MEMORY_BACKTRACE + +/** + * \def MBEDTLS_PK_RSA_ALT_SUPPORT + * + * Support external private RSA keys (eg from a HSM) in the PK layer. + * + * Comment this macro to disable support for external private RSA keys. + */ +#define MBEDTLS_PK_RSA_ALT_SUPPORT + +/** + * \def MBEDTLS_PKCS1_V15 + * + * Enable support for PKCS#1 v1.5 encoding. + * + * Requires: MBEDTLS_RSA_C + * + * This enables support for PKCS#1 v1.5 operations. + */ +#define MBEDTLS_PKCS1_V15 + +/** + * \def MBEDTLS_PKCS1_V21 + * + * Enable support for PKCS#1 v2.1 encoding. + * + * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C + * + * This enables support for RSAES-OAEP and RSASSA-PSS operations. + */ +//#define MBEDTLS_PKCS1_V21 + +/** \def MBEDTLS_PSA_CRYPTO_CLIENT + * + * Enable support for PSA crypto client. + * + * \note This option allows to include the code necessary for a PSA + * crypto client when the PSA crypto implementation is not included in + * the library (MBEDTLS_PSA_CRYPTO_C disabled). The code included is the + * code to set and get PSA key attributes. + * The development of PSA drivers partially relying on the library to + * fulfill the hardware gaps is another possible usage of this option. + * + * \warning This interface is experimental and may change or be removed + * without notice. + */ +//#define MBEDTLS_PSA_CRYPTO_CLIENT + +/** \def MBEDTLS_PSA_CRYPTO_DRIVERS + * + * Enable support for the experimental PSA crypto driver interface. + * + * Requires: MBEDTLS_PSA_CRYPTO_C + * + * \warning This interface is experimental and may change or be removed + * without notice. + */ +//#define MBEDTLS_PSA_CRYPTO_DRIVERS + +/** \def MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG + * + * Make the PSA Crypto module use an external random generator provided + * by a driver, instead of Mbed TLS's entropy and DRBG modules. + * + * \note This random generator must deliver random numbers with cryptographic + * quality and high performance. It must supply unpredictable numbers + * with a uniform distribution. The implementation of this function + * is responsible for ensuring that the random generator is seeded + * with sufficient entropy. If you have a hardware TRNG which is slow + * or delivers non-uniform output, declare it as an entropy source + * with mbedtls_entropy_add_source() instead of enabling this option. + * + * If you enable this option, you must configure the type + * ::mbedtls_psa_external_random_context_t in psa/crypto_platform.h + * and define a function called mbedtls_psa_external_get_random() + * with the following prototype: + * ``` + * psa_status_t mbedtls_psa_external_get_random( + * mbedtls_psa_external_random_context_t *context, + * uint8_t *output, size_t output_size, size_t *output_length); + * ); + * ``` + * The \c context value is initialized to 0 before the first call. + * The function must fill the \c output buffer with \p output_size bytes + * of random data and set \c *output_length to \p output_size. + * + * Requires: MBEDTLS_PSA_CRYPTO_C + * + * \warning If you enable this option, code that uses the PSA cryptography + * interface will not use any of the entropy sources set up for + * the entropy module, nor the NV seed that MBEDTLS_ENTROPY_NV_SEED + * enables. + * + * \note This option is experimental and may be removed without notice. + */ +//#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG + +/** + * \def MBEDTLS_PSA_CRYPTO_SPM + * + * When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is built for SPM (Secure + * Partition Manager) integration which separates the code into two parts: a + * NSPE (Non-Secure Process Environment) and an SPE (Secure Process + * Environment). + * + * Module: library/psa_crypto.c + * Requires: MBEDTLS_PSA_CRYPTO_C + * + */ +//#define MBEDTLS_PSA_CRYPTO_SPM + +/** + * \def MBEDTLS_PSA_INJECT_ENTROPY + * + * Enable support for entropy injection at first boot. This feature is + * required on systems that do not have a built-in entropy source (TRNG). + * This feature is currently not supported on systems that have a built-in + * entropy source. + * + * Requires: MBEDTLS_PSA_CRYPTO_STORAGE_C, MBEDTLS_ENTROPY_NV_SEED + * + */ +//#define MBEDTLS_PSA_INJECT_ENTROPY + +/** + * \def MBEDTLS_RSA_NO_CRT + * + * Do not use the Chinese Remainder Theorem + * for the RSA private operation. + * + * Uncomment this macro to disable the use of CRT in RSA. + * + */ +//#define MBEDTLS_RSA_NO_CRT + +/** + * \def MBEDTLS_SELF_TEST + * + * Enable the checkup functions (*_self_test). + */ +//#define MBEDTLS_SELF_TEST + +/** + * \def MBEDTLS_SHA256_SMALLER + * + * Enable an implementation of SHA-256 that has lower ROM footprint but also + * lower performance. + * + * The default implementation is meant to be a reasonnable compromise between + * performance and size. This version optimizes more aggressively for size at + * the expense of performance. Eg on Cortex-M4 it reduces the size of + * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about + * 30%. + * + * Uncomment to enable the smaller implementation of SHA256. + */ +//#define MBEDTLS_SHA256_SMALLER + +/** + * \def MBEDTLS_SHA512_SMALLER + * + * Enable an implementation of SHA-512 that has lower ROM footprint but also + * lower performance. + * + * Uncomment to enable the smaller implementation of SHA512. + */ +//#define MBEDTLS_SHA512_SMALLER + +/** + * \def MBEDTLS_SHA512_NO_SHA384 + * + * Disable the SHA-384 option of the SHA-512 module. Use this to save some + * code size on devices that don't use SHA-384. + * + * Requires: MBEDTLS_SHA512_C + * + * Uncomment to disable SHA-384 + */ +//#define MBEDTLS_SHA512_NO_SHA384 + +/** + * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES + * + * Enable sending of alert messages in case of encountered errors as per RFC. + * If you choose not to send the alert messages, mbed TLS can still communicate + * with other servers, only debugging of failures is harder. + * + * The advantage of not sending alert messages, is that no information is given + * about reasons for failures thus preventing adversaries of gaining intel. + * + * Enable sending of all alert messages + */ +#define MBEDTLS_SSL_ALL_ALERT_MESSAGES + +/** + * \def MBEDTLS_SSL_RECORD_CHECKING + * + * Enable the function mbedtls_ssl_check_record() which can be used to check + * the validity and authenticity of an incoming record, to verify that it has + * not been seen before. These checks are performed without modifying the + * externally visible state of the SSL context. + * + * See mbedtls_ssl_check_record() for more information. + * + * Uncomment to enable support for record checking. + */ +//#define MBEDTLS_SSL_RECORD_CHECKING + +/** + * \def MBEDTLS_SSL_DTLS_CONNECTION_ID + * + * Enable support for the DTLS Connection ID extension + * (version draft-ietf-tls-dtls-connection-id-05, + * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05) + * which allows to identify DTLS connections across changes + * in the underlying transport. + * + * Setting this option enables the SSL APIs `mbedtls_ssl_set_cid()`, + * `mbedtls_ssl_get_peer_cid()` and `mbedtls_ssl_conf_cid()`. + * See the corresponding documentation for more information. + * + * \warning The Connection ID extension is still in draft state. + * We make no stability promises for the availability + * or the shape of the API controlled by this option. + * + * The maximum lengths of outgoing and incoming CIDs can be configured + * through the options + * - MBEDTLS_SSL_CID_OUT_LEN_MAX + * - MBEDTLS_SSL_CID_IN_LEN_MAX. + * + * Requires: MBEDTLS_SSL_PROTO_DTLS + * + * Uncomment to enable the Connection ID extension. + */ +//#define MBEDTLS_SSL_DTLS_CONNECTION_ID + +/** + * \def MBEDTLS_SSL_ASYNC_PRIVATE + * + * Enable asynchronous external private key operations in SSL. This allows + * you to configure an SSL connection to call an external cryptographic + * module to perform private key operations instead of performing the + * operation inside the library. + * + */ +//#define MBEDTLS_SSL_ASYNC_PRIVATE + +/** + * \def MBEDTLS_SSL_CONTEXT_SERIALIZATION + * + * Enable serialization of the TLS context structures, through use of the + * functions mbedtls_ssl_context_save() and mbedtls_ssl_context_load(). + * + * This pair of functions allows one side of a connection to serialize the + * context associated with the connection, then free or re-use that context + * while the serialized state is persisted elsewhere, and finally deserialize + * that state to a live context for resuming read/write operations on the + * connection. From a protocol perspective, the state of the connection is + * unaffected, in particular this is entirely transparent to the peer. + * + * Note: this is distinct from TLS session resumption, which is part of the + * protocol and fully visible by the peer. TLS session resumption enables + * establishing new connections associated to a saved session with shorter, + * lighter handshakes, while context serialization is a local optimization in + * handling a single, potentially long-lived connection. + * + * Enabling these APIs makes some SSL structures larger, as 64 extra bytes are + * saved after the handshake to allow for more efficient serialization, so if + * you don't need this feature you'll save RAM by disabling it. + * + * Comment to disable the context serialization APIs. + */ +//#define MBEDTLS_SSL_CONTEXT_SERIALIZATION + +/** + * \def MBEDTLS_SSL_DEBUG_ALL + * + * Enable the debug messages in SSL module for all issues. + * Debug messages have been disabled in some places to prevent timing + * attacks due to (unbalanced) debugging function calls. + * + * If you need all error reporting you should enable this during debugging, + * but remove this for production servers that should log as well. + * + * Uncomment this macro to report all debug messages on errors introducing + * a timing side-channel. + * + */ +//#define MBEDTLS_SSL_DEBUG_ALL + +/** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC + * + * Enable support for Encrypt-then-MAC, RFC 7366. + * + * This allows peers that both support it to use a more robust protection for + * ciphersuites using CBC, providing deep resistance against timing attacks + * on the padding or underlying cipher. + * + * This only affects CBC ciphersuites, and is useless if none is defined. + * + * Requires: MBEDTLS_SSL_PROTO_TLS1 or + * MBEDTLS_SSL_PROTO_TLS1_1 or + * MBEDTLS_SSL_PROTO_TLS1_2 + * + * Comment this macro to disable support for Encrypt-then-MAC + */ +#define MBEDTLS_SSL_ENCRYPT_THEN_MAC + +/** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET + * + * Enable support for RFC 7627: Session Hash and Extended Master Secret + * Extension. + * + * This was introduced as "the proper fix" to the Triple Handshake familiy of + * attacks, but it is recommended to always use it (even if you disable + * renegotiation), since it actually fixes a more fundamental issue in the + * original SSL/TLS design, and has implications beyond Triple Handshake. + * + * Requires: MBEDTLS_SSL_PROTO_TLS1 or + * MBEDTLS_SSL_PROTO_TLS1_1 or + * MBEDTLS_SSL_PROTO_TLS1_2 + * + * Comment this macro to disable support for Extended Master Secret. + */ +#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET + +/** + * \def MBEDTLS_SSL_FALLBACK_SCSV + * + * Enable support for RFC 7507: Fallback Signaling Cipher Suite Value (SCSV) + * for Preventing Protocol Downgrade Attacks. + * + * For servers, it is recommended to always enable this, unless you support + * only one version of TLS, or know for sure that none of your clients + * implements a fallback strategy. + * + * For clients, you only need this if you're using a fallback strategy, which + * is not recommended in the first place, unless you absolutely need it to + * interoperate with buggy (version-intolerant) servers. + * + * Comment this macro to disable support for FALLBACK_SCSV + */ +//#define MBEDTLS_SSL_FALLBACK_SCSV + +/** + * \def MBEDTLS_SSL_KEEP_PEER_CERTIFICATE + * + * This option controls the availability of the API mbedtls_ssl_get_peer_cert() + * giving access to the peer's certificate after completion of the handshake. + * + * Unless you need mbedtls_ssl_peer_cert() in your application, it is + * recommended to disable this option for reduced RAM usage. + * + * \note If this option is disabled, mbedtls_ssl_get_peer_cert() is still + * defined, but always returns \c NULL. + * + * \note This option has no influence on the protection against the + * triple handshake attack. Even if it is disabled, Mbed TLS will + * still ensure that certificates do not change during renegotiation, + * for exaple by keeping a hash of the peer's certificate. + * + * Comment this macro to disable storing the peer's certificate + * after the handshake. + */ +//#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE + +/** + * \def MBEDTLS_SSL_HW_RECORD_ACCEL + * + * Enable hooking functions in SSL module for hardware acceleration of + * individual records. + * + * \deprecated This option is deprecated and will be removed in a future + * version of Mbed TLS. + * + * Uncomment this macro to enable hooking functions. + */ +//#define MBEDTLS_SSL_HW_RECORD_ACCEL + +/** + * \def MBEDTLS_SSL_CBC_RECORD_SPLITTING + * + * Enable 1/n-1 record splitting for CBC mode in SSLv3 and TLS 1.0. + * + * This is a countermeasure to the BEAST attack, which also minimizes the risk + * of interoperability issues compared to sending 0-length records. + * + * Comment this macro to disable 1/n-1 record splitting. + */ +//#define MBEDTLS_SSL_CBC_RECORD_SPLITTING + +/** + * \def MBEDTLS_SSL_RENEGOTIATION + * + * Enable support for TLS renegotiation. + * + * The two main uses of renegotiation are (1) refresh keys on long-lived + * connections and (2) client authentication after the initial handshake. + * If you don't need renegotiation, it's probably better to disable it, since + * it has been associated with security issues in the past and is easy to + * misuse/misunderstand. + * + * Comment this to disable support for renegotiation. + * + * \note Even if this option is disabled, both client and server are aware + * of the Renegotiation Indication Extension (RFC 5746) used to + * prevent the SSL renegotiation attack (see RFC 5746 Sect. 1). + * (See \c mbedtls_ssl_conf_legacy_renegotiation for the + * configuration of this extension). + * + */ +//#define MBEDTLS_SSL_RENEGOTIATION + +/** + * \def MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO + * + * Enable support for receiving and parsing SSLv2 Client Hello messages for the + * SSL Server module (MBEDTLS_SSL_SRV_C). + * + * \deprecated This option is deprecated and will be removed in a future + * version of Mbed TLS. + * + * Uncomment this macro to enable support for SSLv2 Client Hello messages. + */ +//#define MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO + +/** + * \def MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE + * + * Pick the ciphersuite according to the client's preferences rather than ours + * in the SSL Server module (MBEDTLS_SSL_SRV_C). + * + * Uncomment this macro to respect client's ciphersuite order + */ +//#define MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE + +/** + * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH + * + * Enable support for RFC 6066 max_fragment_length extension in SSL. + * + * Comment this macro to disable support for the max_fragment_length extension + */ +#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH + +/** + * \def MBEDTLS_SSL_PROTO_SSL3 + * + * Enable support for SSL 3.0. + * + * Requires: MBEDTLS_MD5_C + * MBEDTLS_SHA1_C + * + * \deprecated This option is deprecated and will be removed in a future + * version of Mbed TLS. + * + * Comment this macro to disable support for SSL 3.0 + */ +//#define MBEDTLS_SSL_PROTO_SSL3 + +/** + * \def MBEDTLS_SSL_PROTO_TLS1 + * + * Enable support for TLS 1.0. + * + * Requires: MBEDTLS_MD5_C + * MBEDTLS_SHA1_C + * + * Comment this macro to disable support for TLS 1.0 + */ +//#define MBEDTLS_SSL_PROTO_TLS1 + +/** + * \def MBEDTLS_SSL_PROTO_TLS1_1 + * + * Enable support for TLS 1.1 (and DTLS 1.0 if DTLS is enabled). + * + * Requires: MBEDTLS_MD5_C + * MBEDTLS_SHA1_C + * + * Comment this macro to disable support for TLS 1.1 / DTLS 1.0 + */ +//#define MBEDTLS_SSL_PROTO_TLS1_1 + +/** + * \def MBEDTLS_SSL_PROTO_TLS1_2 + * + * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled). + * + * Requires: MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C + * (Depends on ciphersuites) + * + * Comment this macro to disable support for TLS 1.2 / DTLS 1.2 + */ +#define MBEDTLS_SSL_PROTO_TLS1_2 + +/** + * \def MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL + * + * This macro is used to selectively enable experimental parts + * of the code that contribute to the ongoing development of + * the prototype TLS 1.3 and DTLS 1.3 implementation, and provide + * no other purpose. + * + * \warning TLS 1.3 and DTLS 1.3 aren't yet supported in Mbed TLS, + * and no feature exposed through this macro is part of the + * public API. In particular, features under the control + * of this macro are experimental and don't come with any + * stability guarantees. + * + * Uncomment this macro to enable experimental and partial + * functionality specific to TLS 1.3. + */ +//#define MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL + +/** + * \def MBEDTLS_SSL_PROTO_DTLS + * + * Enable support for DTLS (all available versions). + * + * Enable this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0, + * and/or this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2. + * + * Requires: MBEDTLS_SSL_PROTO_TLS1_1 + * or MBEDTLS_SSL_PROTO_TLS1_2 + * + * Comment this macro to disable support for DTLS + */ +//#define MBEDTLS_SSL_PROTO_DTLS + +/** + * \def MBEDTLS_SSL_ALPN + * + * Enable support for RFC 7301 Application Layer Protocol Negotiation. + * + * Comment this macro to disable support for ALPN. + */ +//#define MBEDTLS_SSL_ALPN + +/** + * \def MBEDTLS_SSL_DTLS_ANTI_REPLAY + * + * Enable support for the anti-replay mechanism in DTLS. + * + * Requires: MBEDTLS_SSL_TLS_C + * MBEDTLS_SSL_PROTO_DTLS + * + * \warning Disabling this is often a security risk! + * See mbedtls_ssl_conf_dtls_anti_replay() for details. + * + * Comment this to disable anti-replay in DTLS. + */ +//#define MBEDTLS_SSL_DTLS_ANTI_REPLAY + +/** + * \def MBEDTLS_SSL_DTLS_HELLO_VERIFY + * + * Enable support for HelloVerifyRequest on DTLS servers. + * + * This feature is highly recommended to prevent DTLS servers being used as + * amplifiers in DoS attacks against other hosts. It should always be enabled + * unless you know for sure amplification cannot be a problem in the + * environment in which your server operates. + * + * \warning Disabling this can ba a security risk! (see above) + * + * Requires: MBEDTLS_SSL_PROTO_DTLS + * + * Comment this to disable support for HelloVerifyRequest. + */ +//#define MBEDTLS_SSL_DTLS_HELLO_VERIFY + +/** + * \def MBEDTLS_SSL_DTLS_SRTP + * + * Enable support for negotiation of DTLS-SRTP (RFC 5764) + * through the use_srtp extension. + * + * \note This feature provides the minimum functionality required + * to negotiate the use of DTLS-SRTP and to allow the derivation of + * the associated SRTP packet protection key material. + * In particular, the SRTP packet protection itself, as well as the + * demultiplexing of RTP and DTLS packets at the datagram layer + * (see Section 5 of RFC 5764), are not handled by this feature. + * Instead, after successful completion of a handshake negotiating + * the use of DTLS-SRTP, the extended key exporter API + * mbedtls_ssl_conf_export_keys_ext_cb() should be used to implement + * the key exporter described in Section 4.2 of RFC 5764 and RFC 5705 + * (this is implemented in the SSL example programs). + * The resulting key should then be passed to an SRTP stack. + * + * Setting this option enables the runtime API + * mbedtls_ssl_conf_dtls_srtp_protection_profiles() + * through which the supported DTLS-SRTP protection + * profiles can be configured. You must call this API at + * runtime if you wish to negotiate the use of DTLS-SRTP. + * + * Requires: MBEDTLS_SSL_PROTO_DTLS + * + * Uncomment this to enable support for use_srtp extension. + */ +//#define MBEDTLS_SSL_DTLS_SRTP + +/** + * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE + * + * Enable server-side support for clients that reconnect from the same port. + * + * Some clients unexpectedly close the connection and try to reconnect using the + * same source port. This needs special support from the server to handle the + * new connection securely, as described in section 4.2.8 of RFC 6347. This + * flag enables that support. + * + * Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY + * + * Comment this to disable support for clients reusing the source port. + */ +//#define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE + +/** + * \def MBEDTLS_SSL_DTLS_BADMAC_LIMIT + * + * Enable support for a limit of records with bad MAC. + * + * See mbedtls_ssl_conf_dtls_badmac_limit(). + * + * Requires: MBEDTLS_SSL_PROTO_DTLS + */ +//#define MBEDTLS_SSL_DTLS_BADMAC_LIMIT + +/** + * \def MBEDTLS_SSL_SESSION_TICKETS + * + * Enable support for RFC 5077 session tickets in SSL. + * Client-side, provides full support for session tickets (maintenance of a + * session store remains the responsibility of the application, though). + * Server-side, you also need to provide callbacks for writing and parsing + * tickets, including authenticated encryption and key management. Example + * callbacks are provided by MBEDTLS_SSL_TICKET_C. + * + * Comment this macro to disable support for SSL session tickets + */ +//#define MBEDTLS_SSL_SESSION_TICKETS + +/** + * \def MBEDTLS_SSL_EXPORT_KEYS + * + * Enable support for exporting key block and master secret. + * This is required for certain users of TLS, e.g. EAP-TLS. + * + * Comment this macro to disable support for key export + */ +//#define MBEDTLS_SSL_EXPORT_KEYS + +/** + * \def MBEDTLS_SSL_SERVER_NAME_INDICATION + * + * Enable support for RFC 6066 server name indication (SNI) in SSL. + * + * Requires: MBEDTLS_X509_CRT_PARSE_C + * + * Comment this macro to disable support for server name indication in SSL + */ +#define MBEDTLS_SSL_SERVER_NAME_INDICATION + +/** + * \def MBEDTLS_SSL_TRUNCATED_HMAC + * + * Enable support for RFC 6066 truncated HMAC in SSL. + * + * Comment this macro to disable support for truncated HMAC in SSL + */ +//#define MBEDTLS_SSL_TRUNCATED_HMAC + +/** + * \def MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT + * + * Fallback to old (pre-2.7), non-conforming implementation of the truncated + * HMAC extension which also truncates the HMAC key. Note that this option is + * only meant for a transitory upgrade period and will be removed in a future + * version of the library. + * + * \warning The old implementation is non-compliant and has a security weakness + * (2^80 brute force attack on the HMAC key used for a single, + * uninterrupted connection). This should only be enabled temporarily + * when (1) the use of truncated HMAC is essential in order to save + * bandwidth, and (2) the peer is an Mbed TLS stack that doesn't use + * the fixed implementation yet (pre-2.7). + * + * \deprecated This option is deprecated and will be removed in a + * future version of Mbed TLS. + * + * Uncomment to fallback to old, non-compliant truncated HMAC implementation. + * + * Requires: MBEDTLS_SSL_TRUNCATED_HMAC + */ +//#define MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT + +/** + * \def MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH + * + * When this option is enabled, the SSL buffer will be resized automatically + * based on the negotiated maximum fragment length in each direction. + * + * Requires: MBEDTLS_SSL_MAX_FRAGMENT_LENGTH + */ +//#define MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH + +/** + * \def MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN + * + * Enable testing of the constant-flow nature of some sensitive functions with + * clang's MemorySanitizer. This causes some existing tests to also test + * this non-functional property of the code under test. + * + * This setting requires compiling with clang -fsanitize=memory. The test + * suites can then be run normally. + * + * \warning This macro is only used for extended testing; it is not considered + * part of the library's API, so it may change or disappear at any time. + * + * Uncomment to enable testing of the constant-flow nature of selected code. + */ +//#define MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN + +/** + * \def MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND + * + * Enable testing of the constant-flow nature of some sensitive functions with + * valgrind's memcheck tool. This causes some existing tests to also test + * this non-functional property of the code under test. + * + * This setting requires valgrind headers for building, and is only useful for + * testing if the tests suites are run with valgrind's memcheck. This can be + * done for an individual test suite with 'valgrind ./test_suite_xxx', or when + * using CMake, this can be done for all test suites with 'make memcheck'. + * + * \warning This macro is only used for extended testing; it is not considered + * part of the library's API, so it may change or disappear at any time. + * + * Uncomment to enable testing of the constant-flow nature of selected code. + */ +//#define MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND + +/** + * \def MBEDTLS_TEST_HOOKS + * + * Enable features for invasive testing such as introspection functions and + * hooks for fault injection. This enables additional unit tests. + * + * Merely enabling this feature should not change the behavior of the product. + * It only adds new code, and new branching points where the default behavior + * is the same as when this feature is disabled. + * However, this feature increases the attack surface: there is an added + * risk of vulnerabilities, and more gadgets that can make exploits easier. + * Therefore this feature must never be enabled in production. + * + * See `docs/architecture/testing/mbed-crypto-invasive-testing.md` for more + * information. + * + * Uncomment to enable invasive tests. + */ +//#define MBEDTLS_TEST_HOOKS + +/** + * \def MBEDTLS_THREADING_ALT + * + * Provide your own alternate threading implementation. + * + * Requires: MBEDTLS_THREADING_C + * + * Uncomment this to allow your own alternate threading implementation. + */ +#define MBEDTLS_THREADING_ALT + +/** + * \def MBEDTLS_THREADING_PTHREAD + * + * Enable the pthread wrapper layer for the threading layer. + * + * Requires: MBEDTLS_THREADING_C + * + * Uncomment this to enable pthread mutexes. + */ +//#define MBEDTLS_THREADING_PTHREAD + +/** + * \def MBEDTLS_USE_PSA_CRYPTO + * + * Make the X.509 and TLS library use PSA for cryptographic operations, and + * enable new APIs for using keys handled by PSA Crypto. + * + * \note Development of this option is currently in progress, and parts of Mbed + * TLS's X.509 and TLS modules are not ported to PSA yet. However, these parts + * will still continue to work as usual, so enabling this option should not + * break backwards compatibility. + * + * \warning The PSA Crypto API is in beta stage. While you're welcome to + * experiment using it, incompatible API changes are still possible, and some + * parts may not have reached the same quality as the rest of Mbed TLS yet. + * + * \warning This option enables new Mbed TLS APIs that are dependent on the + * PSA Crypto API, so can't come with the same stability guarantees as the + * rest of the Mbed TLS APIs. You're welcome to experiment with them, but for + * now, access to these APIs is opt-in (via enabling the present option), in + * order to clearly differentiate them from the stable Mbed TLS APIs. + * + * Requires: MBEDTLS_PSA_CRYPTO_C. + * + * Uncomment this to enable internal use of PSA Crypto and new associated APIs. + */ +//#define MBEDTLS_USE_PSA_CRYPTO + +/** + * \def MBEDTLS_PSA_CRYPTO_CONFIG + * + * This setting allows support for cryptographic mechanisms through the PSA + * API to be configured separately from support through the mbedtls API. + * + * Uncomment this to enable use of PSA Crypto configuration settings which + * can be found in include/psa/crypto_config.h. + * + * If you enable this option and write your own configuration file, you must + * include mbedtls/config_psa.h in your configuration file. The default + * provided mbedtls/config.h contains the necessary inclusion. + * + * This feature is still experimental and is not ready for production since + * it is not completed. + */ +//#define MBEDTLS_PSA_CRYPTO_CONFIG + +/** + * \def MBEDTLS_VERSION_FEATURES + * + * Allow run-time checking of compile-time enabled features. Thus allowing users + * to check at run-time if the library is for instance compiled with threading + * support via mbedtls_version_check_feature(). + * + * Requires: MBEDTLS_VERSION_C + * + * Comment this to disable run-time checking and save ROM space + */ +//#define MBEDTLS_VERSION_FEATURES + +/** + * \def MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 + * + * If set, the X509 parser will not break-off when parsing an X509 certificate + * and encountering an extension in a v1 or v2 certificate. + * + * Uncomment to prevent an error. + */ +//#define MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 + +/** + * \def MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION + * + * If set, the X509 parser will not break-off when parsing an X509 certificate + * and encountering an unknown critical extension. + * + * \warning Depending on your PKI use, enabling this can be a security risk! + * + * Uncomment to prevent an error. + */ +//#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION + +/** + * \def MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK + * + * If set, this enables the X.509 API `mbedtls_x509_crt_verify_with_ca_cb()` + * and the SSL API `mbedtls_ssl_conf_ca_cb()` which allow users to configure + * the set of trusted certificates through a callback instead of a linked + * list. + * + * This is useful for example in environments where a large number of trusted + * certificates is present and storing them in a linked list isn't efficient + * enough, or when the set of trusted certificates changes frequently. + * + * See the documentation of `mbedtls_x509_crt_verify_with_ca_cb()` and + * `mbedtls_ssl_conf_ca_cb()` for more information. + * + * Uncomment to enable trusted certificate callbacks. + */ +//#define MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK + +/** + * \def MBEDTLS_X509_CHECK_KEY_USAGE + * + * Enable verification of the keyUsage extension (CA and leaf certificates). + * + * Disabling this avoids problems with mis-issued and/or misused + * (intermediate) CA and leaf certificates. + * + * \warning Depending on your PKI use, disabling this can be a security risk! + * + * Comment to skip keyUsage checking for both CA and leaf certificates. + */ +#define MBEDTLS_X509_CHECK_KEY_USAGE + +/** + * \def MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE + * + * Enable verification of the extendedKeyUsage extension (leaf certificates). + * + * Disabling this avoids problems with mis-issued and/or misused certificates. + * + * \warning Depending on your PKI use, disabling this can be a security risk! + * + * Comment to skip extendedKeyUsage checking for certificates. + */ +#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE + +/** + * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT + * + * Enable parsing and verification of X.509 certificates, CRLs and CSRS + * signed with RSASSA-PSS (aka PKCS#1 v2.1). + * + * Comment this macro to disallow using RSASSA-PSS in certificates. + */ +//#define MBEDTLS_X509_RSASSA_PSS_SUPPORT + +/** + * \def MBEDTLS_ZLIB_SUPPORT + * + * If set, the SSL/TLS module uses ZLIB to support compression and + * decompression of packet data. + * + * \warning TLS-level compression MAY REDUCE SECURITY! See for example the + * CRIME attack. Before enabling this option, you should examine with care if + * CRIME or similar exploits may be applicable to your use case. + * + * \note Currently compression can't be used with DTLS. + * + * \deprecated This feature is deprecated and will be removed + * in the next major revision of the library. + * + * Used in: library/ssl_tls.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * This feature requires zlib library and headers to be present. + * + * Uncomment to enable use of ZLIB + */ +//#define MBEDTLS_ZLIB_SUPPORT +/* \} name SECTION: mbed TLS feature support */ + +/** + * \name SECTION: mbed TLS modules + * + * This section enables or disables entire modules in mbed TLS + * \{ + */ + +/** + * \def MBEDTLS_AESNI_C + * + * Enable AES-NI support on x86-64. + * + * Module: library/aesni.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_HAVE_ASM + * + * This modules adds support for the AES-NI instructions on x86-64 + */ +//#define MBEDTLS_AESNI_C + +/** + * \def MBEDTLS_AES_C + * + * Enable the AES block cipher. + * + * Module: library/aes.c + * Caller: library/cipher.c + * library/pem.c + * library/ctr_drbg.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA + * + * PEM_PARSE uses AES for decrypting encrypted keys. + */ +#define MBEDTLS_AES_C + +/** + * \def MBEDTLS_ARC4_C + * + * Enable the ARCFOUR stream cipher. + * + * Module: library/arc4.c + * Caller: library/cipher.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA + * MBEDTLS_TLS_RSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 + * MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA + * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA + * + * \warning ARC4 is considered a weak cipher and its use constitutes a + * security risk. If possible, we recommend avoidng dependencies on + * it, and considering stronger ciphers instead. + * + */ +//#define MBEDTLS_ARC4_C + +/** + * \def MBEDTLS_ASN1_PARSE_C + * + * Enable the generic ASN1 parser. + * + * Module: library/asn1.c + * Caller: library/x509.c + * library/dhm.c + * library/pkcs12.c + * library/pkcs5.c + * library/pkparse.c + */ +#define MBEDTLS_ASN1_PARSE_C + +/** + * \def MBEDTLS_ASN1_WRITE_C + * + * Enable the generic ASN1 writer. + * + * Module: library/asn1write.c + * Caller: library/ecdsa.c + * library/pkwrite.c + * library/x509_create.c + * library/x509write_crt.c + * library/x509write_csr.c + */ +#define MBEDTLS_ASN1_WRITE_C + +/** + * \def MBEDTLS_BASE64_C + * + * Enable the Base64 module. + * + * Module: library/base64.c + * Caller: library/pem.c + * + * This module is required for PEM support (required by X.509). + */ +#define MBEDTLS_BASE64_C + +/** + * \def MBEDTLS_BIGNUM_C + * + * Enable the multi-precision integer library. + * + * Module: library/bignum.c + * Caller: library/dhm.c + * library/ecp.c + * library/ecdsa.c + * library/rsa.c + * library/rsa_internal.c + * library/ssl_tls.c + * + * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. + */ +#define MBEDTLS_BIGNUM_C + +/** + * \def MBEDTLS_BLOWFISH_C + * + * Enable the Blowfish block cipher. + * + * Module: library/blowfish.c + */ +//#define MBEDTLS_BLOWFISH_C + +/** + * \def MBEDTLS_CAMELLIA_C + * + * Enable the Camellia block cipher. + * + * Module: library/camellia.c + * Caller: library/cipher.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 + */ +//#define MBEDTLS_CAMELLIA_C + +/** + * \def MBEDTLS_ARIA_C + * + * Enable the ARIA block cipher. + * + * Module: library/aria.c + * Caller: library/cipher.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * + * MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 + */ +//#define MBEDTLS_ARIA_C + +/** + * \def MBEDTLS_CCM_C + * + * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. + * + * Module: library/ccm.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C + * + * This module enables the AES-CCM ciphersuites, if other requisites are + * enabled as well. + */ +#define MBEDTLS_CCM_C + +/** + * \def MBEDTLS_CERTS_C + * + * Enable the test certificates. + * + * Module: library/certs.c + * Caller: + * + * This module is used for testing (ssl_client/server). + */ +//#define MBEDTLS_CERTS_C + +/** + * \def MBEDTLS_CHACHA20_C + * + * Enable the ChaCha20 stream cipher. + * + * Module: library/chacha20.c + */ +//#define MBEDTLS_CHACHA20_C + +/** + * \def MBEDTLS_CHACHAPOLY_C + * + * Enable the ChaCha20-Poly1305 AEAD algorithm. + * + * Module: library/chachapoly.c + * + * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C + */ +//#define MBEDTLS_CHACHAPOLY_C + +/** + * \def MBEDTLS_CIPHER_C + * + * Enable the generic cipher layer. + * + * Module: library/cipher.c + * Caller: library/ssl_tls.c + * + * Uncomment to enable generic cipher wrappers. + */ +#define MBEDTLS_CIPHER_C + +/** + * \def MBEDTLS_CMAC_C + * + * Enable the CMAC (Cipher-based Message Authentication Code) mode for block + * ciphers. + * + * Module: library/cmac.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C + * + */ +//#define MBEDTLS_CMAC_C + +/** + * \def MBEDTLS_CTR_DRBG_C + * + * Enable the CTR_DRBG AES-based random generator. + * The CTR_DRBG generator uses AES-256 by default. + * To use AES-128 instead, enable \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY above. + * + * \note To achieve a 256-bit security strength with CTR_DRBG, + * you must use AES-256 *and* use sufficient entropy. + * See ctr_drbg.h for more details. + * + * Module: library/ctr_drbg.c + * Caller: + * + * Requires: MBEDTLS_AES_C + * + * This module provides the CTR_DRBG AES random number generator. + */ +#define MBEDTLS_CTR_DRBG_C + +/** + * \def MBEDTLS_DEBUG_C + * + * Enable the debug functions. + * + * Module: library/debug.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * This module provides debugging functions. + */ +#define MBEDTLS_DEBUG_C + +/** + * \def MBEDTLS_DES_C + * + * Enable the DES block cipher. + * + * Module: library/des.c + * Caller: library/pem.c + * library/cipher.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA + * + * PEM_PARSE uses DES/3DES for decrypting encrypted keys. + * + * \warning DES is considered a weak cipher and its use constitutes a + * security risk. We recommend considering stronger ciphers instead. + */ +//#define MBEDTLS_DES_C + +/** + * \def MBEDTLS_DHM_C + * + * Enable the Diffie-Hellman-Merkle module. + * + * Module: library/dhm.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * This module is used by the following key exchanges: + * DHE-RSA, DHE-PSK + * + * \warning Using DHE constitutes a security risk as it + * is not possible to validate custom DH parameters. + * If possible, it is recommended users should consider + * preferring other methods of key exchange. + * See dhm.h for more details. + * + */ +//#define MBEDTLS_DHM_C + +/** + * \def MBEDTLS_ECDH_C + * + * Enable the elliptic curve Diffie-Hellman library. + * + * Module: library/ecdh.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK + * + * Requires: MBEDTLS_ECP_C + */ +#define MBEDTLS_ECDH_C + +/** + * \def MBEDTLS_ECDSA_C + * + * Enable the elliptic curve DSA library. + * + * Module: library/ecdsa.c + * Caller: + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA + * + * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C, + * and at least one MBEDTLS_ECP_DP_XXX_ENABLED for a + * short Weierstrass curve. + */ +#define MBEDTLS_ECDSA_C + +/** + * \def MBEDTLS_ECJPAKE_C + * + * Enable the elliptic curve J-PAKE library. + * + * \warning This is currently experimental. EC J-PAKE support is based on the + * Thread v1.0.0 specification; incompatible changes to the specification + * might still happen. For this reason, this is disabled by default. + * + * Module: library/ecjpake.c + * Caller: + * + * This module is used by the following key exchanges: + * ECJPAKE + * + * Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C + */ +//#define MBEDTLS_ECJPAKE_C + +/** + * \def MBEDTLS_ECP_C + * + * Enable the elliptic curve over GF(p) library. + * + * Module: library/ecp.c + * Caller: library/ecdh.c + * library/ecdsa.c + * library/ecjpake.c + * + * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED + */ +#define MBEDTLS_ECP_C + +/** + * \def MBEDTLS_ENTROPY_C + * + * Enable the platform-specific entropy code. + * + * Module: library/entropy.c + * Caller: + * + * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C + * + * This module provides a generic entropy pool + */ +#define MBEDTLS_ENTROPY_C + +/** + * \def MBEDTLS_ERROR_C + * + * Enable error code to error string conversion. + * + * Module: library/error.c + * Caller: + * + * This module enables mbedtls_strerror(). + */ +#define MBEDTLS_ERROR_C + +/** + * \def MBEDTLS_GCM_C + * + * Enable the Galois/Counter Mode (GCM). + * + * Module: library/gcm.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or MBEDTLS_ARIA_C + * + * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other + * requisites are enabled as well. + */ +#define MBEDTLS_GCM_C + +/** + * \def MBEDTLS_HAVEGE_C + * + * Enable the HAVEGE random generator. + * + * Warning: the HAVEGE random generator is not suitable for virtualized + * environments + * + * Warning: the HAVEGE random generator is dependent on timing and specific + * processor traits. It is therefore not advised to use HAVEGE as + * your applications primary random generator or primary entropy pool + * input. As a secondary input to your entropy pool, it IS able add + * the (limited) extra entropy it provides. + * + * Module: library/havege.c + * Caller: + * + * Requires: MBEDTLS_TIMING_C + * + * Uncomment to enable the HAVEGE random generator. + */ +//#define MBEDTLS_HAVEGE_C + +/** + * \def MBEDTLS_HKDF_C + * + * Enable the HKDF algorithm (RFC 5869). + * + * Module: library/hkdf.c + * Caller: + * + * Requires: MBEDTLS_MD_C + * + * This module adds support for the Hashed Message Authentication Code + * (HMAC)-based key derivation function (HKDF). + */ +#define MBEDTLS_HKDF_C + +/** + * \def MBEDTLS_HMAC_DRBG_C + * + * Enable the HMAC_DRBG random generator. + * + * Module: library/hmac_drbg.c + * Caller: + * + * Requires: MBEDTLS_MD_C + * + * Uncomment to enable the HMAC_DRBG random number geerator. + */ +//#define MBEDTLS_HMAC_DRBG_C + +/** + * \def MBEDTLS_NIST_KW_C + * + * Enable the Key Wrapping mode for 128-bit block ciphers, + * as defined in NIST SP 800-38F. Only KW and KWP modes + * are supported. At the moment, only AES is approved by NIST. + * + * Module: library/nist_kw.c + * + * Requires: MBEDTLS_AES_C and MBEDTLS_CIPHER_C + */ +//#define MBEDTLS_NIST_KW_C + +/** + * \def MBEDTLS_MD_C + * + * Enable the generic message digest layer. + * + * Module: library/md.c + * Caller: + * + * Uncomment to enable generic message digest wrappers. + */ +#define MBEDTLS_MD_C + +/** + * \def MBEDTLS_MD2_C + * + * Enable the MD2 hash algorithm. + * + * Module: library/md2.c + * Caller: + * + * Uncomment to enable support for (rare) MD2-signed X.509 certs. + * + * \warning MD2 is considered a weak message digest and its use constitutes a + * security risk. If possible, we recommend avoiding dependencies on + * it, and considering stronger message digests instead. + * + */ +//#define MBEDTLS_MD2_C + +/** + * \def MBEDTLS_MD4_C + * + * Enable the MD4 hash algorithm. + * + * Module: library/md4.c + * Caller: + * + * Uncomment to enable support for (rare) MD4-signed X.509 certs. + * + * \warning MD4 is considered a weak message digest and its use constitutes a + * security risk. If possible, we recommend avoiding dependencies on + * it, and considering stronger message digests instead. + * + */ +//#define MBEDTLS_MD4_C + +/** + * \def MBEDTLS_MD5_C + * + * Enable the MD5 hash algorithm. + * + * Module: library/md5.c + * Caller: library/md.c + * library/pem.c + * library/ssl_tls.c + * + * This module is required for SSL/TLS up to version 1.1, and for TLS 1.2 + * depending on the handshake parameters. Further, it is used for checking + * MD5-signed certificates, and for PBKDF1 when decrypting PEM-encoded + * encrypted keys. + * + * \warning MD5 is considered a weak message digest and its use constitutes a + * security risk. If possible, we recommend avoiding dependencies on + * it, and considering stronger message digests instead. + * + */ +//#define MBEDTLS_MD5_C + +/** + * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C + * + * Enable the buffer allocator implementation that makes use of a (stack) + * based buffer to 'allocate' dynamic memory. (replaces calloc() and free() + * calls) + * + * Module: library/memory_buffer_alloc.c + * + * Requires: MBEDTLS_PLATFORM_C + * MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS) + * + * Enable this module to enable the buffer memory allocator. + */ +//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C + +/** + * \def MBEDTLS_NET_C + * + * Enable the TCP and UDP over IPv6/IPv4 networking routines. + * + * \note This module only works on POSIX/Unix (including Linux, BSD and OS X) + * and Windows. For other platforms, you'll want to disable it, and write your + * own networking callbacks to be passed to \c mbedtls_ssl_set_bio(). + * + * \note See also our Knowledge Base article about porting to a new + * environment: + * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS + * + * Module: library/net_sockets.c + * + * This module provides networking routines. + */ +//#define MBEDTLS_NET_C + +/** + * \def MBEDTLS_OID_C + * + * Enable the OID database. + * + * Module: library/oid.c + * Caller: library/asn1write.c + * library/pkcs5.c + * library/pkparse.c + * library/pkwrite.c + * library/rsa.c + * library/x509.c + * library/x509_create.c + * library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * library/x509write_crt.c + * library/x509write_csr.c + * + * This modules translates between OIDs and internal values. + */ +#define MBEDTLS_OID_C + +/** + * \def MBEDTLS_PADLOCK_C + * + * Enable VIA Padlock support on x86. + * + * Module: library/padlock.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_HAVE_ASM + * + * This modules adds support for the VIA PadLock on x86. + */ +//#define MBEDTLS_PADLOCK_C + +/** + * \def MBEDTLS_PEM_PARSE_C + * + * Enable PEM decoding / parsing. + * + * Module: library/pem.c + * Caller: library/dhm.c + * library/pkparse.c + * library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * + * Requires: MBEDTLS_BASE64_C + * + * This modules adds support for decoding / parsing PEM files. + */ +#define MBEDTLS_PEM_PARSE_C + +/** + * \def MBEDTLS_PEM_WRITE_C + * + * Enable PEM encoding / writing. + * + * Module: library/pem.c + * Caller: library/pkwrite.c + * library/x509write_crt.c + * library/x509write_csr.c + * + * Requires: MBEDTLS_BASE64_C + * + * This modules adds support for encoding / writing PEM files. + */ +#define MBEDTLS_PEM_WRITE_C + +/** + * \def MBEDTLS_PK_C + * + * Enable the generic public (asymetric) key layer. + * + * Module: library/pk.c + * Caller: library/ssl_tls.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C + * + * Uncomment to enable generic public key wrappers. + */ +#define MBEDTLS_PK_C + +/** + * \def MBEDTLS_PK_PARSE_C + * + * Enable the generic public (asymetric) key parser. + * + * Module: library/pkparse.c + * Caller: library/x509_crt.c + * library/x509_csr.c + * + * Requires: MBEDTLS_PK_C + * + * Uncomment to enable generic public key parse functions. + */ +#define MBEDTLS_PK_PARSE_C + +/** + * \def MBEDTLS_PK_WRITE_C + * + * Enable the generic public (asymetric) key writer. + * + * Module: library/pkwrite.c + * Caller: library/x509write.c + * + * Requires: MBEDTLS_PK_C + * + * Uncomment to enable generic public key write functions. + */ +#define MBEDTLS_PK_WRITE_C + +/** + * \def MBEDTLS_PKCS5_C + * + * Enable PKCS#5 functions. + * + * Module: library/pkcs5.c + * + * Requires: MBEDTLS_MD_C + * + * This module adds support for the PKCS#5 functions. + */ +#define MBEDTLS_PKCS5_C + +/** + * \def MBEDTLS_PKCS11_C + * + * Enable wrapper for PKCS#11 smartcard support via the pkcs11-helper library. + * + * \deprecated This option is deprecated and will be removed in a future + * version of Mbed TLS. + * + * Module: library/pkcs11.c + * Caller: library/pk.c + * + * Requires: MBEDTLS_PK_C + * + * This module enables SSL/TLS PKCS #11 smartcard support. + * Requires the presence of the PKCS#11 helper library (libpkcs11-helper) + */ +//#define MBEDTLS_PKCS11_C + +/** + * \def MBEDTLS_PKCS12_C + * + * Enable PKCS#12 PBE functions. + * Adds algorithms for parsing PKCS#8 encrypted private keys + * + * Module: library/pkcs12.c + * Caller: library/pkparse.c + * + * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C, MBEDTLS_MD_C + * Can use: MBEDTLS_ARC4_C + * + * This module enables PKCS#12 functions. + */ +//#define MBEDTLS_PKCS12_C + +/** + * \def MBEDTLS_PLATFORM_C + * + * Enable the platform abstraction layer that allows you to re-assign + * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit(). + * + * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT + * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned + * above to be specified at runtime or compile time respectively. + * + * \note This abstraction layer must be enabled on Windows (including MSYS2) + * as other module rely on it for a fixed snprintf implementation. + * + * Module: library/platform.c + * Caller: Most other .c files + * + * This module enables abstraction of common (libc) functions. + */ +#define MBEDTLS_PLATFORM_C + +/** + * \def MBEDTLS_POLY1305_C + * + * Enable the Poly1305 MAC algorithm. + * + * Module: library/poly1305.c + * Caller: library/chachapoly.c + */ +//#define MBEDTLS_POLY1305_C + +/** + * \def MBEDTLS_PSA_CRYPTO_C + * + * Enable the Platform Security Architecture cryptography API. + * + * \warning The PSA Crypto API is still beta status. While you're welcome to + * experiment using it, incompatible API changes are still possible, and some + * parts may not have reached the same quality as the rest of Mbed TLS yet. + * + * Module: library/psa_crypto.c + * + * Requires: either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C, + * or MBEDTLS_HMAC_DRBG_C and MBEDTLS_ENTROPY_C, + * or MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG. + * + */ +//#define MBEDTLS_PSA_CRYPTO_C + +/** + * \def MBEDTLS_PSA_CRYPTO_SE_C + * + * Enable secure element support in the Platform Security Architecture + * cryptography API. + * + * \warning This feature is not yet suitable for production. It is provided + * for API evaluation and testing purposes only. + * + * Module: library/psa_crypto_se.c + * + * Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_PSA_CRYPTO_STORAGE_C + * + */ +//#define MBEDTLS_PSA_CRYPTO_SE_C + +/** + * \def MBEDTLS_PSA_CRYPTO_STORAGE_C + * + * Enable the Platform Security Architecture persistent key storage. + * + * Module: library/psa_crypto_storage.c + * + * Requires: MBEDTLS_PSA_CRYPTO_C, + * either MBEDTLS_PSA_ITS_FILE_C or a native implementation of + * the PSA ITS interface + */ +//#define MBEDTLS_PSA_CRYPTO_STORAGE_C + +/** + * \def MBEDTLS_PSA_ITS_FILE_C + * + * Enable the emulation of the Platform Security Architecture + * Internal Trusted Storage (PSA ITS) over files. + * + * Module: library/psa_its_file.c + * + * Requires: MBEDTLS_FS_IO + */ +//#define MBEDTLS_PSA_ITS_FILE_C + +/** + * \def MBEDTLS_RIPEMD160_C + * + * Enable the RIPEMD-160 hash algorithm. + * + * Module: library/ripemd160.c + * Caller: library/md.c + * + */ +//#define MBEDTLS_RIPEMD160_C + +/** + * \def MBEDTLS_RSA_C + * + * Enable the RSA public-key cryptosystem. + * + * Module: library/rsa.c + * library/rsa_internal.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * library/x509.c + * + * This module is used by the following key exchanges: + * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK + * + * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C + */ +#define MBEDTLS_RSA_C + +/** + * \def MBEDTLS_SHA1_C + * + * Enable the SHA1 cryptographic hash algorithm. + * + * Module: library/sha1.c + * Caller: library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * library/x509write_crt.c + * + * This module is required for SSL/TLS up to version 1.1, for TLS 1.2 + * depending on the handshake parameters, and for SHA1-signed certificates. + * + * \warning SHA-1 is considered a weak message digest and its use constitutes + * a security risk. If possible, we recommend avoiding dependencies + * on it, and considering stronger message digests instead. + * + */ +#define MBEDTLS_SHA1_C + +/** + * \def MBEDTLS_SHA256_C + * + * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. + * + * Module: library/sha256.c + * Caller: library/entropy.c + * library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * This module adds support for SHA-224 and SHA-256. + * This module is required for the SSL/TLS 1.2 PRF function. + */ +#define MBEDTLS_SHA256_C + +/** + * \def MBEDTLS_SHA512_C + * + * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. + * + * Module: library/sha512.c + * Caller: library/entropy.c + * library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * This module adds support for SHA-384 and SHA-512. + */ +//#define MBEDTLS_SHA512_C + +/** + * \def MBEDTLS_SSL_CACHE_C + * + * Enable simple SSL cache implementation. + * + * Module: library/ssl_cache.c + * Caller: + * + * Requires: MBEDTLS_SSL_CACHE_C + */ +//#define MBEDTLS_SSL_CACHE_C + +/** + * \def MBEDTLS_SSL_COOKIE_C + * + * Enable basic implementation of DTLS cookies for hello verification. + * + * Module: library/ssl_cookie.c + * Caller: + */ +//#define MBEDTLS_SSL_COOKIE_C + +/** + * \def MBEDTLS_SSL_TICKET_C + * + * Enable an implementation of TLS server-side callbacks for session tickets. + * + * Module: library/ssl_ticket.c + * Caller: + * + * Requires: MBEDTLS_CIPHER_C + */ +//#define MBEDTLS_SSL_TICKET_C + +/** + * \def MBEDTLS_SSL_CLI_C + * + * Enable the SSL/TLS client code. + * + * Module: library/ssl_cli.c + * Caller: + * + * Requires: MBEDTLS_SSL_TLS_C + * + * This module is required for SSL/TLS client support. + */ +#define MBEDTLS_SSL_CLI_C + +/** + * \def MBEDTLS_SSL_SRV_C + * + * Enable the SSL/TLS server code. + * + * Module: library/ssl_srv.c + * Caller: + * + * Requires: MBEDTLS_SSL_TLS_C + * + * This module is required for SSL/TLS server support. + */ +//#define MBEDTLS_SSL_SRV_C + +/** + * \def MBEDTLS_SSL_TLS_C + * + * Enable the generic SSL/TLS code. + * + * Module: library/ssl_tls.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C + * and at least one of the MBEDTLS_SSL_PROTO_XXX defines + * + * This module is required for SSL/TLS. + */ +#define MBEDTLS_SSL_TLS_C + +/** + * \def MBEDTLS_THREADING_C + * + * Enable the threading abstraction layer. + * By default mbed TLS assumes it is used in a non-threaded environment or that + * contexts are not shared between threads. If you do intend to use contexts + * between threads, you will need to enable this layer to prevent race + * conditions. See also our Knowledge Base article about threading: + * https://tls.mbed.org/kb/development/thread-safety-and-multi-threading + * + * Module: library/threading.c + * + * This allows different threading implementations (self-implemented or + * provided). + * + * You will have to enable either MBEDTLS_THREADING_ALT or + * MBEDTLS_THREADING_PTHREAD. + * + * Enable this layer to allow use of mutexes within mbed TLS + */ +#define MBEDTLS_THREADING_C + +/** + * \def MBEDTLS_TIMING_C + * + * Enable the semi-portable timing interface. + * + * \note The provided implementation only works on POSIX/Unix (including Linux, + * BSD and OS X) and Windows. On other platforms, you can either disable that + * module and provide your own implementations of the callbacks needed by + * \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and provide + * your own implementation of the whole module by setting + * \c MBEDTLS_TIMING_ALT in the current file. + * + * \note See also our Knowledge Base article about porting to a new + * environment: + * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS + * + * Module: library/timing.c + * Caller: library/havege.c + * + * This module is used by the HAVEGE random number generator. + */ +//#define MBEDTLS_TIMING_C + +/** + * \def MBEDTLS_VERSION_C + * + * Enable run-time version information. + * + * Module: library/version.c + * + * This module provides run-time version information. + */ +//#define MBEDTLS_VERSION_C + +/** + * \def MBEDTLS_X509_USE_C + * + * Enable X.509 core for using certificates. + * + * Module: library/x509.c + * Caller: library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * + * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, + * MBEDTLS_PK_PARSE_C + * + * This module is required for the X.509 parsing modules. + */ +#define MBEDTLS_X509_USE_C + +/** + * \def MBEDTLS_X509_CRT_PARSE_C + * + * Enable X.509 certificate parsing. + * + * Module: library/x509_crt.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * Requires: MBEDTLS_X509_USE_C + * + * This module is required for X.509 certificate parsing. + */ +#define MBEDTLS_X509_CRT_PARSE_C + +/** + * \def MBEDTLS_X509_CRL_PARSE_C + * + * Enable X.509 CRL parsing. + * + * Module: library/x509_crl.c + * Caller: library/x509_crt.c + * + * Requires: MBEDTLS_X509_USE_C + * + * This module is required for X.509 CRL parsing. + */ +//#define MBEDTLS_X509_CRL_PARSE_C + +/** + * \def MBEDTLS_X509_CSR_PARSE_C + * + * Enable X.509 Certificate Signing Request (CSR) parsing. + * + * Module: library/x509_csr.c + * Caller: library/x509_crt_write.c + * + * Requires: MBEDTLS_X509_USE_C + * + * This module is used for reading X.509 certificate request. + */ +#define MBEDTLS_X509_CSR_PARSE_C + +/** + * \def MBEDTLS_X509_CREATE_C + * + * Enable X.509 core for creating certificates. + * + * Module: library/x509_create.c + * + * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_WRITE_C + * + * This module is the basis for creating X.509 certificates and CSRs. + */ +#define MBEDTLS_X509_CREATE_C + +/** + * \def MBEDTLS_X509_CRT_WRITE_C + * + * Enable creating X.509 certificates. + * + * Module: library/x509_crt_write.c + * + * Requires: MBEDTLS_X509_CREATE_C + * + * This module is required for X.509 certificate creation. + */ +//#define MBEDTLS_X509_CRT_WRITE_C + +/** + * \def MBEDTLS_X509_CSR_WRITE_C + * + * Enable creating X.509 Certificate Signing Requests (CSR). + * + * Module: library/x509_csr_write.c + * + * Requires: MBEDTLS_X509_CREATE_C + * + * This module is required for X.509 certificate request writing. + */ +#define MBEDTLS_X509_CSR_WRITE_C + +/** + * \def MBEDTLS_XTEA_C + * + * Enable the XTEA block cipher. + * + * Module: library/xtea.c + * Caller: + */ +//#define MBEDTLS_XTEA_C + +/* \} name SECTION: mbed TLS modules */ + +/** + * \name SECTION: Module configuration options + * + * This section allows for the setting of module specific sizes and + * configuration options. The default values are already present in the + * relevant header files and should suffice for the regular use cases. + * + * Our advice is to enable options and change their values here + * only if you have a good reason and know the consequences. + * + * Please check the respective header file for documentation on these + * parameters (to prevent duplicate documentation). + * \{ + */ + +/* MPI / BIGNUM options */ +//#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum window size used. */ +//#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ + +/* CTR_DRBG options */ +//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with +// SHA-512, 32 with SHA-256) */ #define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is +// performed by default */ #define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input +// bytes */ #define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* HMAC_DRBG options */ +//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* ECP options */ +//#define MBEDTLS_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ +//#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ +//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ + +/* Entropy options */ +//#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ +//#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ +//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware +// entropy source mbedtls_hardware_poll() before entropy is released */ + +/* Memory buffer allocator options */ +//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ + +/* Platform options */ +//#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is +// defined. Don't define if no header is needed. */ #define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default +// allocator to use, can be undefined */ #define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can +// be undefined */ #define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must +// be enabled */ #define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ +/* Note: your snprintf must correctly zero-terminate the buffer! */ +//#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to +// use, can be undefined */ #define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default +// nv_seed_write function to use, can be undefined */ #define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed +// file to read/write with default implementation */ + +/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */ +/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */ +//#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. +// MBEDTLS_HAVE_TIME must be enabled */ #define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to +// use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ #define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< +// Default fprintf macro to use, can be undefined */ #define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default +// printf macro to use, can be undefined */ +/* Note: your snprintf must correctly zero-terminate the buffer! */ +//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_VSNPRINTF_MACRO vsnprintf /**< Default vsnprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to +// use, can be undefined */ #define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< +// Default nv_seed_write function to use, can be undefined */ + +/** + * \brief This macro is invoked by the library when an invalid parameter + * is detected that is only checked with #MBEDTLS_CHECK_PARAMS + * (see the documentation of that option for context). + * + * When you leave this undefined here, the library provides + * a default definition. If the macro #MBEDTLS_CHECK_PARAMS_ASSERT + * is defined, the default definition is `assert(cond)`, + * otherwise the default definition calls a function + * mbedtls_param_failed(). This function is declared in + * `platform_util.h` for the benefit of the library, but + * you need to define in your application. + * + * When you define this here, this replaces the default + * definition in platform_util.h (which no longer declares the + * function mbedtls_param_failed()) and it is your responsibility + * to make sure this macro expands to something suitable (in + * particular, that all the necessary declarations are visible + * from within the library - you can ensure that by providing + * them in this file next to the macro definition). + * If you define this macro to call `assert`, also define + * #MBEDTLS_CHECK_PARAMS_ASSERT so that library source files + * include ``. + * + * Note that you may define this macro to expand to nothing, in + * which case you don't have to worry about declarations or + * definitions. However, you will then be notified about invalid + * parameters only in non-void functions, and void function will + * just silently return early on invalid parameters, which + * partially negates the benefits of enabling + * #MBEDTLS_CHECK_PARAMS in the first place, so is discouraged. + * + * \param cond The expression that should evaluate to true, but doesn't. + */ +//#define MBEDTLS_PARAM_FAILED( cond ) assert( cond ) + +/* PSA options */ +/** + * Use HMAC_DRBG with the specified hash algorithm for HMAC_DRBG for the + * PSA crypto subsystem. + * + * If this option is unset: + * - If CTR_DRBG is available, the PSA subsystem uses it rather than HMAC_DRBG. + * - Otherwise, the PSA subsystem uses HMAC_DRBG with either + * #MBEDTLS_MD_SHA512 or #MBEDTLS_MD_SHA256 based on availability and + * on unspecified heuristics. + */ +//#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256 + +/** \def MBEDTLS_PSA_KEY_SLOT_COUNT + * Restrict the PSA library to supporting a maximum amount of simultaneously + * loaded keys. A loaded key is a key stored by the PSA Crypto core as a + * volatile key, or a persistent key which is loaded temporarily by the + * library as part of a crypto operation in flight. + * + * If this option is unset, the library will fall back to a default value of + * 32 keys. + */ +//#define MBEDTLS_PSA_KEY_SLOT_COUNT 32 + +/* SSL Cache options */ +//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ +//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ + +/* SSL options */ + +/** \def MBEDTLS_SSL_MAX_CONTENT_LEN + * + * Maximum length (in bytes) of incoming and outgoing plaintext fragments. + * + * This determines the size of both the incoming and outgoing TLS I/O buffers + * in such a way that both are capable of holding the specified amount of + * plaintext data, regardless of the protection mechanism used. + * + * To configure incoming and outgoing I/O buffers separately, use + * #MBEDTLS_SSL_IN_CONTENT_LEN and #MBEDTLS_SSL_OUT_CONTENT_LEN, + * which overwrite the value set by this option. + * + * \note When using a value less than the default of 16KB on the client, it is + * recommended to use the Maximum Fragment Length (MFL) extension to + * inform the server about this limitation. On the server, there + * is no supported, standardized way of informing the client about + * restriction on the maximum size of incoming messages, and unless + * the limitation has been communicated by other means, it is recommended + * to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN + * while keeping the default value of 16KB for the incoming buffer. + * + * Uncomment to set the maximum plaintext size of both + * incoming and outgoing I/O buffers. + */ +#define MBEDTLS_SSL_MAX_CONTENT_LEN 8192 + +/** \def MBEDTLS_SSL_IN_CONTENT_LEN + * + * Maximum length (in bytes) of incoming plaintext fragments. + * + * This determines the size of the incoming TLS I/O buffer in such a way + * that it is capable of holding the specified amount of plaintext data, + * regardless of the protection mechanism used. + * + * If this option is undefined, it inherits its value from + * #MBEDTLS_SSL_MAX_CONTENT_LEN. + * + * \note When using a value less than the default of 16KB on the client, it is + * recommended to use the Maximum Fragment Length (MFL) extension to + * inform the server about this limitation. On the server, there + * is no supported, standardized way of informing the client about + * restriction on the maximum size of incoming messages, and unless + * the limitation has been communicated by other means, it is recommended + * to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN + * while keeping the default value of 16KB for the incoming buffer. + * + * Uncomment to set the maximum plaintext size of the incoming I/O buffer + * independently of the outgoing I/O buffer. + */ +//#define MBEDTLS_SSL_IN_CONTENT_LEN 16384 + +/** \def MBEDTLS_SSL_CID_IN_LEN_MAX + * + * The maximum length of CIDs used for incoming DTLS messages. + * + */ +//#define MBEDTLS_SSL_CID_IN_LEN_MAX 32 + +/** \def MBEDTLS_SSL_CID_OUT_LEN_MAX + * + * The maximum length of CIDs used for outgoing DTLS messages. + * + */ +//#define MBEDTLS_SSL_CID_OUT_LEN_MAX 32 + +/** \def MBEDTLS_SSL_CID_PADDING_GRANULARITY + * + * This option controls the use of record plaintext padding + * when using the Connection ID extension in DTLS 1.2. + * + * The padding will always be chosen so that the length of the + * padded plaintext is a multiple of the value of this option. + * + * Note: A value of \c 1 means that no padding will be used + * for outgoing records. + * + * Note: On systems lacking division instructions, + * a power of two should be preferred. + * + */ +//#define MBEDTLS_SSL_CID_PADDING_GRANULARITY 16 + +/** \def MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY + * + * This option controls the use of record plaintext padding + * in TLS 1.3. + * + * The padding will always be chosen so that the length of the + * padded plaintext is a multiple of the value of this option. + * + * Note: A value of \c 1 means that no padding will be used + * for outgoing records. + * + * Note: On systems lacking division instructions, + * a power of two should be preferred. + */ +//#define MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY 1 + +/** \def MBEDTLS_SSL_OUT_CONTENT_LEN + * + * Maximum length (in bytes) of outgoing plaintext fragments. + * + * This determines the size of the outgoing TLS I/O buffer in such a way + * that it is capable of holding the specified amount of plaintext data, + * regardless of the protection mechanism used. + * + * If this option undefined, it inherits its value from + * #MBEDTLS_SSL_MAX_CONTENT_LEN. + * + * It is possible to save RAM by setting a smaller outward buffer, while keeping + * the default inward 16384 byte buffer to conform to the TLS specification. + * + * The minimum required outward buffer size is determined by the handshake + * protocol's usage. Handshaking will fail if the outward buffer is too small. + * The specific size requirement depends on the configured ciphers and any + * certificate data which is sent during the handshake. + * + * Uncomment to set the maximum plaintext size of the outgoing I/O buffer + * independently of the incoming I/O buffer. + */ +//#define MBEDTLS_SSL_OUT_CONTENT_LEN 16384 + +/** \def MBEDTLS_SSL_DTLS_MAX_BUFFERING + * + * Maximum number of heap-allocated bytes for the purpose of + * DTLS handshake message reassembly and future message buffering. + * + * This should be at least 9/8 * MBEDTLSSL_IN_CONTENT_LEN + * to account for a reassembled handshake message of maximum size, + * together with its reassembly bitmap. + * + * A value of 2 * MBEDTLS_SSL_IN_CONTENT_LEN (32768 by default) + * should be sufficient for all practical situations as it allows + * to reassembly a large handshake message (such as a certificate) + * while buffering multiple smaller handshake messages. + * + */ +//#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768 + +//#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ +//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ +//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, +// or in number of cookies issued */ + +/** + * Complete list of ciphersuites to use, in order of preference. + * + * \warning No dependency checking is done on that field! This option can only + * be used to restrict the set of available ciphersuites. It is your + * responsibility to make sure the needed modules are active. + * + * Use this to save a few hundred bytes of ROM (default ordering of all + * available ciphersuites) and a few to a few hundred bytes of RAM. + * + * The value below is only an example, not the default. + */ +//#define MBEDTLS_SSL_CIPHERSUITES +// MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + +/* X509 options */ +//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */ +//#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 /**< Maximum length of a path/filename string in bytes including the +// null terminator character ('\0'). */ + +/** + * Allow SHA-1 in the default TLS configuration for certificate signing. + * Without this build-time option, SHA-1 support must be activated explicitly + * through mbedtls_ssl_conf_cert_profile. Turning on this option is not + * recommended because of it is possible to generate SHA-1 collisions, however + * this may be safe for legacy infrastructure where additional controls apply. + * + * \warning SHA-1 is considered a weak message digest and its use constitutes + * a security risk. If possible, we recommend avoiding dependencies + * on it, and considering stronger message digests instead. + * + */ +//#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES + +/** + * Allow SHA-1 in the default TLS configuration for TLS 1.2 handshake + * signature and ciphersuite selection. Without this build-time option, SHA-1 + * support must be activated explicitly through mbedtls_ssl_conf_sig_hashes. + * The use of SHA-1 in TLS <= 1.1 and in HMAC-SHA-1 is always allowed by + * default. At the time of writing, there is no practical attack on the use + * of SHA-1 in handshake signatures, hence this option is turned on by default + * to preserve compatibility with existing peers, but the general + * warning applies nonetheless: + * + * \warning SHA-1 is considered a weak message digest and its use constitutes + * a security risk. If possible, we recommend avoiding dependencies + * on it, and considering stronger message digests instead. + * + */ +//#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE + +/** + * Uncomment the macro to let mbed TLS use your alternate implementation of + * mbedtls_platform_zeroize(). This replaces the default implementation in + * platform_util.c. + * + * mbedtls_platform_zeroize() is a widely used function across the library to + * zero a block of memory. The implementation is expected to be secure in the + * sense that it has been written to prevent the compiler from removing calls + * to mbedtls_platform_zeroize() as part of redundant code elimination + * optimizations. However, it is difficult to guarantee that calls to + * mbedtls_platform_zeroize() will not be optimized by the compiler as older + * versions of the C language standards do not provide a secure implementation + * of memset(). Therefore, MBEDTLS_PLATFORM_ZEROIZE_ALT enables users to + * configure their own implementation of mbedtls_platform_zeroize(), for + * example by using directives specific to their compiler, features from newer + * C standards (e.g using memset_s() in C11) or calling a secure memset() from + * their system (e.g explicit_bzero() in BSD). + */ +//#define MBEDTLS_PLATFORM_ZEROIZE_ALT + +/** + * Uncomment the macro to let Mbed TLS use your alternate implementation of + * mbedtls_platform_gmtime_r(). This replaces the default implementation in + * platform_util.c. + * + * gmtime() is not a thread-safe function as defined in the C standard. The + * library will try to use safer implementations of this function, such as + * gmtime_r() when available. However, if Mbed TLS cannot identify the target + * system, the implementation of mbedtls_platform_gmtime_r() will default to + * using the standard gmtime(). In this case, calls from the library to + * gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex + * if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the + * library are also guarded with this mutex to avoid race conditions. However, + * if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will + * unconditionally use the implementation for mbedtls_platform_gmtime_r() + * supplied at compile time. + */ +//#define MBEDTLS_PLATFORM_GMTIME_R_ALT + +/** + * Enable the verified implementations of ECDH primitives from Project Everest + * (currently only Curve25519). This feature changes the layout of ECDH + * contexts and therefore is a compatibility break for applications that access + * fields of a mbedtls_ecdh_context structure directly. See also + * MBEDTLS_ECDH_LEGACY_CONTEXT in include/mbedtls/ecdh.h. + */ +//#define MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED + +#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) +#include "mbedtls/config_psa.h" +#endif + +#include "mbedtls/check_config.h" + +#endif /* MBEDTLS_CONFIG_H */ diff --git a/config/openiotsdk/mbedtls/platform_alt.cpp b/config/openiotsdk/mbedtls/platform_alt.cpp new file mode 100644 index 00000000000000..803b5f50c4adc8 --- /dev/null +++ b/config/openiotsdk/mbedtls/platform_alt.cpp @@ -0,0 +1,72 @@ +/* + * + * 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 + * This file provides the Mbedtls platform aternative implementation. + * It contains custom setup() and teardown() functions. + */ + +#include "mbedtls/platform.h" +#include "mbedtls/threading.h" + +#ifdef MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT + +#include + +#ifdef MBEDTLS_PLATFORM_NV_SEED_ALT +static int mbedtls_platform_nv_seed_read(unsigned char * buf, size_t buf_len) +{ + if (buf == NULL) + { + return (-1); + } + memset(buf, 0xA5, buf_len); + return 0; +} + +static int mbedtls_platform_nv_seed_write(unsigned char * buf, size_t buf_len) +{ + return 0; +} +#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ + +int mbedtls_platform_setup(mbedtls_platform_context * ctx) +{ + (void) ctx; + int ret = 0; + +#ifdef MBEDTLS_PLATFORM_NV_SEED_ALT + ret = mbedtls_platform_set_nv_seed(mbedtls_platform_nv_seed_read, mbedtls_platform_nv_seed_write); + if (ret) + { + return ret; + } +#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ +#ifdef MBEDTLS_THREADING_ALT + mbedtls_threading_set_cmsis_rtos(); +#endif /* MBEDTLS_THREADING_ALT */ + return ret; +} + +void mbedtls_platform_teardown(mbedtls_platform_context * ctx) +{ + (void) ctx; +} + +#endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ diff --git a/config/openiotsdk/mbedtls/platform_alt.h b/config/openiotsdk/mbedtls/platform_alt.h new file mode 100644 index 00000000000000..0b7d50bae5b1b7 --- /dev/null +++ b/config/openiotsdk/mbedtls/platform_alt.h @@ -0,0 +1,36 @@ +/* + * + * 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 + * This file provides the Mbedtls platform aternative implementation. + * It contains custom setup() and teardown() functions. + */ + +#ifndef MBEDTLS_PLATFORM_ALT +#define MBEDTLS_PLATFORM_ALT + +/** + * \brief The dummy platform context structure. + */ +typedef struct mbedtls_platform_context +{ + char dummy; +} mbedtls_platform_context; + +#endif /* MBEDTLS_PLATFORM_ALT */ diff --git a/config/openiotsdk/mbedtls/threading_alt.h b/config/openiotsdk/mbedtls/threading_alt.h new file mode 100644 index 00000000000000..6d7af567793141 --- /dev/null +++ b/config/openiotsdk/mbedtls/threading_alt.h @@ -0,0 +1,30 @@ +/* + * + * 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 + * This file provides the Mbedtls threading aternative implementation. + * It inludes the CMSIS-RTOS threading adaptation. + */ + +#ifndef MBEDTLS_THREADING_ALT_H +#define MBEDTLS_THREADING_ALT_H + +#include "mbedtls_threading_cmsis_rtos.h" + +#endif // ! MBEDTLS_THREADING_ALT_H diff --git a/config/openiotsdk/util.cmake b/config/openiotsdk/util.cmake new file mode 100644 index 00000000000000..23e0aabe662ee3 --- /dev/null +++ b/config/openiotsdk/util.cmake @@ -0,0 +1,152 @@ +# +# 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. +# + +# +# @file +# CMake utilities for managing and retrieving build configuration +# + +# Get compilation flags for specific lang +# The flags might contains compile language generator expressions that +# look like this: +# $<$:-fno-exceptions> +# Applying a regex to extract the flag and also to find out if the language matches. +# [Args]: +# input - list of flags to parse +# output - list of flags set to specific language +function(get_flags_for_lang lang input output) + set(tmp_list "") + + list(LENGTH ${input} nb_elem) + set(index 0) + set(is_compile_lang_expression 0) + + while(${index} LESS ${nb_elem}) + list(GET ${input} ${index} value) + if(value MATCHES ":([^>]+)") + string(REGEX REPLACE "^[^:]*:" "" updated_flag ${value}) + list(APPEND tmp_list ${updated_flag}) + if(NOT value MATCHES ">$") + set(is_compile_lang_expression 1) + endif() + elseif(is_compile_lang_expression) + if(value MATCHES ">$") + set(is_compile_lang_expression 0) + endif() + string(REPLACE ">" "" updated_flag ${value}) + list(APPEND tmp_list ${updated_flag}) + endif() + math(EXPR index "${index}+1") + endwhile() + + set(${output} ${tmp_list} PARENT_SCOPE) +endfunction() + +# Get include directory of target build +# Get target property of includes directories +# For each flag add -I prefix and put it in quotation marks +# [Args]: +# target - target name +# output - output variable name +function(get_include_directories target output) + get_property(flags TARGET ${target} PROPERTY INTERFACE_INCLUDE_DIRECTORIES) + list(APPEND CFLAG_LIST) + foreach(flag ${flags}) + list(APPEND CFLAG_LIST "\"-isystem${flag}\"") + endforeach() + set(${output} ${CFLAG_LIST} PARENT_SCOPE) +endfunction() + +# Get compile definitions of target build +# Get target property of compile definitions +# For each flag change format, add -D prefix and put it in quotation marks +# [Args]: +# target - target name +# output - output variable name +function(get_compile_definitions target output) + get_property(flags TARGET ${target} PROPERTY INTERFACE_COMPILE_DEFINITIONS) + + list(APPEND CFLAG_LIST) + foreach(flag ${flags}) + # Replace each quote with a '\"' - format required for the GN arguments + string(REPLACE "\"" "\\\\\"" output_flag ${flag}) + list(APPEND CFLAG_LIST "\"-D${output_flag}\"") + endforeach() + set(${output} ${CFLAG_LIST} PARENT_SCOPE) +endfunction() + +# Get compile options of build for specific language +# Get property of compile options +# [Args]: +# lang - compilation languge (C, C++ or ASM) +# target - target name +# output - output variable name +function(get_compile_options_for_lang lang target output) + get_property(flags TARGET ${target} PROPERTY INTERFACE_COMPILE_OPTIONS) + get_flags_for_lang(${lang} flags output_list) + set(${output} ${output_list} PARENT_SCOPE) +endfunction() + + +# Retrieve common compilation flags specific for target +# [Args]: +# VAR - flags variable name +# TARGET - target name +function(get_target_common_compile_flags VAR TARGET) + get_include_directories(${TARGET} INCLUDES) + get_compile_definitions(${TARGET} DEFINES) + set(${VAR} ${INCLUDES} ${DEFINES} ${${VAR}} PARENT_SCOPE) +endfunction() + +# Retrieve target compiler flags for the specific language (C or CXX) +# [Args]: +# VAR - flags variable name +# TARGET - target name +# LANG - compilation languge (C, C++ or ASM) +function(get_lang_compile_flags VAR TARGET LANG) + get_compile_options_for_lang(${LANG} ${TARGET} FLAGS) + set(${VAR} ${FLAGS} ${${VAR}} PARENT_SCOPE) +endfunction() + +# Convert list of flags to string format +# [Args]: +# ptr_list_of_flags - list fo flags +# string_of_flags - output string +# separator - flags separator +function(convert_list_of_flags_to_string_of_flags ptr_list_of_flags string_of_flags separator) + # Convert the list to a string so we can do string replace + # operations on it and replace the ";" list separators with a + # desirable one so the flags are spaced out + string(REPLACE ";" ${separator} locally_scoped_string_of_flags "${${ptr_list_of_flags}}") + # Removing excess spaces + string(REPLACE " " " " locally_scoped_string_of_flags "${locally_scoped_string_of_flags}") + + # Set the output variable in the parent scope + set(${string_of_flags} ${locally_scoped_string_of_flags} PARENT_SCOPE) +endfunction() + + +function (get_all_cmake_targets out_var current_dir) + get_property(targets DIRECTORY ${current_dir} PROPERTY BUILDSYSTEM_TARGETS) + get_property(subdirs DIRECTORY ${current_dir} PROPERTY SUBDIRECTORIES) + + foreach(subdir ${subdirs}) + get_all_cmake_targets(subdir_targets ${subdir}) + list(APPEND targets ${subdir_targets}) + endforeach() + + set(${out_var} ${targets} PARENT_SCOPE) +endfunction() \ No newline at end of file diff --git a/docs/examples/openiotsdk_examples.md b/docs/examples/openiotsdk_examples.md new file mode 100644 index 00000000000000..41e8c88152b7e8 --- /dev/null +++ b/docs/examples/openiotsdk_examples.md @@ -0,0 +1,258 @@ +# Matter Open IoT SDK Example Application + +These examples are built using +[Open IoT SDK](https://gitlab.arm.com/iot/open-iot-sdk) and runs inside an +emulated target through the +[Arm FVP model for the Corstone-300 MPS3](https://developer.arm.com/downloads/-/arm-ecosystem-fvps). + +You can use these example as a reference for creating your own applications. + +## Environment setup + +Before building the examples, check out the Matter repository and sync +submodules using the following command: + +``` +$ git submodule update --init +``` + +The VSCode devcontainer has all dependencies pre-installed. Using the VSCode +devcontainer is the recommended way to interact with Open IoT SDK port of the +Matter Project. Please read this +[README.md](../../..//docs/VSCODE_DEVELOPMENT.md) for more information. + +### Networking setup + +Running ARM Fast Model with TAP/TUN device networking mode requires setup proper +network interfaces. Special scripts were designed to make setup easy. In +`scripts/setup/openiotsdk` directory you can find: + +- **network_setup.sh** - script to create the specific network namespace and + Virtual Ethernet interface to connect with host network. Both host and + namespace sides have linked IP addresses. Inside the network namespace the + TAP device interface is created and bridged with Virtual Ethernet peer. + There is also option to enable Internet connection in namespace by + forwarding traffic to host default interface. + + To enable Open IoT SDK networking environment: + + ``` + ${MATTER_ROOT}/scripts/setup/openiotsdk/network_setup.sh up + ``` + + To disable Open IoT SDK networking environment: + + ``` + ${MATTER_ROOT}/scripts/setup/openiotsdk/network_setup.sh down + ``` + + Use `--help` to get more information about the script options. + +- **connect_if.sh** - script that connects specified network interfaces with + the default route interface. It creates a bridge and links all interfaces to + it. The bridge becomes the default interface. + + Example: + + ``` + ${MATTER_ROOT}/scripts/setup/openiotsdk/connect_if.sh ARMhveth + ``` + + Use `--help` to get more information about the script options. + +Open IoT SDK network setup scripts contain commands that require root +permissions. Use `sudo` to run the scripts in user account with root privileges. + +After setting up the Open IoT SDK network environment the user will be able to +run Matter examples on `FVP` in an isolated network namespace in TAP device +mode. + +To execute a command in a specific network namespace use the helper script +`scripts/run_in_ns.sh`. + +Example: + +``` +${MATTER_ROOT}/scripts/run_in_ns.sh ARMns +``` + +Use `--help` to get more information about the script options. + +**NOTE** + +For Docker environment users it's recommended to use the +[default bridge network](https://docs.docker.com/network/bridge/#use-the-default-bridge-network) +for a running container. This guarantees full isolation of the Open IoT SDK +network from host settings. + +### Debugging setup + +Debugging Matter application running on `FVP` model requires GDB Remote +Connection Plugin for Fast Model. More details +[GDBRemoteConnection](https://developer.arm.com/documentation/100964/1116/Plug-ins-for-Fast-Models/GDBRemoteConnection). + +The Third-Party IP add-on package can be downloaded from ARM developer website +[Fast models](https://developer.arm.com/downloads/-/fast-models). Currently +required version is `11.16`. + +To install Fast Model Third-Party IP package: + +- unpack the installation package in a temporary location +- execute the command `./setup.bin` (Linux) or `Setup.exe` (Windows), and + follow the installation instructions. + +After installation the GDB Remote Connection Plugin should be visible in +`FastModelsPortfolio_11.16/plugins` directory. + +Then add the GDB plugin to your development environment: + +- host environment - add GDB plugin path to environment variable as + FAST_MODEL_PLUGINS_PATH. + + Example + + ``` + export FAST_MODEL_PLUGINS_PATH=/opt/FastModelsPortfolio_11.16/plugins/Linux64_GCC-9.3 + ``` + +- Docker container environment - mount the Fast Model Third-Party IP directory + into the `/opt/FastModelsPortfolio_11.16` directory in container. + + The Vscode devcontainer users should add a volume bound to this directory + [Add local file mount](https://code.visualstudio.com/remote/advancedcontainers/add-local-file-mount). + + You can edit the `.devcontainer/devcontainer.json` file, for example: + + ``` + ... + "mounts": [ + ... + "source=/opt/FastModelsPortfolio_11.16,target=/opt/FastModelsPortfolio_11.16,type=bind,consistency=cached" + ... + ], + ... + ``` + + In this case, the FAST MODEL PLUGINS PATH environment variable is already + created. + + If you launch the Docker container directly from CLI, use the above + arguments with `docker run` command. Remember add GDB plugin path to + environment variable as FAST_MODEL_PLUGINS_PATH inside container. + +## Building + +You build using a vscode task or call the script directly from the command line. + +### Building using vscode task + +``` +Command Palette (F1) => Run Task... => Build Open IoT SDK example => (debug on/off) => +``` + +This will call the scripts with the selected parameters. + +### Building using CLI + +You can call the script directly yourself. + +``` +${MATTER_ROOT}/scripts/examples/openiotsdk_example.sh +``` + +Use `--help` to get more information about the script options. + +## Running + +The application runs in the background and opens a telnet session. The script +will open telnet for you and connect to the port used by the `FVP`. When the +telnet process is terminated it will also terminate the `FVP` instance. + +You can run the application script from a vscode task or call the script +directly. + +### Running using vscode task + +``` +Command Palette (F1) => Run Task... => Run Open IoT SDK example => (network namespace) => (network interface) => +``` + +This will call the scripts with the selected example name. + +### Running using CLI + +You can call the script directly yourself. + +``` +${MATTER_ROOT}/scripts/examples/openiotsdk_example.sh -C run +``` + +Run example in specific network namespace with TAP device mode: + +``` +${MATTER_ROOT}/scripts/run_in_ns.sh ARMns ${MATTER_ROOT}/scripts/examples/openiotsdk_example.sh -C run -n ARMtap +``` + +### Commissioning + +Once booted the application can be commissioned, please refer to +[docs/guides/openiotsdk_commissioning.md](/../guides/openiotsdk_commissioning.md) +for further instructions. + +## Testing + +Run the Pytest integration test for specific application. + +The test result can be found in +`src/test_driver/openiotsdk/integration-tests//test_report.json` +file. + +You run testing using a vscode task or call the script directly from the command +line. + +### Testing using vscode task + +``` +Command Palette (F1) => Run Task... => Test Open IoT SDK example => (network namespace) => (network interface) => +``` + +This will call the scripts with the selected example name. + +### Testing using CLI + +You can call the script directly yourself. + +``` +${MATTER_ROOT}/scripts/examples/openiotsdk_example.sh -C test +``` + +Test example in specific network namespace with TAP device mode: + +``` +${MATTER_ROOT}/scripts/run_in_ns.sh ARMns ${MATTER_ROOT}/scripts/examples/openiotsdk_example.sh -C test -n ARMtap +``` + +## Debugging + +Debugging can be started using a VS code launch task: + +``` +Run and Debug (Ctrl+Shift+D) => Debug Open IoT SDK example application => Start +Debugging (F5) => => (GDB target address) => (network namespace) => (network interface) => +``` + +For debugging remote targets (i.e. run in other network namespaces) you need to +pass hostname/IP address of external GDB target that you want to connect to +(_GDB target address_). In case of using the +[Open IoT SDK network environment](#networking-setup) the GDB server runs inside +a namespace and has the same IP address as bridge interface. + +``` +${MATTER_ROOT}/scripts/run_in_ns.sh ifconfig +``` + +**NOTE** + +As you can see above, you will need to select the name of the example twice. +This is because the debug task needs to launch the run task and currently VS +code has no way of passing parameters between tasks. diff --git a/docs/guides/openiotsdk_commissioning.md b/docs/guides/openiotsdk_commissioning.md new file mode 100644 index 00000000000000..596184fd27a961 --- /dev/null +++ b/docs/guides/openiotsdk_commissioning.md @@ -0,0 +1,47 @@ +# Commissioning Open IoT SDK devices + +Matter devices based on Open IoT SDK reset into a ready for commissioning state. +This allows a controller to connect to them and set configuration options before +the device becomes available on the Matter network. + +Open IoT SDK Matter devices, due to the connectivity setup, start already +connected to the IP network and do not require credentials provisioning. + +## Building and installing the Python Device Controller + +To make provisioning possible and to control the Matter device with a Python +application, you can build and run the Python controller application. Please +read the guide +[Python Device Controller guide](python_chip_controller_building.md) for further +instructions. + +## Device commissioning + +Run chip-device-ctrl and use the interactive prompt to commission the device. + +After the device boots, it's in ready for commissioning mode and starts the mDNS +advertisement. This can be discovered by the controller using: + +``` +discover -all +``` + +This will list the devices and their addresses. To commission the device use: + +``` +connect -ip
[] +``` + +The setup pin code is printed in the log of the device. The `` can be +chosen by the user, if left blank it will be automatically picked. + +## Sending ZCL commands + +If the commissioning process was successful, it is possible to send a ZCL +command to the device which initiates a certain action. + +`zcl [arguments]` + +Example: + + chip-device-ctrl > zcl LevelControl MoveWithOnOff 12344321 1 0 moveMode=1 rate=2 diff --git a/docs/guides/openiotsdk_platform_overview.md b/docs/guides/openiotsdk_platform_overview.md new file mode 100644 index 00000000000000..2c4d04754dcc4a --- /dev/null +++ b/docs/guides/openiotsdk_platform_overview.md @@ -0,0 +1,95 @@ +# Open IoT SDK platform port + +This platform is based on +[Open IoT SDK](https://gitlab.arm.com/iot/open-iot-sdk). Open IoT SDK is a +reference implementation of [Open-CMSIS-CDI](https://www.open-cmsis-cdi.org/) +which defines a common device interface for microcontroller-based devices used +in the Internet of Things. It is delivered as a framework of software components +with a set of feature-rich example applications. + +## Building + +Open IoT SDK uses CMake as its build system. To integrate with Matter's GN build +system our top level CMakeLists.txt generates GN configuration files that pass +on the required configs required by the GN build. + +## Targets + +Supported targets are the ones supported by the Open IoT SDK. Currently it ships +with support for +[Corstone-300](https://developer.arm.com/Processors/Corstone-300) and +[Corstone-310](https://developer.arm.com/Processors/Corstone-310). This platform +makes no assumption on the target and will support any targets added to Open IoT +SDK. + +## Fast model network + +The fast models of supported platforms have two network modes: + +- user mode networking - emulates a built-in IP router and DHCP server, and + routes TCP and UDP traffic between the guest and host. It uses the user mode + socket layer of the host to communicate with other hosts. See more details: + [User mode networking](https://developer.arm.com/documentation/100964/1116/Introduction-to-the-Fast-Models-Reference-Manual/User-mode-networking) + +- TAP/TUN networking mode - set fast model to host bridge component which acts + as a networking gateway to exchange Ethernet packets with the TAP device on + the host, and to forward packets to model. See more details + [TAP/TUN networking mode](https://developer.arm.com/documentation/100964/1116/Introduction-to-the-Fast-Models-Reference-Manual/TAP-TUN-networking) + +Due the user mode limitations, the **TAP/TUN networking mode** is preferred for +implementing IP communication for a Matter project. + +## RTOS + +Open IoT SDK uses +[CMSIS-RTOS2 API](https://www.keil.com/pack/doc/cmsis/RTOS2/html/group__CMSIS__RTOS.html) +as its RTOS API. It offers the choice of implementation between FreeRTOS or +CMSIS RTX but this is hidden below the API so your choice has no bearing on this +port and indeed your application may provide your own implementation entirely. + +## Connectivity + +The platform currently only offers connectivity through the Ethernet interface. +This is limited by current support for network interfaces in Open IoT SDK. + +This means that commissioning is simplified since no provisioning is required to +provide the device with network credentials. + +LWIP is used in the implementation of endpoints as the IP stack. LWIP library is +provided through the Open IoT SDK. + +## Mbed TLS + +Mbed TLS is provided through the Open IoT SDK, the Matter version is not used. +Configuration of Mbed TLS is in +[config/openiotsdk/mbedtls](../../config/openiotsdk/mbedtls). + +## Storage + +Storage in Open IoT SDK is provided by +[TDBStore](https://gitlab.arm.com/iot/open-iot-sdk/storage) which is a simple +Key-Value Storage over a block device. + +--- + +**NOTE** + +On the Corstone targets this currently is implemented as a RAM memory region +emulating a Flash device. This does not offer persistence between launches. + +--- + +## Clocks + +Open IoT SDK does not currently offer an RTC. Matter configuration has been set +accordingly and real time cannot be read from the system. + +Monotonic clocks are available and are based on system tick count. They are +limited by the target configuration. The current targets set the tick to 1 ms. +This becomes the lower bound for timers. + +## Drivers + +Drivers are provided by +[Reference MCU-Driver-HAL driver implementation for Arm platforms](https://gitlab.arm.com/iot/open-iot-sdk/mcu-driver-hal/mcu-driver-reference-platforms-for-arm) +which is provided by Open IoT SDK. diff --git a/examples/lock-app/openiotsdk/.gitignore b/examples/lock-app/openiotsdk/.gitignore new file mode 100644 index 00000000000000..567609b1234a9b --- /dev/null +++ b/examples/lock-app/openiotsdk/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/examples/lock-app/openiotsdk/CMakeLists.txt b/examples/lock-app/openiotsdk/CMakeLists.txt new file mode 100644 index 00000000000000..67308591faa7a0 --- /dev/null +++ b/examples/lock-app/openiotsdk/CMakeLists.txt @@ -0,0 +1,85 @@ +# +# 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. +# + +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(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) + +list(APPEND CMAKE_MODULE_PATH ${OPEN_IOT_SDK_CONFIG}/cmake) + +set(APP_TARGET chip-openiotsdk-lock-app-example) + +# Toolchain files need to exist before first call to project +include(toolchain) + +project(${APP_TARGET} LANGUAGES C CXX ASM) + +include(sdk) + +# LwIP configuration +if(TARGET lwip-cmsis-port) + # lwip requires user_lwipopts.h, we use the custom settings + target_include_directories(lwipopts + INTERFACE + ${OPEN_IOT_SDK_CONFIG}/lwip + ) + + if (${CMAKE_BUILD_TYPE} STREQUAL "Debug") + target_compile_definitions(lwipopts + INTERFACE + LWIP_DEBUG + ) + endif() +endif() + +add_executable(${APP_TARGET}) + +# Application CHIP build configuration +include(chip) + +add_subdirectory(${OPEN_IOT_SDK_EXAMPLE_COMMON}/app ./app_build) + +target_include_directories(${APP_TARGET} + PRIVATE + main/include + ${GEN_DIR}/app-common + ${GEN_DIR}/lock-app +) + +target_sources(${APP_TARGET} + PRIVATE + main/main.cpp + main/ZclCallbacks.cpp + main/LockManager.cpp + main/LockEndpoint.cpp + ${GEN_DIR}/lock-app/zap-generated/IMClusterCommandHandler.cpp +) + +target_link_libraries(${APP_TARGET} + openiotsdk-app +) + +include(${CHIP_ROOT}/src/app/chip_data_model.cmake) +chip_configure_data_model(${APP_TARGET} + INCLUDE_SERVER + ZAP_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../lock-common/lock-app.zap +) + +include(linker) +set_target_link(${APP_TARGET}) diff --git a/examples/lock-app/openiotsdk/README.md b/examples/lock-app/openiotsdk/README.md new file mode 100644 index 00000000000000..4ff38ecc3a1445 --- /dev/null +++ b/examples/lock-app/openiotsdk/README.md @@ -0,0 +1,54 @@ +# Matter Open IoT SDK Lock-App Example Application + +The Open IoT SDK Lock Example demonstrates how to remotely control a door lock a +device with one basic bolt. + +The example behaves as a Matter accessory, device that can be paired into an +existing Matter network and can be controlled by it. + +## Build and run + +For information on how to build and run this example and further information +about the platform it is run on see +[Open IoT SDK examples](../../../docs/examples/openiotsdk_examples.md). + +The example name to use in the scripts is `lock-app`. + +## Using the example + +Communication with the application goes through the active telnet session. When +the application runs these lines should be visible: + +``` +[INF] [-] Open IoT SDK lock-app example application start +... +[INF] [-] Open IoT SDK lock-app example application run +``` + +The lock-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. + +### DoorLock cluster usage + +The application fully supports the DoorLock cluster. Use its 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: + +``` +zcl DoorLock LockDoor 1234 1 pinCode=str:12345 +``` + +In response the device will output this line to the terminal: + +``` +[INF] [ZC] Lock App: specified PIN code was found in the database, setting door lock state to "Locked" [endpointId=1] +``` diff --git a/examples/lock-app/openiotsdk/cmsis-config/RTE_Components.h b/examples/lock-app/openiotsdk/cmsis-config/RTE_Components.h new file mode 100644 index 00000000000000..3921500daecafb --- /dev/null +++ b/examples/lock-app/openiotsdk/cmsis-config/RTE_Components.h @@ -0,0 +1,24 @@ +/* + * + * 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 + +#define OS_STACK_SIZE (4 * 1024) + +#endif // RTE_COMPONENTS_H diff --git a/examples/lock-app/openiotsdk/freertos-config/FreeRTOSConfig.h b/examples/lock-app/openiotsdk/freertos-config/FreeRTOSConfig.h new file mode 100644 index 00000000000000..c95af61db3c84d --- /dev/null +++ b/examples/lock-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 1 + +// 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/lock-app/openiotsdk/main/LockEndpoint.cpp b/examples/lock-app/openiotsdk/main/LockEndpoint.cpp new file mode 100644 index 00000000000000..82e91a53aceb23 --- /dev/null +++ b/examples/lock-app/openiotsdk/main/LockEndpoint.cpp @@ -0,0 +1,348 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "LockEndpoint.h" +#include + +using chip::to_underlying; + +bool LockEndpoint::Lock(const Optional & pin, DlOperationError & err) +{ + return setLockState(DlLockState::kLocked, pin, err); +} + +bool LockEndpoint::Unlock(const Optional & pin, DlOperationError & err) +{ + return setLockState(DlLockState::kUnlocked, pin, err); +} + +bool LockEndpoint::GetUser(uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user) const +{ + ChipLogDetail(Zcl, "Lock App: LockEndpoint::GetUser [endpoint=%d,userIndex=%hu]", mEndpointId, userIndex); + + auto adjustedUserIndex = static_cast(userIndex - 1); + if (adjustedUserIndex > mLockUsers.size()) + { + ChipLogError(Zcl, "Cannot get user - index out of range [endpoint=%d,index=%hu,adjustedIndex=%d]", mEndpointId, userIndex, + adjustedUserIndex); + return false; + } + + const auto & userInDb = mLockUsers[adjustedUserIndex]; + user.userStatus = userInDb.userStatus; + if (DlUserStatus::kAvailable == user.userStatus) + { + ChipLogDetail(Zcl, "Found unoccupied user [endpoint=%d,adjustedIndex=%hu]", mEndpointId, adjustedUserIndex); + return true; + } + + user.userName = chip::CharSpan(userInDb.userName, strlen(userInDb.userName)); + user.credentials = chip::Span(userInDb.credentials.data(), userInDb.credentials.size()); + user.userUniqueId = userInDb.userUniqueId; + user.userType = userInDb.userType; + user.credentialRule = userInDb.credentialRule; + user.createdBy = userInDb.createdBy; + user.lastModifiedBy = userInDb.lastModifiedBy; + + ChipLogDetail(Zcl, + "Found occupied user " + "[endpoint=%d,adjustedIndex=%hu,name=\"%.*s\",credentialsCount=%u,uniqueId=%x,type=%u,credentialRule=%u," + "createdBy=%d,lastModifiedBy=%d]", + mEndpointId, adjustedUserIndex, static_cast(user.userName.size()), user.userName.data(), + static_cast(user.credentials.size()), user.userUniqueId, to_underlying(user.userType), + to_underlying(user.credentialRule), user.createdBy, user.lastModifiedBy); + + return true; +} + +bool LockEndpoint::SetUser(uint16_t userIndex, chip::FabricIndex creator, chip::FabricIndex modifier, + const chip::CharSpan & userName, uint32_t uniqueId, DlUserStatus userStatus, DlUserType usertype, + DlCredentialRule credentialRule, const DlCredential * credentials, size_t totalCredentials) +{ + ChipLogProgress(Zcl, + "SetUser " + "[endpoint=%d,userIndex=%u,creator=%d,modifier=%d,userName=\"%.*s\",uniqueId=%" PRIx32 + ",userStatus=%u,userType=%u," + "credentialRule=%u,credentials=%p,totalCredentials=%u]", + mEndpointId, userIndex, creator, modifier, static_cast(userName.size()), userName.data(), uniqueId, + to_underlying(userStatus), to_underlying(usertype), to_underlying(credentialRule), credentials, + static_cast(totalCredentials)); + + auto adjustedUserIndex = static_cast(userIndex - 1); + if (adjustedUserIndex > mLockUsers.size()) + { + ChipLogError(Zcl, "Cannot set user - index out of range [endpoint=%d,index=%d,adjustedUserIndex=%u]", mEndpointId, + userIndex, adjustedUserIndex); + return false; + } + + auto & userInStorage = mLockUsers[adjustedUserIndex]; + if (userName.size() > DOOR_LOCK_MAX_USER_NAME_SIZE) + { + ChipLogError(Zcl, "Cannot set user - user name is too long [endpoint=%d,index=%d,adjustedUserIndex=%u]", mEndpointId, + userIndex, adjustedUserIndex); + return false; + } + + if (totalCredentials > userInStorage.credentials.capacity()) + { + ChipLogError(Zcl, + "Cannot set user - total number of credentials is too big [endpoint=%d,index=%d,adjustedUserIndex=%u" + ",totalCredentials=%u,maxNumberOfCredentials=%u]", + mEndpointId, userIndex, adjustedUserIndex, static_cast(totalCredentials), + static_cast(userInStorage.credentials.capacity())); + return false; + } + + chip::Platform::CopyString(userInStorage.userName, userName); + userInStorage.userName[userName.size()] = 0; + userInStorage.userUniqueId = uniqueId; + userInStorage.userStatus = userStatus; + userInStorage.userType = usertype; + userInStorage.credentialRule = credentialRule; + userInStorage.lastModifiedBy = modifier; + userInStorage.createdBy = creator; + + userInStorage.credentials.clear(); + for (size_t i = 0; i < totalCredentials; ++i) + { + userInStorage.credentials.push_back(credentials[i]); + } + + ChipLogProgress(Zcl, "Successfully set the user [mEndpointId=%d,index=%d,adjustedIndex=%d]", mEndpointId, userIndex, + adjustedUserIndex); + + return true; +} + +bool LockEndpoint::GetCredential(uint16_t credentialIndex, DlCredentialType credentialType, + EmberAfPluginDoorLockCredentialInfo & credential) const +{ + ChipLogDetail(Zcl, "GetCredential [endpoint=%d,credentialIndex=%u,credentialType=%u]", mEndpointId, credentialIndex, + to_underlying(credentialType)); + + if (credentialIndex >= mLockCredentials.size() || (0 == credentialIndex && DlCredentialType::kProgrammingPIN != credentialType)) + { + ChipLogError(Zcl, "Cannot get the credential - index out of range [endpoint=%d,index=%d]", mEndpointId, credentialIndex); + return false; + } + + const auto & credentialInStorage = mLockCredentials[credentialIndex]; + + credential.status = credentialInStorage.status; + if (DlCredentialStatus::kAvailable == credential.status) + { + ChipLogDetail(Zcl, "Found unoccupied credential [endpoint=%d,index=%u]", mEndpointId, credentialIndex); + return true; + } + credential.credentialType = credentialInStorage.credentialType; + credential.credentialData = chip::ByteSpan(credentialInStorage.credentialData, credentialInStorage.credentialDataSize); + credential.createdBy = credentialInStorage.createdBy; + credential.lastModifiedBy = credentialInStorage.modifiedBy; + + ChipLogDetail(Zcl, "Found occupied credential [endpoint=%d,index=%u,type=%u,dataSize=%u,createdBy=%u,modifiedBy=%u]", + mEndpointId, credentialIndex, to_underlying(credential.credentialType), + static_cast(credential.credentialData.size()), credential.createdBy, credential.lastModifiedBy); + + return true; +} + +bool LockEndpoint::SetCredential(uint16_t credentialIndex, chip::FabricIndex creator, chip::FabricIndex modifier, + DlCredentialStatus credentialStatus, DlCredentialType credentialType, + const chip::ByteSpan & credentialData) +{ + ChipLogDetail( + Zcl, + "SetCredential " + "[endpoint=%d,credentialIndex=%u,credentialStatus=%u,credentialType=%u,credentialDataSize=%u,creator=%u,modifier=%u]", + mEndpointId, credentialIndex, to_underlying(credentialStatus), to_underlying(credentialType), + static_cast(credentialData.size()), creator, modifier); + + if (credentialIndex >= mLockCredentials.size() || (0 == credentialIndex && DlCredentialType::kProgrammingPIN != credentialType)) + { + ChipLogError(Zcl, "Cannot set the credential - index out of range [endpoint=%d,index=%d]", mEndpointId, credentialIndex); + return false; + } + + auto & credentialInStorage = mLockCredentials[credentialIndex]; + if (credentialData.size() > DOOR_LOCK_CREDENTIAL_INFO_MAX_DATA_SIZE) + { + ChipLogError(Zcl, + "Cannot get the credential - data size exceeds limit " + "[endpoint=%d,index=%d,dataSize=%u,maxDataSize=%u]", + mEndpointId, credentialIndex, static_cast(credentialData.size()), + static_cast(DOOR_LOCK_CREDENTIAL_INFO_MAX_DATA_SIZE)); + return false; + } + credentialInStorage.status = credentialStatus; + credentialInStorage.credentialType = credentialType; + credentialInStorage.createdBy = creator; + credentialInStorage.modifiedBy = modifier; + std::memcpy(credentialInStorage.credentialData, credentialData.data(), credentialData.size()); + credentialInStorage.credentialDataSize = credentialData.size(); + + ChipLogProgress(Zcl, "Successfully set the credential [mEndpointId=%d,index=%d,credentialType=%u,creator=%u,modifier=%u]", + mEndpointId, credentialIndex, to_underlying(credentialType), credentialInStorage.createdBy, + credentialInStorage.modifiedBy); + + return true; +} + +DlStatus LockEndpoint::GetSchedule(uint8_t weekDayIndex, uint16_t userIndex, EmberAfPluginDoorLockWeekDaySchedule & schedule) +{ + if (0 == userIndex || userIndex > mWeekDaySchedules.size()) + { + return DlStatus::kFailure; + } + + if (0 == weekDayIndex || weekDayIndex > mWeekDaySchedules.at(userIndex - 1).size()) + { + return DlStatus::kFailure; + } + + const auto & scheduleInStorage = mWeekDaySchedules.at(userIndex - 1).at(weekDayIndex - 1); + if (DlScheduleStatus::kAvailable == scheduleInStorage.status) + { + return DlStatus::kNotFound; + } + + schedule = scheduleInStorage.schedule; + + return DlStatus::kSuccess; +} + +DlStatus LockEndpoint::SetSchedule(uint8_t weekDayIndex, uint16_t userIndex, DlScheduleStatus status, DlDaysMaskMap daysMask, + uint8_t startHour, uint8_t startMinute, uint8_t endHour, uint8_t endMinute) +{ + if (0 == userIndex || userIndex > mWeekDaySchedules.size()) + { + return DlStatus::kFailure; + } + + if (0 == weekDayIndex || weekDayIndex > mWeekDaySchedules.at(userIndex - 1).size()) + { + return DlStatus::kFailure; + } + + auto & scheduleInStorage = mWeekDaySchedules.at(userIndex - 1).at(weekDayIndex - 1); + + scheduleInStorage.schedule.daysMask = daysMask; + scheduleInStorage.schedule.startHour = startHour; + scheduleInStorage.schedule.startMinute = startMinute; + scheduleInStorage.schedule.endHour = endHour; + scheduleInStorage.schedule.endMinute = endMinute; + scheduleInStorage.status = status; + + return DlStatus::kSuccess; +} + +DlStatus LockEndpoint::GetSchedule(uint8_t yearDayIndex, uint16_t userIndex, EmberAfPluginDoorLockYearDaySchedule & schedule) +{ + if (0 == userIndex || userIndex > mYearDaySchedules.size()) + { + return DlStatus::kFailure; + } + + if (0 == yearDayIndex || yearDayIndex > mYearDaySchedules.at(userIndex - 1).size()) + { + return DlStatus::kFailure; + } + + const auto & scheduleInStorage = mYearDaySchedules.at(userIndex - 1).at(yearDayIndex - 1); + if (DlScheduleStatus::kAvailable == scheduleInStorage.status) + { + return DlStatus::kNotFound; + } + + schedule = scheduleInStorage.schedule; + + return DlStatus::kSuccess; +} + +DlStatus LockEndpoint::SetSchedule(uint8_t yearDayIndex, uint16_t userIndex, DlScheduleStatus status, uint32_t localStartTime, + uint32_t localEndTime) +{ + if (0 == userIndex || userIndex > mYearDaySchedules.size()) + { + return DlStatus::kFailure; + } + + if (0 == yearDayIndex || yearDayIndex > mYearDaySchedules.at(userIndex - 1).size()) + { + return DlStatus::kFailure; + } + + auto & scheduleInStorage = mYearDaySchedules.at(userIndex - 1).at(yearDayIndex - 1); + scheduleInStorage.schedule.localStartTime = localStartTime; + scheduleInStorage.schedule.localEndTime = localEndTime; + scheduleInStorage.status = status; + + return DlStatus::kSuccess; +} + +bool LockEndpoint::setLockState(DlLockState lockState, const Optional & pin, DlOperationError & err) +{ + if (!pin.HasValue()) + { + ChipLogDetail(Zcl, "PIN code is not specified, setting door lock state to \"%s\" [endpointId=%d]", + lockStateToString(lockState), mEndpointId); + mLockState = lockState; + return true; + } + + // Check the PIN code + for (const auto & pinCredential : mLockCredentials) + { + if (pinCredential.credentialType != DlCredentialType::kPin || pinCredential.status == DlCredentialStatus::kAvailable) + { + continue; + } + + chip::ByteSpan credentialData(pinCredential.credentialData, pinCredential.credentialDataSize); + if (credentialData.data_equal(pin.Value())) + { + ChipLogProgress(Zcl, "Setting door lock state to \"%s\" [endpointId=%d]", lockStateToString(lockState), mEndpointId); + + mLockState = lockState; + return true; + } + } + + ChipLogDetail(Zcl, + "Specified PIN code was not found in the database, ignoring command to set lock state to \"%s\" " + "[endpointId=%d]", + lockStateToString(lockState), mEndpointId); + + err = DlOperationError::kInvalidCredential; + return false; +} + +const char * LockEndpoint::lockStateToString(DlLockState lockState) const +{ + switch (lockState) + { + case DlLockState::kNotFullyLocked: + return "Not Fully Locked"; + case DlLockState::kLocked: + return "Locked"; + case DlLockState::kUnlocked: + return "Unlocked"; + } + + return "Unknown"; +} diff --git a/examples/lock-app/openiotsdk/main/LockManager.cpp b/examples/lock-app/openiotsdk/main/LockManager.cpp new file mode 100644 index 00000000000000..33397bbf3113df --- /dev/null +++ b/examples/lock-app/openiotsdk/main/LockManager.cpp @@ -0,0 +1,248 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "LockManager.h" + +#include + +#include +#include +#include + +using chip::to_underlying; + +LockManager LockManager::instance; + +LockManager & LockManager::Instance() +{ + return instance; +} + +bool LockManager::InitEndpoint(chip::EndpointId endpointId) +{ + uint16_t numberOfSupportedUsers = 0; + if (!DoorLockServer::Instance().GetNumberOfUserSupported(endpointId, numberOfSupportedUsers)) + { + ChipLogError(Zcl, + "Unable to get number of supported users when initializing lock endpoint, defaulting to 10 [endpointId=%d]", + endpointId); + numberOfSupportedUsers = CHIP_LOCK_MANAGER_USER_NUMBER; + } + + uint16_t numberOfSupportedCredentials = 0; + // We're planning to use shared storage for PIN and RFID users so we will have the maximum of both sizes her to simplify logic + uint16_t numberOfPINCredentialsSupported = 0; + uint16_t numberOfRFIDCredentialsSupported = 0; + if (!DoorLockServer::Instance().GetNumberOfPINCredentialsSupported(endpointId, numberOfPINCredentialsSupported) || + !DoorLockServer::Instance().GetNumberOfRFIDCredentialsSupported(endpointId, numberOfRFIDCredentialsSupported)) + { + ChipLogError( + Zcl, "Unable to get number of supported credentials when initializing lock endpoint, defaulting to 10 [endpointId=%d]", + endpointId); + numberOfSupportedCredentials = CHIP_LOCK_MANAGER_CREDENTIALS_NUMBER; + } + else + { + numberOfSupportedCredentials = std::max(numberOfPINCredentialsSupported, numberOfRFIDCredentialsSupported); + } + + uint8_t numberOfCredentialsSupportedPerUser = 0; + if (!DoorLockServer::Instance().GetNumberOfCredentialsSupportedPerUser(endpointId, numberOfCredentialsSupportedPerUser)) + { + ChipLogError(Zcl, + "Unable to get number of credentials supported per user when initializing lock endpoint, defaulting to 5 " + "[endpointId=%d]", + endpointId); + numberOfCredentialsSupportedPerUser = CHIP_LOCK_MANAGER_CREDENTIALS_PER_USER_NUMBER; + } + + uint8_t numberOfWeekDaySchedulesPerUser = 0; + if (!DoorLockServer::Instance().GetNumberOfWeekDaySchedulesPerUserSupported(endpointId, numberOfWeekDaySchedulesPerUser)) + { + ChipLogError(Zcl, + "Unable to get number of supported week day schedules per user when initializing lock endpoint, defaulting to " + "10 [endpointId=%d]", + endpointId); + numberOfWeekDaySchedulesPerUser = CHIP_LOCK_MANAGER_WEEK_DAY_SCHEDULES_PER_USER_NUMBER; + } + + uint8_t numberOfYearDaySchedulesPerUser = 0; + if (!DoorLockServer::Instance().GetNumberOfYearDaySchedulesPerUserSupported(endpointId, numberOfYearDaySchedulesPerUser)) + { + ChipLogError(Zcl, + "Unable to get number of supported year day schedules per user when initializing lock endpoint, defaulting to " + "10 [endpointId=%d]", + endpointId); + numberOfYearDaySchedulesPerUser = CHIP_LOCK_MANAGER_YEAR_DAY_SCHEDULES_PER_USER_NUMBER; + } + + mEndpoints.emplace_back(endpointId, numberOfSupportedUsers, numberOfSupportedCredentials, numberOfWeekDaySchedulesPerUser, + numberOfYearDaySchedulesPerUser, numberOfCredentialsSupportedPerUser); + + ChipLogProgress(Zcl, + "Initialized new lock door endpoint " + "[id=%d,users=%d,credentials=%d,weekDaySchedulesPerUser=%d,yearDaySchedulesPerUser=%d," + "numberOfCredentialsSupportedPerUser=%d]", + endpointId, numberOfSupportedUsers, numberOfSupportedCredentials, numberOfWeekDaySchedulesPerUser, + numberOfYearDaySchedulesPerUser, numberOfCredentialsSupportedPerUser); + + return true; +} + +bool LockManager::Lock(chip::EndpointId endpointId, const Optional & pin, DlOperationError & err) +{ + auto lockEndpoint = getEndpoint(endpointId); + if (nullptr == lockEndpoint) + { + ChipLogError(Zcl, "Unable to lock the door - endpoint does not exist or not initialized [endpointId=%d]", endpointId); + return false; + } + + VerifyOrReturnValue(lockEndpoint->Lock(pin, err), false); + + return DoorLockServer::Instance().SetLockState(endpointId, DlLockState::kLocked); +} + +bool LockManager::Unlock(chip::EndpointId endpointId, const Optional & pin, DlOperationError & err) +{ + auto lockEndpoint = getEndpoint(endpointId); + if (nullptr == lockEndpoint) + { + ChipLogError(Zcl, "Unable to unlock the door - endpoint does not exist or not initialized [endpointId=%d]", endpointId); + return false; + } + + VerifyOrReturnValue(lockEndpoint->Unlock(pin, err), false); + + return DoorLockServer::Instance().SetLockState(endpointId, DlLockState::kUnlocked); +} + +bool LockManager::GetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user) +{ + auto lockEndpoint = getEndpoint(endpointId); + if (nullptr == lockEndpoint) + { + ChipLogError(Zcl, "Unable to get the user - endpoint does not exist or not initialized [endpointId=%d]", endpointId); + return false; + } + return lockEndpoint->GetUser(userIndex, user); +} + +bool LockManager::SetUser(chip::EndpointId endpointId, uint16_t userIndex, chip::FabricIndex creator, chip::FabricIndex modifier, + const chip::CharSpan & userName, uint32_t uniqueId, DlUserStatus userStatus, DlUserType usertype, + DlCredentialRule credentialRule, const DlCredential * credentials, size_t totalCredentials) +{ + auto lockEndpoint = getEndpoint(endpointId); + if (nullptr == lockEndpoint) + { + ChipLogError(Zcl, "Unable to set the user - endpoint does not exist or not initialized [endpointId=%d]", endpointId); + return false; + } + return lockEndpoint->SetUser(userIndex, creator, modifier, userName, uniqueId, userStatus, usertype, credentialRule, + credentials, totalCredentials); +} + +bool LockManager::GetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, DlCredentialType credentialType, + EmberAfPluginDoorLockCredentialInfo & credential) +{ + auto lockEndpoint = getEndpoint(endpointId); + if (nullptr == lockEndpoint) + { + ChipLogError(Zcl, "Unable to get the credential - endpoint does not exist or not initialized [endpointId=%d]", endpointId); + return false; + } + return lockEndpoint->GetCredential(credentialIndex, credentialType, credential); +} + +bool LockManager::SetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, chip::FabricIndex creator, + chip::FabricIndex modifier, DlCredentialStatus credentialStatus, DlCredentialType credentialType, + const chip::ByteSpan & credentialData) +{ + auto lockEndpoint = getEndpoint(endpointId); + if (nullptr == lockEndpoint) + { + ChipLogError(Zcl, "Unable to set the credential - endpoint does not exist or not initialized [endpointId=%d]", endpointId); + return false; + } + return lockEndpoint->SetCredential(credentialIndex, creator, modifier, credentialStatus, credentialType, credentialData); +} + +DlStatus LockManager::GetSchedule(chip::EndpointId endpointId, uint8_t weekDayIndex, uint16_t userIndex, + EmberAfPluginDoorLockWeekDaySchedule & schedule) +{ + auto lockEndpoint = getEndpoint(endpointId); + if (nullptr == lockEndpoint) + { + ChipLogError(Zcl, "Unable to get the week day schedule - endpoint does not exist or not initialized [endpointId=%d]", + endpointId); + return DlStatus::kFailure; + } + return lockEndpoint->GetSchedule(weekDayIndex, userIndex, schedule); +} + +DlStatus LockManager::SetSchedule(chip::EndpointId endpointId, uint8_t weekDayIndex, uint16_t userIndex, DlScheduleStatus status, + DlDaysMaskMap daysMask, uint8_t startHour, uint8_t startMinute, uint8_t endHour, + uint8_t endMinute) +{ + auto lockEndpoint = getEndpoint(endpointId); + if (nullptr == lockEndpoint) + { + ChipLogError(Zcl, "Unable to set the week day schedule - endpoint does not exist or not initialized [endpointId=%d]", + endpointId); + return DlStatus::kFailure; + } + return lockEndpoint->SetSchedule(weekDayIndex, userIndex, status, daysMask, startHour, startMinute, endHour, endMinute); +} + +DlStatus LockManager::GetSchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex, + EmberAfPluginDoorLockYearDaySchedule & schedule) +{ + auto lockEndpoint = getEndpoint(endpointId); + if (nullptr == lockEndpoint) + { + ChipLogError(Zcl, "Unable to get the year day schedule - endpoint does not exist or not initialized [endpointId=%d]", + endpointId); + return DlStatus::kFailure; + } + return lockEndpoint->GetSchedule(yearDayIndex, userIndex, schedule); +} + +DlStatus LockManager::SetSchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex, DlScheduleStatus status, + uint32_t localStartTime, uint32_t localEndTime) +{ + auto lockEndpoint = getEndpoint(endpointId); + if (nullptr == lockEndpoint) + { + ChipLogError(Zcl, "Unable to set the year day schedule - endpoint does not exist or not initialized [endpointId=%d]", + endpointId); + return DlStatus::kFailure; + } + return lockEndpoint->SetSchedule(yearDayIndex, userIndex, status, localStartTime, localEndTime); +} + +LockEndpoint * LockManager::getEndpoint(chip::EndpointId endpointId) +{ + for (auto & mEndpoint : mEndpoints) + { + if (mEndpoint.GetEndpointId() == endpointId) + { + return &mEndpoint; + } + } + return nullptr; +} diff --git a/examples/lock-app/openiotsdk/main/ZclCallbacks.cpp b/examples/lock-app/openiotsdk/main/ZclCallbacks.cpp new file mode 100644 index 00000000000000..f383377cfd77f7 --- /dev/null +++ b/examples/lock-app/openiotsdk/main/ZclCallbacks.cpp @@ -0,0 +1,106 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "LockManager.h" + +using namespace chip; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::DoorLock; + +bool emberAfPluginDoorLockOnDoorLockCommand(chip::EndpointId endpointId, const Optional & pinCode, DlOperationError & err) +{ + return LockManager::Instance().Lock(endpointId, pinCode, err); +} + +bool emberAfPluginDoorLockOnDoorUnlockCommand(chip::EndpointId endpointId, const Optional & pinCode, + DlOperationError & err) +{ + return LockManager::Instance().Unlock(endpointId, pinCode, err); +} + +bool emberAfPluginDoorLockGetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user) +{ + return LockManager::Instance().GetUser(endpointId, userIndex, user); +} + +bool emberAfPluginDoorLockSetUser(chip::EndpointId endpointId, uint16_t userIndex, chip::FabricIndex creator, + chip::FabricIndex modifier, const chip::CharSpan & userName, uint32_t uniqueId, + DlUserStatus userStatus, DlUserType usertype, DlCredentialRule credentialRule, + const DlCredential * credentials, size_t totalCredentials) +{ + + return LockManager::Instance().SetUser(endpointId, userIndex, creator, modifier, userName, uniqueId, userStatus, usertype, + credentialRule, credentials, totalCredentials); +} + +bool emberAfPluginDoorLockGetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, DlCredentialType credentialType, + EmberAfPluginDoorLockCredentialInfo & credential) +{ + return LockManager::Instance().GetCredential(endpointId, credentialIndex, credentialType, credential); +} + +bool emberAfPluginDoorLockSetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, chip::FabricIndex creator, + chip::FabricIndex modifier, DlCredentialStatus credentialStatus, + DlCredentialType credentialType, const chip::ByteSpan & credentialData) +{ + return LockManager::Instance().SetCredential(endpointId, credentialIndex, creator, modifier, credentialStatus, credentialType, + credentialData); +} + +DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex, + EmberAfPluginDoorLockWeekDaySchedule & schedule) +{ + return LockManager::Instance().GetSchedule(endpointId, weekdayIndex, userIndex, schedule); +} + +DlStatus emberAfPluginDoorLockSetSchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex, + DlScheduleStatus status, DlDaysMaskMap daysMask, uint8_t startHour, uint8_t startMinute, + uint8_t endHour, uint8_t endMinute) +{ + return LockManager::Instance().SetSchedule(endpointId, weekdayIndex, userIndex, status, daysMask, startHour, startMinute, + endHour, endMinute); +} + +DlStatus emberAfPluginDoorLockSetSchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex, + DlScheduleStatus status, uint32_t localStartTime, uint32_t localEndTime) +{ + return LockManager::Instance().SetSchedule(endpointId, yearDayIndex, userIndex, status, localStartTime, localEndTime); +} + +DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex, + EmberAfPluginDoorLockYearDaySchedule & schedule) +{ + return LockManager::Instance().GetSchedule(endpointId, yearDayIndex, userIndex, schedule); +} + +void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size, + uint8_t * value) +{ + VerifyOrReturn(attributePath.mClusterId == DoorLock::Id && attributePath.mAttributeId == DoorLock::Attributes::LockState::Id); + + emberAfDoorLockClusterPrintln("Door Lock attribute changed"); +} + +void emberAfDoorLockClusterInitCallback(EndpointId endpoint) +{ + DoorLockServer::Instance().InitServer(endpoint); + LockManager::Instance().InitEndpoint(endpoint); +} diff --git a/examples/lock-app/openiotsdk/main/include/CHIPProjectConfig.h b/examples/lock-app/openiotsdk/main/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..b72d5bd3db306b --- /dev/null +++ b/examples/lock-app/openiotsdk/main/include/CHIPProjectConfig.h @@ -0,0 +1,33 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#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/lock-app/openiotsdk/main/include/LockEndpoint.h b/examples/lock-app/openiotsdk/main/include/LockEndpoint.h new file mode 100644 index 00000000000000..bee91e7265239f --- /dev/null +++ b/examples/lock-app/openiotsdk/main/include/LockEndpoint.h @@ -0,0 +1,117 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +struct LockUserInfo +{ + char userName[DOOR_LOCK_USER_NAME_BUFFER_SIZE]; + uint32_t userUniqueId; + DlUserStatus userStatus; + DlUserType userType; + DlCredentialRule credentialRule; + std::vector credentials; + chip::FabricIndex createdBy; + chip::FabricIndex lastModifiedBy; +}; + +struct LockCredentialInfo; +struct WeekDaysScheduleInfo; +struct YearDayScheduleInfo; + +static constexpr size_t DOOR_LOCK_CREDENTIAL_INFO_MAX_DATA_SIZE = 20; + +class LockEndpoint +{ +public: + LockEndpoint(chip::EndpointId endpointId, uint16_t numberOfLockUsersSupported, uint16_t numberOfCredentialsSupported, + uint8_t weekDaySchedulesPerUser, uint8_t yearDaySchedulesPerUser, uint8_t numberOfCredentialsPerUser) : + mEndpointId{ endpointId }, + mLockState{ DlLockState::kLocked }, mLockUsers(numberOfLockUsersSupported), + mLockCredentials(numberOfCredentialsSupported + 1), + mWeekDaySchedules(numberOfLockUsersSupported, std::vector(weekDaySchedulesPerUser)), + mYearDaySchedules(numberOfLockUsersSupported, std::vector(yearDaySchedulesPerUser)) + { + for (auto & lockUser : mLockUsers) + { + lockUser.credentials.reserve(numberOfCredentialsPerUser); + } + } + + inline chip::EndpointId GetEndpointId() const { return mEndpointId; } + + bool Lock(const Optional & pin, DlOperationError & err); + bool Unlock(const Optional & pin, DlOperationError & err); + + bool GetUser(uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user) const; + bool SetUser(uint16_t userIndex, chip::FabricIndex creator, chip::FabricIndex modifier, const chip::CharSpan & userName, + uint32_t uniqueId, DlUserStatus userStatus, DlUserType usertype, DlCredentialRule credentialRule, + const DlCredential * credentials, size_t totalCredentials); + + bool GetCredential(uint16_t credentialIndex, DlCredentialType credentialType, + EmberAfPluginDoorLockCredentialInfo & credential) const; + + bool SetCredential(uint16_t credentialIndex, chip::FabricIndex creator, chip::FabricIndex modifier, + DlCredentialStatus credentialStatus, DlCredentialType credentialType, const chip::ByteSpan & credentialData); + + DlStatus GetSchedule(uint8_t weekDayIndex, uint16_t userIndex, EmberAfPluginDoorLockWeekDaySchedule & schedule); + DlStatus GetSchedule(uint8_t yearDayIndex, uint16_t userIndex, EmberAfPluginDoorLockYearDaySchedule & schedule); + DlStatus SetSchedule(uint8_t weekDayIndex, uint16_t userIndex, DlScheduleStatus status, DlDaysMaskMap daysMask, + uint8_t startHour, uint8_t startMinute, uint8_t endHour, uint8_t endMinute); + DlStatus SetSchedule(uint8_t yearDayIndex, uint16_t userIndex, DlScheduleStatus status, uint32_t localStartTime, + uint32_t localEndTime); + +private: + bool setLockState(DlLockState lockState, const Optional & pin, DlOperationError & err); + const char * lockStateToString(DlLockState lockState) const; + + chip::EndpointId mEndpointId; + DlLockState mLockState; + + // This is very naive implementation of users/credentials/schedules database and by no means the best practice. Proper storage + // of those items is out of scope of this example. + std::vector mLockUsers; + std::vector mLockCredentials; + std::vector> mWeekDaySchedules; + std::vector> mYearDaySchedules; +}; + +struct LockCredentialInfo +{ + DlCredentialStatus status; + DlCredentialType credentialType; + chip::FabricIndex createdBy; + chip::FabricIndex modifiedBy; + uint8_t credentialData[DOOR_LOCK_CREDENTIAL_INFO_MAX_DATA_SIZE]; + size_t credentialDataSize; +}; + +struct WeekDaysScheduleInfo +{ + DlScheduleStatus status; + EmberAfPluginDoorLockWeekDaySchedule schedule; +}; + +struct YearDayScheduleInfo +{ + DlScheduleStatus status; + EmberAfPluginDoorLockYearDaySchedule schedule; +}; diff --git a/examples/lock-app/openiotsdk/main/include/LockManager.h b/examples/lock-app/openiotsdk/main/include/LockManager.h new file mode 100644 index 00000000000000..2fccdc9745f7a7 --- /dev/null +++ b/examples/lock-app/openiotsdk/main/include/LockManager.h @@ -0,0 +1,65 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +#include + +class LockManager +{ +public: + LockManager() {} + + bool InitEndpoint(chip::EndpointId endpointId); + + bool Lock(chip::EndpointId endpointId, const Optional & pin, DlOperationError & err); + bool Unlock(chip::EndpointId endpointId, const Optional & pin, DlOperationError & err); + + bool GetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user); + bool SetUser(chip::EndpointId endpointId, uint16_t userIndex, chip::FabricIndex creator, chip::FabricIndex modifier, + const chip::CharSpan & userName, uint32_t uniqueId, DlUserStatus userStatus, DlUserType usertype, + DlCredentialRule credentialRule, const DlCredential * credentials, size_t totalCredentials); + + bool GetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, DlCredentialType credentialType, + EmberAfPluginDoorLockCredentialInfo & credential); + + bool SetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, chip::FabricIndex creator, chip::FabricIndex modifier, + DlCredentialStatus credentialStatus, DlCredentialType credentialType, const chip::ByteSpan & credentialData); + + DlStatus GetSchedule(chip::EndpointId endpointId, uint8_t weekDayIndex, uint16_t userIndex, + EmberAfPluginDoorLockWeekDaySchedule & schedule); + DlStatus GetSchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex, + EmberAfPluginDoorLockYearDaySchedule & schedule); + DlStatus SetSchedule(chip::EndpointId endpointId, uint8_t weekDayIndex, uint16_t userIndex, DlScheduleStatus status, + DlDaysMaskMap daysMask, uint8_t startHour, uint8_t startMinute, uint8_t endHour, uint8_t endMinute); + DlStatus SetSchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex, DlScheduleStatus status, + uint32_t localStartTime, uint32_t localEndTime); + + static LockManager & Instance(); + +private: + LockEndpoint * getEndpoint(chip::EndpointId endpointId); + + std::vector mEndpoints; + + static LockManager instance; +}; diff --git a/examples/lock-app/openiotsdk/main/main.cpp b/examples/lock-app/openiotsdk/main/main.cpp new file mode 100644 index 00000000000000..fbd72e0542fc85 --- /dev/null +++ b/examples/lock-app/openiotsdk/main/main.cpp @@ -0,0 +1,112 @@ +/* + * + * 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 + +#include +#include +#include +#include + +#include "openiotsdk_platform.h" + +using namespace ::chip; +using namespace ::chip::DeviceLayer; + +static void app_thread(void * argument) +{ + CHIP_ERROR error; + + if (openiotsdk_network_init(true)) + { + ChipLogError(NotSpecified, "Network initialization failed"); + goto exit; + } + + // Init ZCL Data Model and start server + static chip::CommonCaseDeviceServerInitParams initParams; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); + initParams.operationalServicePort = CHIP_PORT; + initParams.userDirectedCommissioningPort = CHIP_UDC_PORT; + + error = Server::GetInstance().Init(initParams); + SuccessOrExit(error); + + // Now that the server has started and we are done with our startup logging, + // log our discovery/onboarding information again so it's not lost in the + // noise. + ConfigurationMgr().LogDeviceConfig(); + + PrintOnboardingCodes(RendezvousInformationFlags(RendezvousInformationFlag::kOnNetwork)); + + // Initialize device attestation config + SetDeviceAttestationCredentialsProvider(Credentials::Examples::GetExampleDACProvider()); + + ChipLogProgress(NotSpecified, "Open IoT SDK lock-app example application run"); + + while (true) + { + // Add forever delay to ensure proper workload for this thread + osDelay(osWaitForever); + } + + Server::GetInstance().Shutdown(); + +exit: + osThreadTerminate(osThreadGetId()); +} + +int main() +{ + ChipLogProgress(NotSpecified, "Open IoT SDK lock-app example application start"); + + 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; + } + + static const osThreadAttr_t thread_attr = { + .stack_size = 16 * 1024 // Allocate enough stack for app thread + }; + + osThreadId_t appThread = osThreadNew(app_thread, NULL, &thread_attr); + if (appThread == NULL) + { + ChipLogError(NotSpecified, "Failed to create app thread"); + return EXIT_FAILURE; + } + + if (openiotsdk_platform_run()) + { + ChipLogError(NotSpecified, "Open IoT SDK platform run failed"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/examples/platform/openiotsdk/app/CMakeLists.txt b/examples/platform/openiotsdk/app/CMakeLists.txt new file mode 100644 index 00000000000000..191409ac8c815c --- /dev/null +++ b/examples/platform/openiotsdk/app/CMakeLists.txt @@ -0,0 +1,35 @@ +# +# 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. +# + +cmake_minimum_required(VERSION 3.21) + +# Declare Open IoT SDK app interface target +add_library(openiotsdk-app + openiotsdk_platform.cpp + ${CHIP_ROOT}/examples/providers/DeviceInfoProviderImpl.cpp +) + +target_include_directories(openiotsdk-app + PUBLIC + . + ${CHIP_ROOT}/examples/providers +) + +target_link_libraries(openiotsdk-app + PUBLIC + openiotsdk-chip + cmsis-rtos-implementation +) diff --git a/examples/platform/openiotsdk/app/openiotsdk_platform.cpp b/examples/platform/openiotsdk/app/openiotsdk_platform.cpp new file mode 100644 index 00000000000000..18ca62d06b4ac2 --- /dev/null +++ b/examples/platform/openiotsdk/app/openiotsdk_platform.cpp @@ -0,0 +1,218 @@ +/* + * + * 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 + * This file provides the common Open IoT SDK platform functions. + * It can be used in Matter examples implementation. + */ + +#include "openiotsdk_platform.h" + +#include "cmsis_os2.h" +#include "iotsdk/ip_network_api.h" +#include "mbedtls/platform.h" + +#include +#include +#include +#include +#include +#include + +using namespace ::chip; +using namespace ::chip::Platform; +using namespace ::chip::DeviceLayer; + +#define NETWORK_UP_FLAG 0x00000001U +#define NETWORK_DOWN_FLAG 0x00000002U +#define ALL_EVENTS_FLAGS (NETWORK_UP_FLAG | NETWORK_DOWN_FLAG) + +#define EVENT_TIMEOUT 5000 + +static osEventFlagsId_t event_flags_id; + +static DeviceLayer::DeviceInfoProviderImpl gDeviceInfoProvider; + +/** Wait for specific event and check error */ +static int wait_for_event(uint32_t event) +{ + int res = EXIT_SUCCESS; + int ret = osEventFlagsWait(event_flags_id, ALL_EVENTS_FLAGS, osFlagsWaitAny, ms2tick(EVENT_TIMEOUT)); + if (ret < 0) + { + ChipLogError(NotSpecified, "osEventFlagsWait failed %d", ret); + return EXIT_FAILURE; + } + + if (!(ret & event)) + { + res = EXIT_FAILURE; + } + + ret = osEventFlagsClear(event_flags_id, ALL_EVENTS_FLAGS); + if (ret < 0) + { + ChipLogError(NotSpecified, "osEventFlagsClear failed %d", ret); + return EXIT_FAILURE; + } + + return res; +} + +static void post_network_connect() +{ + // Iterate on the network interface to see if we already have beed assigned addresses. + for (chip::Inet::InterfaceAddressIterator it; it.HasCurrent(); it.Next()) + { + char ifName[chip::Inet::InterfaceId::kMaxIfNameLength]; + if (it.IsUp() && CHIP_NO_ERROR == it.GetInterfaceName(ifName, sizeof(ifName))) + { + chip::Inet::IPAddress addr; + if ((it.GetAddress(addr) == CHIP_NO_ERROR)) + { + char ipStrBuf[chip::Inet::IPAddress::kMaxStringLength] = { 0 }; + addr.ToString(ipStrBuf); + + ChipLogProgress(DeviceLayer, "Got IP address on interface: %s IP: %s", ifName, ipStrBuf); + } + } + } +} + +/** This callback is called by the ip network task. It translates from a network event code + * to platform event and sends it. + * + * @param event network up or down event. + */ +static void network_state_callback(network_state_callback_event_t event) +{ + uint32_t event_flag = (event == NETWORK_UP) ? NETWORK_UP_FLAG : NETWORK_DOWN_FLAG; + ChipLogDetail(NotSpecified, "Network %s", (event == NETWORK_UP) ? "UP" : "DOWN"); + int res = osEventFlagsSet(event_flags_id, event_flag); + if (res < 0) + { + ChipLogError(NotSpecified, "osEventFlagsSet failed %d", res); + } +} + +int openiotsdk_platform_init(void) +{ + int ret; + osKernelState_t state; + + ret = mbedtls_platform_setup(NULL); + if (ret) + { + ChipLogError(NotSpecified, "Mbed TLS platform initialization failed: %d", ret); + return EXIT_FAILURE; + } + + ret = osKernelInitialize(); + if (ret != osOK) + { + ChipLogError(NotSpecified, "osKernelInitialize failed: %d", ret); + return EXIT_FAILURE; + } + + state = osKernelGetState(); + if (state != osKernelReady) + { + ChipLogError(NotSpecified, "Kernel not ready: %d", state); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +int openiotsdk_chip_init(void) +{ + CHIP_ERROR err; + +#if NDEBUG + chip::Logging::SetLogFilter(chip::Logging::LogCategory::kLogCategory_Progress); +#endif + + err = MemoryInit(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Memory initialization failed: %s", err.AsString()); + return EXIT_FAILURE; + } + + err = PlatformMgr().InitChipStack(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Chip stack initialization failed: %s", err.AsString()); + return EXIT_FAILURE; + } + + err = PlatformMgr().StartEventLoopTask(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Chip stack start failed: %s", err.AsString()); + return EXIT_FAILURE; + } + + DeviceLayer::SetDeviceInfoProvider(&gDeviceInfoProvider); + + return EXIT_SUCCESS; +} + +int openiotsdk_platform_run(void) +{ + int ret = osKernelStart(); + if (ret != osOK) + { + ChipLogError(NotSpecified, "Failed to start kernel: %d", ret); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +int openiotsdk_network_init(bool wait) +{ + int ret; + + event_flags_id = osEventFlagsNew(NULL); + if (event_flags_id == NULL) + { + ChipLogError(NotSpecified, "Create event flags failed"); + return EXIT_FAILURE; + } + + ret = start_network_task(network_state_callback, NETWORK_THREAD_STACK_SIZE_DEFAULT); + if (ret != osOK) + { + ChipLogError(NotSpecified, "start_network_task failed %d", ret); + return EXIT_FAILURE; + } + + if (wait) + { + if (wait_for_event(NETWORK_UP_FLAG) != EXIT_SUCCESS) + { + ChipLogError(NotSpecified, "Network initialization failed"); + return EXIT_FAILURE; + } + post_network_connect(); + } + + return EXIT_SUCCESS; +} diff --git a/examples/platform/openiotsdk/app/openiotsdk_platform.h b/examples/platform/openiotsdk/app/openiotsdk_platform.h new file mode 100644 index 00000000000000..5dee7b82c7049d --- /dev/null +++ b/examples/platform/openiotsdk/app/openiotsdk_platform.h @@ -0,0 +1,69 @@ +/* + * + * 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 + * This file provides the common Open IoT SDK platform functions. + * It can be used in Matter examples implementation. + */ + +#ifndef OPENIOTSDK_PLATFORM_H +#define OPENIOTSDK_PLATFORM_H + +#include +#include + +// Default stack size for network thread (8kB) +#define NETWORK_THREAD_STACK_SIZE_DEFAULT (8 * 1024) + +/** + * @brief Initialise the Open IoT SDK platform + * Mbedtls platform setup + * OS kernel initialization and check + * + * @return EXIT_SUCCESS or EXIT_FAILURE + */ +int openiotsdk_platform_init(void); + +/** + * @brief Initialise the CHIP sources + * Platform memory and CHIP stack initialization + * Start CHIP event loop task + * + * @return EXIT_SUCCESS or EXIT_FAILURE + */ +int openiotsdk_chip_init(void); + +/** + * @brief Run the Open IoT SDK platform + * Start the OS kernel + * + * @return EXIT_SUCCESS or EXIT_FAILURE + */ +int openiotsdk_platform_run(void); + +/** + * @brief Initialise the Open IoT SDK network + * Run the network task and wait for newtork up + * + * @param wait Wait for network up + * @return EXIT_SUCCESS or EXIT_FAILURE + */ +int openiotsdk_network_init(bool wait); + +#endif /* ! OPENIOTSDK_PLATFORM_H */ diff --git a/examples/shell/openiotsdk/.gitignore b/examples/shell/openiotsdk/.gitignore new file mode 100644 index 00000000000000..567609b1234a9b --- /dev/null +++ b/examples/shell/openiotsdk/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/examples/shell/openiotsdk/CMakeLists.txt b/examples/shell/openiotsdk/CMakeLists.txt new file mode 100644 index 00000000000000..2d9cf86d9a95bb --- /dev/null +++ b/examples/shell/openiotsdk/CMakeLists.txt @@ -0,0 +1,77 @@ +# +# 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. +# + +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(SHELL_COMMON ${CHIP_ROOT}/examples/shell/shell_common REALPATH) + +list(APPEND CMAKE_MODULE_PATH ${OPEN_IOT_SDK_CONFIG}/cmake) + +set(APP_TARGET chip-openiotsdk-shell-example) + +# Toolchain files need to exist before first call to project +include(toolchain) + +project(${APP_TARGET} LANGUAGES C CXX ASM) + +include(sdk) + +# LwIP configuration +if(TARGET lwip-cmsis-port) + # lwip requires user_lwipopts.h, we use the custom settings + target_include_directories(lwipopts + INTERFACE + ${OPEN_IOT_SDK_CONFIG}/lwip + ) + + if (${CMAKE_BUILD_TYPE} STREQUAL "Debug") + target_compile_definitions(lwipopts + INTERFACE + LWIP_DEBUG + ) + endif() +endif() + +add_executable(${APP_TARGET}) + +# Application CHIP build configuration +set(CONFIG_CHIP_LIB_SHELL YES) +include(chip) + +add_subdirectory(${OPEN_IOT_SDK_EXAMPLE_COMMON}/app ./app_build) + +target_include_directories(${APP_TARGET} + PRIVATE + main/include + ${SHELL_COMMON}/include +) + +target_sources(${APP_TARGET} + PRIVATE + main/main.cpp + ${SHELL_COMMON}/cmd_misc.cpp + ${SHELL_COMMON}/globals.cpp +) + +target_link_libraries(${APP_TARGET} + openiotsdk-app +) + +include(linker) +set_target_link(${APP_TARGET}) diff --git a/examples/shell/openiotsdk/README.md b/examples/shell/openiotsdk/README.md new file mode 100644 index 00000000000000..5307edf1f86cd2 --- /dev/null +++ b/examples/shell/openiotsdk/README.md @@ -0,0 +1,45 @@ +# Matter Open IoT SDK Shell Example Application + +The example exposes configuration and management APIs via a command line +interface. It parses a command line and calls the corresponding service +execution. There is a set of common shell commands which perform basic device +operations. + +For more details see +[Common shell commands](../README.md#chip-shell-command-details). + +## Build and run + +For information on how to build and run this example and further information +about the platform it is run on see +[Open IoT SDK examples](../../../docs/examples/openiotsdk_examples.md). + +The example name to use in the scripts is `shell`. + +## Using the example + +Communication with the application goes through the active telnet session. When +the application runs these lines should be visible: + +``` +[INF] [SH] Open IoT SDK shell example application start +[INF] [SH] Open IoT SDK shell example application run +> +``` + +The shell application launched correctly. + +Pass commands to the terminal and wait for the response. The application +supports common Matter shell commands. They are used to control the basic +functionalities of the device. + +For more details read: +[Common shell commands](../README.md#chip-shell-command-details) + +Example: + +``` +> echo Hello +Hello +Done +``` diff --git a/examples/shell/openiotsdk/cmsis-config/RTE_Components.h b/examples/shell/openiotsdk/cmsis-config/RTE_Components.h new file mode 100644 index 00000000000000..e86df2b4e44e06 --- /dev/null +++ b/examples/shell/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/shell/openiotsdk/freertos-config/FreeRTOSConfig.h b/examples/shell/openiotsdk/freertos-config/FreeRTOSConfig.h new file mode 100644 index 00000000000000..6011c1e9d6bf79 --- /dev/null +++ b/examples/shell/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: 128 +#define configMINIMAL_STACK_SIZE ((uint16_t)(4 * 1024)) + +// Total heap size [bytes] <0-0xFFFFFFFF> +// Heap memory size in bytes. +// Default: 8192 +#define configTOTAL_HEAP_SIZE ((size_t) 8192) + +// 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 1 + +// 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/shell/openiotsdk/main/include/CHIPProjectConfig.h b/examples/shell/openiotsdk/main/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..7089ae47a8038f --- /dev/null +++ b/examples/shell/openiotsdk/main/include/CHIPProjectConfig.h @@ -0,0 +1,30 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION 0 +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP 0 + +#define CHIP_SHELL_MAX_MODULES 30 + +// 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 + +#define CHIP_DISPATCH_EVENT_LONG_DISPATCH_TIME_WARNING_THRESHOLD_MS 500 diff --git a/examples/shell/openiotsdk/main/main.cpp b/examples/shell/openiotsdk/main/main.cpp new file mode 100644 index 00000000000000..c832b2df4e49cf --- /dev/null +++ b/examples/shell/openiotsdk/main/main.cpp @@ -0,0 +1,94 @@ +/* + * + * 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 + +#include "cmsis_os2.h" +#include "openiotsdk_platform.h" + +using namespace ::chip; +using namespace ::chip::Shell; + +static void app_thread(void * argument) +{ + int ret; + + if (openiotsdk_network_init(true)) + { + ChipLogError(Shell, "Network initialization failed"); + goto exit; + } + + // Initialize the default streamer that was linked. + ret = Engine::Root().Init(); + if (ret) + { + ChipLogError(Shell, "Streamer initialization failed [%d]", ret); + goto exit; + } + + cmd_misc_init(); + + ChipLogProgress(Shell, "Open IoT SDK shell example application run"); + + Engine::Root().RunMainLoop(); + +exit: + osThreadTerminate(osThreadGetId()); +} + +int main() +{ + ChipLogProgress(Shell, "Open IoT SDK shell example application start"); + + if (openiotsdk_platform_init()) + { + ChipLogError(Shell, "Open IoT SDK platform initialization failed"); + return EXIT_FAILURE; + } + + if (openiotsdk_chip_init()) + { + ChipLogError(Shell, "Open IoT SDK CHIP stack initialization failed"); + return EXIT_FAILURE; + } + + static const osThreadAttr_t thread_attr = { + .stack_size = 8 * 1024 // Allocate enough stack for app thread + }; + + osThreadId_t appThread = osThreadNew(app_thread, NULL, &thread_attr); + if (appThread == NULL) + { + ChipLogError(Shell, "Failed to create app thread"); + return EXIT_FAILURE; + } + + if (openiotsdk_platform_run()) + { + ChipLogError(Shell, "Open IoT SDK platform run failed"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/scripts/build/BUILD.gn b/scripts/build/BUILD.gn index 60356666c0f6ae..39580c63f86341 100644 --- a/scripts/build/BUILD.gn +++ b/scripts/build/BUILD.gn @@ -31,6 +31,8 @@ pw_python_package("build_examples") { "testdata/dry_run_linux-arm64-ota-requestor-nodeps-ipv6only.txt", "testdata/dry_run_linux-x64-all-clusters-coverage.txt", "testdata/dry_run_nrf-nrf52840dk-pump.txt", + "testdata/dry_run_openiotsdk-lock.txt", + "testdata/dry_run_openiotsdk-shell.txt", ] sources = [ @@ -54,6 +56,7 @@ pw_python_package("build_examples") { "builders/mbed.py", "builders/mw320.py", "builders/nrf.py", + "builders/openiotsdk.py", "builders/qpg.py", "builders/telink.py", "builders/tizen.py", diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index b68e6fa59e43fb..789818e5a89140 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -37,6 +37,7 @@ from builders.bouffalolab import BouffalolabApp, BouffalolabBoard, BouffalolabBuilder from builders.imx import IMXApp, IMXBuilder from builders.genio import GenioApp, GenioBuilder +from builders.openiotsdk import OpenIotSdkApp, OpenIotSdkBuilder def BuildHostTestRunnerTarget(): @@ -529,6 +530,17 @@ def BuildTelinkTarget(): return target +def BuildOpenIotSdkTargets(): + target = BuildTarget('openiotsdk', OpenIotSdkBuilder) + + target.AppendFixedTargets([ + TargetPart('shell', app=OpenIotSdkApp.SHELL), + TargetPart('lock', app=OpenIotSdkApp.LOCK), + ]) + + return target + + BUILD_TARGETS = [ BuildAmebaTarget(), BuildAndroidTarget(), @@ -551,6 +563,5 @@ def BuildTelinkTarget(): BuildQorvoTarget(), BuildTizenTarget(), BuildTelinkTarget(), - - + BuildOpenIotSdkTargets(), ] diff --git a/scripts/build/builders/openiotsdk.py b/scripts/build/builders/openiotsdk.py new file mode 100644 index 00000000000000..dd24618e11e00e --- /dev/null +++ b/scripts/build/builders/openiotsdk.py @@ -0,0 +1,85 @@ +# 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. + +import os +import shlex +from enum import Enum, auto + +from .builder import Builder + + +class OpenIotSdkApp(Enum): + SHELL = auto() + LOCK = auto() + + @property + def ExampleName(self): + if self == OpenIotSdkApp.SHELL: + return 'shell' + elif self == OpenIotSdkApp.LOCK: + return 'lock-app' + else: + raise Exception('Unknown app type: %r' % self) + + @property + def AppNamePrefix(self): + if self == OpenIotSdkApp.SHELL: + return 'chip-openiotsdk-shell-example' + elif self == OpenIotSdkApp.LOCK: + return 'chip-openiotsdk-lock-app-example' + else: + raise Exception('Unknown app type: %r' % self) + + +class OpenIotSdkBuilder(Builder): + def __init__(self, + root, + runner, + app: OpenIotSdkApp = OpenIotSdkApp.SHELL): + super(OpenIotSdkBuilder, self).__init__(root, runner) + self.app = app + self.toolchain_path = os.path.join( + 'toolchains', 'toolchain-arm-none-eabi-gcc.cmake') + self.system_processor = 'cortex-m55' + + @property + def ExamplePath(self): + return os.path.join(self.root, 'examples', self.app.ExampleName, 'openiotsdk') + + def generate(self): + if not os.path.exists(self.output_dir): + self._Execute(['cmake', '-GNinja', '-S', shlex.quote(self.ExamplePath), '-B', shlex.quote(self.output_dir), + '--toolchain={}'.format( + shlex.quote(self.toolchain_path)), + '-DCMAKE_SYSTEM_PROCESSOR={}'.format( + self.system_processor), + ], title='Generating ' + self.identifier) + + def _build(self): + # Remove old artifacts to force linking + cmd = 'rm -rf {}/chip-*'.format(self.output_dir) + self._Execute(['bash', '-c', cmd], + title='Remove old artifacts ' + self.identifier) + + self._Execute(['cmake', '--build', shlex.quote(self.output_dir)], + title='Building ' + self.identifier) + + def build_outputs(self): + return { + self.app.AppNamePrefix + '.elf': + os.path.join(self.output_dir, self.app.AppNamePrefix + '.elf'), + self.app.AppNamePrefix + '.map': + os.path.join(self.output_dir, + self.app.AppNamePrefix + '.map'), + } diff --git a/scripts/build/test.py b/scripts/build/test.py index b0ba8a0d685c38..85f66535c49106 100644 --- a/scripts/build/test.py +++ b/scripts/build/test.py @@ -107,7 +107,9 @@ def test_general_dry_runs(self): 'esp32-m5stack-all-clusters-minimal-rpc-ipv6only', 'android-arm64-chip-tool', 'nrf-nrf52840dk-pump', - 'efr32-brd4161a-light-rpc' + 'efr32-brd4161a-light-rpc', + 'openiotsdk-lock', + 'openiotsdk-shell' ] for target in TARGETS: diff --git a/scripts/build/testdata/all_targets_linux_x64.txt b/scripts/build/testdata/all_targets_linux_x64.txt index 644a6d22b89cdf..a879bcf9b5c6a5 100644 --- a/scripts/build/testdata/all_targets_linux_x64.txt +++ b/scripts/build/testdata/all_targets_linux_x64.txt @@ -19,3 +19,4 @@ nrf-native-posix-64-tests qpg-qpg6105-{lock,light,shell,persistent-storage} tizen-arm-{all-clusters,all-clusters-minimal,chip-tool,light}[-no-ble][-no-wifi][-asan] telink-tlsr9518adk80d-{all-clusters,all-clusters-minimal,light,light-switch,ota-requestor,thermostat} +openiotsdk-{shell,lock} diff --git a/scripts/build/testdata/dry_run_openiotsdk-lock.txt b/scripts/build/testdata/dry_run_openiotsdk-lock.txt new file mode 100644 index 00000000000000..d00bdae66c6358 --- /dev/null +++ b/scripts/build/testdata/dry_run_openiotsdk-lock.txt @@ -0,0 +1,11 @@ +# Commands will be run in CHIP project root. +cd "{root}" + +# Generating openiotsdk-lock +cmake -GNinja -S {root}/examples/lock-app/openiotsdk -B {out}/openiotsdk-lock --toolchain=toolchains/toolchain-arm-none-eabi-gcc.cmake -DCMAKE_SYSTEM_PROCESSOR=cortex-m55 + +# Remove old artifacts openiotsdk-lock +bash -c 'rm -rf {out}/openiotsdk-lock/chip-*' + +# Building openiotsdk-lock +cmake --build {out}/openiotsdk-lock diff --git a/scripts/build/testdata/dry_run_openiotsdk-shell.txt b/scripts/build/testdata/dry_run_openiotsdk-shell.txt new file mode 100644 index 00000000000000..f93c6a3201b591 --- /dev/null +++ b/scripts/build/testdata/dry_run_openiotsdk-shell.txt @@ -0,0 +1,11 @@ +# Commands will be run in CHIP project root. +cd "{root}" + +# Generating openiotsdk-shell +cmake -GNinja -S {root}/examples/shell/openiotsdk -B {out}/openiotsdk-shell --toolchain=toolchains/toolchain-arm-none-eabi-gcc.cmake -DCMAKE_SYSTEM_PROCESSOR=cortex-m55 + +# Remove old artifacts openiotsdk-shell +bash -c 'rm -rf {out}/openiotsdk-shell/chip-*' + +# Building openiotsdk-shell +cmake --build {out}/openiotsdk-shell diff --git a/scripts/examples/openiotsdk_example.sh b/scripts/examples/openiotsdk_example.sh new file mode 100755 index 00000000000000..d700a227d0b767 --- /dev/null +++ b/scripts/examples/openiotsdk_example.sh @@ -0,0 +1,383 @@ +#!/bin/bash + +# +# 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. +# + +# Build and/or run Open IoT SDK examples. + +IS_TEST=0 +NAME="$(basename "$0")" +HERE="$(dirname "$0")" +CHIP_ROOT="$(realpath "$HERE"/../..)" +COMMAND=build +PLATFORM=corstone300 +CLEAN=0 +SCRATCH=0 +EXAMPLE_PATH="" +BUILD_PATH="" +TOOLCHAIN=arm-none-eabi-gcc +DEBUG=false +EXAMPLE="" +FVP_BIN=FVP_Corstone_SSE-300_Ethos-U55 +GDB_PLUGIN="$FAST_MODEL_PLUGINS_PATH/GDBRemoteConnection.so" +OIS_CONFIG="$CHIP_ROOT/config/openiotsdk" +FVP_CONFIG_FILE="$OIS_CONFIG/fvp/cs300.conf" +EXAMPLE_TEST_PATH="$CHIP_ROOT/src/test_driver/openiotsdk/integration-tests" +TELNET_TERMINAL_PORT=5000 +FAILED_TESTS=0 +FVP_NETWORK="user" + +readarray -t TEST_NAMES <"$CHIP_ROOT"/src/test_driver/openiotsdk/unit-tests/testnames.txt + +function show_usage() { + cat < Action to execute + -d,--debug Build in debug mode + -p,--path Build path + -n,--network FVP network interface name + +Examples: + shell + lock-app + unit-tests + +You can run individual test suites of unit tests by using their names [test_name] with the run command: + +EOF + cat "$CHIP_ROOT"/src/test_driver/openiotsdk/unit-tests/testnames.txt + echo "" + cat < parameter as [test_name] + +The "test" command can be used for all supported examples expect the unit-tests. + +EOF +} + +function build_with_cmake() { + CMAKE="$(which cmake)" + if [[ ! -f "$CMAKE" ]]; then + echo "$NAME: cmake is not in PATH" >&2 + exit 1 + fi + + set -e + + mkdir -p "$BUILD_PATH" + + if [[ $CLEAN -ne 0 ]]; then + echo "Clean build" >&2 + if compgen -G "$BUILD_PATH/CMake*" >/dev/null; then + cmake --build "$BUILD_PATH" --target clean + find "$BUILD_PATH" -name 'CMakeCache.txt' -delete + fi + fi + + if [[ $SCRATCH -ne 0 ]]; then + echo "Remove building directory" >&2 + rm -rf "$BUILD_PATH" + fi + + BUILD_OPTIONS=(-DCMAKE_SYSTEM_PROCESSOR=cortex-m55) + if "$DEBUG"; then + BUILD_OPTIONS+=(-DCMAKE_BUILD_TYPE=Debug) + fi + + # Remove old artifacts to force linking + rm -rf "$BUILD_PATH/chip-"* + + # Activate Matter environment + source "$CHIP_ROOT"/scripts/activate.sh + # Remove access to ARM GCC toolchain from Matter environment, use higher version from OIS environment + PATH=$(echo "$PATH" | sed 's/:/\n/g' | grep -v "$PW_ARM_CIPD_INSTALL_DIR" | xargs | tr ' ' ':') + + cmake -G Ninja -S "$EXAMPLE_PATH" -B "$BUILD_PATH" --toolchain="$TOOLCHAIN_PATH" "${BUILD_OPTIONS[@]}" + cmake --build "$BUILD_PATH" +} + +function run_fvp() { + + set -e + + # Check if FVP exists + if ! [ -x "$(command -v "$FVP_BIN")" ]; then + echo "Error: $FVP_BIN not installed." >&2 + exit 1 + fi + + if [[ $IS_TEST -eq 0 ]]; then + EXAMPLE_EXE_PATH="$BUILD_PATH/chip-openiotsdk-$EXAMPLE-example.elf" + else + EXAMPLE_EXE_PATH="$BUILD_PATH/$EXAMPLE.elf" + fi + + # Check if executable file exists + if ! [ -f "$EXAMPLE_EXE_PATH" ]; then + echo "Error: $EXAMPLE_EXE_PATH does not exist." >&2 + exit 1 + fi + + RUN_OPTIONS=(-C mps3_board.telnetterminal0.start_port="$TELNET_TERMINAL_PORT") + RUN_OPTIONS+=(--quantum=25) + + if "$DEBUG"; then + RUN_OPTIONS+=(--allow-debug-plugin --plugin "$GDB_PLUGIN") + fi + + if [[ $FVP_NETWORK == "user" ]]; then + RUN_OPTIONS+=(-C mps3_board.hostbridge.userNetworking=1) + else + RUN_OPTIONS+=(-C mps3_board.hostbridge.interfaceName="$FVP_NETWORK") + fi + + echo "Running $EXAMPLE_EXE_PATH with options: ${RUN_OPTIONS[@]}" + + "$FVP_BIN" "${RUN_OPTIONS[@]}" -f "$FVP_CONFIG_FILE" --application "$EXAMPLE_EXE_PATH" >/dev/null 2>&1 & + FVP_PID=$! + sleep 1 + + if [[ $IS_TEST -eq 1 ]]; then + set +e + expect <"$EXAMPLE_PATH"/test_report.json + else + telnet localhost "$TELNET_TERMINAL_PORT" + fi + + # stop the fvp + kill -9 "$FVP_PID" || true + set -e + sleep 1 +} + +function run_test() { + + EXAMPLE_EXE_PATH="$BUILD_PATH/chip-openiotsdk-$EXAMPLE-example.elf" + # Check if executable file exists + if ! [ -f "$EXAMPLE_EXE_PATH" ]; then + echo "Error: $EXAMPLE_EXE_PATH does not exist." >&2 + exit 1 + fi + + # Check if FVP exists + if ! [ -x "$(command -v "$FVP_BIN")" ]; then + echo "Error: $FVP_BIN not installed." >&2 + exit 1 + fi + + # Activate Matter environment with pytest + source "$CHIP_ROOT"/scripts/activate.sh + + # Check if pytest exists + if ! [ -x "$(command -v pytest)" ]; then + echo "Error: pytest not installed." >&2 + exit 1 + fi + + TEST_OPTIONS=() + + if [[ $FVP_NETWORK ]]; then + TEST_OPTIONS+=(--networkInterface="$FVP_NETWORK") + fi + + if [[ -f $EXAMPLE_TEST_PATH/$EXAMPLE/test_report.json ]]; then + rm -rf "$EXAMPLE_TEST_PATH/$EXAMPLE"/test_report.json + fi + + set +e + pytest --json-report --json-report-summary --json-report-file="$EXAMPLE_TEST_PATH/$EXAMPLE"/test_report.json --binaryPath="$EXAMPLE_EXE_PATH" --fvp="$FVP_BIN" --fvpConfig="$FVP_CONFIG_FILE" "${TEST_OPTIONS[@]}" "$EXAMPLE_TEST_PATH/$EXAMPLE"/test_app.py + set -e + + if [[ ! -f $EXAMPLE_TEST_PATH/$EXAMPLE/test_report.json ]]; then + exit 1 + else + if [[ $(jq '.summary | has("failed")' $EXAMPLE_TEST_PATH/$EXAMPLE/test_report.json) == true ]]; then + FAILED_TESTS=$(jq '.summary.failed' "$EXAMPLE_TEST_PATH/$EXAMPLE"/test_report.json) + fi + fi +} + +SHORT=C:,p:,d:.n:,c,s,h +LONG=command:,path:,debug:.network:,clean,scratch,help +OPTS=$(getopt -n build --options "$SHORT" --longoptions "$LONG" -- "$@") + +eval set -- "$OPTS" + +while :; do + case "$1" in + -h | --help) + show_usage + exit 0 + ;; + -c | --clean) + CLEAN=1 + shift + ;; + -s | --scratch) + SCRATCH=1 + shift + ;; + -C | --command) + COMMAND=$2 + shift 2 + ;; + -d | --debug) + DEBUG=$2 + shift 2 + ;; + -p | --path) + BUILD_PATH=$CHIP_ROOT/$2 + shift 2 + ;; + -n | --network) + FVP_NETWORK=$2 + shift 2 + ;; + -* | --*) + shift + break + ;; + *) + echo "Unexpected option: $1" + show_usage + exit 2 + ;; + esac +done + +if [[ $# -lt 1 ]]; then + show_usage >&2 + exit 1 +fi + +case "$1" in + shell | unit-tests | lock-app) + EXAMPLE=$1 + ;; + *) + echo "Wrong example name" + show_usage + exit 2 + ;; +esac + +if [[ "$EXAMPLE" == "unit-tests" ]]; then + if [ ! -z "$2" ]; then + if [[ " ${TEST_NAMES[*]} " =~ " $2 " ]]; then + if [[ "$COMMAND" != *"run"* ]]; then + echo "Test suites can only accept --command run" + show_usage + exit 2 + fi + EXAMPLE=$2 + echo "Run specific unit test $EXAMPLE" + elif [[ "$2" == "all" ]]; then + echo "Use all unit tests" + else + echo " Wrong unit test name" + show_usage + exit 2 + fi + else + echo "Use all unit tests" + fi + IS_TEST=1 +fi + +case "$COMMAND" in + build | run | test | build-run) ;; + *) + echo "Wrong command definition" + show_usage + exit 2 + ;; +esac + +TOOLCHAIN_PATH="toolchains/toolchain-$TOOLCHAIN.cmake" + +if [[ $IS_TEST -eq 0 ]]; then + EXAMPLE_PATH="$CHIP_ROOT/examples/$EXAMPLE/openiotsdk" +else + EXAMPLE_PATH="$CHIP_ROOT/src/test_driver/openiotsdk/unit-tests" + if [[ -f $EXAMPLE_PATH/test_report.json ]]; then + rm -rf "$EXAMPLE_PATH"/test_report.json + fi + echo "{}" >"$EXAMPLE_PATH"/test_report.json +fi + +if [ -z "$BUILD_PATH" ]; then + BUILD_PATH="$EXAMPLE_PATH/build" +fi + +if [[ "$COMMAND" == *"build"* ]]; then + build_with_cmake +fi + +if [[ "$COMMAND" == *"run"* ]]; then + # If user wants to run unit-tests we need to loop through all test names + if [[ "$EXAMPLE" == "unit-tests" ]]; then + if "$DEBUG"; then + echo "You have to specify the test suites to run in debug mode" + show_usage + exit 2 + else + for NAME in "${TEST_NAMES[@]}"; do + EXAMPLE=$NAME + echo "$EXAMPLE_PATH" + echo "Run specific unit test $EXAMPLE" + run_fvp + done + echo "Failed tests total: $FAILED_TESTS" + fi + else + run_fvp + fi +fi + +if [[ "$COMMAND" == *"test"* ]]; then + if [[ "$EXAMPLE" == "unit-tests" ]]; then + echo "The test command can not be applied to the unit-tests example" + show_usage + exit 2 + else + IS_TEST=1 + run_test + fi +fi + +if [[ $IS_TEST -eq 1 ]]; then + exit "$FAILED_TESTS" +fi diff --git a/scripts/run_in_ns.sh b/scripts/run_in_ns.sh new file mode 100755 index 00000000000000..33d4f6661f432d --- /dev/null +++ b/scripts/run_in_ns.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# +# 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. +# + +# This script executes the command given as an argument within +# CHIP_ROOT in a specific network namespace. + +NETWORK_NAMESPACE="default" + +function show_usage() { + cat <&2 + exit 1 +fi + +NETWORK_NAMESPACE=$1 +shift + +if [[ $NETWORK_NAMESPACE == "default" ]]; then + "$@" +else + if [ ! -f /var/run/netns/"$NETWORK_NAMESPACE" ]; then + echo "$NETWORK_NAMESPACE network namespace does not exist" + show_usage >&2 + exit 1 + fi + echo "Run command: $@ in $NETWORK_NAMESPACE namespace" + if [ "$EUID" -ne 0 ]; then + sudo env PATH="$PATH" ip netns exec "$NETWORK_NAMESPACE" "$@" + else + ip netns exec "$NETWORK_NAMESPACE" "$@" + fi +fi diff --git a/scripts/setup/openiotsdk/connect_if.sh b/scripts/setup/openiotsdk/connect_if.sh new file mode 100755 index 00000000000000..21c7460a01fb79 --- /dev/null +++ b/scripts/setup/openiotsdk/connect_if.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +# +# 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. +# + +# Enable/disable/restart TAP/TUN Open IoT SDK networking environment. + +HOST_BRIDGE="ARMhbr" +DEFAULT_ROUTE_IF="" +USER="$(id -u -n)" +INTERFACES=() + +declare -A default_if_info + +if [ "$EUID" -ne 0 ]; then + echo "Run a script with root permissions" + exit 1 +fi + +function show_usage() { + cat < ... + +Connect specific network interfaces with the default route interface. Create a bridge and link all interfaces to it. +Keep the default route of network traffic. + +EOF +} + +function get_default_if_info() { + default_if_info[ip]="$(ifconfig "$DEFAULT_ROUTE_IF" | grep -w inet | awk '{print $2}' | cut -d ":" -f 2)" + default_if_info[netmask]="$(ifconfig "$DEFAULT_ROUTE_IF" | grep -w inet | awk '{print $4}' | cut -d ":" -f 2)" + default_if_info[broadcast]="$(ifconfig "$DEFAULT_ROUTE_IF" | grep -w inet | awk '{print $6}' | cut -d ":" -f 2)" + default_if_info[gateway]="$(ip route show 0.0.0.0/0 dev "$DEFAULT_ROUTE_IF" | cut -d\ -f3)" +} + +function connect_with_host() { + ip link add name "$HOST_BRIDGE" type bridge + ip link set "$DEFAULT_ROUTE_IF" master "$HOST_BRIDGE" + ip addr flush dev "$DEFAULT_ROUTE_IF" + for interface in "${INTERFACES[@]}"; do + ip link set "$interface" master "$HOST_BRIDGE" + ip addr flush dev "$interface" + done + ifconfig "$HOST_BRIDGE" "${default_if_info[ip]}" netmask "${default_if_info[netmask]}" broadcast "${default_if_info[broadcast]}" + route add default gw "${default_if_info[gateway]}" "$HOST_BRIDGE" +} + +if [[ $# -lt 1 ]]; then + show_usage >&2 + exit 1 +fi + +INTERFACES=("$*") +DEFAULT_ROUTE_IF=$(route | grep '^default' | grep -o '[^ ]*$') +echo "Default route interface $DEFAULT_ROUTE_IF" +get_default_if_info +echo "Connect $INTERFACES to $DEFAULT_ROUTE_IF via bridge" +connect_with_host diff --git a/scripts/setup/openiotsdk/network_setup.sh b/scripts/setup/openiotsdk/network_setup.sh new file mode 100755 index 00000000000000..e5d5739ac129e1 --- /dev/null +++ b/scripts/setup/openiotsdk/network_setup.sh @@ -0,0 +1,189 @@ +#!/bin/bash + +# +# 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. +# + +# Enable/disable/restart Open IoT SDK networking environment. + +NAMESPACE_NAME="ns" +HOST_SIDE_IF_NAME="hveth" +NAMESPACE_SIDE_IF_NAME="nveth" +TAP_TUN_INTERFACE_NAME="tap" +BRIDGE_INTERFACE_NAME="br" +HOST_IPV6_ADDR="fe00::1" +NAMESPACE_IPV6_ADDR="fe00::2" +HOST_IPV4_ADDR="10.200.1.1" +NAMESPACE_IPV4_ADDR="10.200.1.2" +NAME="ARM" +INTERNET_ENABLE=false +USER="$(id -u -n)" + +if [ "$EUID" -ne 0 ]; then + echo "Run a script with root permissions" + exit 1 +fi + +function show_usage() { + cat < Open IoT SDK network base name + -u,--user Network user + -I,--Internet Add Internet connection support to network namespace + +command: + up + down + restart + +EOF +} + +function net_ns_up() { + # Enable IPv6 and IP-forwarding + sysctl net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1 + + echo "Create $NAMESPACE_NAME network namespace" + # Create namespace. + ip netns add "$NAMESPACE_NAME" + + # Enable lo interface in namespace + ip netns exec "$NAMESPACE_NAME" ip link set dev lo up + + echo "Adding $HOST_SIDE_IF_NAME veth with peer $NAMESPACE_SIDE_IF_NAME" + # Create two virtual interfaces and link them - one on host side, one on namespace side. + ip link add "$HOST_SIDE_IF_NAME" type veth peer name "$NAMESPACE_SIDE_IF_NAME" + + # Give the host a known IPv6 addr and set the host side up + echo "Set IP addresses $HOST_IPV4_ADDR/24 $HOST_IPV6_ADDR/64 to $HOST_SIDE_IF_NAME interface" + ip addr add "$HOST_IPV4_ADDR"/24 dev "$HOST_SIDE_IF_NAME" + ip -6 addr add "$HOST_IPV6_ADDR"/64 dev "$HOST_SIDE_IF_NAME" + ip link set "$HOST_SIDE_IF_NAME" up + + echo "Adding $NAMESPACE_SIDE_IF_NAME veth to namespace $NAMESPACE_NAME" + # Associate namespace IF with the namespace + ip link set "$NAMESPACE_SIDE_IF_NAME" netns "$NAMESPACE_NAME" + ip netns exec "$NAMESPACE_NAME" ip link set dev "$NAMESPACE_SIDE_IF_NAME" up + + echo "Create $TAP_TUN_INTERFACE_NAME TAP device" + ip netns exec "$NAMESPACE_NAME" ip tuntap add dev "$TAP_TUN_INTERFACE_NAME" mode tap user "$USER" + ip netns exec "$NAMESPACE_NAME" ifconfig "$TAP_TUN_INTERFACE_NAME" 0.0.0.0 promisc + + echo "Create $BRIDGE_INTERFACE_NAME bridge interface between $NAMESPACE_SIDE_IF_NAME and $TAP_TUN_INTERFACE_NAME" + ip netns exec "$NAMESPACE_NAME" ip link add "$BRIDGE_INTERFACE_NAME" type bridge + echo "Set IP addresses $NAMESPACE_IPV4_ADDR/24 $NAMESPACE_IPV6_ADDR/64 to $BRIDGE_INTERFACE_NAME bridge interface" + ip netns exec "$NAMESPACE_NAME" ip -6 addr add "$NAMESPACE_IPV6_ADDR"/64 dev "$BRIDGE_INTERFACE_NAME" + ip netns exec "$NAMESPACE_NAME" ip addr add "$NAMESPACE_IPV4_ADDR"/24 dev "$BRIDGE_INTERFACE_NAME" + ip netns exec "$NAMESPACE_NAME" ip addr flush dev "$NAMESPACE_SIDE_IF_NAME" + ip netns exec "$NAMESPACE_NAME" ip link set "$TAP_TUN_INTERFACE_NAME" master "$BRIDGE_INTERFACE_NAME" + ip netns exec "$NAMESPACE_NAME" ip link set "$NAMESPACE_SIDE_IF_NAME" master "$BRIDGE_INTERFACE_NAME" + ip netns exec "$NAMESPACE_NAME" ip link set dev "$BRIDGE_INTERFACE_NAME" up + + ip netns exec "$NAMESPACE_NAME" ip route add default via "$HOST_IPV4_ADDR" + + if "$INTERNET_ENABLE"; then + echo "Set Internet connection to $NAMESPACE_NAME namespace" + DEFAULT_ROUTE=$(route | grep '^default' | grep -o '[^ ]*$') + echo "Default route interface $DEFAULT_ROUTE" + # Enable masquerading of namespace IP address + iptables -t nat -A POSTROUTING -s "$NAMESPACE_IPV4_ADDR"/24 -o "$DEFAULT_ROUTE" -j MASQUERADE + + iptables -A FORWARD -i "$DEFAULT_ROUTE" -o "$HOST_SIDE_IF_NAME" -j ACCEPT + iptables -A FORWARD -o "$DEFAULT_ROUTE" -i "$HOST_SIDE_IF_NAME" -j ACCEPT + fi + + echo "$NAMESPACE_NAME namespace configuration" + ip netns exec "$NAMESPACE_NAME" ifconfig + echo "Host configuration" + ifconfig +} + +function net_ns_down() { + ip netns delete "$NAMESPACE_NAME" + ip link delete dev "$HOST_SIDE_IF_NAME" + echo "Host configuration" + ifconfig +} + +SHORT=n:,u:,I,h, +LONG=name:,user:,Internet,help +OPTS=$(getopt -n build --options "$SHORT" --longoptions "$LONG" -- "$@") + +eval set -- "$OPTS" + +while :; do + case "$1" in + -h | --help) + show_usage + exit 0 + ;; + -n | --name) + NAME=$2 + shift 2 + ;; + -u | --user) + USER=$2 + shift 2 + ;; + -I | --Internet) + INTERNET_ENABLE=true + shift + ;; + -* | --*) + shift + break + ;; + *) + echo "Unexpected option: $1" + show_usage + exit 2 + ;; + esac +done + +if [[ $# -lt 1 ]]; then + show_usage >&2 + exit 1 +fi + +case "$1" in + up | down | restart) + COMMAND=$1 + ;; + *) + echo "ERROR: Command $COMMAND not supported" + show_usage + exit 1 + ;; +esac + +NAMESPACE_NAME="$NAME$NAMESPACE_NAME" +HOST_SIDE_IF_NAME="$NAME$HOST_SIDE_IF_NAME" +NAMESPACE_SIDE_IF_NAME="$NAME$NAMESPACE_SIDE_IF_NAME" +TAP_TUN_INTERFACE_NAME="$NAME$TAP_TUN_INTERFACE_NAME" +BRIDGE_INTERFACE_NAME="$NAME$BRIDGE_INTERFACE_NAME" + +if [[ "$COMMAND" == *"down"* || "$COMMAND" == *"restart"* ]]; then + net_ns_down +fi + +if [[ "$COMMAND" == *"up"* || "$COMMAND" == *"restart"* ]]; then + net_ns_up +fi diff --git a/scripts/tools/memory/platform/openiotsdk.cfg b/scripts/tools/memory/platform/openiotsdk.cfg new file mode 100644 index 00000000000000..4717f1278044dd --- /dev/null +++ b/scripts/tools/memory/platform/openiotsdk.cfg @@ -0,0 +1,23 @@ +# 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. + +# Memory tools default configuation for Open IoT SDK platform. + +{ + 'section': { + # By default, only these sections will be included + # when operating by sections. + 'default': ['.text', '.data', '.bss', '.stack', '.heap'], + }, +} diff --git a/src/BUILD.gn b/src/BUILD.gn index c495ca83d1d908..2a24d53c8fce01 100644 --- a/src/BUILD.gn +++ b/src/BUILD.gn @@ -107,10 +107,13 @@ if (chip_build_tests) { if (chip_device_platform != "nrfconnect" && chip_device_platform != "efr32") { # TODO(#10447): Controller test has HF on EFR32. - deps += [ - "${chip_root}/src/controller/tests", - "${chip_root}/src/controller/tests/data_model", - ] + deps += [ "${chip_root}/src/controller/tests/data_model" ] + + # Skip controller test for Open IoT SDK + # https://github.com/project-chip/connectedhomeip/issues/23747 + if (chip_device_platform != "openiotsdk") { + deps += [ "${chip_root}/src/controller/tests" ] + } } if (current_os != "zephyr" && current_os != "mbed" && diff --git a/src/app/tests/TestFailSafeContext.cpp b/src/app/tests/TestFailSafeContext.cpp index 9e5d11dc320b73..f0631cd7a92386 100644 --- a/src/app/tests/TestFailSafeContext.cpp +++ b/src/app/tests/TestFailSafeContext.cpp @@ -50,8 +50,10 @@ constexpr FabricIndex kTestAccessingFabricIndex2 = 2; static void TestPlatformMgr_Init(nlTestSuite * inSuite, void * inContext) { +#if !defined(CHIP_DEVICE_LAYER_TARGET_OPEN_IOT_SDK) CHIP_ERROR err = PlatformMgr().InitChipStack(); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); +#endif // !defined(CHIP_DEVICE_LAYER_TARGET_OPEN_IOT_SDK) } static void TestFailSafeContext_ArmFailSafe(nlTestSuite * inSuite, void * inContext) @@ -121,7 +123,9 @@ int TestFailSafeContext_Setup(void * inContext) */ int TestFailSafeContext_Teardown(void * inContext) { +#if !defined(CHIP_DEVICE_LAYER_TARGET_OPEN_IOT_SDK) PlatformMgr().Shutdown(); +#endif // !defined(CHIP_DEVICE_LAYER_TARGET_OPEN_IOT_SDK) chip::Platform::MemoryShutdown(); return SUCCESS; } diff --git a/src/controller/tests/BUILD.gn b/src/controller/tests/BUILD.gn index ec7f26b6d7d2d4..0528c977c95a3b 100644 --- a/src/controller/tests/BUILD.gn +++ b/src/controller/tests/BUILD.gn @@ -26,9 +26,9 @@ chip_test_suite("tests") { if (chip_device_platform != "mbed" && chip_device_platform != "efr32" && chip_device_platform != "esp32") { test_sources += [ "TestServerCommandDispatch.cpp" ] - test_sources += [ "TestReadChunking.cpp" ] test_sources += [ "TestEventChunking.cpp" ] test_sources += [ "TestEventCaching.cpp" ] + test_sources += [ "TestReadChunking.cpp" ] test_sources += [ "TestWriteChunking.cpp" ] } diff --git a/src/credentials/BUILD.gn b/src/credentials/BUILD.gn index b33a9bcdbf1b5d..82cf18b6bc0fd7 100644 --- a/src/credentials/BUILD.gn +++ b/src/credentials/BUILD.gn @@ -59,9 +59,10 @@ static_library("credentials") { # TODO: These tests files should be removed after the DeviceAttestationCredsExample implementation # is changed to generate it's own credentials instead of using Test credentials. - # For mbed and nrfconnect test builds, which are bilding monolithic test library these files are not needed. + # For some platforms test builds, which are bilding monolithic test library these files are not needed. import("${chip_root}/build/chip/tests.gni") if (!(chip_build_tests && (chip_device_platform == "mbed" || + chip_device_platform == "openiotsdk" || chip_device_platform == "nrfconnect"))) { sources += [ "tests/CHIPAttCert_test_vectors.cpp", @@ -70,7 +71,7 @@ static_library("credentials") { } if (chip_device_platform == "esp32" || chip_device_platform == "nrfconnect" || - chip_device_platform == "efr32") { + chip_device_platform == "efr32" || chip_device_platform == "openiotsdk") { defines = [ "CURRENT_TIME_NOT_IMPLEMENTED=1" ] } @@ -98,7 +99,7 @@ static_library("default_attestation_verifier") { ] if (chip_device_platform == "esp32" || chip_device_platform == "nrfconnect" || - chip_device_platform == "efr32") { + chip_device_platform == "efr32" || chip_device_platform == "openiotsdk") { defines = [ "CURRENT_TIME_NOT_IMPLEMENTED=1" ] } diff --git a/src/credentials/tests/BUILD.gn b/src/credentials/tests/BUILD.gn index 041d26e20e3138..fd24132e4cab1b 100644 --- a/src/credentials/tests/BUILD.gn +++ b/src/credentials/tests/BUILD.gn @@ -46,7 +46,6 @@ chip_test_suite("tests") { test_sources = [ "TestCertificationDeclaration.cpp", "TestChipCert.cpp", - "TestCommissionerDUTVectors.cpp", "TestDeviceAttestationConstruction.cpp", "TestDeviceAttestationCredentials.cpp", "TestFabricTable.cpp", @@ -54,6 +53,11 @@ chip_test_suite("tests") { "TestPersistentStorageOpCertStore.cpp", ] + # DUTVectors test requires which is not supported on all platforms + if (chip_device_platform != "openiotsdk") { + test_sources += [ "TestCommissionerDUTVectors.cpp" ] + } + cflags = [ "-Wconversion" ] public_deps = [ diff --git a/src/crypto/BUILD.gn b/src/crypto/BUILD.gn index 5d0e0f4198d012..93293295a1ca1e 100644 --- a/src/crypto/BUILD.gn +++ b/src/crypto/BUILD.gn @@ -22,7 +22,8 @@ import("crypto.gni") if (chip_crypto == "") { if (current_os == "android" || current_os == "freertos" || - current_os == "zephyr" || current_os == "mbed" || current_os == "webos") { + current_os == "zephyr" || current_os == "mbed" || current_os == "webos" || + current_os == "cmsis-rtos") { chip_crypto = "mbedtls" } else { chip_crypto = "openssl" diff --git a/src/crypto/tests/BUILD.gn b/src/crypto/tests/BUILD.gn index fac74ed677c009..1865d875a90f2c 100644 --- a/src/crypto/tests/BUILD.gn +++ b/src/crypto/tests/BUILD.gn @@ -49,7 +49,7 @@ chip_test_suite("tests") { ] if (chip_device_platform == "esp32" || chip_device_platform == "nrfconnect" || - chip_device_platform == "efr32") { + chip_device_platform == "efr32" || chip_device_platform == "openiotsdk") { defines = [ "CURRENT_TIME_NOT_IMPLEMENTED=1" ] } diff --git a/src/inet/tests/TestInetCommonPosix.cpp b/src/inet/tests/TestInetCommonPosix.cpp index e7e658e0252a2c..d7820303a9a995 100644 --- a/src/inet/tests/TestInetCommonPosix.cpp +++ b/src/inet/tests/TestInetCommonPosix.cpp @@ -287,7 +287,9 @@ void InitNetwork() } } #endif // CHIP_TARGET_STYLE_UNIX +#if !defined(CHIP_DEVICE_LAYER_TARGET_OPEN_IOT_SDK) tcpip_init(OnLwIPInitComplete, NULL); +#endif // !defined(CHIP_DEVICE_LAYER_TARGET_OPEN_IOT_SDK) // Lock LwIP stack LOCK_TCPIP_CORE(); @@ -457,6 +459,13 @@ void ServiceEvents(uint32_t aSleepTimeMilliseconds) if (sRemainingSystemLayerEventDelay == 0) { +#if defined(CHIP_DEVICE_LAYER_TARGET_OPEN_IOT_SDK) + // We need to terminate event loop after performance single step. + // Event loop processing work items until StopEventLoopTask is called. + // Scheduling StopEventLoop task guarantees correct operation of the loop. + chip::DeviceLayer::PlatformMgr().ScheduleWork( + [](intptr_t) -> void { chip::DeviceLayer::PlatformMgr().StopEventLoopTask(); }, (intptr_t) nullptr); +#endif // CHIP_DEVICE_LAYER_TARGET_OPEN_IOT_SDK chip::DeviceLayer::PlatformMgr().RunEventLoop(); sRemainingSystemLayerEventDelay = gNetworkOptions.EventDelay; } diff --git a/src/lib/core/core.gni b/src/lib/core/core.gni index da4cf547e7c80a..ddd32fdd958b4d 100644 --- a/src/lib/core/core.gni +++ b/src/lib/core/core.gni @@ -87,7 +87,7 @@ declare_args() { if (chip_target_style == "") { if (current_os != "freertos" && current_os != "zephyr" && - current_os != "mbed") { + current_os != "mbed" && current_os != "cmsis-rtos") { chip_target_style = "unix" } else { chip_target_style = "embedded" diff --git a/src/lib/shell/BUILD.gn b/src/lib/shell/BUILD.gn index 34a4cfc91122b8..d3fc4a4ee01127 100644 --- a/src/lib/shell/BUILD.gn +++ b/src/lib/shell/BUILD.gn @@ -104,6 +104,11 @@ static_library("shell") { "MainLoopDefault.cpp", "streamer_ameba.cpp", ] + } else if (chip_device_platform == "openiotsdk") { + sources += [ + "MainLoopDefault.cpp", + "streamer_openiotsdk.cpp", + ] } else { sources += [ "MainLoopDefault.cpp" ] } diff --git a/src/lib/shell/streamer_openiotsdk.cpp b/src/lib/shell/streamer_openiotsdk.cpp new file mode 100644 index 00000000000000..ae0e9d824aebb9 --- /dev/null +++ b/src/lib/shell/streamer_openiotsdk.cpp @@ -0,0 +1,62 @@ +/* + * + * 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. + */ + +/** + * @file + * Source implementation of an input / output stream for Open IoT SDK platform. + */ + +#include +#include +#include + +#include + +namespace chip { +namespace Shell { + +int streamer_openiotsdk_init(streamer_t * streamer) +{ + (void) streamer; + return 0; +} + +ssize_t streamer_openiotsdk_read(streamer_t * streamer, char * buf, size_t len) +{ + (void) streamer; + return read(STDIN_FILENO, buf, len); +} + +ssize_t streamer_openiotsdk_write(streamer_t * streamer, const char * buf, size_t len) +{ + (void) streamer; + return write(STDOUT_FILENO, buf, len); +} + +static streamer_t streamer_openiotsdk = { + .init_cb = streamer_openiotsdk_init, + .read_cb = streamer_openiotsdk_read, + .write_cb = streamer_openiotsdk_write, +}; + +streamer_t * streamer_get() +{ + return &streamer_openiotsdk; +} + +} // namespace Shell +} // namespace chip diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn index 92687ba2969a0a..b9f75555e02cd8 100644 --- a/src/platform/BUILD.gn +++ b/src/platform/BUILD.gn @@ -283,6 +283,11 @@ if (chip_device_platform != "none" && chip_device_platform != "external") { "CHIP_DEVICE_LAYER_TARGET=mt793x", "CHIP_DEVICE_CONFIG_ENABLE_WIFI=${chip_enable_wifi}", ] + } else if (chip_device_platform == "openiotsdk") { + defines += [ + "CHIP_DEVICE_LAYER_TARGET_OPEN_IOT_SDK=1", + "CHIP_DEVICE_LAYER_TARGET=openiotsdk", + ] } if (chip_device_config_device_software_version_string != "") { @@ -459,6 +464,8 @@ if (chip_device_platform != "none") { _platform_target = "Beken" } else if (chip_device_platform == "mt793x") { _platform_target = "mt793x" + } else if (chip_device_platform == "openiotsdk") { + _platform_target = "openiotsdk" } else { assert(false, "Unknown chip_device_platform: ${chip_device_platform}") } diff --git a/src/platform/device.gni b/src/platform/device.gni index c0ad4bb5daa3a7..70cbe9955e7419 100755 --- a/src/platform/device.gni +++ b/src/platform/device.gni @@ -16,7 +16,7 @@ import("//build_overrides/chip.gni") import("${chip_root}/src/ble/ble.gni") declare_args() { - # Device platform layer: cc13x2_26x2, cc32xx, darwin, efr32, esp32, external, freertos, linux, nrfconnect, k32w0, qpg, tizen, cyw30739, bl602, mw320, zephyr, beken, none. + # Device platform layer: cc13x2_26x2, cc32xx, darwin, efr32, esp32, external, freertos, linux, nrfconnect, k32w0, qpg, tizen, cyw30739, bl602, mw320, zephyr, beken, openiotsdk, none. chip_device_platform = "auto" chip_platform_target = "" @@ -86,7 +86,8 @@ declare_args() { chip_device_platform == "ameba" || chip_device_platform == "webos" || chip_device_platform == "cc32xx" || chip_device_platform == "bl602" || chip_device_platform == "mw320" || chip_device_platform == "beken" || - chip_device_platform == "mt793x") { + chip_device_platform == "mt793x" || + chip_device_platform == "openiotsdk") { chip_mdns = "minimal" } else if (chip_device_platform == "darwin" || chip_device_platform == "cc13x2_26x2" || current_os == "android" || @@ -153,6 +154,8 @@ if (chip_device_platform == "cc13x2_26x2") { _chip_device_layer = "Beken" } else if (chip_device_platform == "mt793x") { _chip_device_layer = "mt793x" +} else if (chip_device_platform == "openiotsdk") { + _chip_device_layer = "openiotsdk" } if (chip_device_platform != "external") { @@ -214,5 +217,6 @@ assert( chip_device_platform == "webos" || chip_device_platform == "bl602" || chip_device_platform == "mw320" || chip_device_platform == "zephyr" || chip_device_platform == "beken" || chip_device_platform == "bl702" || - chip_device_platform == "mt793x" || chip_device_platform == "SiWx917", + chip_device_platform == "mt793x" || chip_device_platform == "SiWx917" || + chip_device_platform == "openiotsdk", "Please select a valid value for chip_device_platform") diff --git a/src/platform/openiotsdk/BUILD.gn b/src/platform/openiotsdk/BUILD.gn new file mode 100644 index 00000000000000..2b80b49a8aeb6b --- /dev/null +++ b/src/platform/openiotsdk/BUILD.gn @@ -0,0 +1,51 @@ +# 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. + +import("//build_overrides/chip.gni") + +import("${chip_root}/src/platform/device.gni") + +assert(chip_device_platform == "openiotsdk") + +static_library("openiotsdk") { + sources = [ + "../SingletonConfigurationManager.cpp", + "BlePlatformConfig.h", + "CHIPDevicePlatformConfig.h", + "CHIPDevicePlatformEvent.h", + "CHIPPlatformConfig.h", + "ConfigurationManagerImpl.cpp", + "ConfigurationManagerImpl.h", + "ConnectivityManagerImpl.cpp", + "ConnectivityManagerImpl.h", + "DiagnosticDataProviderImpl.cpp", + "DiagnosticDataProviderImpl.h", + "InetPlatformConfig.h", + "KeyValueStoreManagerImpl.cpp", + "KeyValueStoreManagerImpl.h", + "Logging.cpp", + "NetworkCommissioningDriver.h", + "NetworkCommissioningEthernetDriver.cpp", + "OpenIoTSDKArchUtils.c", + "OpenIoTSDKArchUtils.h", + "OpenIoTSDKConfig.cpp", + "OpenIoTSDKConfig.h", + "PlatformManagerImpl.cpp", + "PlatformManagerImpl.h", + "SystemPlatformConfig.h", + "SystemTimeSupport.cpp", + ] + + public_deps = [ "${chip_root}/src/platform:platform_base" ] +} diff --git a/src/platform/openiotsdk/BlePlatformConfig.h b/src/platform/openiotsdk/BlePlatformConfig.h new file mode 100644 index 00000000000000..55b4eccdebdbb4 --- /dev/null +++ b/src/platform/openiotsdk/BlePlatformConfig.h @@ -0,0 +1,30 @@ +/* + * + * 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 + * Platform-specific configuration overrides for the CHIP BLE + * Layer on Open IoT SDK platform. + * + */ + +#pragma once + +// ==================== Platform Adaptations ==================== + +// ========== Platform-specific Configuration Overrides ========= diff --git a/src/platform/openiotsdk/CHIPDevicePlatformConfig.h b/src/platform/openiotsdk/CHIPDevicePlatformConfig.h new file mode 100644 index 00000000000000..3e9c17c22edc67 --- /dev/null +++ b/src/platform/openiotsdk/CHIPDevicePlatformConfig.h @@ -0,0 +1,40 @@ +/* + * + * 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 + * Platform-specific configuration overrides for the chip Device Layer + * on Open IOT SDK platform. + */ + +#pragma once + +// ==================== Platform Adaptations ==================== + +#define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 0 + +#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 0 +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD 0 + +// ========== Platform-specific Configuration Overrides ========= + +#define CHIP_DEVICE_CONFIG_LOG_PROVISIONING_HASH 0 + +#ifndef CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE +#define CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE 8192 +#endif // CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE diff --git a/src/platform/openiotsdk/CHIPDevicePlatformEvent.h b/src/platform/openiotsdk/CHIPDevicePlatformEvent.h new file mode 100644 index 00000000000000..035bf1f168af5e --- /dev/null +++ b/src/platform/openiotsdk/CHIPDevicePlatformEvent.h @@ -0,0 +1,60 @@ +/* + * + * 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 + * Defines platform-specific event types and data for the chip + * Device Layer on the Open IOT SDK platform. + */ + +#pragma once + +#include + +namespace chip { +namespace DeviceLayer { + +namespace DeviceEventType { + +/** + * Enumerates Open IoT SDK platform-specific event types that are visible to the application. + */ +enum PublicPlatformSpecificEventTypes +{ + /* None currently defined */ +}; + +/** + * Enumerates Open IoT SDK platform-specific event types that are internal to the chip Device Layer. + */ +enum InternalPlatformSpecificEventTypes +{ + +}; + +} // namespace DeviceEventType + +/** + * Represents platform-specific event information for Open IoT SDK platform. + */ +struct ChipDevicePlatformEvent final +{ +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/openiotsdk/CHIPPlatformConfig.h b/src/platform/openiotsdk/CHIPPlatformConfig.h new file mode 100644 index 00000000000000..58da36298c27ef --- /dev/null +++ b/src/platform/openiotsdk/CHIPPlatformConfig.h @@ -0,0 +1,35 @@ +/* + * + * 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 + * Platform-specific configuration overrides for CHIP on + * Open IoT SDK platform. + */ + +#pragma once + +#include + +// ==================== General Platform Adaptations ==================== + +#define CHIP_CONFIG_EXPECTED_LOW_PROCESSING_TIME 10 + +// ==================== Security Adaptations ==================== + +// ==================== General Configuration Overrides ==================== diff --git a/src/platform/openiotsdk/ConfigurationManagerImpl.cpp b/src/platform/openiotsdk/ConfigurationManagerImpl.cpp new file mode 100644 index 00000000000000..58e6e70c995509 --- /dev/null +++ b/src/platform/openiotsdk/ConfigurationManagerImpl.cpp @@ -0,0 +1,161 @@ +/* + * + * 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 + * Provides the implementation of the Device Layer ConfigurationManager class + * for the Open IOT SDK platform. + */ + +#include + +#include + +#include + +#include "cmsis.h" + +namespace chip { +namespace DeviceLayer { + +using namespace ::chip::DeviceLayer::Internal; + +ConfigurationManagerImpl & ConfigurationManagerImpl::GetDefaultInstance() +{ + static ConfigurationManagerImpl sInstance; + return sInstance; +} + +CHIP_ERROR ConfigurationManagerImpl::Init() +{ + CHIP_ERROR err; + + // Initialize the generic implementation base class. + err = Internal::GenericConfigurationManagerImpl::Init(); + SuccessOrExit(err); + +exit: + return err; +} + +bool ConfigurationManagerImpl::CanFactoryReset() +{ + return true; +} + +void ConfigurationManagerImpl::InitiateFactoryReset(void) +{ + PlatformMgr().ScheduleWork(DoFactoryReset); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t & value) +{ + CHIP_ERROR err = ReadConfigValue(key, value); + if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) + { + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + return err; +} + +CHIP_ERROR ConfigurationManagerImpl::WritePersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t value) +{ + return OpenIoTSDKConfig::WriteCounter(key, value); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadConfigValue(Key key, bool & val) +{ + return OpenIoTSDKConfig::ReadConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadConfigValue(Key key, uint32_t & val) +{ + return OpenIoTSDKConfig::ReadConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadConfigValue(Key key, uint64_t & val) +{ + return OpenIoTSDKConfig::ReadConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) +{ + return OpenIoTSDKConfig::ReadConfigValueStr(key, buf, bufSize, outLen); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) +{ + return OpenIoTSDKConfig::ReadConfigValueBin(key, buf, bufSize, outLen); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValue(Key key, bool val) +{ + return OpenIoTSDKConfig::WriteConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValue(Key key, uint32_t val) +{ + return OpenIoTSDKConfig::WriteConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValue(Key key, uint64_t val) +{ + return OpenIoTSDKConfig::WriteConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValueStr(Key key, const char * str) +{ + return OpenIoTSDKConfig::WriteConfigValueStr(key, str); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValueStr(Key key, const char * str, size_t strLen) +{ + return OpenIoTSDKConfig::WriteConfigValueStr(key, str, strLen); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) +{ + return OpenIoTSDKConfig::WriteConfigValueBin(key, data, dataLen); +} + +void ConfigurationManagerImpl::RunConfigUnitTest(void) +{ + OpenIoTSDKConfig::RunConfigUnitTest(); +} + +void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg) +{ + ChipLogProgress(DeviceLayer, "Performing factory reset"); + const CHIP_ERROR err = OpenIoTSDKConfig::FactoryResetConfig(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "FactoryResetConfig() failed: %s", ErrorStr(err)); + } + + // Restart the system. + ChipLogProgress(DeviceLayer, "System restarting"); + NVIC_SystemReset(); +} + +ConfigurationManager & ConfigurationMgrImpl() +{ + return ConfigurationManagerImpl::GetDefaultInstance(); +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/openiotsdk/ConfigurationManagerImpl.h b/src/platform/openiotsdk/ConfigurationManagerImpl.h new file mode 100644 index 00000000000000..ad4effe0645978 --- /dev/null +++ b/src/platform/openiotsdk/ConfigurationManagerImpl.h @@ -0,0 +1,82 @@ +/* + * + * 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 + * Provides an implementation of the ConfigurationManager class + * for the Open IOT SDK platform. + */ + +#pragma once + +#include +#include + +namespace chip { +namespace DeviceLayer { + +/** + * Concrete implementation of the ConfigurationManager singleton object for the Zephyr platform. + */ +class ConfigurationManagerImpl : public Internal::GenericConfigurationManagerImpl +{ + +public: + // This returns an instance of this class. + static ConfigurationManagerImpl & GetDefaultInstance(); + +private: + // ===== Members that implement the ConfigurationManager public interface. + + CHIP_ERROR Init(void) override; + bool CanFactoryReset(void) override; + void InitiateFactoryReset(void) override; + CHIP_ERROR ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t & value) override; + CHIP_ERROR WritePersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t value) override; + + // NOTE: Other public interface methods are implemented by GenericConfigurationManagerImpl<>. + + // ===== Members that implement the GenericConfigurationManagerImpl protected interface. + CHIP_ERROR ReadConfigValue(Key key, bool & val) override; + CHIP_ERROR ReadConfigValue(Key key, uint32_t & val) override; + CHIP_ERROR ReadConfigValue(Key key, uint64_t & val) override; + CHIP_ERROR ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) override; + CHIP_ERROR ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) override; + CHIP_ERROR WriteConfigValue(Key key, bool val) override; + CHIP_ERROR WriteConfigValue(Key key, uint32_t val) override; + CHIP_ERROR WriteConfigValue(Key key, uint64_t val) override; + CHIP_ERROR WriteConfigValueStr(Key key, const char * str) override; + CHIP_ERROR WriteConfigValueStr(Key key, const char * str, size_t strLen) override; + CHIP_ERROR WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) override; + void RunConfigUnitTest(void) override; + + // ===== Private members reserved for use by this class only. + + static void DoFactoryReset(intptr_t arg); +}; + +/** + * Returns the platform-specific implementation of the ConfigurationManager object. + * + * Applications can use this to gain access to features of the ConfigurationManager + * that are specific to the selected platform. + */ +ConfigurationManager & ConfigurationMgrImpl(); + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/openiotsdk/ConnectivityManagerImpl.cpp b/src/platform/openiotsdk/ConnectivityManagerImpl.cpp new file mode 100644 index 00000000000000..438697dde666fc --- /dev/null +++ b/src/platform/openiotsdk/ConnectivityManagerImpl.cpp @@ -0,0 +1,69 @@ +/* + * + * 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 + * Provides the implementation of the Device Layer Connectivity Manager class + * for Open IOT SDK platform. + */ + +#include + +#include + +#include + +#if INET_CONFIG_ENABLE_TCP_ENDPOINT +#include +#endif + +namespace chip { +namespace DeviceLayer { + +ConnectivityManagerImpl ConnectivityManagerImpl::sInstance; + +// ==================== ConnectivityManager Platform Internal Methods ==================== +CHIP_ERROR ConnectivityManagerImpl::_Init() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + return err; +} + +void ConnectivityManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) {} + +CHIP_ERROR ConnectivityManagerImpl::PostEvent(const ChipDeviceEvent * event, bool die) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + if (die) + { + PlatformMgr().PostEventOrDie(event); + } + else + { + err = PlatformMgr().PostEvent(event); + } + + return err; +} +void ConnectivityManagerImpl::AddTask(AsyncWorkFunct workFunct, intptr_t arg) +{ + PlatformMgr().ScheduleWork(workFunct, arg); +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/openiotsdk/ConnectivityManagerImpl.h b/src/platform/openiotsdk/ConnectivityManagerImpl.h new file mode 100644 index 00000000000000..d558dbc2533c26 --- /dev/null +++ b/src/platform/openiotsdk/ConnectivityManagerImpl.h @@ -0,0 +1,98 @@ +/* + * + * 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 + * Provides the implementation of the Device Layer Connectivity Manager class + * for the Open IOT SDK platform. + */ + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include + +#if INET_CONFIG_ENABLE_TCP_ENDPOINT +#include +#endif + +namespace chip { +namespace DeviceLayer { + +/** + * Concrete implementation of the ConnectivityManager singleton object for the Open IoT SDK platform. + */ +class ConnectivityManagerImpl final : public ConnectivityManager, + public Internal::GenericConnectivityManagerImpl, + public Internal::GenericConnectivityManagerImpl_UDP, +#if INET_CONFIG_ENABLE_TCP_ENDPOINT + public Internal::GenericConnectivityManagerImpl_TCP, +#endif + public Internal::GenericConnectivityManagerImpl_NoWiFi, + public Internal::GenericConnectivityManagerImpl_NoBLE, + public Internal::GenericConnectivityManagerImpl_NoThread + +{ + // Allow the ConnectivityManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend class ConnectivityManager; + +private: + CHIP_ERROR _Init(void); + void _OnPlatformEvent(const ChipDeviceEvent * event); + + friend ConnectivityManager & ConnectivityMgr(void); + friend ConnectivityManagerImpl & ConnectivityMgrImpl(void); + + static ConnectivityManagerImpl sInstance; + +public: + CHIP_ERROR PostEvent(const ChipDeviceEvent * event, bool die); + void AddTask(AsyncWorkFunct workFunct, intptr_t arg); +}; + +/** + * Returns the public interface of the ConnectivityManager singleton object. + * + * chip applications should use this to access features of the ConnectivityManager object + * that are common to all platforms. + */ +inline ConnectivityManager & ConnectivityMgr(void) +{ + return ConnectivityManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the ConnectivityManager singleton object. + * + * chip applications can use this to gain access to features of the ConnectivityManager + * that are specific to the Open IoT SDK platform. + */ +inline ConnectivityManagerImpl & ConnectivityMgrImpl(void) +{ + return ConnectivityManagerImpl::sInstance; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/openiotsdk/DiagnosticDataProviderImpl.cpp b/src/platform/openiotsdk/DiagnosticDataProviderImpl.cpp new file mode 100644 index 00000000000000..38d394b8d24864 --- /dev/null +++ b/src/platform/openiotsdk/DiagnosticDataProviderImpl.cpp @@ -0,0 +1,46 @@ +/* + * + * 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 + * Provides an implementation of the Diagnostic Data Provider class + * for Open IOT SDK platform. + */ + +#include + +#include +#include +#include + +namespace chip { +namespace DeviceLayer { + +DiagnosticDataProviderImpl & DiagnosticDataProviderImpl::GetDefaultInstance() +{ + static DiagnosticDataProviderImpl sInstance; + return sInstance; +} + +DiagnosticDataProvider & GetDiagnosticDataProviderImpl() +{ + return DiagnosticDataProviderImpl::GetDefaultInstance(); +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/openiotsdk/DiagnosticDataProviderImpl.h b/src/platform/openiotsdk/DiagnosticDataProviderImpl.h new file mode 100644 index 00000000000000..c660cef8d43761 --- /dev/null +++ b/src/platform/openiotsdk/DiagnosticDataProviderImpl.h @@ -0,0 +1,50 @@ +/* + * + * 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 + * Provides an implementation of the Diagnostic Data Provider class + * for Open IOT SDK platform. + */ + +#pragma once + +#include + +namespace chip { +namespace DeviceLayer { + +/** + * Concrete implementation of the PlatformManager singleton object for Linux platforms. + */ +class DiagnosticDataProviderImpl : public DiagnosticDataProvider +{ +public: + static DiagnosticDataProviderImpl & GetDefaultInstance(); +}; + +/** + * Returns the platform-specific implementation of the DiagnosticDataProvider singleton object. + * + * Applications can use this to gain access to features of the DiagnosticDataProvider + * that are specific to the selected platform. + */ +DiagnosticDataProvider & GetDiagnosticDataProviderImpl(); + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/openiotsdk/InetPlatformConfig.h b/src/platform/openiotsdk/InetPlatformConfig.h new file mode 100644 index 00000000000000..d571369d3820f7 --- /dev/null +++ b/src/platform/openiotsdk/InetPlatformConfig.h @@ -0,0 +1,30 @@ +/* + * + * 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 + * Platform-specific configuration overrides for the CHIP Inet + * Layer on Open IoT SDK platform. + * + */ + +#pragma once + +// ==================== Platform Adaptations ==================== + +// ========== Platform-specific Configuration Overrides ========= diff --git a/src/platform/openiotsdk/KeyValueStoreManagerImpl.cpp b/src/platform/openiotsdk/KeyValueStoreManagerImpl.cpp new file mode 100644 index 00000000000000..e88772995c41c0 --- /dev/null +++ b/src/platform/openiotsdk/KeyValueStoreManagerImpl.cpp @@ -0,0 +1,131 @@ +/* + * + * 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 + * Provides an implementation of the key-value storage manager class + * for Open IOT SDK platform. + */ + +#include +#include + +#include +#include +#include + +using chip::DeviceLayer::Internal::OpenIoTSDKConfig; + +namespace chip { +namespace DeviceLayer { +namespace PersistedStorage { + +class KeyBuilder +{ +public: + KeyBuilder(const char * key) + { + // Check sign by sign if key contains illegal characters + // Each illegal character will be replaced by '!' + capital encoded letter value + char * out = buffer + strlen(buffer); + char * illegal_ptr; + while ((out < buffer + sizeof(buffer) - 3) && *key) // 2 chars for potential illegal char + 1 for \0 + { + illegal_ptr = strchr(illegalCharacters, *key); + if (illegal_ptr) + { + *out++ = '!'; + *out++ = 'A' + (int) (illegal_ptr - illegalCharacters); + } + else + { + *out++ = *key; + } + key++; + } + valid = true; + } + + const char * str() const { return valid ? buffer : nullptr; } + +private: + char buffer[100] = "chip-kvs-"; + bool valid; + // Mbed KV storage does not accept these characters in the key definition + const char * illegalCharacters = " */?:;\"|<>\\"; +}; + +// NOTE: Currently this platform does not support partial and offset reads +// these will return CHIP_ERROR_NOT_IMPLEMENTED. +CHIP_ERROR +KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size, size_t offset) +{ + if (offset > 0) + { + // Offset and partial reads are not supported. + // Support can be added in the future if this is needed. + return CHIP_ERROR_NOT_IMPLEMENTED; + } + + KeyBuilder key_builder(key); + if (!key_builder.str()) + { + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + } + + auto err = + OpenIoTSDKConfig::ReadConfigValueBin(key_builder.str(), reinterpret_cast(value), value_size, *read_bytes_size); + if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) + { + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + return err; +} + +CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key) +{ + KeyBuilder key_builder(key); + if (!key_builder.str()) + { + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + } + + auto err = OpenIoTSDKConfig::ClearConfigValue(key_builder.str()); + if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) + { + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + return err; +} + +CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, size_t value_size) +{ + KeyBuilder key_builder(key); + if (!key_builder.str()) + { + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + } + + return OpenIoTSDKConfig::WriteConfigValueBin(key_builder.str(), reinterpret_cast(value), value_size); +} + +KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance; + +} // namespace PersistedStorage +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/openiotsdk/KeyValueStoreManagerImpl.h b/src/platform/openiotsdk/KeyValueStoreManagerImpl.h new file mode 100644 index 00000000000000..9257c33c6f25d7 --- /dev/null +++ b/src/platform/openiotsdk/KeyValueStoreManagerImpl.h @@ -0,0 +1,80 @@ +/* + * + * 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 + * Provides an implementation of the key-value storage manager class + * for Open IOT SDK platform. + */ + +#pragma once + +#include + +namespace chip { +namespace DeviceLayer { +namespace PersistedStorage { + +class KeyValueStoreManagerImpl final : public KeyValueStoreManager +{ + // Allow the KeyValueStoreManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend class KeyValueStoreManager; + +public: + // NOTE: Currently this platform does not support partial and offset reads + // these will return CHIP_ERROR_NOT_IMPLEMENTED. + CHIP_ERROR _Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size = nullptr, size_t offset = 0); + + CHIP_ERROR _Delete(const char * key); + + CHIP_ERROR _Put(const char * key, const void * value, size_t value_size); + +private: + // ===== Members for internal use by the following friends. + friend KeyValueStoreManager & KeyValueStoreMgr(); + friend KeyValueStoreManagerImpl & KeyValueStoreMgrImpl(); + + static KeyValueStoreManagerImpl sInstance; +}; + +/** + * Returns the public interface of the KeyValueStoreManager singleton object. + * + * Chip applications should use this to access features of the KeyValueStoreManager object + * that are common to all platforms. + */ +inline KeyValueStoreManager & KeyValueStoreMgr(void) +{ + return KeyValueStoreManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the KeyValueStoreManager singleton object. + * + * Chip applications can use this to gain access to features of the KeyValueStoreManager + * that are specific to the OpenIoTSDK platform. + */ +inline KeyValueStoreManagerImpl & KeyValueStoreMgrImpl(void) +{ + return KeyValueStoreManagerImpl::sInstance; +} + +} // namespace PersistedStorage +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/openiotsdk/Logging.cpp b/src/platform/openiotsdk/Logging.cpp new file mode 100644 index 00000000000000..2a3ecfa7e64e7b --- /dev/null +++ b/src/platform/openiotsdk/Logging.cpp @@ -0,0 +1,90 @@ +/* + * + * 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 + * Provides an implementation of logging support + * for Open IOT SDK platform. + */ + +#include +#include +#include +#include +#include + +#include +#include + +namespace chip { +namespace DeviceLayer { + +/** + * Called whenever a log message is emitted by chip or LwIP. + * + * This function is intended be overridden by the application to, e.g., + * schedule output of queued log entries. + */ +void __attribute__((weak)) OnLogOutput() {} + +} // namespace DeviceLayer + +namespace Logging { +namespace Platform { + +/** + * Logging static buffer + */ +namespace { +char logMsgBuffer[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE]; +} + +/** + * CHIP log output functions. + */ +void ENFORCE_FORMAT(3, 0) LogV(const char * module, uint8_t category, const char * msg, va_list v) +{ + vsnprintf(logMsgBuffer, sizeof(logMsgBuffer), msg, v); + + const char * category_prefix; + switch (category) + { + case kLogCategory_Error: + category_prefix = "\x1b[31m[ERR]\x1b[0m"; + break; + case kLogCategory_Progress: + default: + category_prefix = "\x1b[32m[INF]\x1b[0m"; + break; + case kLogCategory_Detail: + category_prefix = "\x1b[90m[DBG]\x1b[0m"; + break; + case kLogCategory_Automation: + category_prefix = ""; + break; + } + + printf("%s [%s] %s\r\n", category_prefix, module, logMsgBuffer); + + // Let the application know that a log message has been emitted. + DeviceLayer::OnLogOutput(); +} + +} // namespace Platform +} // namespace Logging +} // namespace chip diff --git a/src/platform/openiotsdk/NetworkCommissioningDriver.h b/src/platform/openiotsdk/NetworkCommissioningDriver.h new file mode 100644 index 00000000000000..524f575e9e7bd8 --- /dev/null +++ b/src/platform/openiotsdk/NetworkCommissioningDriver.h @@ -0,0 +1,67 @@ +/* + * + * 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. + */ + +/** + * @file + * Provides an implementation of the network commissioning drivers + * for Open IOT SDK platform. + */ + +#pragma once + +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace NetworkCommissioning { + +class OpenIoTSDKEthernetDriver final : public EthernetDriver +{ +public: + struct EthernetNetworkIterator final : public NetworkIterator + { + EthernetNetworkIterator() = default; + size_t Count() override { return interfaceNameLen > 0 ? 1 : 0; } + bool Next(Network & item) override + { + if (exhausted) + { + return false; + } + exhausted = true; + memcpy(item.networkID, interfaceName, interfaceNameLen); + item.networkIDLen = interfaceNameLen; + item.connected = true; + return true; + } + void Release() override { delete this; } + ~EthernetNetworkIterator() override = default; + + // Public, but cannot be accessed via NetworkIterator interface. + uint8_t interfaceName[kMaxNetworkIDLen]; + uint8_t interfaceNameLen = 0; + bool exhausted = false; + }; + + uint8_t GetMaxNetworks() override { return 1; }; + NetworkIterator * GetNetworks() override; +}; + +} // namespace NetworkCommissioning +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/openiotsdk/NetworkCommissioningEthernetDriver.cpp b/src/platform/openiotsdk/NetworkCommissioningEthernetDriver.cpp new file mode 100644 index 00000000000000..df36092c5e2e8d --- /dev/null +++ b/src/platform/openiotsdk/NetworkCommissioningEthernetDriver.cpp @@ -0,0 +1,52 @@ +/* + * + * 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 + * Provides an implementation of the network commissioning drivers + * for Open IOT SDK platform. + */ + +#include +#include +#include + +using namespace ::chip::Inet; +using namespace ::chip::DeviceLayer; +using namespace ::chip::DeviceLayer::Internal; + +namespace chip { +namespace DeviceLayer { +namespace NetworkCommissioning { + +NetworkIterator * OpenIoTSDKEthernetDriver::GetNetworks() +{ + auto ret = new EthernetNetworkIterator(); + + char buf[NETIF_NAMESIZE]; + char * ifname = netif_index_to_name(0, buf); + + ret->interfaceNameLen = strlen(ifname); + memcpy(ret->interfaceName, ifname, ret->interfaceNameLen); + + return ret; +} + +} // namespace NetworkCommissioning +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/openiotsdk/OpenIoTSDKArchUtils.c b/src/platform/openiotsdk/OpenIoTSDKArchUtils.c new file mode 100644 index 00000000000000..d7c74ac5a21cae --- /dev/null +++ b/src/platform/openiotsdk/OpenIoTSDKArchUtils.c @@ -0,0 +1,138 @@ +/* + * + * 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. + */ + +/** + * @file + * Open IOT SDK platform adaptation file + */ + +#include "OpenIoTSDKArchUtils.h" +#include +#ifdef __cplusplus +extern "C" { +#endif + +static uint32_t tick_h = 0U; +static uint32_t tick_l = 0U; + +// GetTick() needs to be called at least twice per tick overflow to work properly. +uint64_t GetTick(void) +{ + uint32_t tick = osKernelGetTickCount(); + + if (tick < tick_l) + { + tick_h++; + } + tick_l = tick; + + return (((uint64_t) tick_h << 32) | tick_l); +} + +/* Time to kernel ticks */ +uint32_t sec2tick(uint32_t sec) +{ + if (sec == 0U) + { + return (osWaitForever); + } + + return (sec * osKernelGetTickFreq()); +} + +uint32_t ms2tick(uint32_t ms) +{ + if (ms == 0U) + { + return (osWaitForever); + } + + return (uint32_t)(((uint64_t) ms * (uint64_t) osKernelGetTickFreq()) / 1000U); +} + +uint32_t us2tick(uint32_t usec) +{ + if (usec == 0U) + { + return osWaitForever; + } + + // round division up because our tick is so long this might become 0 + // we need the timer to sleep at least one tick as it otherwise breaks expectations + return (uint32_t)(((uint64_t) usec * osKernelGetTickFreq() + (1000000 - 1)) / 1000000); +} + +/* Kernel ticks to time */ +uint64_t tick2sec(uint64_t tick) +{ + if (osKernelGetTickFreq() == 0U) + { + return 0; + } + + return (tick / osKernelGetTickFreq()); +} + +uint64_t tick2ms(uint64_t tick) +{ + if (osKernelGetTickFreq() == 0U) + { + return 0; + } + + return ((tick * 1000U) / osKernelGetTickFreq()); +} + +uint64_t tick2us(uint64_t tick) +{ + if (osKernelGetTickFreq() == 0U) + { + return 0; + } + + return ((tick * 1000U * 1000U) / osKernelGetTickFreq()); +} + +void sleep(uint32_t sec) +{ + if (sec) + { + osDelay(sec2tick(sec)); + } +} + +void usleep(uint32_t usec) +{ + if (usec) + { + osDelay(us2tick(usec)); + } +} + +time_t time(time_t * __timer) +{ + time_t seconds = (time_t)(tick2sec(GetTick())); + if (__timer) + { + *__timer = seconds; + } + return seconds; +} + +#ifdef __cplusplus +} +#endif diff --git a/src/platform/openiotsdk/OpenIoTSDKArchUtils.h b/src/platform/openiotsdk/OpenIoTSDKArchUtils.h new file mode 100644 index 00000000000000..4fffbf7fc62efe --- /dev/null +++ b/src/platform/openiotsdk/OpenIoTSDKArchUtils.h @@ -0,0 +1,50 @@ +/* + * + * 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 + * Defines timing helper functions. + */ + +#pragma once + +#include "cmsis_os2.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint64_t GetTick(void); + +/* Time to kernel ticks */ +uint32_t sec2tick(uint32_t sec); + +uint32_t ms2tick(uint32_t ms); + +uint32_t us2tick(uint32_t usec); + +/* Kernel ticks to time */ +uint64_t tick2sec(uint64_t tick); + +uint64_t tick2ms(uint64_t tick); + +uint64_t tick2us(uint64_t tick); + +#ifdef __cplusplus +} +#endif diff --git a/src/platform/openiotsdk/OpenIoTSDKConfig.cpp b/src/platform/openiotsdk/OpenIoTSDKConfig.cpp new file mode 100644 index 00000000000000..d156e417ff324d --- /dev/null +++ b/src/platform/openiotsdk/OpenIoTSDKConfig.cpp @@ -0,0 +1,452 @@ +/* + * + * 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. + */ + +/** + * @file + * Utilities for interacting with the the Open IoT SDK key-value storage. + */ + +#include + +#include +#include +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +// *** CAUTION ***: Changing the names or namespaces of these values will *break* existing devices. + +#define STR_EXPAND(tok) #tok + +// Note: An external mbed parameter could be useful so an application can put +// chip NVS values in a single place +#define CHIP_CONFIG_KV_STORE_PARTITION STR_EXPAND(MBED_CONF_STORAGE_DEFAULT_KV) + +// NVS namespaces used to store device configuration information. +#define CHIP_CONFIG_FACTORY_PREFIX "chip-factory-" +#define CHIP_CONFIG_CONFIG_PREFIX "chip-config-" +#define CHIP_CONFIG_COUNTER_PREFIX "chip-counters-" + +#define FACTORY_KEY(key) CHIP_CONFIG_KV_STORE_PARTITION CHIP_CONFIG_FACTORY_PREFIX key +#define CONFIG_KEY(key) CHIP_CONFIG_KV_STORE_PARTITION CHIP_CONFIG_CONFIG_PREFIX key + +const char OpenIoTSDKConfig::kConfigNamespace_ChipFactory[] = CHIP_CONFIG_KV_STORE_PARTITION CHIP_CONFIG_FACTORY_PREFIX; +const char OpenIoTSDKConfig::kConfigNamespace_ChipConfig[] = CHIP_CONFIG_KV_STORE_PARTITION CHIP_CONFIG_CONFIG_PREFIX; +const char OpenIoTSDKConfig::kConfigNamespace_ChipCounters[] = CHIP_CONFIG_KV_STORE_PARTITION CHIP_CONFIG_COUNTER_PREFIX; + +// Keys stored in the chip-factory namespace +const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_SerialNum = { FACTORY_KEY("serial-num") }; +const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_MfrDeviceId = { FACTORY_KEY("device-id") }; +const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_MfrDeviceCert = { FACTORY_KEY("device-cert") }; +const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_MfrDeviceICACerts = { FACTORY_KEY("device-ca-certs") }; +const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_MfrDevicePrivateKey = { FACTORY_KEY("device-key") }; +const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_HardwareVersion = { FACTORY_KEY("hardware-ver") }; +const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_ManufacturingDate = { FACTORY_KEY("mfg-date") }; +const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_SetupPinCode = { FACTORY_KEY("pin-code") }; +const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_SetupDiscriminator = { FACTORY_KEY("discriminator") }; +const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_Spake2pIterationCount = { FACTORY_KEY("iteration-count") }; +const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_Spake2pSalt = { FACTORY_KEY("salt") }; +const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_Spake2pVerifier = { FACTORY_KEY("verifier") }; + +// Keys stored in the chip-config namespace +const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_ServiceConfig = { CONFIG_KEY("service-config") }; +const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_PairedAccountId = { CONFIG_KEY("account-id") }; +const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_ServiceId = { CONFIG_KEY("service-id") }; +const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_LastUsedEpochKeyId = { CONFIG_KEY("last-ek-id") }; +const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_FailSafeArmed = { CONFIG_KEY("fail-safe-armed") }; +const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_WiFiStationSecType = { CONFIG_KEY("sta-sec-type") }; +const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_RegulatoryLocation = { CONFIG_KEY("regulatory-location") }; +const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_CountryCode = { CONFIG_KEY("country-code") }; +const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_UniqueId = { CONFIG_KEY("unique-id") }; + +using iotsdk::storage::kv_status; +using iotsdk::storage::KVStore; + +CHIP_ERROR OpenIoTSDKConfig::ReadConfigValue(Key key, bool & val) +{ + if (Init() != CHIP_NO_ERROR) + { + return CHIP_ERROR_INTERNAL; + } + + if (!ConfigValueExists(key)) + { + return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + + size_t actual_size = 0; + kv_status err = tdb->get(key, reinterpret_cast(&val), sizeof(val), &actual_size); + + if (err != kv_status::OK) + { + return CHIP_ERROR_INTERNAL; + } + + if (actual_size != sizeof(val)) + { + return CHIP_ERROR_BAD_REQUEST; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OpenIoTSDKConfig::ReadConfigValue(Key key, uint32_t & val) +{ + if (Init() != CHIP_NO_ERROR) + { + return CHIP_ERROR_INTERNAL; + } + + if (!ConfigValueExists(key)) + { + return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + + size_t actual_size = 0; + kv_status err = tdb->get(key, reinterpret_cast(&val), sizeof(val), &actual_size); + + if (err != kv_status::OK) + { + return CHIP_ERROR_INTERNAL; + } + + if (actual_size != sizeof(val)) + { + return CHIP_ERROR_BAD_REQUEST; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OpenIoTSDKConfig::ReadConfigValue(Key key, uint64_t & val) +{ + if (Init() != CHIP_NO_ERROR) + { + return CHIP_ERROR_INTERNAL; + } + + if (!ConfigValueExists(key)) + { + return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + + size_t actual_size = 0; + kv_status err = tdb->get(key, &val, sizeof(val), &actual_size); + + if (err != kv_status::OK) + { + return CHIP_ERROR_INTERNAL; + } + + if (actual_size != sizeof(val)) + { + return CHIP_ERROR_BAD_REQUEST; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OpenIoTSDKConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) +{ + CHIP_ERROR err = ReadConfigValueBin(key, reinterpret_cast(buf), bufSize, outLen); + // Note: The system expect the trailing null to be added. + if (err != CHIP_NO_ERROR) + { + return err; + } + if (outLen >= bufSize) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + buf[outLen] = 0; + return CHIP_NO_ERROR; +} + +CHIP_ERROR OpenIoTSDKConfig::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) +{ + if (Init() != CHIP_NO_ERROR) + { + return CHIP_ERROR_INTERNAL; + } + + if (!ConfigValueExists(key)) + { + return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + + KVStore::info_t info; + + kv_status err = tdb->get_info(key, &info); + if (err != kv_status::OK) + { + return CHIP_ERROR_INTERNAL; + } + + err = tdb->get(key, reinterpret_cast(buf), bufSize, &outLen); + if (err != kv_status::OK) + { + return CHIP_ERROR_INTERNAL; + } + + if (bufSize < info.size) + { + return CHIP_ERROR_BUFFER_TOO_SMALL; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OpenIoTSDKConfig::WriteConfigValue(Key key, bool val) +{ + if (Init() != CHIP_NO_ERROR) + { + return CHIP_ERROR_INTERNAL; + } + + kv_status err = tdb->set(key, reinterpret_cast(&val), sizeof(val), 0); + return err == kv_status::OK ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; +} + +CHIP_ERROR OpenIoTSDKConfig::WriteConfigValue(Key key, uint32_t val) +{ + if (Init() != CHIP_NO_ERROR) + { + return CHIP_ERROR_INTERNAL; + } + + kv_status err = tdb->set(key, reinterpret_cast(&val), sizeof(val), 0); + return err == kv_status::OK ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; +} + +CHIP_ERROR OpenIoTSDKConfig::WriteConfigValue(Key key, uint64_t val) +{ + if (Init() != CHIP_NO_ERROR) + { + return CHIP_ERROR_INTERNAL; + } + + kv_status err = tdb->set(key, reinterpret_cast(&val), sizeof(val), 0); + return err == kv_status::OK ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; +} + +CHIP_ERROR OpenIoTSDKConfig::WriteConfigValueStr(Key key, const char * str) +{ + return WriteConfigValueBin(key, reinterpret_cast(str), strlen(str)); +} + +CHIP_ERROR OpenIoTSDKConfig::WriteConfigValueStr(Key key, const char * str, size_t strLen) +{ + return WriteConfigValueBin(key, reinterpret_cast(str), strLen); +} + +CHIP_ERROR OpenIoTSDKConfig::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) +{ + if (Init() != CHIP_NO_ERROR) + { + return CHIP_ERROR_INTERNAL; + } + + // Two different behavior: If the pointer is not null, the value is updated + // or create. If the pointer is null, the key is removed if it exist. + if (data != nullptr) + { + kv_status err = tdb->set(key, reinterpret_cast(data), dataLen, 0); + return err == kv_status::OK ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; + } + else if (ConfigValueExists(key)) + { + return ClearConfigValue(key); + } + else + { + // Nothing to do, data is null and the key does not exist. + return CHIP_NO_ERROR; + } +} + +CHIP_ERROR OpenIoTSDKConfig::ClearConfigValue(Key key) +{ + if (Init() != CHIP_NO_ERROR) + { + return CHIP_ERROR_INTERNAL; + } + + kv_status err = tdb->remove(key); + if (err == kv_status::ITEM_NOT_FOUND) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + return err == kv_status::OK ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; +} + +bool OpenIoTSDKConfig::ConfigValueExists(Key key) +{ + if (Init() != CHIP_NO_ERROR) + { + return false; + } + + KVStore::info_t info; + kv_status err = tdb->get_info(key, &info); + return err == kv_status::OK ? true : false; +} + +CHIP_ERROR OpenIoTSDKConfig::FactoryResetConfig() +{ + // tdb->reset is not used, we want to preserve other setting and factory + // configuration + auto err = ClearNamespace(kConfigNamespace_ChipConfig); + if (err != CHIP_NO_ERROR) + { + return err; + } + return ClearNamespace(kConfigNamespace_ChipCounters); +} + +CHIP_ERROR OpenIoTSDKConfig::ConstructCounterKey(Key id, char * buf, size_t bufSize) +{ + auto length = snprintf(buf, bufSize - 1, CHIP_CONFIG_KV_STORE_PARTITION CHIP_CONFIG_COUNTER_PREFIX "%s", id); + if (length < 0) + { + return CHIP_ERROR_INTERNAL; + } + else if ((size_t) length > (bufSize - 1)) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + else + { + return CHIP_NO_ERROR; + } +} + +CHIP_ERROR OpenIoTSDKConfig::ReadCounter(Key counterId, uint32_t & value) +{ + char key[50] = { 0 }; + auto err = ConstructCounterKey(counterId, key, sizeof(key)); + if (err != CHIP_NO_ERROR) + { + return err; + } + + return ReadConfigValue(key, value); +} + +CHIP_ERROR OpenIoTSDKConfig::WriteCounter(Key counterId, uint32_t value) +{ + char key[50] = { 0 }; + auto err = ConstructCounterKey(counterId, key, sizeof(key)); + if (err != CHIP_NO_ERROR) + { + return err; + } + + return WriteConfigValue(key, value); +} + +CHIP_ERROR OpenIoTSDKConfig::ClearNamespace(const char * ns) +{ + if (Init() != CHIP_NO_ERROR) + { + return CHIP_ERROR_INTERNAL; + } + + iotsdk::storage::KVStore::iterator_t it; + char key[iotsdk::storage::KVStore::MAX_KEY_SIZE]; + kv_status err = tdb->iterator_open(&it, ns); + if (err != kv_status::OK) + { + return CHIP_ERROR_INTERNAL; + } + + while (true) + { + err = tdb->iterator_next(it, key, sizeof(key)); + if (err == kv_status::OK) + { + tdb->remove(key); + memset(key, 0, sizeof(key)); + } + else if (err == kv_status::ITEM_NOT_FOUND) + { + break; + } + else + { + (void) tdb->iterator_close(it); + return CHIP_ERROR_INTERNAL; + } + } + + err = tdb->iterator_close(it); + return err == kv_status::OK ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; +} + +void OpenIoTSDKConfig::RunConfigUnitTest() +{ + // Run common unit test. + ::chip::DeviceLayer::Internal::RunConfigUnitTest(); +} + +CHIP_ERROR OpenIoTSDKConfig::Init(void) +{ + if (tdb) + { + return CHIP_NO_ERROR; + } + + flash_bd = new iotsdk::storage::FlashIAPBlockDevice(get_ram_drive_instance(), 0, 0); + + if (!flash_bd) + { + return CHIP_ERROR_INTERNAL; + } + + // Create a TDBStore using the underlying storage + tdb = new iotsdk::storage::TDBStore(flash_bd); + + if (!tdb) + { + delete flash_bd; + return CHIP_ERROR_INTERNAL; + } + + // KVStore uses dual stage initialization so we can handle any errors + // Call the `init` method to setup the TDBStore + kv_status err = tdb->init(); + if (err != kv_status::OK) + { + delete flash_bd; + delete tdb; + // zero tdb as we use it keep track of init + tdb = nullptr; + return CHIP_ERROR_INTERNAL; + } + + return CHIP_NO_ERROR; +} + +iotsdk::storage::TDBStore * OpenIoTSDKConfig::tdb = nullptr; +iotsdk::storage::FlashIAPBlockDevice * OpenIoTSDKConfig::flash_bd = nullptr; + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/openiotsdk/OpenIoTSDKConfig.h b/src/platform/openiotsdk/OpenIoTSDKConfig.h new file mode 100644 index 00000000000000..ed056f1fd8f1c0 --- /dev/null +++ b/src/platform/openiotsdk/OpenIoTSDKConfig.h @@ -0,0 +1,113 @@ +/* + * + * 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. + */ + +/** + * @file + * Utilities for interacting with the the Open IoT SDK key-value storage. + */ + +#pragma once + +#include +#include + +#include "iotsdk/BufferedBlockDevice.h" +#include "iotsdk/FlashIAPBlockDevice.h" + +extern "C" { +#include "flash_cs300.h" +#include "hal/flash_api.h" +#include "iotsdk/TDBStore.h" +} +#include + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +/** + * Provides functions and definitions for accessing device configuration information on the ESP32. + * + * This class is designed to be mixed-in to concrete implementation classes as a means to + * provide access to configuration information to generic base classes. + */ +class OpenIoTSDKConfig +{ +public: + using Key = const char *; + + // NVS prefix used to store device configuration information. + static const char kConfigNamespace_ChipFactory[]; + static const char kConfigNamespace_ChipConfig[]; + static const char kConfigNamespace_ChipCounters[]; + + // Key definitions for well-known keys. + static const Key kConfigKey_SerialNum; + static const Key kConfigKey_UniqueId; + static const Key kConfigKey_MfrDeviceId; + static const Key kConfigKey_MfrDeviceCert; + static const Key kConfigKey_MfrDeviceICACerts; + static const Key kConfigKey_MfrDevicePrivateKey; + static const Key kConfigKey_HardwareVersion; + static const Key kConfigKey_ManufacturingDate; + static const Key kConfigKey_SetupPinCode; + static const Key kConfigKey_ServiceConfig; + static const Key kConfigKey_PairedAccountId; + static const Key kConfigKey_ServiceId; + static const Key kConfigKey_LastUsedEpochKeyId; + static const Key kConfigKey_FailSafeArmed; + static const Key kConfigKey_WiFiStationSecType; + static const Key kConfigKey_SetupDiscriminator; + static const Key kConfigKey_RegulatoryLocation; + static const Key kConfigKey_CountryCode; + static const Key kConfigKey_Spake2pIterationCount; + static const Key kConfigKey_Spake2pSalt; + static const Key kConfigKey_Spake2pVerifier; + + // Config value accessors. + static CHIP_ERROR ReadConfigValue(Key key, bool & val); + static CHIP_ERROR ReadConfigValue(Key key, uint32_t & val); + static CHIP_ERROR ReadConfigValue(Key key, uint64_t & val); + static CHIP_ERROR ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen); + static CHIP_ERROR ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen); + static CHIP_ERROR WriteConfigValue(Key key, bool val); + static CHIP_ERROR WriteConfigValue(Key key, uint32_t val); + static CHIP_ERROR WriteConfigValue(Key key, uint64_t val); + static CHIP_ERROR WriteConfigValueStr(Key key, const char * str); + static CHIP_ERROR WriteConfigValueStr(Key key, const char * str, size_t strLen); + static CHIP_ERROR WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen); + static CHIP_ERROR ClearConfigValue(Key key); + static bool ConfigValueExists(Key key); + static CHIP_ERROR FactoryResetConfig(); + static CHIP_ERROR Init(void); + + // NVS Namespace helper functions. + static CHIP_ERROR ConstructCounterKey(Key id, char * buf, size_t bufSize); + static CHIP_ERROR ReadCounter(Key counterId, uint32_t & value); + static CHIP_ERROR WriteCounter(Key counterId, uint32_t value); + static CHIP_ERROR ClearNamespace(const char * ns); + + static void RunConfigUnitTest(void); + +private: + static iotsdk::storage::TDBStore * tdb; + static iotsdk::storage::FlashIAPBlockDevice * flash_bd; +}; + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/openiotsdk/PlatformManagerImpl.cpp b/src/platform/openiotsdk/PlatformManagerImpl.cpp new file mode 100644 index 00000000000000..47b8a5293dafdf --- /dev/null +++ b/src/platform/openiotsdk/PlatformManagerImpl.cpp @@ -0,0 +1,316 @@ +/* + * + * 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 + * Provides the implementation of the Device Layer Platform Manager class + * for Open IOT SDK platform. + */ + +#include "OpenIoTSDKArchUtils.h" +#include "platform/internal/CHIPDeviceLayerInternal.h" +#include + +#include +#include +#include +#include + +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::System; + +namespace chip { +namespace DeviceLayer { + +CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) +{ + // Members are initialized by the stack + osMutexAttr_t mut_att = { .attr_bits = osMutexRecursive }; + + // Reinitialize the Mutexes + mChipStackMutex = osMutexNew(&mut_att); + mEventTaskMutex = osMutexNew(nullptr); + mPlatformFlags = osEventFlagsNew(nullptr); + mQueue = osMessageQueueNew(CHIP_DEVICE_CONFIG_MAX_EVENT_QUEUE_SIZE, sizeof(ChipDeviceEvent), nullptr); + mTimer = osTimerNew(TimerCallback, osTimerOnce, NULL, NULL); + + if (!mChipStackMutex || !mEventTaskMutex || !mPlatformFlags || !mQueue || !mTimer) + { + osMutexDelete(mChipStackMutex); + osMutexDelete(mEventTaskMutex); + osEventFlagsDelete(mPlatformFlags); + osMessageQueueDelete(mQueue); + osTimerDelete(mTimer); + mChipStackMutex = mEventTaskMutex = mPlatformFlags = mQueue = mTimer = nullptr; + + return CHIP_ERROR_INTERNAL; + } + + SetConfigurationMgr(&ConfigurationManagerImpl::GetDefaultInstance()); + SetDiagnosticDataProvider(&DiagnosticDataProviderImpl::GetDefaultInstance()); + + // Call up to the base class _InitChipStack() to perform the bulk of the initialization. + CHIP_ERROR err = GenericPlatformManagerImpl::_InitChipStack(); + SuccessOrExit(err); + +exit: + return err; +} + +void PlatformManagerImpl::_LockChipStack() +{ + osMutexAcquire(mChipStackMutex, osWaitForever); +} + +bool PlatformManagerImpl::_TryLockChipStack() +{ + if (osMutexAcquire(mChipStackMutex, 0U) == osOK) + { + return true; + } + else + { + return false; + } +} + +void PlatformManagerImpl::_UnlockChipStack() +{ + osMutexRelease(mChipStackMutex); +} + +CHIP_ERROR PlatformManagerImpl::_PostEvent(const ChipDeviceEvent * eventPtr) +{ + osStatus_t status = osMessageQueuePut(mQueue, eventPtr, 0, 0); + CHIP_ERROR ret = (status == osOK) ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; + osEventFlagsSet(mPlatformFlags, kPostEventFlag); + return ret; +} + +void PlatformManagerImpl::HandlePostEvent() +{ + /* handle an event */ + ChipDeviceEvent event; + osStatus_t status = osMessageQueueGet(mQueue, &event, nullptr, 0); + if (status == osOK) + { + LockChipStack(); + DispatchEvent(&event); + UnlockChipStack(); + } +} + +void PlatformManagerImpl::HandleTimerEvent(void) +{ + const CHIP_ERROR err = static_cast(DeviceLayer::SystemLayer()).HandlePlatformTimer(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "HandlePlatformTimer %ld", err.AsInteger()); + } +} + +void PlatformManagerImpl::RunEventLoopInternal() +{ + uint32_t flags = 0; + while (true) + { + flags = osEventFlagsWait(mPlatformFlags, kPostEventFlag | kTimerEventFlag | kTaskStopEventFlag, + osFlagsWaitAny | osFlagsNoClear, ms2tick(1000)); + + // in case of error we still need to know the value of flags we're not waiting for + if (flags & osFlagsError) + { + flags = osEventFlagsGet(mPlatformFlags); + } + + if (flags & kTaskStopEventFlag) + { + osEventFlagsClear(mPlatformFlags, kTaskStopEventFlag); + osEventFlagsClear(mPlatformFlags, kTaskRunningEventFlag); + break; + } + + if (flags & kTimerEventFlag) + { + osEventFlagsClear(mPlatformFlags, kTimerEventFlag); + HandleTimerEvent(); + } + + if (flags & kPostEventFlag) + { + HandlePostEvent(); + + if (!osMessageQueueGetCount(mQueue)) + { + osEventFlagsClear(mPlatformFlags, kPostEventFlag); + } + } + + if ((flags & kTaskRunningEventFlag) == 0) + { + break; + } + } +} + +void PlatformManagerImpl::_RunEventLoop() +{ + osEventFlagsSet(mPlatformFlags, kTaskRunningEventFlag); + + RunEventLoopInternal(); +} + +void PlatformManagerImpl::EventLoopTask(void * arg) +{ + (void) arg; + PlatformMgrImpl().RunEventLoopInternal(); + osThreadTerminate(osThreadGetId()); +} + +CHIP_ERROR PlatformManagerImpl::_StartEventLoopTask() +{ + // this mutex only needed to guard against multiple launches + { + osMutexAcquire(mEventTaskMutex, osWaitForever); + + if (kTaskRunningEventFlag & osEventFlagsGet(mPlatformFlags)) + { + osMutexRelease(mEventTaskMutex); + return CHIP_ERROR_BUSY; + } + + const osThreadAttr_t tread_attr = { + .name = CHIP_DEVICE_CONFIG_CHIP_TASK_NAME, + .stack_size = CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE, + .priority = osPriorityNormal, + + }; + + osEventFlagsSet(mPlatformFlags, kTaskRunningEventFlag); + + // this thread is self terminating + osThreadId_t mEventTask = osThreadNew(EventLoopTask, NULL, &tread_attr); + + if (mEventTask == nullptr) + { + osMutexRelease(mEventTaskMutex); + return CHIP_ERROR_INTERNAL; + } + + osMutexRelease(mEventTaskMutex); + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR PlatformManagerImpl::_StopEventLoopTask() +{ + // this mutex only needed to guard against multiple calls to stop + { + osMutexAcquire(mEventTaskMutex, osWaitForever); + + uint32_t flags = osEventFlagsGet(mPlatformFlags); + if ((kTaskRunningEventFlag & flags) == 0) + { + osMutexRelease(mEventTaskMutex); + return CHIP_ERROR_INCORRECT_STATE; + } + + if (kTaskStopEventFlag & flags) + { + osMutexRelease(mEventTaskMutex); + return CHIP_ERROR_INCORRECT_STATE; + } + + osEventFlagsSet(mPlatformFlags, kTaskStopEventFlag); + + osMutexRelease(mEventTaskMutex); + } + + return CHIP_NO_ERROR; +} + +void PlatformManagerImpl::SetEventFlags(uint32_t flags) +{ + osEventFlagsSet(mPlatformFlags, flags); +} + +void PlatformManagerImpl::TimerCallback(void * arg) +{ + PlatformMgrImpl().SetEventFlags(kTimerEventFlag); +} + +CHIP_ERROR PlatformManagerImpl::_StartChipTimer(System::Clock::Timeout duration) +{ + if (duration.count() == 0) + { + TimerCallback(0); + } + else + { + auto res = osTimerStart(mTimer, ms2tick(duration.count())); + if (res) + { + ChipLogError(DeviceLayer, "osTimerStart failed %d", res); + return CHIP_ERROR_INTERNAL; + } + } + return CHIP_NO_ERROR; +} + +void PlatformManagerImpl::_Shutdown() +{ + // + // Call up to the base class _Shutdown() to perform the actual stack de-initialization + // and clean-up + // + + (void) _StopEventLoopTask(); + + // the task thread is self terminating, we might have to wait if it's still processing + while (true) + { + uint32_t flags = osEventFlagsGet(mPlatformFlags); + if ((kTaskRunningEventFlag & flags) == 0) + { + break; + } + osDelay(1); + } + + osMutexDelete(mChipStackMutex); + osMutexDelete(mEventTaskMutex); + osEventFlagsDelete(mPlatformFlags); + osMessageQueueDelete(mQueue); + osTimerDelete(mTimer); + mChipStackMutex = nullptr; + mPlatformFlags = nullptr; + mEventTaskMutex = nullptr; + mQueue = nullptr; + mTimer = nullptr; + + GenericPlatformManagerImpl::_Shutdown(); +} + +// ===== Members for internal use by the following friends. + +PlatformManagerImpl PlatformManagerImpl::sInstance; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/openiotsdk/PlatformManagerImpl.h b/src/platform/openiotsdk/PlatformManagerImpl.h new file mode 100644 index 00000000000000..70664944002143 --- /dev/null +++ b/src/platform/openiotsdk/PlatformManagerImpl.h @@ -0,0 +1,128 @@ +/* + * + * 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 + * Provides the implementation of the Device Layer Platform Manager class + * for Open IOT SDK platform. + */ + +#pragma once + +#include "cmsis_os2.h" +#include "mbedtls/platform.h" +#include +#include +#include + +namespace chip { +namespace DeviceLayer { + +/** + * Concrete implementation of the PlatformManager singleton object for the nRF Connect SDK platforms. + */ +class PlatformManagerImpl final : public PlatformManager, public Internal::GenericPlatformManagerImpl +{ + // Allow the PlatformManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend PlatformManager; + + // Allow the generic implementation base class to call helper methods on + // this class. +#ifndef DOXYGEN_SHOULD_SKIP_THIS + friend Internal::GenericPlatformManagerImpl; +#endif +public: + // ===== Platform-specific members that may be accessed directly by the application. + + /* none so far */ + +private: + static constexpr uint32_t kTaskRunningEventFlag = 1 << 0; + static constexpr uint32_t kTaskStopEventFlag = 1 << 1; + static constexpr uint32_t kPostEventFlag = 1 << 2; + static constexpr uint32_t kTimerEventFlag = 1 << 3; + + // ===== Methods that implement the PlatformManager abstract interface. + + CHIP_ERROR _InitChipStack(void); + void _LockChipStack(); + bool _TryLockChipStack(); + void _UnlockChipStack(); + + CHIP_ERROR _PostEvent(const ChipDeviceEvent * event); + + void _RunEventLoop(); + CHIP_ERROR _StartEventLoopTask(); + CHIP_ERROR _StopEventLoopTask(); + + CHIP_ERROR _StartChipTimer(System::Clock::Timeout duration); + void _Shutdown(); + + void SetEventFlags(uint32_t flags); + void HandleTimerEvent(void); + void HandlePostEvent(void); + + static void EventLoopTask(void * arg); + static void TimerCallback(void * arg); + + void RunEventLoopInternal(void); + + // ===== Members for internal use by the following friends. + + friend PlatformManager & PlatformMgr(void); + friend PlatformManagerImpl & PlatformMgrImpl(void); + friend class ConnectivityManagerImpl; + friend class GapEventHandler; + friend class CHIPService; + + using PlatformManager::PostEvent; + using PlatformManager::PostEventOrDie; + static PlatformManagerImpl sInstance; + + osEventFlagsId_t mPlatformFlags = nullptr; + osMutexId_t mChipStackMutex = nullptr; + osMutexId_t mEventTaskMutex = nullptr; + osMessageQueueId_t mQueue = nullptr; + osTimerId_t mTimer = nullptr; +}; + +/** + * Returns the public interface of the PlatformManager singleton object. + * + * chip applications should use this to access features of the PlatformManager object + * that are common to all platforms. + */ +inline PlatformManager & PlatformMgr(void) +{ + return PlatformManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the PlatformManager singleton object. + * + * chip applications can use this to gain access to features of the PlatformManager + * that are specific to the Mbed platform. + */ +inline PlatformManagerImpl & PlatformMgrImpl() +{ + return PlatformManagerImpl::sInstance; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/openiotsdk/SystemPlatformConfig.h b/src/platform/openiotsdk/SystemPlatformConfig.h new file mode 100644 index 00000000000000..c17393375bbe4c --- /dev/null +++ b/src/platform/openiotsdk/SystemPlatformConfig.h @@ -0,0 +1,42 @@ +/* + * + * 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 + * Platform-specific configuration overrides for the CHIP System + * Layer on Open IoT SDK platform. + * + */ + +#pragma once + +#include + +// ==================== Platform Adaptations ==================== +#define CHIP_SYSTEM_CONFIG_POSIX_LOCKING 0 +#define CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING 0 +#define CHIP_SYSTEM_CONFIG_MBED_LOCKING 0 +#define CHIP_SYSTEM_CONFIG_NO_LOCKING 0 +#define CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING 1 + +#define CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME 1 +#ifndef CHIP_SYSTEM_CONFIG_USE_LWIP_MONOTONIC_TIME +#define CHIP_SYSTEM_CONFIG_USE_LWIP_MONOTONIC_TIME 0 +#endif // CHIP_SYSTEM_CONFIG_USE_LWIP_MONOTONIC_TIME + +// ========== Platform-specific Configuration Overrides ========= diff --git a/src/platform/openiotsdk/SystemTimeSupport.cpp b/src/platform/openiotsdk/SystemTimeSupport.cpp new file mode 100644 index 00000000000000..60b7dc0f00ebd6 --- /dev/null +++ b/src/platform/openiotsdk/SystemTimeSupport.cpp @@ -0,0 +1,71 @@ +/* + * + * 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. + */ + +/** + * @file + * Provides an implementation of the system time support + * for Open IOT SDK platform. + */ + +#include +#include + +#include +#include +#include + +#include "OpenIoTSDKArchUtils.h" +#include "cmsis_os2.h" + +namespace chip { +namespace System { +namespace Clock { + +namespace Internal { + +ClockImpl gClockImpl; + +} // namespace Internal + +Clock::Microseconds64 ClockImpl::GetMonotonicMicroseconds64(void) +{ + return Clock::Microseconds64(tick2us(GetTick())); +} + +Clock::Milliseconds64 ClockImpl::GetMonotonicMilliseconds64(void) +{ + return Clock::Milliseconds64(tick2ms(GetTick())); +} + +CHIP_ERROR ClockImpl::GetClock_RealTime(Clock::Microseconds64 & aCurTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR ClockImpl::GetClock_RealTimeMS(Clock::Milliseconds64 & aCurTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR ClockImpl::SetClock_RealTime(Clock::Microseconds64 aNewCurTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +} // namespace Clock +} // namespace System +} // namespace chip diff --git a/src/platform/tests/BUILD.gn b/src/platform/tests/BUILD.gn index d34c8b00c88ce4..1de55b7be409ce 100644 --- a/src/platform/tests/BUILD.gn +++ b/src/platform/tests/BUILD.gn @@ -83,7 +83,7 @@ if (chip_device_platform != "none" && chip_device_platform != "fake") { } if (current_os == "zephyr" || current_os == "android" || - current_os == "mbed") { + current_os == "mbed" || current_os == "cmsis-rtos") { test_sources += [ "TestKeyValueStoreMgr.cpp" ] } diff --git a/src/system/BUILD.gn b/src/system/BUILD.gn index 76d64235fd0389..348e3af0ebf5f1 100644 --- a/src/system/BUILD.gn +++ b/src/system/BUILD.gn @@ -65,6 +65,8 @@ buildconfig_header("system_buildconfig") { chip_system_config_posix_locking = chip_system_config_locking == "posix" chip_system_config_freertos_locking = chip_system_config_locking == "freertos" chip_system_config_mbed_locking = chip_system_config_locking == "mbed" + chip_system_config_cmsis_rtos_locking = + chip_system_config_locking == "cmsis-rtos" chip_system_config_no_locking = chip_system_config_locking == "none" have_clock_gettime = chip_system_config_clock == "clock_gettime" have_clock_settime = have_clock_gettime @@ -82,6 +84,7 @@ buildconfig_header("system_buildconfig") { "CHIP_SYSTEM_CONFIG_POSIX_LOCKING=${chip_system_config_posix_locking}", "CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING=${chip_system_config_freertos_locking}", "CHIP_SYSTEM_CONFIG_MBED_LOCKING=${chip_system_config_mbed_locking}", + "CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING=${chip_system_config_cmsis_rtos_locking}", "CHIP_SYSTEM_CONFIG_NO_LOCKING=${chip_system_config_no_locking}", "CHIP_SYSTEM_CONFIG_PROVIDE_STATISTICS=${chip_system_config_provide_statistics}", "HAVE_CLOCK_GETTIME=${have_clock_gettime}", diff --git a/src/system/SystemConfig.h b/src/system/SystemConfig.h index 11ba2a0157ad0e..c214e922ca84f8 100644 --- a/src/system/SystemConfig.h +++ b/src/system/SystemConfig.h @@ -155,6 +155,10 @@ #define CHIP_SYSTEM_CONFIG_MBED_LOCKING INET_CONFIG_MBED_LOCKING #endif // !defined(CHIP_SYSTEM_CONFIG_MBED_LOCKING) && defined(INET_CONFIG_MBED_LOCKING) +#if !defined(CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING) && defined(INET_CONFIG_CMSIS_RTOS_LOCKING) +#define CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING INET_CONFIG_CMSIS_RTOS_LOCKING +#endif // !defined(CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING) && defined(INET_CONFIG_CMSIS_RTOS_LOCKING) + #if !defined(CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE) && defined(INET_CONFIG_NUM_BUFS) #define CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE INET_CONFIG_NUM_BUFS #endif // !defined(CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE) && defined(INET_CONFIG_NUM_BUFS) @@ -214,6 +218,20 @@ #define CHIP_SYSTEM_CONFIG_MBED_LOCKING 0 #endif /* CHIP_SYSTEM_CONFIG_MBED_LOCKING */ +/** + * @def CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING + * + * @brief + * Use CMSIS-RTOS locking. + * + * This should be generally asserted (1) for CMSIS-RTOS. + * + * However, if you are simulating an LwIP-based system atop POSIX threads and BSD sockets, this should also be deasserted (0). + */ +#ifndef CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING +#define CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING 0 +#endif /* CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING */ + /** * @def CHIP_SYSTEM_CONFIG_POOL_USE_HEAP * @@ -236,13 +254,13 @@ #define CHIP_SYSTEM_CONFIG_NO_LOCKING 0 #endif /* CHIP_SYSTEM_CONFIG_NO_LOCKING */ -#if !(CHIP_SYSTEM_CONFIG_POSIX_LOCKING || CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING || CHIP_SYSTEM_CONFIG_MBED_LOCKING || CHIP_SYSTEM_CONFIG_NO_LOCKING) -#error "REQUIRED: CHIP_SYSTEM_CONFIG_POSIX_LOCKING || CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING || CHIP_SYSTEM_CONFIG_MBED_LOCKING || CHIP_SYSTEM_CONFIG_NO_LOCKING" -#endif // !(CHIP_SYSTEM_CONFIG_POSIX_LOCKING || CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING || CHIP_SYSTEM_CONFIG_MBED_LOCKING || CHIP_SYSTEM_CONFIG_NO_LOCKING) +#if !(CHIP_SYSTEM_CONFIG_POSIX_LOCKING || CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING || CHIP_SYSTEM_CONFIG_MBED_LOCKING || CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING ||CHIP_SYSTEM_CONFIG_NO_LOCKING) +#error "REQUIRED: CHIP_SYSTEM_CONFIG_POSIX_LOCKING || CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING || CHIP_SYSTEM_CONFIG_MBED_LOCKING || CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING || CHIP_SYSTEM_CONFIG_NO_LOCKING" +#endif // !(CHIP_SYSTEM_CONFIG_POSIX_LOCKING || CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING || CHIP_SYSTEM_CONFIG_MBED_LOCKING || CHIP_SYSTEM_CONFIG_NO_LOCKING || CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING) -#if CHIP_SYSTEM_CONFIG_NO_LOCKING && (CHIP_SYSTEM_CONFIG_POSIX_LOCKING || CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING || CHIP_SYSTEM_CONFIG_MBED_LOCKING) -#error "FORBIDDEN: CHIP_SYSTEM_CONFIG_NO_LOCKING && (CHIP_SYSTEM_CONFIG_POSIX_LOCKING || CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING || CHIP_SYSTEM_CONFIG_MBED_LOCKING)" -#endif // CHIP_SYSTEM_CONFIG_NO_LOCKING && (CHIP_SYSTEM_CONFIG_POSIX_LOCKING || CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING || CHIP_SYSTEM_CONFIG_MBED_LOCKING) +#if CHIP_SYSTEM_CONFIG_NO_LOCKING && (CHIP_SYSTEM_CONFIG_POSIX_LOCKING || CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING || CHIP_SYSTEM_CONFIG_MBED_LOCKING || CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING) +#error "FORBIDDEN: CHIP_SYSTEM_CONFIG_NO_LOCKING && (CHIP_SYSTEM_CONFIG_POSIX_LOCKING || CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING || CHIP_SYSTEM_CONFIG_MBED_LOCKING || CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING)" +#endif // CHIP_SYSTEM_CONFIG_NO_LOCKING && (CHIP_SYSTEM_CONFIG_POSIX_LOCKING || CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING || CHIP_SYSTEM_CONFIG_MBED_LOCKING || CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING) #if CHIP_SYSTEM_CONFIG_POSIX_LOCKING && CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING #error "FORBIDDEN: CHIP_SYSTEM_CONFIG_POSIX_LOCKING && CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING" @@ -256,6 +274,18 @@ #error "FORBIDDEN: CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING && CHIP_SYSTEM_CONFIG_MBED_LOCKING" #endif // CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING && CHIP_SYSTEM_CONFIG_MBED_LOCKING +#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING && CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING +#error "FORBIDDEN: CHIP_SYSTEM_CONFIG_POSIX_LOCKING && CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING" +#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING && CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING + +#if CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING && CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING +#error "FORBIDDEN: CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING && CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING" +#endif // CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING && CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING + +#if CHIP_SYSTEM_CONFIG_MBED_LOCKING && CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING +#error "FORBIDDEN: CHIP_SYSTEM_CONFIG_MBED_LOCKING && CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING" +#endif // CHIP_SYSTEM_CONFIG_MBED_LOCKING && CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING + /** * @def CHIP_SYSTEM_HEADER_RESERVE_SIZE * diff --git a/src/system/SystemMutex.cpp b/src/system/SystemMutex.cpp index 878a1dda9b1983..ca6283ccd000aa 100644 --- a/src/system/SystemMutex.cpp +++ b/src/system/SystemMutex.cpp @@ -25,6 +25,8 @@ // Include module header #include +#include + #if !CHIP_SYSTEM_CONFIG_NO_LOCKING // Include system headers @@ -108,6 +110,35 @@ DLL_EXPORT void Mutex::Lock(void) } #endif // CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING +#if CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING +DLL_EXPORT CHIP_ERROR Mutex::Init(Mutex & aThis) +{ + aThis.mCmsisRTOSMutex = osMutexNew(NULL); + if (aThis.mCmsisRTOSMutex == NULL) + { + ChipLogError(chipSystemLayer, "osMutexNew failed"); + return CHIP_ERROR_NO_MEMORY; + } + return CHIP_NO_ERROR; +} + +DLL_EXPORT void Mutex::Lock(void) +{ + if (mCmsisRTOSMutex && osMutexAcquire(mCmsisRTOSMutex, osWaitForever) != osOK) + { + ChipLogError(chipSystemLayer, "osMutexAcquire failed"); + } +} + +DLL_EXPORT void Mutex::Unlock(void) +{ + if (mCmsisRTOSMutex && osMutexRelease(mCmsisRTOSMutex) != osOK) + { + ChipLogError(chipSystemLayer, "osMutexRelease failed"); + } +} +#endif // CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING + } // namespace System } // namespace chip diff --git a/src/system/SystemMutex.h b/src/system/SystemMutex.h index 09470b4d66df8b..13c8337c6c7ffb 100644 --- a/src/system/SystemMutex.h +++ b/src/system/SystemMutex.h @@ -52,6 +52,10 @@ #include #endif // CHIP_SYSTEM_CONFIG_MBED_LOCKING +#if CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING +#include +#endif // CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING + namespace chip { namespace System { @@ -101,6 +105,10 @@ class DLL_EXPORT Mutex rtos::Mutex mMbedMutex; #endif // CHIP_SYSTEM_CONFIG_MBED_LOCKING +#if CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING + osMutexId_t mCmsisRTOSMutex; +#endif // CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING + Mutex(const Mutex &) = delete; Mutex & operator=(const Mutex &) = delete; }; diff --git a/src/system/system.gni b/src/system/system.gni index 330f96be7a4c36..f65a610bd88161 100644 --- a/src/system/system.gni +++ b/src/system/system.gni @@ -57,7 +57,9 @@ if (chip_system_config_locking == "") { chip_system_config_locking = "freertos" } else if (current_os == "mbed") { chip_system_config_locking = "mbed" - } else if (!chip_system_config_use_dispatch) { + } else if (current_os == "cmsis-rtos") { + chip_system_config_locking = "cmsis-rtos" + } else if (chip_system_config_use_dispatch == false) { chip_system_config_locking = "posix" } else { chip_system_config_locking = "none" @@ -68,8 +70,9 @@ assert( chip_system_config_locking == "posix" || chip_system_config_locking == "freertos" || chip_system_config_locking == "none" || - chip_system_config_locking == "mbed", - "Please select a valid mutex implementation: posix, freertos, mbed, none") + chip_system_config_locking == "mbed" || + chip_system_config_locking == "cmsis-rtos", + "Please select a valid mutex implementation: posix, freertos, mbed, cmsis-rtos, none") assert( chip_system_config_clock == "clock_gettime" || diff --git a/src/system/tests/TestSystemTimer.cpp b/src/system/tests/TestSystemTimer.cpp index 19a179b2114585..9188d63656a06a 100644 --- a/src/system/tests/TestSystemTimer.cpp +++ b/src/system/tests/TestSystemTimer.cpp @@ -625,12 +625,14 @@ static int TestSetup(void * aContext) return FAILURE; } +#if !defined(CHIP_DEVICE_LAYER_TARGET_OPEN_IOT_SDK) #if CHIP_SYSTEM_CONFIG_USE_LWIP && LWIP_VERSION_MAJOR == 2 && LWIP_VERSION_MINOR == 0 static sys_mbox_t * sLwIPEventQueue = NULL; sys_mbox_new(sLwIPEventQueue, 100); tcpip_init(NULL, NULL); #endif // CHIP_SYSTEM_CONFIG_USE_LWIP && LWIP_VERSION_MAJOR == 2 && LWIP_VERSION_MINOR == 0 +#endif // !defined(CHIP_DEVICE_LAYER_TARGET_OPEN_IOT_SDK) sLayer.Init(); @@ -650,9 +652,11 @@ static int TestTeardown(void * aContext) lContext.mLayer->Shutdown(); +#if !defined(CHIP_DEVICE_LAYER_TARGET_OPEN_IOT_SDK) #if CHIP_SYSTEM_CONFIG_USE_LWIP && (LWIP_VERSION_MAJOR == 2) && (LWIP_VERSION_MINOR == 0) tcpip_finish(NULL, NULL); #endif // CHIP_SYSTEM_CONFIG_USE_LWIP && (LWIP_VERSION_MAJOR == 2) && (LWIP_VERSION_MINOR == 0) +#endif // !defined(CHIP_DEVICE_LAYER_TARGET_OPEN_IOT_SDK) ::chip::Platform::MemoryShutdown(); return (SUCCESS); diff --git a/src/test_driver/openiotsdk/integration-tests/.gitignore b/src/test_driver/openiotsdk/integration-tests/.gitignore new file mode 100644 index 00000000000000..9e76edca71065a --- /dev/null +++ b/src/test_driver/openiotsdk/integration-tests/.gitignore @@ -0,0 +1 @@ +/**/test_report.json diff --git a/src/test_driver/openiotsdk/integration-tests/common/__init__.py b/src/test_driver/openiotsdk/integration-tests/common/__init__.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/src/test_driver/openiotsdk/integration-tests/common/device.py b/src/test_driver/openiotsdk/integration-tests/common/device.py new file mode 100644 index 00000000000000..eff76e1c5ad413 --- /dev/null +++ b/src/test_driver/openiotsdk/integration-tests/common/device.py @@ -0,0 +1,120 @@ +# +# 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. +# + +import logging +import queue +from time import sleep, time +from typing import Optional + +log = logging.getLogger(__name__) + + +class Device: + + def __init__(self, name: Optional[str] = None): + """ + Base Device runner class containing device handling functions and logging + :param name: Logging name for the client + """ + self.iq = queue.Queue() + self.oq = queue.Queue() + if name is None: + self.name = str(hex(id(self))) + else: + self.name = name + + def send(self, command, expected_output=None, wait_before_read=None, wait_for_response=10, assert_output=True): + """ + Send command for client + :param command: Command + :param expected_output: Reply to wait from the client + :param wait_before_read: Timeout after write + :param wait_for_response: Timeout waiting the response + :param assert_output: Assert the fail situations to end the test run + :return: If there's expected output then the response line is returned + """ + log.debug('{}: Sending command to client: "{}"'.format( + self.name, command)) + self.flush(0) + self._write(command) + if expected_output is not None: + if wait_before_read is not None: + sleep(wait_before_read) + return self.wait_for_output(expected_output, wait_for_response, assert_output) + + def flush(self, timeout: float = 0) -> [str]: + """ + Flush the lines in the input queue + :param timeout: The timeout before flushing starts + :type timeout: float + :return: The lines removed from the input queue + :rtype: list of str + """ + sleep(timeout) + lines = [] + while True: + try: + lines.append(self._read_line(0)) + except queue.Empty: + return lines + + def wait_for_output(self, search: str, timeout: float = 10, assert_timeout: bool = True) -> [str]: + """ + Wait for expected output response + :param search: Expected response string + :type search: str + :param timeout: Response waiting time + :type timeout: float + :param assert_timeout: Assert on timeout situations + :type assert_timeout: bool + :return: Line received before a match + :rtype: list of str + """ + lines = [] + start = time() + now = 0 + timeout_error_msg = '{}: Didn\'t find {} in {} s'.format( + self.name, search, timeout) + + while time() - start <= timeout: + try: + line = self._read_line(1) + if line: + lines.append(line) + if search in line: + end = time() + return lines + + except queue.Empty: + last = now + now = time() + if now - start >= timeout: + if assert_timeout: + log.error(timeout_error_msg) + assert False, timeout_error_msg + else: + log.warning(timeout_error_msg) + return [] + if now - last > 1: + log.info('{}: Waiting for "{}" string... Timeout in {:.0f} s'.format(self.name, search, + abs(now - start - timeout))) + + def _write(self, data): + self.oq.put(data) + + def _read_line(self, timeout): + return self.iq.get(timeout=timeout) diff --git a/src/test_driver/openiotsdk/integration-tests/common/fixtures.py b/src/test_driver/openiotsdk/integration-tests/common/fixtures.py new file mode 100644 index 00000000000000..2613b196567c00 --- /dev/null +++ b/src/test_driver/openiotsdk/integration-tests/common/fixtures.py @@ -0,0 +1,122 @@ +# +# 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. +# + +import pytest +import os +import pathlib +from time import sleep +import shutil + +from .telnet_connection import TelnetConnection +from .fvp_device import FvpDevice + +from chip import exceptions + +from chip import ChipDeviceCtrl +from chip.ChipStack import * +import chip.native +import chip.CertificateAuthority + +import logging +log = logging.getLogger(__name__) + + +@pytest.fixture(scope="session") +def rootDir(): + return pathlib.Path(__file__).parents[5].absolute() + + +@pytest.fixture(scope="session") +def fvp(request): + if request.config.getoption('fvp'): + return request.config.getoption('fvp') + else: + return shutil.which('FVP_Corstone_SSE-300_Ethos-U55') + + +@pytest.fixture(scope="session") +def fvpConfig(request, rootDir): + if request.config.getoption('fvpConfig'): + return request.config.getoption('fvpConfig') + else: + return os.path.join(rootDir, 'config/openiotsdk/fvp/cs300.conf') + + +@pytest.fixture(scope="session") +def telnetPort(request): + return request.config.getoption('telnetPort') + + +@pytest.fixture(scope="session") +def networkInterface(request): + if request.config.getoption('networkInterface'): + return request.config.getoption('networkInterface') + else: + return None + + +@pytest.fixture(scope="function") +def device(fvp, fvpConfig, binaryPath, telnetPort, networkInterface): + connection = TelnetConnection('localhost', telnetPort) + device = FvpDevice(fvp, fvpConfig, binaryPath, connection, networkInterface, "FVPdev") + device.start() + yield device + device.stop() + + +@pytest.fixture(scope="session") +def vendor_id(): + return 0xFFF1 + + +@pytest.fixture(scope="session") +def fabric_id(): + return 1 + + +@pytest.fixture(scope="session") +def node_id(): + return 1 + + +@pytest.fixture(scope="function") +def controller(vendor_id, fabric_id, node_id): + try: + chip.native.Init() + chipStack = chip.ChipStack.ChipStack( + persistentStoragePath='/tmp/openiotsdk-test-storage.json', enableServerInteractions=False) + certificateAuthorityManager = chip.CertificateAuthority.CertificateAuthorityManager( + chipStack, chipStack.GetStorageManager()) + certificateAuthorityManager.LoadAuthoritiesFromStorage() + if (len(certificateAuthorityManager.activeCaList) == 0): + ca = certificateAuthorityManager.NewCertificateAuthority() + ca.NewFabricAdmin(vendorId=vendor_id, fabricId=fabric_id) + elif (len(certificateAuthorityManager.activeCaList[0].adminList) == 0): + certificateAuthorityManager.activeCaList[0].NewFabricAdmin(vendorId=vendor_id, fabricId=fabric_id) + + caList = certificateAuthorityManager.activeCaList + + devCtrl = caList[0].adminList[0].NewController() + + except exceptions.ChipStackException as ex: + log.error("Controller initialization failed {}".format(ex)) + return None + except: + log.error("Controller initialization failed") + return None + + yield devCtrl diff --git a/src/test_driver/openiotsdk/integration-tests/common/fvp_device.py b/src/test_driver/openiotsdk/integration-tests/common/fvp_device.py new file mode 100644 index 00000000000000..3255e6a42eaf48 --- /dev/null +++ b/src/test_driver/openiotsdk/integration-tests/common/fvp_device.py @@ -0,0 +1,102 @@ +# +# 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. +# + +import logging +import threading +import os +import subprocess +from time import sleep + +from .device import Device + +log = logging.getLogger(__name__) + + +class FvpDevice(Device): + + def __init__(self, fvp, fvp_config, binary_file, connection_channel, network_interface, name=None): + + self.run = False + self.connection_channel = connection_channel + super(FvpDevice, self).__init__(name) + + input_thread_name = '<-- {}'.format(self.name) + output_thread_name = '--> {}'.format(self.name) + + self.fvp_cmd = [ + fvp, + '-f', f'{fvp_config}', + '--application', f'{binary_file}', + '--quantum=25', + '-C', 'mps3_board.telnetterminal0.start_port={}'.format(self.connection_channel.get_port()) + ] + + if network_interface != None: + self.fvp_cmd.extend(['-C', 'mps3_board.hostbridge.interfaceName={}'.format(network_interface), ]) + else: + self.fvp_cmd.extend(['-C', 'mps3_board.hostbridge.userNetworking=1']) + + self.it = threading.Thread( + target=self._input_thread, name=input_thread_name) + self.ot = threading.Thread( + target=self._output_thread, name=output_thread_name) + + def start(self): + """ + Start the FVP and connection channel with device + """ + log.info('Starting "{}" runner...'.format(self.name)) + + self.proc = subprocess.Popen(self.fvp_cmd) + sleep(3) + self.connection_channel.open() + self.run = True + self.it.start() + self.ot.start() + log.info('"{}" runner started'.format(self.name)) + + def stop(self): + """ + Stop the FVP and connection channel + """ + log.info('Stopping "{}" runner...'.format(self.name)) + self.run = False + self.connection_channel.close() + self.oq.put(None) + self.it.join() + self.ot.join() + self.proc.terminate() + self.proc.wait() + log.info('"{}" runner stoped'.format(self.name)) + + def _input_thread(self): + while self.run: + line = self.connection_channel.readline() + if line: + log.info('<--|{}| {}'.format(self.name, line.strip())) + self.iq.put(line) + else: + pass + + def _output_thread(self): + while self.run: + line = self.oq.get() + if line: + log.info('-->|{}| {}'.format(self.name, line.strip())) + self.connection_channel.write(line) + else: + log.debug('Nothing sent') diff --git a/src/test_driver/openiotsdk/integration-tests/common/telnet_connection.py b/src/test_driver/openiotsdk/integration-tests/common/telnet_connection.py new file mode 100644 index 00000000000000..b5367ed5747387 --- /dev/null +++ b/src/test_driver/openiotsdk/integration-tests/common/telnet_connection.py @@ -0,0 +1,123 @@ +# Copyright (c) 2009-2021 Arm Limited +# SPDX-License-Identifier: Apache-2.0 +# +# 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 +from time import sleep +import re + +from telnetlib import Telnet + +log = logging.getLogger(__name__) + + +class TelnetConnection: + """ + Telnet Connection class containing telnet connection handling functions + :param host: host name + :param port: prot number + """ + + def __init__(self, host=None, port=0): + self.telnet = Telnet() + self.host = host + self.port = port + self.is_open = False + + def open(self): + """ + Open telnet connection + """ + try: + self.telnet.open(self.host, self.port) + except Exception as e: + log.error('Open telnet connection to {}:{} failed {}'.format(self.host, self.port, e)) + return None + + self.is_open = True + + def __strip_escape(self, string_to_escape) -> str: + """ + Strip escape characters from string. + :param string_to_escape: string to work on + :return: stripped string + """ + raw_ansi_pattern = r'\033\[((?:\d|;)*)([a-zA-Z])' + ansi_pattern = raw_ansi_pattern.encode() + ansi_eng = re.compile(ansi_pattern) + matches = [] + for match in ansi_eng.finditer(string_to_escape): + matches.append(match) + matches.reverse() + for match in matches: + start = match.start() + end = match.end() + string_to_escape = string_to_escape[0:start] + string_to_escape[end:] + return string_to_escape + + def __formatline(self, line) -> str: + output_line = self.__strip_escape(line) + # Testapp uses \r to print characters to the same line, strip those and return only the last part + # If there is only one \r, don't remove anything. + if b'\r' in line and line.count(b'\r') > 1: + output_line = output_line.split(b'\r')[-2] + # Debug traces use tabulator characters, change those to spaces for readability + output_line = output_line.replace(b'\t', b' ') + output_line = output_line.decode('utf-8', 'ignore') + output_line.rstrip() + return output_line + + def readline(self): + """ + Read line from telnet session + :return: One line from telnet stream + """ + if not self.is_open: + return None + try: + output = self.telnet.read_until(b"\n", 1) + return self.__formatline(output) + except Exception as e: + log.error('Telnet read failed {}'.format(e)) + return None + + def write(self, data): + """ + Write data to telnet input + :param data: Data to send [bytes array] + """ + if not self.is_open: + return None + try: + data = data + '\n' + for item in data: + self.telnet.write(item.encode('utf-8')) + sleep(0.03) + except Exception as e: + log.error('Telnet write failed {}'.format(e)) + return None + + def close(self): + """ + Close telnet connection + """ + self.telnet.close() + self.is_open = False + + def get_port(self): + """ + Get port number of telnet connection + :return: Port Nnumber + """ + return self.port diff --git a/src/test_driver/openiotsdk/integration-tests/common/utils.py b/src/test_driver/openiotsdk/integration-tests/common/utils.py new file mode 100644 index 00000000000000..04d463d8558d38 --- /dev/null +++ b/src/test_driver/openiotsdk/integration-tests/common/utils.py @@ -0,0 +1,249 @@ +# +# 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. +# + +import os +import random +import shlex +import re +import ctypes +import asyncio +from time import sleep + +from chip.setup_payload import SetupPayload +from chip import exceptions + +from chip.clusters import Objects as GeneratedObjects +from chip import discovery + +import logging +log = logging.getLogger(__name__) + +IP_ADDRESS_BUFFER_LEN = 100 + + +def get_setup_payload(device): + """ + Get device setup payload from logs + :param device: serial device instance + :return: setup payload or None + """ + ret = device.wait_for_output("SetupQRCode") + if ret == None or len(ret) < 2: + return None + + qr_code = re.sub( + r"[\[\]]", "", ret[-1].partition("SetupQRCode:")[2]).strip() + try: + setup_payload = SetupPayload().ParseQrCode( + "VP:vendorpayload%{}".format(qr_code)) + except exceptions.ChipStackError as ex: + log.error("SetupPayload failed {}".format(str(ex))) + return None + + return setup_payload + + +def discover_device(devCtrl, setupPayload): + """ + Discover specific device in network. + Search by device discriminator from setup payload + :param devCtrl: device controller instance + :param setupPayload: device setup payload + :return: CommissionableNode object if node device discovered or None if failed + """ + log.info("Attempting to find device on network") + longDiscriminator = int(setupPayload.attributes['Long discriminator']) + try: + res = devCtrl.DiscoverCommissionableNodes( + discovery.FilterType.LONG_DISCRIMINATOR, longDiscriminator, stopOnFirst=True, timeoutSecond=5) + except exceptions.ChipStackError as ex: + log.error("DiscoverCommissionableNodes failed {}".format(str(ex))) + return None + if not res: + log.info("Device not found") + return None + return res[0] + + +def connect_device(setupPayload, commissionableDevice, nodeId=None): + """ + Connect to Matter discovered device on network + :param setupPayload: device setup payload + :param commissionableDevice: CommissionableNode object with discovered device + :param nodeId: device node ID + :return: node ID if connection successful or None if failed + """ + if nodeId == None: + nodeId = random.randint(1, 1000000) + + pincode = int(setupPayload.attributes['SetUpPINCode']) + try: + commissionableDevice.Commission(nodeId, pincode) + except exceptions.ChipStackError as ex: + log.error("Commission discovered device failed {}".format(str(ex))) + return None + return nodeId + + +def disconnect_device(devCtrl, nodeId): + """ + Disconnect Matter device + :param devCtrl: device controller instance + :param nodeId: device node ID + :return: node ID if connection successful or None if failed + """ + try: + devCtrl.CloseSession(nodeId) + except exceptions.ChipStackException as ex: + log.error("CloseSession failed {}".format(str(ex))) + return False + return True + + +class ParsingError(exceptions.ChipStackException): + def __init__(self, msg=None): + self.msg = "Parsing Error: " + msg + + def __str__(self): + return self.msg + + +def ParseEncodedString(value): + if value.find(":") < 0: + raise ParsingError( + "Value should be encoded in encoding:encodedvalue format") + enc, encValue = value.split(":", 1) + if enc == "str": + return encValue.encode("utf-8") + b'\x00' + elif enc == "hex": + return bytes.fromhex(encValue) + raise ParsingError("Only str and hex encoding is supported") + + +def ParseValueWithType(value, type): + if type == 'int': + return int(value) + elif type == 'str': + return value + elif type == 'bytes': + return ParseEncodedString(value) + elif type == 'bool': + return (value.upper() not in ['F', 'FALSE', '0']) + else: + raise ParsingError('Cannot recognize type: {}'.format(type)) + + +def ParseValueWithStruct(value, cluster): + return eval(f"GeneratedObjects.{cluster}.Structs.{value}") + + +def ParseValue(value, valueType, cluster): + if valueType: + return ParseValueWithType(value, valueType) + elif value.find(":") > 0 and value.split(":", 1)[0] == "struct": + return ParseValueWithStruct(value.split(":", 1)[1], cluster) + else: + raise ParsingError('Cannot parse value: {}'.format(value)) + + +def FormatZCLArguments(cluster, args, cmdArgsWithType): + cmdArgsDict = {} + for kvPair in args: + if kvPair.find("=") < 0: + raise ParsingError("Argument should in key=value format") + key, value = kvPair.split("=", 1) + valueType = cmdArgsWithType.get(key, None) + cmdArgsDict[key] = ParseValue(value, valueType, cluster) + return cmdArgsDict + + +def send_zcl_command(devCtrl, line, requestTimeoutMs: int = None): + """ + Format and send ZCL message to device. + :param devCtrl: device controller instance + :param line: command line + :param requestTimeoutMs: command request timeout in ms + :return: error code and command response + """ + res = None + err = 0 + try: + args = shlex.split(line) + if len(args) < 4: + raise exceptions.InvalidArgumentCount(4, len(args)) + + cluster, command, nodeId, endpoint = args[0:4] + cmdArgsLine = args[4:] + allCommands = devCtrl.ZCLCommandList() + if cluster not in allCommands: + raise exceptions.UnknownCluster(cluster) + cmdArgsWithType = allCommands.get(cluster).get(command, None) + # When command takes no arguments, (not command) is True + if command == None: + raise exceptions.UnknownCommand(cluster, command) + + args = FormatZCLArguments(cluster, cmdArgsLine, cmdArgsWithType) + clusterObj = getattr(GeneratedObjects, cluster) + commandObj = getattr(clusterObj.Commands, command) + req = commandObj(**args) + + res = asyncio.run(devCtrl.SendCommand(int(nodeId), int(endpoint), req, timedRequestTimeoutMs=requestTimeoutMs)) + + except exceptions.ChipStackException as ex: + log.error("An exception occurred during processing ZCL command: {}".format(str(ex))) + err = -1 + except Exception as ex: + log.error("An exception occurred during processing input: {}".format(str(ex))) + err = -1 + + return (err, res) + + +def read_zcl_attribute(devCtrl, line): + """ + Read ZCL attribute from device: + + :param devCtrl: device controller instance + :param line: command line + :return: error code and attribute response + """ + res = None + err = 0 + try: + args = shlex.split(line) + if len(args) < 4: + raise exceptions.InvalidArgumentCount(4, len(args)) + + cluster, attribute, nodeId, endpoint = args[0:4] + allAttrs = devCtrl.ZCLAttributeList() + if cluster not in allAttrs: + raise exceptions.UnknownCluster(cluster) + + attrDetails = allAttrs.get(cluster).get(attribute, None) + if attrDetails == None: + raise exceptions.UnknownAttribute(cluster, attribute) + + res = devCtrl.ZCLReadAttribute(cluster, attribute, int( + nodeId), int(endpoint), 0) + except exceptions.ChipStackException as ex: + log.error("An exception occurred during processing ZCL attribute: {}".format(str(ex))) + err = -1 + except Exception as ex: + log.error("An exception occurred during processing input: {}".format(str(ex))) + err = -1 + + return (err, res) diff --git a/src/test_driver/openiotsdk/integration-tests/conftest.py b/src/test_driver/openiotsdk/integration-tests/conftest.py new file mode 100644 index 00000000000000..90116956e55dec --- /dev/null +++ b/src/test_driver/openiotsdk/integration-tests/conftest.py @@ -0,0 +1,38 @@ +# +# 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. +# + +import pytest + +pytest_plugins = ['common.fixtures'] + + +def pytest_addoption(parser): + """ + Function for pytest to enable own custom commandline arguments + :param parser: argparser + :return: + """ + parser.addoption('--binaryPath', action='store', + help='Application binary path') + parser.addoption('--fvp', action='store', + help='FVP instance path') + parser.addoption('--fvpConfig', action='store', + help='FVP configuration file path') + parser.addoption('--telnetPort', action='store', + help='Telnet terminal port number.', default="5000") + parser.addoption('--networkInterface', action='store', + help='FVP network interface name') diff --git a/src/test_driver/openiotsdk/integration-tests/lock-app/__init__.py b/src/test_driver/openiotsdk/integration-tests/lock-app/__init__.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/src/test_driver/openiotsdk/integration-tests/lock-app/test_app.py b/src/test_driver/openiotsdk/integration-tests/lock-app/test_app.py new file mode 100644 index 00000000000000..d89d26dc32d698 --- /dev/null +++ b/src/test_driver/openiotsdk/integration-tests/lock-app/test_app.py @@ -0,0 +1,176 @@ +# +# 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. +# + +import pytest +from time import sleep + +from common.utils import * + +from chip.clusters.Objects import DoorLock + +import logging +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/lock-app/openiotsdk/build/chip-openiotsdk-lock-app-example.elf') + + +@pytest.mark.smoketest +def test_smoke_test(device): + ret = device.wait_for_output("Open IoT SDK lock-app example application start") + assert ret != None and len(ret) > 0 + ret = device.wait_for_output("Open IoT SDK lock-app example application run") + assert ret != None and len(ret) > 0 + + +@pytest.mark.commissioningtest +def test_commissioning(device, controller): + assert controller != None + devCtrl = controller + + setupPayload = get_setup_payload(device) + assert setupPayload != None + + commissionable_device = discover_device(devCtrl, setupPayload) + assert commissionable_device != None + + assert commissionable_device.vendorId == int(setupPayload.attributes['VendorID']) + assert commissionable_device.productId == int(setupPayload.attributes['ProductID']) + assert commissionable_device.addresses[0] != None + + nodeId = connect_device(setupPayload, commissionable_device) + assert nodeId != None + log.info("Device {} connected".format(commissionable_device.addresses[0])) + + ret = device.wait_for_output("Commissioning completed successfully", timeout=30) + assert ret != None and len(ret) > 0 + + assert disconnect_device(devCtrl, nodeId) + + +LOCK_CTRL_TEST_PIN_CODE = 12345 +LOCK_CTRL_TEST_USER_INDEX = 1 +LOCK_CTRL_TEST_ENDPOINT_ID = 1 +LOCK_CTRL_TEST_USER_NAME = 'testUser' +LOCK_CTRL_TEST_CREDENTIAL_INDEX = 1 + + +@pytest.mark.ctrltest +def test_lock_ctrl(device, controller): + assert controller != None + devCtrl = controller + + setupPayload = get_setup_payload(device) + assert setupPayload != None + + commissionable_device = discover_device(devCtrl, setupPayload) + assert commissionable_device != None + + nodeId = connect_device(setupPayload, commissionable_device) + assert nodeId != None + + ret = device.wait_for_output("Commissioning completed successfully", timeout=30) + assert ret != None and len(ret) > 0 + + err, res = send_zcl_command( + devCtrl, "DoorLock SetUser {} {} operationType={} userIndex={} userName={} userUniqueId={} " + "userStatus={} userType={} credentialRule={}".format(nodeId, LOCK_CTRL_TEST_ENDPOINT_ID, + DoorLock.Enums.DlDataOperationType.kAdd, + LOCK_CTRL_TEST_USER_INDEX, + LOCK_CTRL_TEST_USER_NAME, + LOCK_CTRL_TEST_USER_INDEX, + DoorLock.Enums.DlUserStatus.kOccupiedEnabled, + DoorLock.Enums.DlUserType.kUnrestrictedUser, + DoorLock.Enums.DlCredentialRule.kSingle), requestTimeoutMs=1000) + assert err == 0 + + ret = device.wait_for_output("Successfully set the user [mEndpointId={},index={},adjustedIndex=0]".format( + LOCK_CTRL_TEST_ENDPOINT_ID, + LOCK_CTRL_TEST_USER_INDEX)) + assert ret != None and len(ret) > 0 + + err, res = send_zcl_command( + devCtrl, "DoorLock GetUser {} {} userIndex={}".format(nodeId, LOCK_CTRL_TEST_ENDPOINT_ID, + LOCK_CTRL_TEST_USER_INDEX)) + assert err == 0 + assert res.userIndex == LOCK_CTRL_TEST_USER_INDEX + assert res.userName == LOCK_CTRL_TEST_USER_NAME + assert res.userUniqueId == LOCK_CTRL_TEST_USER_INDEX + assert res.userStatus == DoorLock.Enums.DlUserStatus.kOccupiedEnabled + assert res.userType == DoorLock.Enums.DlUserType.kUnrestrictedUser + assert res.credentialRule == DoorLock.Enums.DlCredentialRule.kSingle + + err, res = send_zcl_command( + devCtrl, "DoorLock SetCredential {} {} operationType={} " + "credential=struct:DlCredential(credentialType={},credentialIndex={}) credentialData=str:{} " + "userIndex={} userStatus={} userType={}".format(nodeId, LOCK_CTRL_TEST_ENDPOINT_ID, + DoorLock.Enums.DlDataOperationType.kAdd, + DoorLock.Enums.DlCredentialType.kPin, + LOCK_CTRL_TEST_CREDENTIAL_INDEX, + LOCK_CTRL_TEST_PIN_CODE, + LOCK_CTRL_TEST_USER_INDEX, + DoorLock.Enums.DlUserStatus.kOccupiedEnabled, + DoorLock.Enums.DlUserType.kUnrestrictedUser), requestTimeoutMs=1000) + assert err == 0 + assert res.status == DoorLock.Enums.DlStatus.kSuccess + + ret = device.wait_for_output("Successfully set the credential [mEndpointId={},index={}," + "credentialType={},creator=1,modifier=1]".format(LOCK_CTRL_TEST_ENDPOINT_ID, + LOCK_CTRL_TEST_USER_INDEX, DoorLock.Enums.DlCredentialType.kPin)) + assert ret != None and len(ret) > 0 + + err, res = send_zcl_command( + devCtrl, "DoorLock GetCredentialStatus {} {} credential=struct:DlCredential(credentialType={}," + "credentialIndex={})".format(nodeId, LOCK_CTRL_TEST_ENDPOINT_ID, + DoorLock.Enums.DlCredentialType.kPin, + LOCK_CTRL_TEST_CREDENTIAL_INDEX), requestTimeoutMs=1000) + assert err == 0 + assert res.credentialExists + assert res.userIndex == LOCK_CTRL_TEST_USER_INDEX + + err, res = send_zcl_command( + devCtrl, "DoorLock LockDoor {} {} pinCode=str:{}".format(nodeId, LOCK_CTRL_TEST_ENDPOINT_ID, + LOCK_CTRL_TEST_PIN_CODE), requestTimeoutMs=1000) + assert err == 0 + + ret = device.wait_for_output("Setting door lock state to \"Locked\" [endpointId={}]".format(LOCK_CTRL_TEST_ENDPOINT_ID)) + assert ret != None and len(ret) > 0 + + err, res = read_zcl_attribute( + devCtrl, "DoorLock LockState {} {}".format(nodeId, LOCK_CTRL_TEST_ENDPOINT_ID)) + assert err == 0 + assert res.value == DoorLock.Enums.DlLockState.kLocked + + err, res = send_zcl_command( + devCtrl, "DoorLock UnlockDoor {} {} pinCode=str:{}".format(nodeId, LOCK_CTRL_TEST_ENDPOINT_ID, + LOCK_CTRL_TEST_PIN_CODE), requestTimeoutMs=1000) + assert err == 0 + + ret = device.wait_for_output("Setting door lock state to \"Unlocked\" [endpointId={}]".format(LOCK_CTRL_TEST_ENDPOINT_ID)) + assert ret != None and len(ret) > 0 + + err, res = read_zcl_attribute( + devCtrl, "DoorLock LockState {} {}".format(nodeId, LOCK_CTRL_TEST_ENDPOINT_ID)) + assert err == 0 + assert res.value == DoorLock.Enums.DlLockState.kUnlocked + + assert disconnect_device(devCtrl, nodeId) diff --git a/src/test_driver/openiotsdk/integration-tests/pytest.ini b/src/test_driver/openiotsdk/integration-tests/pytest.ini new file mode 100644 index 00000000000000..78c8ab6382ffa5 --- /dev/null +++ b/src/test_driver/openiotsdk/integration-tests/pytest.ini @@ -0,0 +1,9 @@ +[pytest] +log_cli = true +log_level = INFO +log_format = %(asctime)s.%(msecs)03d %(levelname)s %(message)s +log_cli_format = %(asctime)s.%(msecs)03d %(levelname)s %(message)s +markers = + smoketest: A simple test to verify that the application is properly launched + commissioningtest: Test to validate the commissionign process + ctrltest: Test checking the operation of the application through integration with it diff --git a/src/test_driver/openiotsdk/integration-tests/shell/__init__.py b/src/test_driver/openiotsdk/integration-tests/shell/__init__.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/src/test_driver/openiotsdk/integration-tests/shell/test_app.py b/src/test_driver/openiotsdk/integration-tests/shell/test_app.py new file mode 100644 index 00000000000000..72cd8d0166c50f --- /dev/null +++ b/src/test_driver/openiotsdk/integration-tests/shell/test_app.py @@ -0,0 +1,191 @@ +# Copyright (c) 2009-2021 Arm Limited +# SPDX-License-Identifier: Apache-2.0 +# +# 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 pytest +import re +from packaging import version +from time import sleep + +from chip.setup_payload import SetupPayload +from chip import exceptions +import chip.native + +from common.utils import * + +import logging +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/shell/openiotsdk/build/chip-openiotsdk-shell-example.elf') + + +SHELL_COMMAND_NAME = ["base64", "exit", "help", "version", + "config", "device", "onboardingcodes", "dns", + "echo", "log", "rand"] + + +def get_shell_command(response): + return [line.split()[0].strip() for line in response] + + +def parse_config_response(response): + config = {} + for param in response: + param_name = param.split(":")[0].lower() + if "discriminator" in param_name: + value = int(param.split(":")[1].strip(), 16) + elif "pincode" in param_name: + value = int(param.split(":")[1].strip()) + else: + value = int(param.split(":")[1].split()[0].strip()) + + if "hardwareversion" in param_name: + param_name = "hardwarever" + + config[param_name] = value + return config + + +def parse_boarding_codes_response(response): + codes = {} + for param in response: + codes[param.split(":")[0].lower()] = param.split()[1].strip() + return codes + + +@pytest.mark.smoketest +def test_smoke_test(device): + ret = device.wait_for_output("Open IoT SDK shell example application start") + assert ret != None and len(ret) > 0 + ret = device.wait_for_output("Open IoT SDK shell example application run") + assert ret != None and len(ret) > 0 + + +@pytest.mark.ctrltest +def test_command_check(device): + try: + chip.native.Init() + except exceptions.ChipStackException as ex: + log.error("CHIP initialization failed {}".format(ex)) + assert False + except: + log.error("CHIP initialization failed") + assert False + + ret = device.wait_for_output("Open IoT SDK shell example application start") + assert ret != None and len(ret) > 0 + ret = device.wait_for_output("Open IoT SDK shell example application run") + assert ret != None and len(ret) > 0 + + # Help + ret = device.send(command="help", expected_output="Done") + assert ret != None and len(ret) > 1 + shell_commands = get_shell_command(ret[1:-1]) + assert set(SHELL_COMMAND_NAME) == set(shell_commands) + + # Echo + ret = device.send(command="echo Hello", expected_output="Done") + assert ret != None and len(ret) > 1 + assert "Hello" in ret[-2] + + # Log + ret = device.send(command="log Hello", expected_output="Done") + assert ret != None and len(ret) > 1 + assert "[INF] [TOO] Hello" in ret[-2] + + # Rand + ret = device.send(command="rand", expected_output="Done") + assert ret != None and len(ret) > 1 + assert ret[-2].rstrip().isdigit() + + # Base64 + hex_string = "1234" + ret = device.send(command="base64 encode {}".format( + hex_string), expected_output="Done") + assert ret != None and len(ret) > 1 + base64code = ret[-2] + ret = device.send(command="base64 decode {}".format( + base64code), expected_output="Done") + assert ret != None and len(ret) > 1 + assert ret[-2].rstrip() == hex_string + + # Version + ret = device.send(command="version", expected_output="Done") + assert ret != None and len(ret) > 1 + assert "CHIP" in ret[-2].split()[0] + app_version = ret[-2].split()[1] + assert isinstance(version.parse(app_version), version.Version) + + # Config + ret = device.send(command="config", expected_output="Done") + assert ret != None and len(ret) > 2 + + config = parse_config_response(ret[1:-1]) + + for param_name, value in config.items(): + ret = device.send(command="config {}".format( + param_name), expected_output="Done") + assert ret != None and len(ret) > 1 + if "discriminator" in param_name: + assert int(ret[-2].split()[0], 16) == value + else: + assert int(ret[-2].split()[0]) == value + + new_value = int(config['discriminator']) + 1 + ret = device.send(command="config discriminator {}".format( + new_value), expected_output="Done") + assert ret != None and len(ret) > 1 + assert "Setup discriminator set to: {}".format(new_value) in ret[-2] + + ret = device.send(command="config discriminator", expected_output="Done") + assert ret != None and len(ret) > 1 + assert int(ret[-2].split()[0], 16) == new_value + + # Onboardingcodes + ret = device.send(command="onboardingcodes none", expected_output="Done") + assert ret != None and len(ret) > 2 + + boarding_codes = parse_boarding_codes_response(ret[1:-1]) + + for param, value in boarding_codes.items(): + ret = device.send(command="onboardingcodes none {}".format( + param), expected_output="Done") + assert ret != None and len(ret) > 1 + assert value == ret[-2].strip() + + try: + device_details = dict(SetupPayload().ParseQrCode( + "VP:vendorpayload%{}".format(boarding_codes['qrcode'])).attributes) + except exceptions.ChipStackError as ex: + log.error(ex.msg) + assert False + assert device_details != None and len(device_details) != 0 + + try: + device_details = dict(SetupPayload().ParseManualPairingCode( + boarding_codes['manualpairingcode']).attributes) + except exceptions.ChipStackError as ex: + log.error(ex.msg) + assert False + assert device_details != None and len(device_details) != 0 + + # Exit - should be the last check + ret = device.send(command="exit", expected_output="Goodbye") + assert ret != None and len(ret) > 0 diff --git a/src/test_driver/openiotsdk/unit-tests/.gitignore b/src/test_driver/openiotsdk/unit-tests/.gitignore new file mode 100644 index 00000000000000..bcd261e241a6c2 --- /dev/null +++ b/src/test_driver/openiotsdk/unit-tests/.gitignore @@ -0,0 +1,2 @@ +build/ +test_report.json diff --git a/src/test_driver/openiotsdk/unit-tests/CMakeLists.txt b/src/test_driver/openiotsdk/unit-tests/CMakeLists.txt new file mode 100644 index 00000000000000..15470ba12589f8 --- /dev/null +++ b/src/test_driver/openiotsdk/unit-tests/CMakeLists.txt @@ -0,0 +1,83 @@ +# +# 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. +# + +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) + +list(APPEND CMAKE_MODULE_PATH ${OPEN_IOT_SDK_CONFIG}/cmake) + +# Toolchain files need to exist before first call to project +include(toolchain) + +project(chip-open-iot-sdk-unit-tests LANGUAGES C CXX ASM) + +include(sdk) +include(linker) + +# LwIP configuration +if(TARGET lwip-cmsis-port) + # lwip requires user_lwipopts.h, we use the custom settings + target_include_directories(lwipopts + INTERFACE + lwip-config + ) +endif() + +# Application CHIP build configuration +set(CONFIG_CHIP_LIB_TESTS YES) +set(CONFIG_CHIP_DETAIL_LOGGING NO) +set(CONFIG_CHIP_PROGRESS_LOGGING NO) +set(CONFIG_CHIP_AUTOMATION_LOGGING YES) +set(CONFIG_CHIP_ERROR_LOGGING NO) + +include(chip) + +add_subdirectory(${OPEN_IOT_SDK_EXAMPLE_COMMON}/app ./app_build) + +file(STRINGS testnames.txt TEST_NAMES_FROM_FILE) +STRING(REGEX REPLACE "\n" ";" TEST_NAMES_FROM_FILE "${TEST_NAMES_FROM_FILE}") + +foreach(TEST_NAME IN LISTS TEST_NAMES_FROM_FILE) + add_executable(${TEST_NAME}) + target_include_directories(${TEST_NAME} + PRIVATE + main/include + ${CHIP_ROOT}/third_party/nlunit-test/repo/src + ) + + target_sources(${TEST_NAME} + PRIVATE + main/main.cpp + ) + + target_link_libraries(${TEST_NAME} + openiotsdk-app + ) + + # Link the *whole-archives* to keep the static test objects. + target_link_options(${TEST_NAME} + PUBLIC + -Wl,--whole-archive "${CMAKE_CURRENT_BINARY_DIR}/chip_build/lib/lib${TEST_NAME}.a" + -Wl,--no-whole-archive "${CMAKE_CURRENT_BINARY_DIR}/chip_build/lib/libCHIP_tests.a" + -Wl,--no-whole-archive) + + # set_target_link requires APP_TARGET to be defined + set(APP_TARGET ${TEST_NAME}) + set_target_link(${TEST_NAME}) +endforeach() diff --git a/src/test_driver/openiotsdk/unit-tests/README.md b/src/test_driver/openiotsdk/unit-tests/README.md new file mode 100644 index 00000000000000..584f31aea71e0d --- /dev/null +++ b/src/test_driver/openiotsdk/unit-tests/README.md @@ -0,0 +1,86 @@ +# Matter Open IoT Unit Tests Application + +The Open IoT SDK Unit Tests Application executes all supported unit tests on the +target. + +The Matter unit tests are included in a set of libraries and allow to validate +most of the components used by Matter examples applications. The main goal of +this application is to run registered tests on Open IoT SDK target and check the +results. The final result is the number of tests that failed. + +## Environment setup + +The required environment is the same as for the Matter examples. For information +on how to setup it see +[Open IoT SDK examples](../../../../docs/examples/openiotsdk_examples.md#Environment-setup). + +## Building + +The build process means creating separate executable file for each Matter tested +component. It assumes the use of all supported test libraries and creating +independent applications from them. + +You build using a vscode task or call the script directly from the command line. + +### Building using vscode task + +``` +Command Palette (F1) => Run Task... => Build Open IoT SDK unit-tests => (debug on/off) +``` + +This will call the scripts with the selected parameters. + +### Building using CLI + +You can call the script directly yourself. + +``` +${MATTER_ROOT}/scripts/examples/openiotsdk_example.sh unit-tests +``` + +Use `--help` to get more information about the script options. + +## Running + +Unit-tests applications can be run independently or as an entire set. It runs in +the background and opens a telnet session. The script will open telnet for you +and connect to the port used by the `FVP`. When the telnet process is terminated +it will also terminate the `FVP` instance. + +You can run the application script from a vscode task or call the script +directly. + +Expected output of each executed test: + +``` + [ATM] Open IoT SDK unit-tests start + [ATM] Open IoT SDK unit-tests run... + ... + [ATM] Test status: 0 +``` + +### Running using vscode task + +``` +Command Palette (F1) => Run Task... => Run Open IoT SDK unit-tests => or all (to run all tests) +``` + +### Running using CLI + +You can call the script directly yourself. + +``` +${MATTER_ROOT}/scripts/examples/openiotsdk_example.sh -C run unit-tests (optional to run specific test) +``` + +## Debugging + +Debugging can be started using a VS code launch task: + +``` +Run and Debug (Ctrl+Shift+D) => Debug Open IoT SDK unit-tests application => Start Debugging (F5) => => +``` + +As you can see above, you will need to select the name of the test twice. This +is because the debug task needs to launch the run task and currently VS code has +no way of passing parameters between tasks. diff --git a/src/test_driver/openiotsdk/unit-tests/cmsis-config/RTE_Components.h b/src/test_driver/openiotsdk/unit-tests/cmsis-config/RTE_Components.h new file mode 100644 index 00000000000000..e86df2b4e44e06 --- /dev/null +++ b/src/test_driver/openiotsdk/unit-tests/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/src/test_driver/openiotsdk/unit-tests/freertos-config/FreeRTOSConfig.h b/src/test_driver/openiotsdk/unit-tests/freertos-config/FreeRTOSConfig.h new file mode 100644 index 00000000000000..6011c1e9d6bf79 --- /dev/null +++ b/src/test_driver/openiotsdk/unit-tests/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: 128 +#define configMINIMAL_STACK_SIZE ((uint16_t)(4 * 1024)) + +// Total heap size [bytes] <0-0xFFFFFFFF> +// Heap memory size in bytes. +// Default: 8192 +#define configTOTAL_HEAP_SIZE ((size_t) 8192) + +// 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 1 + +// 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/src/test_driver/openiotsdk/unit-tests/lwip-config/user_lwipopts.h b/src/test_driver/openiotsdk/unit-tests/lwip-config/user_lwipopts.h new file mode 100644 index 00000000000000..59ed1720c7e36c --- /dev/null +++ b/src/test_driver/openiotsdk/unit-tests/lwip-config/user_lwipopts.h @@ -0,0 +1,25 @@ +/* + * + * 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 USER_LWIPOPTS_H +#define USER_LWIPOPTS_H + +#define LWIP_STATS (0) +#define PBUF_POOL_SIZE (1001) + +#endif /* USER_LWIPOPTS_H */ diff --git a/src/test_driver/openiotsdk/unit-tests/main/include/CHIPProjectConfig.h b/src/test_driver/openiotsdk/unit-tests/main/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..bb2c4755245f95 --- /dev/null +++ b/src/test_driver/openiotsdk/unit-tests/main/include/CHIPProjectConfig.h @@ -0,0 +1,44 @@ +/* + * + * 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 + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +// Enable support functions for parsing command-line arguments +#define CHIP_CONFIG_ENABLE_ARG_PARSER 1 +#define CHIP_CONFIG_NON_POSIX_LONG_OPT 1 + +#define CHIP_SYSTEM_CONFIG_NUM_TIMERS 32 +#define CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE 1 + +#define CONFIG_BUILD_FOR_HOST_UNIT_TEST 1 + +#define CONFIG_IM_BUILD_FOR_UNIT_TEST 1 +#define CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT 64 +#define CHIP_CONFIG_MAX_FABRICS 16 +#define CHIP_DEVICE_CONFIG_MAX_EVENT_QUEUE_SIZE 500 + +#define CHIP_SYSTEM_CONFIG_POOL_USE_HEAP 1 diff --git a/src/test_driver/openiotsdk/unit-tests/main/include/NlTestLogger.h b/src/test_driver/openiotsdk/unit-tests/main/include/NlTestLogger.h new file mode 100644 index 00000000000000..f43e3e19081fc2 --- /dev/null +++ b/src/test_driver/openiotsdk/unit-tests/main/include/NlTestLogger.h @@ -0,0 +1,72 @@ +/* + * + * 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 + * Custom NL test logger implementation + * + */ + +#include +#include + +class NlTestLogger +{ + static void def_log_name(struct _nlTestSuite * inSuite) { printf("[ %s ]\r\n", inSuite->name); } + + static void def_log_initialize(struct _nlTestSuite * inSuite, int inResult, int inWidth) + { + printf("[ %s : %-*s ] : %s\r\n", inSuite->name, inWidth, "Initialize", inResult == FAILURE ? "FAILED" : "PASSED"); + } + static void def_log_terminate(struct _nlTestSuite * inSuite, int inResult, int inWidth) + { + printf("[ %s : %-*s ] : %s\r\n", inSuite->name, inWidth, "Terminate", inResult == FAILURE ? "FAILED" : "PASSED"); + } + + static void def_log_setup(struct _nlTestSuite * inSuite, int inResult, int inWidth) + { + printf("[ %s : %-*s ] : %s\r\n", inSuite->name, inWidth, "Setup", inResult == FAILURE ? "FAILED" : "PASSED"); + } + + static void def_log_test(struct _nlTestSuite * inSuite, int inWidth, int inIndex) + { + printf("[ %s : %-*s ] : %s\r\n", inSuite->name, inWidth, inSuite->tests[inIndex].name, + inSuite->flagError ? "FAILED" : "PASSED"); + } + + static void def_log_teardown(struct _nlTestSuite * inSuite, int inResult, int inWidth) + { + printf("[ %s : %-*s ] : %s\r\n", inSuite->name, inWidth, "TearDown", inResult == FAILURE ? "FAILED" : "PASSED"); + } + + static void def_log_statTest(struct _nlTestSuite * inSuite) + { + printf("Failed Tests: %d / %d\r\n", inSuite->failedTests, inSuite->runTests); + } + + static void def_log_statAssert(struct _nlTestSuite * inSuite) + { + printf("Failed Asserts: %d / %d\r\n", inSuite->failedAssertions, inSuite->performedAssertions); + } + +public: + static constexpr nl_test_output_logger_t nl_test_logger = { + def_log_name, def_log_initialize, def_log_terminate, def_log_setup, + def_log_test, def_log_teardown, def_log_statTest, def_log_statAssert, + }; +}; diff --git a/src/test_driver/openiotsdk/unit-tests/main/main.cpp b/src/test_driver/openiotsdk/unit-tests/main/main.cpp new file mode 100644 index 00000000000000..8c41fd04d68593 --- /dev/null +++ b/src/test_driver/openiotsdk/unit-tests/main/main.cpp @@ -0,0 +1,90 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include + +#include + +#include "cmsis_os2.h" +#include "openiotsdk_platform.h" + +constexpr nl_test_output_logger_t NlTestLogger::nl_test_logger; + +using namespace ::chip; + +static void test_thread(void * argument) +{ + int status; + CHIP_ERROR err; + + if (openiotsdk_network_init(true)) + { + ChipLogAutomation("ERROR: Network initialization failed"); + goto exit; + } + + err = DeviceLayer::PlatformMgr().InitChipStack(); + if (err != CHIP_NO_ERROR) + { + ChipLogAutomation("Chip stack initialization failed: %s", err.AsString()); + goto exit; + } + + ChipLogAutomation("Open IoT SDK unit-tests run..."); + status = RunRegisteredUnitTests(); + ChipLogAutomation("Test status: %d", status); + ChipLogAutomation("Open IoT SDK unit-tests completed"); +exit: + osThreadTerminate(osThreadGetId()); +} + +int main() +{ + ChipLogAutomation("Open IoT SDK unit-tests start"); + + if (openiotsdk_platform_init()) + { + ChipLogAutomation("ERROR: Open IoT SDK platform initialization failed"); + return EXIT_FAILURE; + } + + nlTestSetLogger(&NlTestLogger::nl_test_logger); + + static const osThreadAttr_t thread_attr = { + .stack_size = 20 * 1024 // Allocate enough stack for app thread + }; + + osThreadId_t testThread = osThreadNew(test_thread, NULL, &thread_attr); + if (testThread == NULL) + { + ChipLogAutomation("ERROR: Failed to create app thread"); + return EXIT_FAILURE; + } + + if (openiotsdk_platform_run()) + { + ChipLogAutomation("ERROR: Open IoT SDK platform run failed"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/src/test_driver/openiotsdk/unit-tests/testnames.txt b/src/test_driver/openiotsdk/unit-tests/testnames.txt new file mode 100644 index 00000000000000..03fa4aee9b70f4 --- /dev/null +++ b/src/test_driver/openiotsdk/unit-tests/testnames.txt @@ -0,0 +1,24 @@ +accesstest +AppTests +ASN1Tests +BDXTests +ChipCryptoTests +CoreTests +CredentialsTest +DataModelTests +InetLayerTests +MdnsTests +MessagingLayerTests +MinimalMdnsCoreTests +MinimalMdnsRecordsTests +MinimalMdnsRespondersTests +PlatformTests +RawTransportTests +RetransmitTests +SecureChannelTests +SetupPayloadTests +SupportTests +SystemLayerTests +TestShell +TransportLayerTests +UserDirectedCommissioningTests