diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 6847480b51a5b9..b5da6c153e4d7f 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -17,7 +17,7 @@ "build": { "dockerfile": "Dockerfile", "args": { - "BUILD_VERSION": "0.6.03" + "BUILD_VERSION": "0.6.06" } }, "remoteUser": "vscode", diff --git a/.github/workflows/bloat_check.yaml b/.github/workflows/bloat_check.yaml index 4849a8df42021b..78f56124d0ba5e 100644 --- a/.github/workflows/bloat_check.yaml +++ b/.github/workflows/bloat_check.yaml @@ -30,7 +30,7 @@ jobs: runs-on: ubuntu-latest container: - image: connectedhomeip/chip-build:0.6.05 + image: connectedhomeip/chip-build:0.6.06 steps: - uses: Wandalen/wretry.action@v1.0.15 diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 750506bbf62a7c..19f1b969c2592b 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -32,7 +32,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:0.6.05 + image: connectedhomeip/chip-build:0.6.06 volumes: - "/tmp/log_output:/tmp/test_logs" options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 @@ -133,7 +133,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:0.6.05 + image: connectedhomeip/chip-build:0.6.06 volumes: - "/tmp/log_output:/tmp/test_logs" options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 @@ -287,7 +287,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:0.6.05 + image: connectedhomeip/chip-build:0.6.06 volumes: - "/tmp/log_output:/tmp/test_logs" options: --sysctl "net.ipv6.conf.all.disable_ipv6=0 diff --git a/.github/workflows/chef.yaml b/.github/workflows/chef.yaml index 9484e01243754b..a473a39fc18102 100644 --- a/.github/workflows/chef.yaml +++ b/.github/workflows/chef.yaml @@ -29,7 +29,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:0.6.05 + image: connectedhomeip/chip-build:0.6.06 options: --user root steps: @@ -57,7 +57,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-esp32:0.6.05 + image: connectedhomeip/chip-build-esp32:0.6.06 options: --user root steps: @@ -85,7 +85,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-nrf-platform:0.6.05 + image: connectedhomeip/chip-build-nrf-platform:0.6.06 options: --user root steps: diff --git a/.github/workflows/cirque.yaml b/.github/workflows/cirque.yaml index 78d501293a33ad..c91c437b8b22fb 100644 --- a/.github/workflows/cirque.yaml +++ b/.github/workflows/cirque.yaml @@ -29,7 +29,7 @@ jobs: timeout-minutes: 90 env: - DOCKER_RUN_VERSION: 0.6.05 + DOCKER_RUN_VERSION: 0.6.06 GITHUB_CACHE_PATH: /tmp/cirque-cache/ runs-on: ubuntu-latest @@ -38,7 +38,7 @@ jobs: # need to run with privilege, which isn't supported by job.XXX.contaner # https://github.com/actions/container-action/issues/2 # container: - # image: connectedhomeip/chip-build-cirque:0.6.05 + # image: connectedhomeip/chip-build-cirque:0.6.06 # volumes: # - "/tmp:/tmp" # - "/dev/pts:/dev/pts" diff --git a/.github/workflows/doxygen.yaml b/.github/workflows/doxygen.yaml index 075154910b4e2a..1d33bd9b8708da 100644 --- a/.github/workflows/doxygen.yaml +++ b/.github/workflows/doxygen.yaml @@ -82,7 +82,7 @@ jobs: runs-on: ubuntu-20.04 container: - image: connectedhomeip/chip-build-doxygen:0.6.05 + image: connectedhomeip/chip-build-doxygen:0.6.06 if: github.actor != 'restyled-io[bot]' diff --git a/.github/workflows/examples-ameba.yaml b/.github/workflows/examples-ameba.yaml index 0f22ae0b5b73ad..50506da74c6c17 100644 --- a/.github/workflows/examples-ameba.yaml +++ b/.github/workflows/examples-ameba.yaml @@ -32,7 +32,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-ameba:0.6.05 + image: connectedhomeip/chip-build-ameba:0.6.06 options: --user root steps: diff --git a/.github/workflows/examples-cc13x2x7_26x2x7.yaml b/.github/workflows/examples-cc13x2x7_26x2x7.yaml index 26a35488aa620f..78e06bbaa04cc9 100644 --- a/.github/workflows/examples-cc13x2x7_26x2x7.yaml +++ b/.github/workflows/examples-cc13x2x7_26x2x7.yaml @@ -34,7 +34,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-ti:0.6.05 + image: connectedhomeip/chip-build-ti:0.6.06 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-efr32.yaml b/.github/workflows/examples-efr32.yaml index 5bf7067b231077..ace5165dcc98f3 100644 --- a/.github/workflows/examples-efr32.yaml +++ b/.github/workflows/examples-efr32.yaml @@ -35,7 +35,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-efr32:0.6.05 + image: connectedhomeip/chip-build-efr32:0.6.06 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-esp32.yaml b/.github/workflows/examples-esp32.yaml index 0da3c73d34794d..4fa36a41dedb6f 100644 --- a/.github/workflows/examples-esp32.yaml +++ b/.github/workflows/examples-esp32.yaml @@ -31,7 +31,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-esp32:0.6.05 + image: connectedhomeip/chip-build-esp32:0.6.06 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" @@ -119,7 +119,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-esp32:0.6.05 + image: connectedhomeip/chip-build-esp32:0.6.06 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-infineon.yaml b/.github/workflows/examples-infineon.yaml index 3bd67ff377bb2f..0cf077b3c11acc 100644 --- a/.github/workflows/examples-infineon.yaml +++ b/.github/workflows/examples-infineon.yaml @@ -32,7 +32,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-infineon:0.6.05 + image: connectedhomeip/chip-build-infineon:0.6.06 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-k32w.yaml b/.github/workflows/examples-k32w.yaml index f62da3a00e23d2..ce7088d499a346 100644 --- a/.github/workflows/examples-k32w.yaml +++ b/.github/workflows/examples-k32w.yaml @@ -34,7 +34,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-k32w:0.6.05 + image: connectedhomeip/chip-build-k32w:0.6.06 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-linux-arm.yaml b/.github/workflows/examples-linux-arm.yaml index 51fae3f86e6e37..c38d8389e617a7 100644 --- a/.github/workflows/examples-linux-arm.yaml +++ b/.github/workflows/examples-linux-arm.yaml @@ -31,7 +31,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-crosscompile:0.6.05 + image: connectedhomeip/chip-build-crosscompile:0.6.06 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-linux-imx.yaml b/.github/workflows/examples-linux-imx.yaml index 81d8d60537ea90..1c17f0b6ddaae7 100644 --- a/.github/workflows/examples-linux-imx.yaml +++ b/.github/workflows/examples-linux-imx.yaml @@ -31,7 +31,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-imx:0.6.05 + image: connectedhomeip/chip-build-imx:0.6.06 steps: - uses: Wandalen/wretry.action@v1.0.15 diff --git a/.github/workflows/examples-linux-standalone.yaml b/.github/workflows/examples-linux-standalone.yaml index 38438ecfea0b8a..77fe6ceb4674b1 100644 --- a/.github/workflows/examples-linux-standalone.yaml +++ b/.github/workflows/examples-linux-standalone.yaml @@ -34,7 +34,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:0.6.05 + image: connectedhomeip/chip-build:0.6.06 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-mbed.yaml b/.github/workflows/examples-mbed.yaml index f7a69bd3de3054..1e38a7f3271924 100644 --- a/.github/workflows/examples-mbed.yaml +++ b/.github/workflows/examples-mbed.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-mbed-os:0.6.05 + image: connectedhomeip/chip-build-mbed-os:0.6.06 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-mw320.yaml b/.github/workflows/examples-mw320.yaml index 93c2327ba3ad74..9f54ec8ae2dbf8 100755 --- a/.github/workflows/examples-mw320.yaml +++ b/.github/workflows/examples-mw320.yaml @@ -34,7 +34,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:0.6.05 + image: connectedhomeip/chip-build:0.6.06 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-nrfconnect.yaml b/.github/workflows/examples-nrfconnect.yaml index c6b729f3776855..f46b3e87426b06 100644 --- a/.github/workflows/examples-nrfconnect.yaml +++ b/.github/workflows/examples-nrfconnect.yaml @@ -34,7 +34,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-nrf-platform:0.6.05 + image: connectedhomeip/chip-build-nrf-platform:0.6.06 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-qpg.yaml b/.github/workflows/examples-qpg.yaml index 56656a645da7cd..86db7a309b5fd2 100644 --- a/.github/workflows/examples-qpg.yaml +++ b/.github/workflows/examples-qpg.yaml @@ -34,7 +34,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:0.6.05 + image: connectedhomeip/chip-build:0.6.06 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-telink.yaml b/.github/workflows/examples-telink.yaml index e20c2690686a19..366cf0857a484a 100644 --- a/.github/workflows/examples-telink.yaml +++ b/.github/workflows/examples-telink.yaml @@ -32,7 +32,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-telink:0.6.05 + image: connectedhomeip/chip-build-telink:0.6.06 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-tizen.yaml b/.github/workflows/examples-tizen.yaml index 47c9e880deae69..c2c39674a65b98 100644 --- a/.github/workflows/examples-tizen.yaml +++ b/.github/workflows/examples-tizen.yaml @@ -32,7 +32,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-tizen:0.6.05 + image: connectedhomeip/chip-build-tizen:0.6.06 options: --user root volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/full-android.yaml b/.github/workflows/full-android.yaml index 176f2ac65a1d81..b3c961edec832e 100644 --- a/.github/workflows/full-android.yaml +++ b/.github/workflows/full-android.yaml @@ -34,7 +34,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-android:0.6.05 + image: connectedhomeip/chip-build-android:0.6.06 volumes: - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/fuzzing-build.yaml b/.github/workflows/fuzzing-build.yaml index b9267d9a5e9afc..6caf55c05773d1 100644 --- a/.github/workflows/fuzzing-build.yaml +++ b/.github/workflows/fuzzing-build.yaml @@ -31,7 +31,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:0.6.05 + image: connectedhomeip/chip-build:0.6.06 volumes: - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 2b4fe4a91150d4..6bb491ff0fb9d7 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -28,7 +28,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:0.6.05 + image: connectedhomeip/chip-build:0.6.06 steps: - uses: Wandalen/wretry.action@v1.0.15 diff --git a/.github/workflows/qemu.yaml b/.github/workflows/qemu.yaml index eb083791dd2a93..ab7eb29d38338a 100644 --- a/.github/workflows/qemu.yaml +++ b/.github/workflows/qemu.yaml @@ -34,7 +34,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-esp32-qemu:0.6.05 + image: connectedhomeip/chip-build-esp32-qemu:0.6.06 volumes: - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/release_artifacts.yaml b/.github/workflows/release_artifacts.yaml index 6bc9abad9d117f..f2124e828a81f5 100644 --- a/.github/workflows/release_artifacts.yaml +++ b/.github/workflows/release_artifacts.yaml @@ -29,7 +29,7 @@ jobs: runs-on: ubuntu-latest container: - image: connectedhomeip/chip-build-esp32:0.6.05 + image: connectedhomeip/chip-build-esp32:0.6.06 steps: - uses: Wandalen/wretry.action@v1.0.15 @@ -75,7 +75,7 @@ jobs: runs-on: ubuntu-latest container: - image: connectedhomeip/chip-build-efr32:0.6.05 + image: connectedhomeip/chip-build-efr32:0.6.06 steps: - uses: Wandalen/wretry.action@v1.0.15 name: Checkout diff --git a/.github/workflows/smoketest-android.yaml b/.github/workflows/smoketest-android.yaml index af5c8c7d565482..7065d26f8e5f06 100644 --- a/.github/workflows/smoketest-android.yaml +++ b/.github/workflows/smoketest-android.yaml @@ -34,7 +34,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-android:0.6.05 + image: connectedhomeip/chip-build-android:0.6.06 volumes: - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 0e88bb57277978..b6c4ab72f129d3 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -44,7 +44,7 @@ jobs: runs-on: ubuntu-latest container: - image: connectedhomeip/chip-build:0.6.05 + image: connectedhomeip/chip-build:0.6.06 options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" @@ -347,7 +347,7 @@ jobs: runs-on: ubuntu-latest container: - image: connectedhomeip/chip-build:0.6.05 + image: connectedhomeip/chip-build:0.6.06 options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=0 net.ipv6.conf.all.forwarding=0" diff --git a/.github/workflows/unit_integration_test.yaml b/.github/workflows/unit_integration_test.yaml index c2875c49d52538..4be02d8c89895d 100644 --- a/.github/workflows/unit_integration_test.yaml +++ b/.github/workflows/unit_integration_test.yaml @@ -37,7 +37,7 @@ jobs: runs-on: ubuntu-latest container: - image: connectedhomeip/chip-build:0.6.05 + image: connectedhomeip/chip-build:0.6.06 volumes: - "/tmp/log_output:/tmp/test_logs" options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" diff --git a/.github/workflows/zap_regeneration.yaml b/.github/workflows/zap_regeneration.yaml index 9f76f042d7f136..19e44cbddb9ee7 100644 --- a/.github/workflows/zap_regeneration.yaml +++ b/.github/workflows/zap_regeneration.yaml @@ -28,7 +28,7 @@ jobs: runs-on: ubuntu-20.04 container: - image: connectedhomeip/chip-build-zap:0.6.05 + image: connectedhomeip/chip-build-zap:0.6.06 defaults: run: shell: sh diff --git a/.github/workflows/zap_templates.yaml b/.github/workflows/zap_templates.yaml index 0a16f8e6ede8e7..03aafce5908a54 100644 --- a/.github/workflows/zap_templates.yaml +++ b/.github/workflows/zap_templates.yaml @@ -29,7 +29,7 @@ jobs: runs-on: ubuntu-20.04 container: - image: connectedhomeip/chip-build-zap:0.6.05 + image: connectedhomeip/chip-build-zap:0.6.06 defaults: run: shell: sh diff --git a/config/telink/chip-module/CMakeLists.txt b/config/telink/chip-module/CMakeLists.txt index f6d93210b4a416..6ef6ac2c882238 100644 --- a/config/telink/chip-module/CMakeLists.txt +++ b/config/telink/chip-module/CMakeLists.txt @@ -28,6 +28,7 @@ if (CONFIG_CHIP) include(ExternalProject) include(../../zephyr/ota-image.cmake) include(../../zephyr/zephyr-util.cmake) +include(generate_factory_data.cmake) # ============================================================================== # Declare configuration variables and define constants @@ -45,7 +46,7 @@ list(APPEND CHIP_CFLAGS_CC) # CHIP libraries that the application should be linked with list(APPEND CHIP_LIBRARIES) -# GN meta-build system arguments in the form of 'key1 = value1\nkey2 = value2...' string +# GN meta-build system arguments passed to the make_gn_args.py script string(APPEND CHIP_GN_ARGS) # C/C++ compiler flags which should not be forwarded to CHIP @@ -67,28 +68,27 @@ set(CHIP_CFLAG_EXCLUDES # ============================================================================== macro(chip_gn_arg_import FILE) - string(APPEND CHIP_GN_ARGS "import(\"${FILE}\")\n") + 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") + string(APPEND CHIP_GN_ARGS "--arg-string\n${ARG}\n${STRING}\n") endmacro() -macro(chip_gn_arg_bool ARG BOOLEAN) - if (${BOOLEAN}) - string(APPEND CHIP_GN_ARGS "${ARG} = true\n") +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} = false\n") + string(APPEND CHIP_GN_ARGS "--arg\n${ARG}\nfalse\n") endif() endmacro() macro(chip_gn_arg_cflags ARG CFLAGS) - set(CFLAG_EXCLUDES "[") - foreach(cflag ${CHIP_CFLAG_EXCLUDES}) - string(APPEND CFLAG_EXCLUDES "\"${cflag}\", ") - endforeach() - string(APPEND CFLAG_EXCLUDES "]") - string(APPEND CHIP_GN_ARGS "${ARG} = filter_exclude(string_split(\"${CFLAGS}\"), ${CFLAG_EXCLUDES})\n") + string(APPEND CHIP_GN_ARGS "--arg-cflags\n${ARG}\n${CFLAGS}\n") +endmacro() + +macro(chip_gn_arg ARG VALUE) + string(APPEND CHIP_GN_ARGS "--arg\n${ARG}\n${VALUE}\n") endmacro() # ============================================================================== @@ -197,8 +197,6 @@ chip_gn_arg_cflags("target_cflags_cc" ${CHIP_CFLAGS_CC}) chip_gn_arg_string("zephyr_ar" ${CMAKE_AR}) chip_gn_arg_string("zephyr_cc" ${CMAKE_C_COMPILER}) chip_gn_arg_string("zephyr_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_enable_openthread" CONFIG_NET_L2_OPENTHREAD) chip_gn_arg_bool ("chip_openthread_ftd" CONFIG_OPENTHREAD_FTD) @@ -208,16 +206,32 @@ chip_gn_arg_bool ("chip_build_tests" CONFIG_CHIP_BUILD_TE chip_gn_arg_bool ("chip_inet_config_enable_tcp_endpoint" CONFIG_CHIP_BUILD_TESTS) chip_gn_arg_bool ("chip_build_libshell" CONFIG_CHIP_LIB_SHELL) +if (CONFIG_CHIP_FACTORY_DATA) + chip_gn_arg_bool ("chip_use_transitional_commissionable_data_provider" "false") + chip_gn_arg_bool ("chip_enable_factory_data" "true") +elseif (CONFIG_CHIP_FACTORY_DATA_CUSTOM_BACKEND) + chip_gn_arg_bool ("chip_use_transitional_commissionable_data_provider" "false") +endif() + +if (CONFIG_CHIP_ROTATING_DEVICE_ID) + chip_gn_arg_bool("chip_enable_rotating_device_id" "true") + chip_gn_arg_bool("chip_enable_additional_data_advertising" "true") +endif() + if (CONFIG_CHIP_ENABLE_DNSSD_SRP) chip_gn_arg_string("chip_mdns" "platform") endif() +if (CHIP_PROJECT_CONFIG) + chip_gn_arg_string("chip_project_config_include" ${CHIP_PROJECT_CONFIG}) + chip_gn_arg_string("chip_system_project_config_include" ${CHIP_PROJECT_CONFIG}) +endif() if (CONFIG_CHIP_EXAMPLE_DEVICE_INFO_PROVIDER) chip_gn_arg_bool("chip_build_example_providers" "true") list(APPEND CHIP_LIBRARIES -lMatterDeviceInfoProviderExample) endif() -file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/args.gn CONTENT ${CHIP_GN_ARGS}) +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 @@ -227,13 +241,17 @@ ExternalProject_Add( PREFIX ${CMAKE_CURRENT_BINARY_DIR} SOURCE_DIR ${CHIP_ROOT} BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} - CONFIGURE_COMMAND ${GN_EXECUTABLE} + CONFIGURE_COMMAND "" + BUILD_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 + --export-compile-commands + gen --check --fail-on-unused-args . && + ninja INSTALL_COMMAND "" BUILD_BYPRODUCTS ${CHIP_LIBRARIES} BUILD_ALWAYS TRUE @@ -288,11 +306,11 @@ if (CONFIG_CHIP_OTA_IMAGE_BUILD) west sign -t imgtool -p ${ZEPHYR_BASE}/../bootloader/mcuboot/scripts/imgtool.py -d ${PROJECT_BINARY_DIR}/.. -- --key ${ZEPHYR_BASE}/../bootloader/mcuboot/root-rsa-2048.pem ) - add_custom_target(final_bin ALL + add_custom_target(merge_mcuboot ALL COMMAND - dd if=${PROJECT_BINARY_DIR}/../modules/chip-module/build_mcuboot/zephyr/zephyr.bin of=${PROJECT_BINARY_DIR}/zephyr_final.bin + dd if=${PROJECT_BINARY_DIR}/../modules/chip-module/build_mcuboot/zephyr/zephyr.bin of=${PROJECT_BINARY_DIR}/zephyr.bin COMMAND - dd if=${PROJECT_BINARY_DIR}/zephyr.signed.bin of=${PROJECT_BINARY_DIR}/zephyr_final.bin bs=1024 seek=64 + dd if=${PROJECT_BINARY_DIR}/zephyr.signed.bin of=${PROJECT_BINARY_DIR}/zephyr.bin bs=1024 seek=64 ) chip_ota_image(chip-ota-image @@ -301,8 +319,28 @@ if (CONFIG_CHIP_OTA_IMAGE_BUILD) ) add_dependencies(west_sign ${ZEPHYR_FINAL_EXECUTABLE}) - add_dependencies(final_bin west_sign) + add_dependencies(merge_mcuboot west_sign) add_dependencies(chip-ota-image west_sign) endif() +if (CONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE) + add_custom_target(merge_factory_data ALL + COMMAND + dd if=${PROJECT_BINARY_DIR}/factory_data.bin of=${PROJECT_BINARY_DIR}/zephyr.bin bs=1024 seek=976 + ) +if (CONFIG_CHIP_OTA_IMAGE_BUILD) + add_dependencies(merge_factory_data merge_mcuboot) +else() + add_dependencies(merge_factory_data ${ZEPHYR_FINAL_EXECUTABLE}) +endif() +endif() + +# ============================================================================== +# Define 'factory_data' target for generating a factory data partition +# ============================================================================== + +if (CONFIG_CHIP_FACTORY_DATA_BUILD) + telink_generate_factory_data() +endif() + endif() # CONFIG_CHIP diff --git a/config/telink/chip-module/Kconfig b/config/telink/chip-module/Kconfig index e02dee92dfccb7..366c43d8eac6db 100644 --- a/config/telink/chip-module/Kconfig +++ b/config/telink/chip-module/Kconfig @@ -59,4 +59,210 @@ config CHIP_EXAMPLE_DEVICE_INFO_PROVIDER # Enable getting reboot reasons information config HWINFO bool - default y \ No newline at end of file + default y + +config CHIP_FACTORY_DATA + bool "Enable Factory Data support" + select ZCBOR + help + Enables support for reading factory data from flash memory partition. + It requires factory_data partition to exist. + +config CHIP_FACTORY_DATA_CUSTOM_BACKEND + bool "Enable Factory Data custom backend" + depends on !CHIP_FACTORY_DATA + help + Enables user custom factory data implementation. It cannot be used + with the CHIP_FACTORY_DATA that enabled default Telink factory data + implementation. + +config CHIP_FACTORY_DATA_BUILD + bool "Enable Factory Data build" + default n + help + Enables generation of factory data during the building. + It requires factory_data partition to exist. + As a result a new output file factory_data.bin will be created. + +config CHIP_FACTORY_DATA_VERSION + int + default 1 + help + The Factory data version contains a current version of a factory data + parameter set that the user cannot change. + After moving to the next version of the factory data set, change the default value. + This config is used to validate the version of a factory data set on a device-side + with the version of factory data saved in the Flash memory. + +if CHIP_FACTORY_DATA_BUILD + +# Factory data definitions +config CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE + bool "Enable merging generated factory data with the build target .bin file" + default y + help + Enables merging generated factory data with the build target zephyr.bin file. + As a result, output file zephyr.bin will consist of all partitions including + factory data. + +# Use default certificates without generating or providing them +config CHIP_FACTORY_DATA_USE_DEFAULT_CERTS + bool "Use default certificates located in Matter repository" + default y + help + Pre-generated certificates can be used for development purpose. + This config includes default pre-generated certificates + which are located in credentials/development/attestation/ directory + instead of generating new ones. + If this config is set to `n` new certificates will be generated. + +# Configs for SPAKE2 generation +config CHIP_FACTORY_DATA_GENERATE_SPAKE2_VERIFIER + bool "Enable spake2 verifier generation" + help + Enables generation of spake2 verifier according to + given iteration counter, salt and passcode. + To generate Spake2 verifier a spake2p executable must be available + from system variables environment. + +config CHIP_DEVICE_GENERATE_ROTATING_DEVICE_UID + bool "Enable generation of a new Rotating device id unique id" + default y + help + Enables generation of a new Rotating device id unique id. + +endif #CHIP_FACTORY_DATA_BUILD + +# Factory data parameters +config CHIP_DEVICE_SERIAL_NUMBER + string "Serial number of device" + default "11223344556677889900" + help + A serial number parameter defines an unique number of manufactured device. + Maximum length of serial number is 32 characters. + +config CHIP_DEVICE_VENDOR_NAME + string "Human-readable vendor name" + default "Telink Semiconductor" + help + A human-readable vendor name which provides a simple string + containing identification of device's vendor for the Content APP. + This information should be included in the Matter Basic Cluster. + +config CHIP_DEVICE_PRODUCT_NAME + string "Human-readable product name" + default "not-specified" + help + A human-readable product name which provides a simple string + containing identification of the product for the Content APP. + +config CHIP_DEVICE_MANUFACTURING_DATE + string "Manufacturing date in ISO 8601" + default "2022-01-01" + help + A manufacturing date specifies the date that the device was manufactured. + The format used for providing a manufacturing date is ISO 8601 e.g. YYYY-MM-DD. + +config CHIP_DEVICE_HARDWARE_VERSION + int "Integer representation of hardware version" + default 0 + help + A hardware version number specifies the version number + of the hardware of the device. The meaning of its value, + and the versioning scheme, are vendor defined. + +config CHIP_DEVICE_HARDWARE_VERSION_STRING + string "user-friendly string representation of hardware version" + default "prerelease" + help + A hardware version string parameter specifies the version + of the hardware of the device as a more user-friendly value + than that represented by the hardware version integer value. + The meaning of its value, and the versioning scheme, are + vendor defined. + +config CHIP_DEVICE_DISCRIMINATOR + hex "Device pairing discriminator" + default 0xF00 + help + A 12-bit value matching the field of the same name in + the setup code. Discriminator is used during + a discovery process. + +config CHIP_DEVICE_SPAKE2_PASSCODE + int "Spake2+ passcode" + default 20202021 + range 1 99999998 + help + A pairing passcode is a 27-bit unsigned integer which serves + as a proof of possession during commissioning. + Its value shall be restricted to the values 0x0000001 to 0x5F5E0FE + (00000001 to 99999998 in decimal), excluding the invalid Passcode values: + - 00000000, 11111111, 22222222, 33333333, 44444444, 55555555, + 66666666, 77777777, 88888888, 99999999, 12345678, 87654321. + +config CHIP_DEVICE_SPAKE2_IT + int "Spake2+ iteration count" + default 1000 + help + The Spake2 iteration count is associated with the ephemeral + PAKE passcode verifier to be used for the commissioning. + The iteration count is used as a crypto parameter to process + spake2 verifier. + +config CHIP_DEVICE_SPAKE2_SALT + string "Spake2+ salt in string format" + default "U1BBS0UyUCBLZXkgU2FsdA==" + help + The spake2 salt is random data that is used as an additional input + to a one-way function that “hashes” data. + A new salt should be randomly generated for each password. + The minimum length of spake2 salt is 16 Bytes. + The maximum length of spake2 salt is 32 Bytes. + +config CHIP_DEVICE_SPAKE2_TEST_VERIFIER + string "Testing spake2+ verifier" + default "uWFwqugDNGiEck/po7KHwwMwwqZgN10XuyBajPGuyzUEV/iree4lOrao5GuwnlQ65CJzbeUB49s31EH+NEkg0JVI5MGCQGMMT/SRPFNRODm3wH/MBiehuFc6FJ/NH6Rmzw==" + help + The spake 2 verifier generated using default SPAKE2 salt, + iteration count and passcode. This value can be used for development + or testing purposes. + Generated with: + spake2p gen-verifier -o - -i 1000 -s "U1BBS0UyUCBLZXkgU2FsdA==" -p 20202021 + +config CHIP_DEVICE_ROTATING_DEVICE_UID + string "A rotating device id unique id" + default "91a9c12a7c80700a31ddcfa7fce63e44" + help + A device rotating id unique id which will be generated if + this config is not set in prj.conf file. + +config CHIP_DEVICE_ENABLE_KEY + string "Enable Key for triggering test actions on device" + default "00112233445566778899AABBCCDDEEFF" + help + The Enable Key is a 128-bit value that triggers test action + while invoking the TestEventTrigger Command. + Pattern: "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + This value is used during Certification Tests, + and should not be present on production devices. + +config CHIP_CERTIFICATION_DECLARATION_STORAGE + bool "Enable storing Certification Declaration" + depends on CHIP_FACTORY_DATA + help + Enables storing Certification Declaration in Zephyr settings + instead of using hardcoded value from firmware. It also adds + support for including new Certification Declaration into a firmware + update image package sent via OTA Software Update. + +if CHIP_CERTIFICATION_DECLARATION_STORAGE + +config CHIP_CERTIFiCATION_DECLARATION_OTA_IMAGE_ID + int "Certification declaration OTA image id" + default 205 #0xcd + help + The image id of Certification Declaration image + for sending it via OTA Software Update purposes. + +endif diff --git a/config/telink/chip-module/generate_factory_data.cmake b/config/telink/chip-module/generate_factory_data.cmake new file mode 100644 index 00000000000000..ff9514e6707481 --- /dev/null +++ b/config/telink/chip-module/generate_factory_data.cmake @@ -0,0 +1,194 @@ +# +# 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. +# + + +# Create a JSON file based on factory data given via kConfigs. +# +# This function creates a list of arguments for external script and then run it to write a JSON file. +# Created JSON file can be checked using JSON SCHEMA file if it is provided. +# +# This script can be manipulated using following kConfigs: +# - To merge generated factory data with final zephyr.hex file set kConfig CONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE=y +# - To use default certification paths set CONFIG_CHIP_FACTORY_DATA_USE_DEFAULTS_CERTS_PATH=y +# +# During generation process a some file will be created in zephyr's build directory: +# - .json a file containing all factory data written in JSON format. +# +# [Args]: +# factory_data_target - a name for target to generate factory_data. +# script_path - a path to script that makes a JSON factory data file from given arguments. +# schema_path - a path to JSON schema file which can be used to verify generated factory data JSON file. +# This argument is optional, if you don't want to verify the JSON file put it empty "". +# output_path - a path to output directory, where created JSON file will be stored. +function(telink_create_factory_data_json factory_data_target script_path schema_path output_path) + +# set script args for future purpose +set(script_args) +## generate all script arguments +string(APPEND script_args "--sn \"${CONFIG_CHIP_DEVICE_SERIAL_NUMBER}\"\n") +string(APPEND script_args "--date \"${CONFIG_CHIP_DEVICE_MANUFACTURING_DATE}\"\n") +string(APPEND script_args "--vendor_id ${CONFIG_CHIP_DEVICE_VENDOR_ID}\n") +string(APPEND script_args "--product_id ${CONFIG_CHIP_DEVICE_PRODUCT_ID}\n") +string(APPEND script_args "--vendor_name \"${CONFIG_CHIP_DEVICE_VENDOR_NAME}\"\n") +string(APPEND script_args "--product_name \"${CONFIG_CHIP_DEVICE_PRODUCT_NAME}\"\n") +string(APPEND script_args "--hw_ver ${CONFIG_CHIP_DEVICE_HARDWARE_VERSION}\n") +string(APPEND script_args "--hw_ver_str \"${CONFIG_CHIP_DEVICE_HARDWARE_VERSION_STRING}\"\n") + +# check if Rotating Device Id Unique Id should be generated +if(NOT CONFIG_CHIP_DEVICE_GENERATE_ROTATING_DEVICE_UID) + if(NOT DEFINED CONFIG_CHIP_DEVICE_ROTATING_DEVICE_UID) + message(FATAL_ERROR "CHIP_DEVICE_ROTATING_DEVICE_UID was not provided. To generate it use CONFIG_CHIP_DEVICE_GENERATE_ROTATING_DEVICE_UID=y") + else() + string(APPEND script_args "--rd_uid \"${CONFIG_CHIP_DEVICE_ROTATING_DEVICE_UID}\"\n") + endif() +else() + string(APPEND script_args "--generate_rd_uid\n") +endif() + +# for development purpose user can use default certs instead of generating or providing them +if(CONFIG_CHIP_FACTORY_DATA_USE_DEFAULT_CERTS) + # convert decimal PID to its hexadecimal representation to find out certification files in repository + math(EXPR LOCAL_PID "${CONFIG_CHIP_DEVICE_PRODUCT_ID}" OUTPUT_FORMAT HEXADECIMAL) + string(SUBSTRING ${LOCAL_PID} 2 -1 raw_pid) + # all certs are located in ${CHIP_ROOT}/credentials/development/attestation + # it can be used during development without need to generate new certifications + string(APPEND script_args "--dac_cert \"${CHIP_ROOT}/credentials/development/attestation/Matter-Development-DAC-${raw_pid}-Cert.der\"\n") + string(APPEND script_args "--dac_key \"${CHIP_ROOT}/credentials/development/attestation/Matter-Development-DAC-${raw_pid}-Key.der\"\n") + string(APPEND script_args "--pai_cert \"${CHIP_ROOT}/credentials/development/attestation/Matter-Development-PAI-noPID-Cert.der\"\n") +else() + find_program(chip_cert_exe NAMES chip-cert REQUIRED) + string(APPEND script_args "--gen_cd\n") + string(APPEND script_args "--chip_cert_path ${chip_cert_exe}\n") +endif() + +# add Password-Authenticated Key Exchange parameters +string(APPEND script_args "--spake2_it \"${CONFIG_CHIP_DEVICE_SPAKE2_IT}\"\n") +string(APPEND script_args "--spake2_salt \"${CONFIG_CHIP_DEVICE_SPAKE2_SALT}\"\n") +string(APPEND script_args "--discriminator ${CONFIG_CHIP_DEVICE_DISCRIMINATOR}\n") +string(APPEND script_args "--passcode ${CONFIG_CHIP_DEVICE_SPAKE2_PASSCODE}\n") +string(APPEND script_args "--overwrite\n") + +# check if spake2 verifier should be generated using script +if(CONFIG_CHIP_FACTORY_DATA_GENERATE_SPAKE2_VERIFIER) + # request script to generate a new spake2_verifier + # by adding an argument to script_args + find_program(spake_exe NAMES spake2p REQUIRED) + string(APPEND script_args "--spake2p_path ${spake_exe}\n") +else() + # Spake2 verifier should be provided using kConfig + string(APPEND script_args "--spake2_verifier \"${CONFIG_CHIP_DEVICE_SPAKE2_TEST_VERIFIER}\"\n") +endif() + +if(CONFIG_CHIP_DEVICE_ENABLE_KEY) +# Add optional EnableKey that triggers user-specific action. +string(APPEND script_args "--enable_key \"${CONFIG_CHIP_DEVICE_ENABLE_KEY}\"\n") +endif() + +# Set output JSON file and path to SCHEMA file to validate generated factory data +set(factory_data_json ${output_path}/${factory_data_target}.json) +string(APPEND script_args "-o \"${factory_data_json}\"\n") +string(APPEND script_args "-s \"${schema_path}\"\n") + +# execute first script to create a JSON file +separate_arguments(separated_script_args NATIVE_COMMAND ${script_args}) +add_custom_command( + OUTPUT ${factory_data_json} + DEPENDS ${FACTORY_DATA_SCRIPT_PATH} + COMMAND ${Python3_EXECUTABLE} ${FACTORY_DATA_SCRIPT_PATH} ${separated_script_args} + COMMENT "Generating new Factory Data..." + ) +add_custom_target(${factory_data_target} ALL + DEPENDS ${factory_data_json} + ) + +endfunction() + + +# Create a .hex file with factory data in CBOR format. +# +# This function creates a .hex and .cbor files from given JSON factory data file. +# +# +# During generation process some files will be created in zephyr's build directory: +# - .hex a file containing all factory data in CBOR format. +# - .bin a binary file containing all raw factory data in CBOR format. +# - .cbor a file containing all factory data in CBOR format. +# +# [Args]: +# factory_data_hex_target - a name for target to generate factory data HEX file. +# factory_data_target - a name for target to generate factory data JSON file. +# script_path - a path to script that makes a factory data .hex file from given arguments. +# output_path - a path to output directory, where created JSON file will be stored. +function(telink_create_factory_data_hex_file factory_data_hex_target factory_data_target script_path output_path) + +# Pass the argument list via file +set(cbor_script_args "-i ${output_path}/${factory_data_target}.json\n") +string(APPEND cbor_script_args "-o ${output_path}/${factory_data_target}\n") +# get partition address and offset from partition manager during compilation +string(APPEND cbor_script_args "--offset 0xf4000\n") +string(APPEND cbor_script_args "--size 0x1000\n") +string(APPEND cbor_script_args "-r\n") + +# execute second script to create a hex file containing factory data in cbor format +separate_arguments(separated_cbor_script_args NATIVE_COMMAND ${cbor_script_args}) +set(factory_data_hex ${output_path}/${factory_data_target}.hex) + +add_custom_command(OUTPUT ${factory_data_hex} + COMMAND ${Python3_EXECUTABLE} ${script_path} ${separated_cbor_script_args} + COMMENT "Generating factory data HEX file..." + DEPENDS ${factory_data_target} ${script_path} + ) +add_custom_target(${factory_data_hex_target} ALL + DEPENDS ${factory_data_hex} + ) + +endfunction() + +# Generate factory data partition using given args +# +# +# During generation process a some file will be created in zephyr's build directory: +# - merged.hex a file containing firmware and factory data merged to single file +# - factory_data.hex a file containing only a factory data partition including proper offset +# +function(telink_generate_factory_data) + +find_package(Python REQUIRED) + +# CHIP_ROOT must be provided as a reference set all localization of scripts +if(NOT CHIP_ROOT) +message(FATAL_ERROR "CHIP_ROOT variable is not set, please add it to CMakeLists.txt file") +endif() + +# Localize all scripts needed to generate factory data partition +set(FACTORY_DATA_SCRIPT_PATH ${CHIP_ROOT}/scripts/tools/telink/generate_telink_chip_factory_data.py) +set(GENERATE_CBOR_SCRIPT_PATH ${CHIP_ROOT}/scripts/tools/telink/telink_generate_partition.py) +set(FACTORY_DATA_SCHEMA_PATH ${CHIP_ROOT}/scripts/tools/telink/telink_factory_data.schema) +set(OUTPUT_FILE_PATH ${APPLICATION_BINARY_DIR}/zephyr) + +# create a JSON file with all factory data +telink_create_factory_data_json(factory_data + ${FACTORY_DATA_SCRIPT_PATH} + ${FACTORY_DATA_SCHEMA_PATH} + ${OUTPUT_FILE_PATH}) + +# create a .hex file with factory data in CBOR format based on the JSON file created previously +telink_create_factory_data_hex_file(factory_data_hex + factory_data + ${GENERATE_CBOR_SCRIPT_PATH} + ${OUTPUT_FILE_PATH}) + +endfunction() diff --git a/config/telink/chip-module/make_gn_args.py b/config/telink/chip-module/make_gn_args.py new file mode 100755 index 00000000000000..f30cd459a6e7d4 --- /dev/null +++ b/config/telink/chip-module/make_gn_args.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 + +# +# 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. +# + +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)) + + cflag_excludes = ', '.join(['"{}"'.format(exclude) + for exclude in GN_CFLAG_EXCLUDES]) + + for key, value in args.arg_cflags: + 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=[]) + args = parser.parse_args() + args.arg_string = escape_strings(args.arg_string) + args.arg_cflags = escape_strings(args.arg_cflags) + write_gn_args(args) + + +if __name__ == "__main__": + main() diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_AB_Test_PAA_vid_0x137B.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_AB_Test_PAA_vid_0x137B.pem index 24e22bedecd0da..e7084302aff4df 100644 --- a/credentials/development/paa-root-certs/dcld_mirror_CN_AB_Test_PAA_vid_0x137B.pem +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_AB_Test_PAA_vid_0x137B.pem @@ -9,4 +9,4 @@ FgQUzfLv60FwRw2mmGqbQBlhNzbBKzwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQY MBaAFM3y7+tBcEcNpphqm0AZYTc2wSs8MAoGCCqGSM49BAMCA0kAMEYCIQCmkeYO 7qrsL+K7lD+83jwG1kwlUjmk7j8TiMRZugoXggIhAKjU1921/HtVg5vruWnAldE0 OluYL3u0qG/zUnQBBZdU ------END CERTIFICATE----- +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_ACK_Test_PAA_vid_0x137A.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_ACK_Test_PAA_vid_0x137A.pem index 19519058135045..bfb549320d83a8 100644 --- a/credentials/development/paa-root-certs/dcld_mirror_CN_ACK_Test_PAA_vid_0x137A.pem +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_ACK_Test_PAA_vid_0x137A.pem @@ -9,4 +9,4 @@ DgQWBBR5tgRpKKdeSNjbz17/o/nb5fWDeDAOBgNVHQ8BAf8EBAMCAYYwHwYDVR0j BBgwFoAUebYEaSinXkjY289e/6P52+X1g3gwCgYIKoZIzj0EAwIDRwAwRAIgWUD0 xLr2FYyVoMzrYMeBS4k5yBpgOFy2lmCd1fbwqUICIAxr0LCI2jDduTxnR/YNbcAx cxTw3DvHgFVC2NzdHsuj ------END CERTIFICATE----- +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Beken_Development_PAA_01_vid_0x1342.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Beken_Development_PAA_01_vid_0x1342.pem index bb9ab61f0c60ad..d2776a705193cd 100644 --- a/credentials/development/paa-root-certs/dcld_mirror_CN_Beken_Development_PAA_01_vid_0x1342.pem +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Beken_Development_PAA_01_vid_0x1342.pem @@ -9,4 +9,4 @@ Af8ECDAGAQH/AgEBMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUwrzWQPP16qF6 7EZqS2lIuWrNDXowHwYDVR0jBBgwFoAUwrzWQPP16qF67EZqS2lIuWrNDXowCgYI KoZIzj0EAwIDSAAwRQIhAMQEa0y9YDbmxw4sH0tsTUR401k2ikOAoPtlhbAJ7kc+ AiAuZvx5Dx2B4jEH7Q6fmeUvecU9VSCmC+WMOtN4bUPt4w== ------END CERTIFICATE----- +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_DigiCert_TEST_Root_CA_for_MATTER_PKI_O_DigiCert___Inc._C_US.der b/credentials/development/paa-root-certs/dcld_mirror_CN_DigiCert_TEST_Root_CA_for_MATTER_PKI_O_DigiCert__Inc_C_US.der similarity index 100% rename from credentials/development/paa-root-certs/dcld_mirror_CN_DigiCert_TEST_Root_CA_for_MATTER_PKI_O_DigiCert___Inc._C_US.der rename to credentials/development/paa-root-certs/dcld_mirror_CN_DigiCert_TEST_Root_CA_for_MATTER_PKI_O_DigiCert__Inc_C_US.der diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_DigiCert_TEST_Root_CA_for_MATTER_PKI_O_DigiCert___Inc._C_US.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_DigiCert_TEST_Root_CA_for_MATTER_PKI_O_DigiCert__Inc_C_US.pem similarity index 96% rename from credentials/development/paa-root-certs/dcld_mirror_CN_DigiCert_TEST_Root_CA_for_MATTER_PKI_O_DigiCert___Inc._C_US.pem rename to credentials/development/paa-root-certs/dcld_mirror_CN_DigiCert_TEST_Root_CA_for_MATTER_PKI_O_DigiCert__Inc_C_US.pem index e66cb04e914ae1..1ca43c140d5443 100644 --- a/credentials/development/paa-root-certs/dcld_mirror_CN_DigiCert_TEST_Root_CA_for_MATTER_PKI_O_DigiCert___Inc._C_US.pem +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_DigiCert_TEST_Root_CA_for_MATTER_PKI_O_DigiCert__Inc_C_US.pem @@ -11,4 +11,4 @@ IaPmNeuTo2YwZDASBgNVHRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBTA4GQVAOxn Z+J8r3xuLUmUx3Pet7owCgYIKoZIzj0EAwIDSQAwRgIhANQPosj8Q06GATusRAtX VQFXJSSm8AgsulWwI35mEf22AiEAxiY2sTXcV3ZUiNl/O4RQ10UWMRMjrgo076cn zy5r7zE= ------END CERTIFICATE----- +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_ELiteu_Matter_Development_PAA_01_vid_0x131F.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_ELiteu_Matter_Development_PAA_01_vid_0x131F.pem index 479e4f00517045..1599c7de48d3e4 100644 --- a/credentials/development/paa-root-certs/dcld_mirror_CN_ELiteu_Matter_Development_PAA_01_vid_0x131F.pem +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_ELiteu_Matter_Development_PAA_01_vid_0x131F.pem @@ -10,4 +10,4 @@ VR0OBBYEFNN/BuHbYf5ymSl9lcFPG2QHWENzMB8GA1UdIwQYMBaAFNN/BuHbYf5y mSl9lcFPG2QHWENzMAoGCCqGSM49BAMCA0gAMEUCIQCcjSilivNmAJtkj0A/utii BNrK8jl4yLq3JwAjKR/pNwIgVygv+9XbvzNTGZoQ8mM2d74vIZ+1y1XH3nM0Xggf 2HE= ------END CERTIFICATE----- +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Govee_Test_PAA__vid_0x1387.der b/credentials/development/paa-root-certs/dcld_mirror_CN_Govee_Test_PAA__vid_0x1387.der deleted file mode 100644 index ff16f809c7fbf2..00000000000000 Binary files a/credentials/development/paa-root-certs/dcld_mirror_CN_Govee_Test_PAA__vid_0x1387.der and /dev/null differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Govee_Test_PAA__vid_0x1387.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Govee_Test_PAA__vid_0x1387.pem deleted file mode 100644 index 6ccf475120de06..00000000000000 --- a/credentials/development/paa-root-certs/dcld_mirror_CN_Govee_Test_PAA__vid_0x1387.pem +++ /dev/null @@ -1,11 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIBpjCCAUygAwIBAgIIJj1Z6cFTVHcwCgYIKoZIzj0EAwIwJDEiMCAGA1UEAwwZ -R292ZWUgVGVzdCBQQUEsdmlkPTB4MTM4NzAgFw0yMjA3MTAxNDIzNDNaGA85OTk5 -MTIzMTIzNTk1OVowJDEiMCAGA1UEAwwZR292ZWUgVGVzdCBQQUEsdmlkPTB4MTM4 -NzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABE3GwFGazJj0Kj6f7IwcIr4OoMwh -EwVNDEZ+UR00ZeJzd+8uGXLjyKZ6v//B34p4RvKJMk+Gq6uF6G6GT1ZXLCOjZjBk -MBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTb -Y6ZTwaH+psljqWJ1ewuBEPWA9DAfBgNVHSMEGDAWgBTbY6ZTwaH+psljqWJ1ewuB -EPWA9DAKBggqhkjOPQQDAgNIADBFAiEAy7R/7blSlNX8WZGQrn63peA493kvYThb -zvmitcKy5fgCIFDvHKy7xkwWUmpcKyDGZn4tYIzvIwm0FvYl1V3mxdaR ------END CERTIFICATE----- diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Govee_Test_PAA_vid_0x1387.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Govee_Test_PAA_vid_0x1387.pem index ba09cdb569ca54..fa96c41af3740d 100644 --- a/credentials/development/paa-root-certs/dcld_mirror_CN_Govee_Test_PAA_vid_0x1387.pem +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Govee_Test_PAA_vid_0x1387.pem @@ -9,4 +9,4 @@ DwEB/wQEAwIBBjAdBgNVHQ4EFgQUk4YyXgbZseQmMESNNOb7SNUM7SUwHwYDVR0j BBgwFoAUk4YyXgbZseQmMESNNOb7SNUM7SUwCgYIKoZIzj0EAwIDSAAwRQIgJeX5 H6GY+nhDObPbinkoEDAweQOOYSPfsgUbypL4yrYCIQCksMRPy62kSdxfaTmR1C4K gYU/+xitxnDp3AmKJKhWeg== ------END CERTIFICATE----- +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Haier-Matter-PAA-01_vid_0x1348.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Haier-Matter-PAA-01_vid_0x1348.pem index babc380cc89dcc..3f6dbdb75274bb 100644 --- a/credentials/development/paa-root-certs/dcld_mirror_CN_Haier-Matter-PAA-01_vid_0x1348.pem +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Haier-Matter-PAA-01_vid_0x1348.pem @@ -9,4 +9,4 @@ cq95hXRsPUirHNQ7IkH6c0b3MYhGCimiKeXD9aNmMGQwEgYDVR0TAQH/BAgwBgEB NGriMB8GA1UdIwQYMBaAFFsjg5exUHGu9YHHsqt2vlbkNGriMAoGCCqGSM49BAMC A0gAMEUCIQCfk1qC0eCKdp/VvPiv8fvnQWnfOgFJQCAKmb1Qp1CIIAIgN9zymm1c FwdwvNhapM3Fsgl5n1J5y7+/fOnVi3kudgs= ------END CERTIFICATE----- +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_Development_PAA.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_Development_PAA.pem index b55bd3978d74d2..cda1af8eb050ac 100644 --- a/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_Development_PAA.pem +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_Development_PAA.pem @@ -8,4 +8,4 @@ EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBT6ks8JXvpC 4RQwZRYy/v4bLHenyDAfBgNVHSMEGDAWgBT6ks8JXvpC4RQwZRYy/v4bLHenyDAK BggqhkjOPQQDAgNIADBFAiBQp5AzZLZT/w6kY9xoSobdJccxo57+s8IM0t7RtmB+ LwIhAK/U7UtqmeX4xVIdcB68+f1TuTlP2A/FmZL/Plu7tgo1 ------END CERTIFICATE----- +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_PAA_1_O_Google_C_US_vid_0x6006.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_PAA_1_O_Google_C_US_vid_0x6006.pem index a22831feda63f3..2ef5d291f89e38 100644 --- a/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_PAA_1_O_Google_C_US_vid_0x6006.pem +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_PAA_1_O_Google_C_US_vid_0x6006.pem @@ -10,4 +10,4 @@ HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLAAVoG4iGKJYoDhIRihqL4J3pMhMB8GA1Ud IwQYMBaAFLAAVoG4iGKJYoDhIRihqL4J3pMhMAoGCCqGSM49BAMCA0gAMEUCIQCV c26cVlyqjhQfcgN3udpne6zZQdyVMNLRWZn3EENBkAIgasUeFU8zaUt8bKNWd0k+ 4RQp5Cp5wYzrE8AxJ9BiA/E= ------END CERTIFICATE----- +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_Test_PAA_O_Samsung_vid_0x10E1.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_Test_PAA_O_Samsung_vid_0x10E1.pem index 120dc7b248a177..72de446f5000ed 100644 --- a/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_Test_PAA_O_Samsung_vid_0x10E1.pem +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_Test_PAA_O_Samsung_vid_0x10E1.pem @@ -10,4 +10,4 @@ qMMAppiYUXy33CEg2y0So2YwZDASBgNVHRMBAf8ECDAGAQH/AgEBMA4GA1UdDwEB FoAUz54KFniLQDDs3as0ucLse+U0VcAwCgYIKoZIzj0EAwIDSQAwRgIhAKAjdnZk FnHDMfhjmhBM+Iy1yLuHIKQxzKSMKSBDwqs9AiEA/FdiFtWLTFiRMVqYw1Cn5ryF VucH+4/cuLf3wdKRl08= ------END CERTIFICATE----- +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_Test_PAA_vid_0x125D.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_Test_PAA_vid_0x125D.pem index b9cd08a28f2512..11fa0b5c3a6680 100644 --- a/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_Test_PAA_vid_0x125D.pem +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_Test_PAA_vid_0x125D.pem @@ -9,4 +9,4 @@ IwQYMBaAFOKQjTacPKPBE7sJ4k3BzMWmZpHUMB0GA1UdDgQWBBTikI02nDyjwRO7 CeJNwczFpmaR1DAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwIDSAAwRQIhAPZJ skxY48EcSnatPseu6GcuFZw/bE/7uvp/PknnofJVAiAFXbU9SkxGi+Lqqa4YQRx9 tpcQ/mhg7DECwutZLCxKyA== ------END CERTIFICATE----- +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Meross_Development_PAA_vid_0x1345.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Meross_Development_PAA_vid_0x1345.pem index 8c7b6cbeb385b4..3179b9f8039f90 100644 --- a/credentials/development/paa-root-certs/dcld_mirror_CN_Meross_Development_PAA_vid_0x1345.pem +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Meross_Development_PAA_vid_0x1345.pem @@ -9,4 +9,4 @@ MAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSTcZ6kFxCT9n6v5jpS xRlH7j5aqDAfBgNVHSMEGDAWgBSTcZ6kFxCT9n6v5jpSxRlH7j5aqDAKBggqhkjO PQQDAgNIADBFAiEA4uhwfF4Nw8rna6gYZV03lEQG2wEwIzo83OiTcknqPC0CIGLG 79IPfTibBunADTztyXRIKwNF7S2+Or8Xc8nsQ4WV ------END CERTIFICATE----- +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Midea_PAA_vid_0x118C.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Midea_PAA_vid_0x118C.pem index 674888053a971d..96e13cc021f4a3 100644 --- a/credentials/development/paa-root-certs/dcld_mirror_CN_Midea_PAA_vid_0x118C.pem +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Midea_PAA_vid_0x118C.pem @@ -9,4 +9,4 @@ MB0GA1UdDgQWBBQSX9Aagss/AwlQ6JWVprNY9SpalDAfBgNVHSMEGDAWgBQSX9Aa gss/AwlQ6JWVprNY9SpalDAKBggqhkjOPQQDAgNHADBEAiBoZq5htW2zMEhKXp9/ JR+KPraZp4oVGh8ZK1IVSbOwagIgQ6Psk09HUrO7Fsgk4/FZqlBuoFQ6+WbfACu/ 5Ijq4O0= ------END CERTIFICATE----- +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Non_Production_ONLY_-_XFN_PAA_Class_3.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Non_Production_ONLY_-_XFN_PAA_Class_3.pem index bf9fa469f7397c..1291a08744cc81 100644 --- a/credentials/development/paa-root-certs/dcld_mirror_CN_Non_Production_ONLY_-_XFN_PAA_Class_3.pem +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Non_Production_ONLY_-_XFN_PAA_Class_3.pem @@ -9,4 +9,4 @@ MAYBAf8CAQEwHwYDVR0jBBgwFoAU+Jmp1a1xceTDgX8UEH948Nn3YukwHQYDVR0O BBYEFPiZqdWtcXHkw4F/FBB/ePDZ92LpMA4GA1UdDwEB/wQEAwIBhjAKBggqhkjO PQQDAgNIADBFAiBYIsjeauI2nDknU1ThEDzyGfg4F9tLSkiuTrTJGr5EqQIhAMFX bxTzgOfx0RPgpEU8syFEYyXCBcv4hV14rWddc08G ------END CERTIFICATE----- +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_OPPO_Test_PAA_vid_0x1341.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_OPPO_Test_PAA_vid_0x1341.pem index 5913e125bd2035..034354f78a7233 100644 --- a/credentials/development/paa-root-certs/dcld_mirror_CN_OPPO_Test_PAA_vid_0x1341.pem +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_OPPO_Test_PAA_vid_0x1341.pem @@ -9,4 +9,4 @@ Af8EBAMCAQYwHQYDVR0OBBYEFMyJ4O3dahIP1NEztGk/BdUX5xPvMB8GA1UdIwQY MBaAFMyJ4O3dahIP1NEztGk/BdUX5xPvMAoGCCqGSM49BAMCA0cAMEQCIHgoNVBU zlr/rbfgtNKXQ/ilwW9BTTkw8CNr7iY6vIqsAiBh1VXKrhwDfwVQ518Un1KuGTfi kA7JtstGj2BddjUFSg== ------END CERTIFICATE----- +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_StrongKey_G1_Development_PAA_O_StrongKey.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_StrongKey_G1_Development_PAA_O_StrongKey.pem index 241741548cd3b7..fc476fb4da10d0 100644 --- a/credentials/development/paa-root-certs/dcld_mirror_CN_StrongKey_G1_Development_PAA_O_StrongKey.pem +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_StrongKey_G1_Development_PAA_O_StrongKey.pem @@ -10,4 +10,4 @@ aev81dsMZDYLPx2GPIcuMB0GA1UdDgQWBBR8ywOatWnr/NXbDGQ2Cz8dhjyHLjAO BgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwIDSAAwRQIhAO5zMiVkAWP/9zVhdN3A 23bzLrRasxMC3qDDpQyMlyMKAiB9DvCoRAt+eD5+HKQMm245vJ57NePvosuiM5oz xzbsqQ== ------END CERTIFICATE----- +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_TP-Link_Matter_Test_PAA_vid_0x1188.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_TP-Link_Matter_Test_PAA_vid_0x1188.pem index 29a72be4f79af1..1838c9cdd4c43d 100644 --- a/credentials/development/paa-root-certs/dcld_mirror_CN_TP-Link_Matter_Test_PAA_vid_0x1188.pem +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_TP-Link_Matter_Test_PAA_vid_0x1188.pem @@ -9,4 +9,4 @@ Af8ECDAGAQH/AgEBMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUdqY/wPeRT+rf 3dOd8BgWRwF9cV8wHwYDVR0jBBgwFoAUdqY/wPeRT+rf3dOd8BgWRwF9cV8wCgYI KoZIzj0EAwIDSAAwRQIhALUi1VbKwRIhQyYDtUOUm4G3CU0hD0lscb4+CI5D4XMi AiACSnX2ca2oOre7SidIUdLfO2MX++rZyfqWDmPMzHSdTw== ------END CERTIFICATE----- +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_deveritec_GmbH_Test_PAA_vid_0x1362.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_deveritec_GmbH_Test_PAA_vid_0x1362.pem index 8de4ef8bd2467e..b3badd941888cd 100644 --- a/credentials/development/paa-root-certs/dcld_mirror_CN_deveritec_GmbH_Test_PAA_vid_0x1362.pem +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_deveritec_GmbH_Test_PAA_vid_0x1362.pem @@ -9,4 +9,4 @@ BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFIC/kimaZjzaNI+i TYBz9PGDJD42MB8GA1UdIwQYMBaAFIC/kimaZjzaNI+iTYBz9PGDJD42MAoGCCqG SM49BAMCA0cAMEQCIHp7fR5Mj2HqqtqTEHqFCApvTYCDy1fv8WwTUiqv7TTzAiA4 yyB38NIexJzRZjmEUcyrD3f2HRw5qEI9s6kHLLMF7w== ------END CERTIFICATE----- +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/fetch-paa-certs-from-dcl.py b/credentials/fetch-paa-certs-from-dcl.py index 141d7ea69e8af1..6b49460efdfae4 100644 --- a/credentials/fetch-paa-certs-from-dcl.py +++ b/credentials/fetch-paa-certs-from-dcl.py @@ -18,19 +18,8 @@ # Script that was used to fetch CHIP Development Product Attestation Authority (PAA) # certificates from DCL. -# The script expects the path to the dcld tool binary as an input argument. -# -# Usage example when the script is run from the CHIP SDK root directory: -# python ./credentials/development/fetch-development-paa-certs-from-dcl.py /path/to/dcld -# -# Usage example when the script is run from the CHIP SDK root directory for fetching production PAAs: -# python ./credentials/development/fetch-development-paa-certs-from-dcl.py /path/to/dcld production -# -# The result will be stored in: -# credentials/development/paa-root-certs -# In case of production - 2nd usage example above - the result will be stored in: -# credentials/production/paa-root-certs -# +# For usage please run:. +# python ./credentials/fetch-paa-certs-from-dcl.py --help from contextlib import nullcontext import os @@ -40,8 +29,13 @@ import re from cryptography.hazmat.primitives import serialization from cryptography import x509 +import click +from click_option_group import optgroup, RequiredMutuallyExclusiveOptionGroup +import requests -PRODUCTION_NODE_URL = 'https://on.dcl.csa-iot.org:26657' +PRODUCTION_NODE_URL = "https://on.dcl.csa-iot.org:26657" +PRODUCTION_NODE_URL_REST = "https://on.dcl.csa-iot.org" +TEST_NODE_URL_REST = "https://on.test-net.dcl.csa-iot.org" def parse_paa_root_certs(cmdpipe, paa_list): @@ -79,90 +73,112 @@ def parse_paa_root_certs(cmdpipe, paa_list): else: if b': ' in line: key, value = line.split(b': ') - result[key.strip(b' -')] = value.strip() + result[key.strip(b' -').decode("utf-8")] = value.strip().decode("utf-8") parse_paa_root_certs.counter += 1 if parse_paa_root_certs.counter % 2 == 0: paa_list.append(copy.deepcopy(result)) -def write_paa_root_cert(cmdpipe, subject, prefix): - pem_read = False - subject_as_text_read = False - - filename = prefix + 'paa-root-certs/dcld_mirror_' + \ +def write_paa_root_cert(certificate, subject): + filename = 'dcld_mirror_' + \ re.sub('[^a-zA-Z0-9_-]', '', re.sub('[=, ]', '_', subject)) - with open(filename + '.pem', 'wb+') as outfile: - while True: - line = cmdpipe.stdout.readline() - if not line: + with open(filename + '.pem', 'w+') as outfile: + outfile.write(certificate) + # convert pem file to der + with open(filename + '.pem', 'rb') as infile: + pem_certificate = x509.load_pem_x509_certificate(infile.read()) + with open(filename + '.der', 'wb+') as outfile: + der_certificate = pem_certificate.public_bytes( + serialization.Encoding.DER) + outfile.write(der_certificate) + + +def parse_paa_root_cert_from_dcld(cmdpipe): + subject = None + certificate = "" + + while True: + line = cmdpipe.stdout.readline() + if not line: + break + else: + if b'pemCert: |' in line: + while True: + line = cmdpipe.stdout.readline() + certificate += line.strip(b' \t').decode("utf-8") + if b'-----END CERTIFICATE-----' in line: + break + if b'subjectAsText:' in line: + subject = line.split(b': ')[1].strip().decode("utf-8") break - else: - if b'pemCert: |' in line: - while True: - line = cmdpipe.stdout.readline() - outfile.write(line.strip(b' \t')) - if b'-----END CERTIFICATE-----' in line: - pem_read = True - break - if b'subjectAsText:' in line: - new_subject = line.split(b': ')[1].strip().decode("utf-8") - new_filename = prefix + 'paa-root-certs/dcld_mirror_' + \ - re.sub('[=,\\\\ ]', '_', new_subject) - subject_as_text_read = True - break - - # if successfully obtained all mandatory fields from the root certificate - if pem_read == True and subject_as_text_read == True: - os.rename(filename + '.pem', new_filename + '.pem') - # convert pem file to der - with open(new_filename + '.pem', 'rb') as infile: - pem_certificate = x509.load_pem_x509_certificate(infile.read()) - with open(new_filename + '.der', 'wb+') as outfile: - der_certificate = pem_certificate.public_bytes( - serialization.Encoding.DER) - outfile.write(der_certificate) - - -def main(): - if len(sys.argv) >= 2: - dcld = sys.argv[1] - else: - sys.exit( - "Error: Please specify exactly one input argument; the path to the dcld tool binary") + + return (certificate, subject) + + +def use_dcld(dcld, production, cmdlist): + return [dcld] + cmdlist + (['--node', PRODUCTION_NODE_URL] if production else []) + + +@click.command() +@click.help_option('-h', '--help') +@optgroup.group('Input data sources', cls=RequiredMutuallyExclusiveOptionGroup) +@optgroup.option('--use-main-net-dcld', type=str, default='', metavar='PATH', help="Location of `dcld` binary, to use `dcld` for mirroring MainNet.") +@optgroup.option('--use-test-net-dcld', type=str, default='', metavar='PATH', help="Location of `dcld` binary, to use `dcld` for mirroring TestNet.") +@optgroup.option('--use-main-net-http', is_flag=True, type=str, help="Use RESTful API with HTTPS against public MainNet observer.") +@optgroup.option('--use-test-net-http', is_flag=True, type=str, help="Use RESTful API with HTTPS against public TestNet observer.") +@optgroup.group('Optional arguments') +@optgroup.option('--paa-trust-store-path', default='paa-root-certs', type=str, metavar='PATH', help="PAA trust store path (default: paa-root-certs)") +def main(use_main_net_dcld, use_test_net_dcld, use_main_net_http, use_test_net_http, paa_trust_store_path): + """DCL PAA mirroring tools""" production = False - if len(sys.argv) >= 3: - if sys.argv[2] == "production": - production = True + dcld = use_test_net_dcld - previous_dir = os.getcwd() - abspath = os.path.dirname(sys.argv[0]) - os.chdir(abspath) + if len(use_main_net_dcld) > 0: + dcld = use_main_net_dcld + production = True - os.makedirs('paa-root-certs', exist_ok=True) + use_rest = use_main_net_http or use_test_net_http + if use_main_net_http: + production = True - cmdlist = ['query', 'pki', 'all-x509-root-certs'] - production_node_cmdlist = ['--node', PRODUCTION_NODE_URL] + rest_node_url = PRODUCTION_NODE_URL_REST if production else TEST_NODE_URL_REST - cmdpipe = subprocess.Popen([dcld] + cmdlist + production_node_cmdlist if production else [], - stdout=subprocess.PIPE, stderr=subprocess.PIPE) + os.makedirs(paa_trust_store_path, exist_ok=True) + os.chdir(paa_trust_store_path) - paa_list = [] - parse_paa_root_certs.counter = 0 - parse_paa_root_certs(cmdpipe, paa_list) + if use_rest: + paa_list = requests.get(f"{rest_node_url}/dcl/pki/root-certificates").json()["approvedRootCertificates"]["certs"] + else: + cmdlist = ['query', 'pki', 'all-x509-root-certs'] + + cmdpipe = subprocess.Popen(use_dcld(dcld, production, cmdlist), stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + paa_list = [] + parse_paa_root_certs.counter = 0 + parse_paa_root_certs(cmdpipe, paa_list) for paa in paa_list: - cmdlist = ['query', 'pki', 'x509-cert', '-u', - paa[b'subject'].decode("utf-8"), '-k', paa[b'subjectKeyId'].decode("utf-8")] + if use_rest: + response = requests.get( + f"{rest_node_url}/dcl/pki/certificates/{paa['subject']}/{paa['subjectKeyId']}").json()["approvedCertificates"]["certs"][0] + certificate = response["pemCert"] + subject = response["subjectAsText"] + else: + cmdlist = ['query', 'pki', 'x509-cert', '-u', paa['subject'], '-k', paa['subjectKeyId']] + + cmdpipe = subprocess.Popen(use_dcld(dcld, production, cmdlist), stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + (certificate, subject) = parse_paa_root_cert_from_dcld(cmdpipe) - cmdpipe = subprocess.Popen( - [dcld] + cmdlist + production_node_cmdlist if production else [], - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - write_paa_root_cert(cmdpipe, paa[b'subject'].decode("utf-8"), "production/" if production else "development/") + certificate = certificate.rstrip('\n') - os.chdir(previous_dir) + write_paa_root_cert(certificate, subject) if __name__ == "__main__": - main() + if len(sys.argv) == 1: + main.main(['--help']) + else: + main() diff --git a/credentials/production/paa-root-certs/dcld_mirror_CN_DigiCert_Root_CA_for_MATTER_PKI_G1_O_DigiCert___Inc._C_US.der b/credentials/production/paa-root-certs/dcld_mirror_CN_DigiCert_Root_CA_for_MATTER_PKI_G1_O_DigiCert__Inc_C_US.der similarity index 100% rename from credentials/production/paa-root-certs/dcld_mirror_CN_DigiCert_Root_CA_for_MATTER_PKI_G1_O_DigiCert___Inc._C_US.der rename to credentials/production/paa-root-certs/dcld_mirror_CN_DigiCert_Root_CA_for_MATTER_PKI_G1_O_DigiCert__Inc_C_US.der diff --git a/credentials/production/paa-root-certs/dcld_mirror_CN_DigiCert_Root_CA_for_MATTER_PKI_G1_O_DigiCert___Inc._C_US.pem b/credentials/production/paa-root-certs/dcld_mirror_CN_DigiCert_Root_CA_for_MATTER_PKI_G1_O_DigiCert__Inc_C_US.pem similarity index 96% rename from credentials/production/paa-root-certs/dcld_mirror_CN_DigiCert_Root_CA_for_MATTER_PKI_G1_O_DigiCert___Inc._C_US.pem rename to credentials/production/paa-root-certs/dcld_mirror_CN_DigiCert_Root_CA_for_MATTER_PKI_G1_O_DigiCert__Inc_C_US.pem index fef0e13a9d9c7c..81f9bf3e7defca 100644 --- a/credentials/production/paa-root-certs/dcld_mirror_CN_DigiCert_Root_CA_for_MATTER_PKI_G1_O_DigiCert___Inc._C_US.pem +++ b/credentials/production/paa-root-certs/dcld_mirror_CN_DigiCert_Root_CA_for_MATTER_PKI_G1_O_DigiCert__Inc_C_US.pem @@ -11,4 +11,4 @@ DgQWBBQyUEUZM0RZm0Zl1Fn9OhXxwRbMvTAfBgNVHSMEGDAWgBQyUEUZM0RZm0Zl 1Fn9OhXxwRbMvTAKBggqhkjOPQQDAgNJADBGAiEAh88I/wwZ6/x4wrLLZeEZZEQi KqmgvTeRD3kPQ1LoCFgCIQCKVfavo16G+mSmMEFD2O/vsx15c2U1SS0rTK/ogRAP 4g== ------END CERTIFICATE----- +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/production/paa-root-certs/dcld_mirror_CN_Matter_Certification_and_Testing_CA_O_CSA_vid_0xC5A0.pem b/credentials/production/paa-root-certs/dcld_mirror_CN_Matter_Certification_and_Testing_CA_O_CSA_vid_0xC5A0.pem index 5a003156fd6c65..0cbffacff83ba4 100644 --- a/credentials/production/paa-root-certs/dcld_mirror_CN_Matter_Certification_and_Testing_CA_O_CSA_vid_0xC5A0.pem +++ b/credentials/production/paa-root-certs/dcld_mirror_CN_Matter_Certification_and_Testing_CA_O_CSA_vid_0xC5A0.pem @@ -10,4 +10,4 @@ HRMBAf8ECDAGAQH/AgEBMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUl+Rp0MUE FMJvxwH3fpR3OQmN9qUwHwYDVR0jBBgwFoAUl+Rp0MUEFMJvxwH3fpR3OQmN9qUw CgYIKoZIzj0EAwIDSAAwRQIgearlB0fCJ49UoJ6xwKPdlPEopCOL9jVCviODEleI +mQCIQDvvDCKi7kvj4R4BoFS4BVZGCk4zJ84W4tfTTfu89lRbQ== ------END CERTIFICATE----- +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/production/paa-root-certs/dcld_mirror_CN_StrongKey_Matter_G1_PAA_O_StrongKey.pem b/credentials/production/paa-root-certs/dcld_mirror_CN_StrongKey_Matter_G1_PAA_O_StrongKey.pem index f88119e4f494f1..3700677aa18fed 100644 --- a/credentials/production/paa-root-certs/dcld_mirror_CN_StrongKey_Matter_G1_PAA_O_StrongKey.pem +++ b/credentials/production/paa-root-certs/dcld_mirror_CN_StrongKey_Matter_G1_PAA_O_StrongKey.pem @@ -9,4 +9,4 @@ MBIGA1UdEwEB/wQIMAYBAf8CAQEwHwYDVR0jBBgwFoAUN04pWsVRcwuvZdUpg5tO 4J05WIowHQYDVR0OBBYEFDdOKVrFUXMLr2XVKYObTuCdOViKMA4GA1UdDwEB/wQE AwIBBjAKBggqhkjOPQQDAgNGADBDAh8a5dw6CObybMr8nqaou9lv9PqPbj3DSd+c yQm19Mg7AiAVcSK0RXTwLjAef55gWgq7SBRM/u3f3nRV/fvCYgWZfA== ------END CERTIFICATE----- +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/production/paa-root-certs/dcld_mirror_CN_TP-Link_Matter_PAA_vid_0x1188.der b/credentials/production/paa-root-certs/dcld_mirror_CN_TP-Link_Matter_PAA_vid_0x1188.der new file mode 100644 index 00000000000000..d1a4731c9449af Binary files /dev/null and b/credentials/production/paa-root-certs/dcld_mirror_CN_TP-Link_Matter_PAA_vid_0x1188.der differ diff --git a/credentials/production/paa-root-certs/dcld_mirror_CN_TP-Link_Matter_PAA_vid_0x1188.pem b/credentials/production/paa-root-certs/dcld_mirror_CN_TP-Link_Matter_PAA_vid_0x1188.pem new file mode 100644 index 00000000000000..7be97c676bc32d --- /dev/null +++ b/credentials/production/paa-root-certs/dcld_mirror_CN_TP-Link_Matter_PAA_vid_0x1188.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBxDCCAWqgAwIBAgIICmgdKV4p8FgwCgYIKoZIzj0EAwIwMzEbMBkGA1UEAwwS +VFAtTGluayBNYXR0ZXIgUEFBMRQwEgYKKwYBBAGConwCAQwEMTE4ODAgFw0yMjEw +MTYxNDIzNDNaGA85OTk5MTIzMTIzNTk1OVowMzEbMBkGA1UEAwwSVFAtTGluayBN +YXR0ZXIgUEFBMRQwEgYKKwYBBAGConwCAQwEMTE4ODBZMBMGByqGSM49AgEGCCqG +SM49AwEHA0IABBthPNrOBLxk1aUHRQ0qNpp5jxrxD0IYU2VrkqPao+N5W8yXX0co +Ye5mQRUoKx/1auDoaKu56CgtKFbP7sHTsoCjZjBkMBIGA1UdEwEB/wQIMAYBAf8C +AQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTFhTFBnuA+5KHc9VHgNEDcK77C +CjAfBgNVHSMEGDAWgBTFhTFBnuA+5KHc9VHgNEDcK77CCjAKBggqhkjOPQQDAgNI +ADBFAiAPczAEcWoN58U17EoNmiFaBzDo1OknOOnJJ7ooAaSWcQIhAPOWwghDzToJ +FGEBvcYtYdEgv9Za5uwKYfQt9J4/loDc +-----END CERTIFICATE----- \ No newline at end of file diff --git a/docs/guides/repl/Matter - Access Control.ipynb b/docs/guides/repl/Matter_Access_Control.ipynb similarity index 100% rename from docs/guides/repl/Matter - Access Control.ipynb rename to docs/guides/repl/Matter_Access_Control.ipynb diff --git a/docs/guides/repl/Matter - Basic Interactions.ipynb b/docs/guides/repl/Matter_Basic_Interactions.ipynb similarity index 100% rename from docs/guides/repl/Matter - Basic Interactions.ipynb rename to docs/guides/repl/Matter_Basic_Interactions.ipynb diff --git a/docs/guides/repl/Matter - Multi Fabric Commissioning.ipynb b/docs/guides/repl/Matter_Multi_Fabric_Commissioning.ipynb similarity index 100% rename from docs/guides/repl/Matter - Multi Fabric Commissioning.ipynb rename to docs/guides/repl/Matter_Multi_Fabric_Commissioning.ipynb diff --git a/docs/guides/repl/Matter - REPL Intro.ipynb b/docs/guides/repl/Matter_REPL_Intro.ipynb similarity index 100% rename from docs/guides/repl/Matter - REPL Intro.ipynb rename to docs/guides/repl/Matter_REPL_Intro.ipynb diff --git a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm index 1ff4a427eeb61e..e886eed2c56b0c 100644 --- a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm +++ b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm @@ -111,15 +111,15 @@ mOTADelegate = [[OTAProviderDelegate alloc] init]; - auto factory = [MTRControllerFactory sharedInstance]; + auto factory = [MTRDeviceControllerFactory sharedInstance]; if (factory == nil) { ChipLogError(chipTool, "Controller factory is nil"); return CHIP_ERROR_INTERNAL; } - auto params = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; + auto params = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; params.port = @(kListenPort); - params.startServer = YES; + params.shouldStartServer = YES; params.otaProviderDelegate = mOTADelegate; NSArray * paaCertResults; ReturnLogErrorOnFailure(GetPAACertsFromFolder(&paaCertResults)); @@ -127,9 +127,10 @@ params.paaCerts = paaCertResults; } - if ([factory startup:params] == NO) { + NSError * error; + if ([factory startControllerFactory:params error:&error] == NO) { ChipLogError(chipTool, "Controller factory startup failed"); - return CHIP_ERROR_INTERNAL; + return MTRErrorToCHIPErrorCode(error); } ReturnLogErrorOnFailure([gNocSigner createOrLoadKeys:storage]); @@ -138,21 +139,19 @@ constexpr const char * identities[] = { kIdentityAlpha, kIdentityBeta, kIdentityGamma }; for (size_t i = 0; i < ArraySize(identities); ++i) { - auto controllerParams = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:gNocSigner - fabricID:@(i + 1) - ipk:ipk]; + auto controllerParams = [[MTRDeviceControllerStartupParams alloc] initWithIPK:ipk fabricID:@(i + 1) nocSigner:gNocSigner]; // We're not sure whether we're creating a new fabric or using an // existing one, so just try both. - auto controller = [factory startControllerOnExistingFabric:controllerParams]; + auto controller = [factory createControllerOnExistingFabric:controllerParams error:&error]; if (controller == nil) { // Maybe we didn't have this fabric yet. controllerParams.vendorID = @(chip::VendorId::TestVendor1); - controller = [factory startControllerOnNewFabric:controllerParams]; + controller = [factory createControllerOnNewFabric:controllerParams error:&error]; } if (controller == nil) { ChipLogError(chipTool, "Controller startup failure."); - return CHIP_ERROR_INTERNAL; + return MTRErrorToCHIPErrorCode(error); } mControllers[identities[i]] = controller; @@ -195,16 +194,14 @@ { StopCommissioners(); - auto factory = [MTRControllerFactory sharedInstance]; + auto factory = [MTRDeviceControllerFactory sharedInstance]; NSData * ipk = [gNocSigner getIPK]; constexpr const char * identities[] = { kIdentityAlpha, kIdentityBeta, kIdentityGamma }; for (size_t i = 0; i < ArraySize(identities); ++i) { - auto controllerParams = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:gNocSigner - fabricID:@(i + 1) - ipk:ipk]; + auto controllerParams = [[MTRDeviceControllerStartupParams alloc] initWithIPK:ipk fabricID:@(i + 1) nocSigner:gNocSigner]; - auto controller = [factory startControllerOnExistingFabric:controllerParams]; + auto controller = [factory createControllerOnExistingFabric:controllerParams error:nil]; mControllers[identities[i]] = controller; } } @@ -216,7 +213,7 @@ mControllers.clear(); mCurrentController = nil; - [[MTRControllerFactory sharedInstance] shutdown]; + [[MTRDeviceControllerFactory sharedInstance] stopControllerFactory]; } CHIP_ERROR CHIPCommandBridge::StartWaiting(chip::System::Clock::Timeout duration) diff --git a/examples/java-matter-controller/BUILD.gn b/examples/java-matter-controller/BUILD.gn index 2eb8a691156f17..7c8bdf2f857144 100644 --- a/examples/java-matter-controller/BUILD.gn +++ b/examples/java-matter-controller/BUILD.gn @@ -31,14 +31,36 @@ android_binary("java-matter-controller") { sources = [ "java/src/com/matter/controller/Main.java", - "java/src/com/matter/controller/Off.java", - "java/src/com/matter/controller/On.java", "java/src/com/matter/controller/commands/common/Argument.java", "java/src/com/matter/controller/commands/common/ArgumentType.java", "java/src/com/matter/controller/commands/common/Command.java", + "java/src/com/matter/controller/commands/common/CommandManager.java", "java/src/com/matter/controller/commands/common/CredentialsIssuer.java", "java/src/com/matter/controller/commands/common/IPAddress.java", "java/src/com/matter/controller/commands/common/MatterCommand.java", + "java/src/com/matter/controller/commands/discover/DiscoverCommand.java", + "java/src/com/matter/controller/commands/discover/DiscoverCommissionablesCommand.java", + "java/src/com/matter/controller/commands/discover/DiscoverCommissionersCommand.java", + "java/src/com/matter/controller/commands/pairing/CloseSessionCommand.java", + "java/src/com/matter/controller/commands/pairing/DiscoveryFilterType.java", + "java/src/com/matter/controller/commands/pairing/PairCodeCommand.java", + "java/src/com/matter/controller/commands/pairing/PairCodePaseCommand.java", + "java/src/com/matter/controller/commands/pairing/PairCodeThreadCommand.java", + "java/src/com/matter/controller/commands/pairing/PairCodeWifiCommand.java", + "java/src/com/matter/controller/commands/pairing/PairEthernetCommand.java", + "java/src/com/matter/controller/commands/pairing/PairOnNetworkCommand.java", + "java/src/com/matter/controller/commands/pairing/PairOnNetworkCommissionerCommand.java", + "java/src/com/matter/controller/commands/pairing/PairOnNetworkCommissioningModeCommand.java", + "java/src/com/matter/controller/commands/pairing/PairOnNetworkDeviceTypeCommand.java", + "java/src/com/matter/controller/commands/pairing/PairOnNetworkFabricCommand.java", + "java/src/com/matter/controller/commands/pairing/PairOnNetworkInstanceNameCommand.java", + "java/src/com/matter/controller/commands/pairing/PairOnNetworkLongCommand.java", + "java/src/com/matter/controller/commands/pairing/PairOnNetworkShortCommand.java", + "java/src/com/matter/controller/commands/pairing/PairOnNetworkVendorCommand.java", + "java/src/com/matter/controller/commands/pairing/PairingCommand.java", + "java/src/com/matter/controller/commands/pairing/PairingModeType.java", + "java/src/com/matter/controller/commands/pairing/PairingNetworkType.java", + "java/src/com/matter/controller/commands/pairing/UnpairCommand.java", "java/src/com/matter/controller/config/PersistentStorage.java", "java/src/com/matter/controller/config/PersistentStorageOpCertStore.java", "java/src/com/matter/controller/config/PersistentStorageOperationalKeystore.java", diff --git a/examples/java-matter-controller/java/src/com/matter/controller/Main.java b/examples/java-matter-controller/java/src/com/matter/controller/Main.java index f27e4463a6d20f..449be3adefcaa6 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/Main.java +++ b/examples/java-matter-controller/java/src/com/matter/controller/Main.java @@ -18,82 +18,91 @@ package com.matter.controller; -import chip.devicecontroller.ChipDeviceController; -import chip.devicecontroller.ControllerParams; -import com.matter.controller.commands.common.Command; -import com.matter.controller.commands.common.CredentialsIssuer; -import java.util.Arrays; +import com.matter.controller.commands.common.*; +import com.matter.controller.commands.discover.*; +import com.matter.controller.commands.pairing.*; +import java.util.ArrayList; public class Main { - private static void ShowUsage(Command[] commands) { - StringBuffer arguments = new StringBuffer(); - StringBuffer attributes = new StringBuffer(); - - for (Command command : commands) { - arguments.append(" "); - arguments.append(command.getName()); - - int argumentsCount = command.getArgumentsCount(); - for (int j = 0; j < argumentsCount; j++) { - arguments.append(" "); - arguments.append(command.getArgumentName(j)); - } - - arguments.append("\n"); - - if ("read".equals(command.getName()) && command.getAttribute().isPresent()) { - attributes.append(" " + command.getAttribute().get() + "\n"); - } - } - - System.out.println( - String.format( - "Usage: \n" - + " java_matter_controller command [params]\n\n" - + " Supported commands and their parameters:\n%s\n" - + " Supported attribute names for the 'read' command:\n%s", - arguments, attributes)); + private static void registerCommandsDiscover( + CommandManager commandManager, CredentialsIssuer credentialsIssuer) { + ArrayList clusterCommands = new ArrayList(); + DiscoverCommand discoverCommand = new DiscoverCommand(credentialsIssuer); + DiscoverCommissionablesCommand discoverCommissionablesCommand = + new DiscoverCommissionablesCommand(credentialsIssuer); + DiscoverCommissionersCommand discoverCommissionersCommand = + new DiscoverCommissionersCommand(credentialsIssuer); + clusterCommands.add(discoverCommand); + clusterCommands.add(discoverCommissionablesCommand); + clusterCommands.add(discoverCommissionersCommand); + + commandManager.register("discover", clusterCommands); } - private static void runCommand(CredentialsIssuer credIssuerCmds, String[] args) { - - // TODO::Start list of available commands, this hard coded list need to be replaced by command - // registration mechanism. - Command[] commands = {new On(credIssuerCmds), new Off(credIssuerCmds)}; - // End list of available commands - - if (args.length == 0) { - ShowUsage(commands); - return; - } - - for (Command cmd : commands) { - if (cmd.getName().equals(args[0])) { - String[] temp = Arrays.copyOfRange(args, 1, args.length); - - try { - cmd.initArguments(args.length - 1, temp); - cmd.run(); - } catch (IllegalArgumentException e) { - System.out.println("Arguments init failed with exception: " + e.getMessage()); - } catch (Exception e) { - System.out.println("Run command failed with exception: " + e.getMessage()); - } - break; - } - } + private static void registerCommandsPairing( + CommandManager commandManager, CredentialsIssuer credentialsIssuer) { + ArrayList clusterCommands = new ArrayList(); + UnpairCommand unpairCommand = new UnpairCommand(credentialsIssuer); + PairCodeCommand pairCodeCommand = new PairCodeCommand(credentialsIssuer); + PairCodePaseCommand pairCodePaseCommand = new PairCodePaseCommand(credentialsIssuer); + PairCodeWifiCommand pairCodeWifiCommand = new PairCodeWifiCommand(credentialsIssuer); + PairCodeThreadCommand pairCodeThreadCommand = new PairCodeThreadCommand(credentialsIssuer); + PairEthernetCommand pairEthernetCommand = new PairEthernetCommand(credentialsIssuer); + PairOnNetworkCommand pairOnNetworkCommand = new PairOnNetworkCommand(credentialsIssuer); + PairOnNetworkShortCommand pairOnNetworkShortCommand = + new PairOnNetworkShortCommand(credentialsIssuer); + PairOnNetworkLongCommand pairOnNetworkLongCommand = + new PairOnNetworkLongCommand(credentialsIssuer); + PairOnNetworkVendorCommand pairOnNetworkVendorCommand = + new PairOnNetworkVendorCommand(credentialsIssuer); + PairOnNetworkCommissioningModeCommand pairOnNetworkCommissioningModeCommand = + new PairOnNetworkCommissioningModeCommand(credentialsIssuer); + PairOnNetworkCommissionerCommand pairOnNetworkCommissionerCommand = + new PairOnNetworkCommissionerCommand(credentialsIssuer); + PairOnNetworkDeviceTypeCommand pairOnNetworkDeviceTypeCommand = + new PairOnNetworkDeviceTypeCommand(credentialsIssuer); + PairOnNetworkInstanceNameCommand pairOnNetworkInstanceNameCommand = + new PairOnNetworkInstanceNameCommand(credentialsIssuer); + clusterCommands.add(unpairCommand); + clusterCommands.add(pairCodeCommand); + clusterCommands.add(pairCodePaseCommand); + clusterCommands.add(pairCodeWifiCommand); + clusterCommands.add(pairCodeThreadCommand); + clusterCommands.add(pairEthernetCommand); + clusterCommands.add(pairOnNetworkCommand); + clusterCommands.add(pairOnNetworkShortCommand); + clusterCommands.add(pairOnNetworkLongCommand); + clusterCommands.add(pairOnNetworkVendorCommand); + clusterCommands.add(pairOnNetworkCommissioningModeCommand); + clusterCommands.add(pairOnNetworkCommissionerCommand); + clusterCommands.add(pairOnNetworkDeviceTypeCommand); + clusterCommands.add(pairOnNetworkInstanceNameCommand); + + commandManager.register("pairing", clusterCommands); } public static void main(String[] args) { + /* TODO: uncomment when SDK integration is done ChipDeviceController controller = new ChipDeviceController( ControllerParams.newBuilder() .setUdpListenPort(0) .setControllerVendorId(0xFFF1) .build()); + */ CredentialsIssuer credentialsIssuer = new CredentialsIssuer(); + CommandManager commandManager = new CommandManager(); + + registerCommandsDiscover(commandManager, credentialsIssuer); + registerCommandsPairing(commandManager, credentialsIssuer); - runCommand(credentialsIssuer, args); + try { + commandManager.run(args); + } catch (IllegalArgumentException e) { + System.out.println("Arguments init failed with exception: " + e.getMessage()); + } catch (Exception e) { + System.out.println("Run command failed with exception: " + e.getMessage()); + } } } diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/common/CommandManager.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/common/CommandManager.java new file mode 100644 index 00000000000000..edcc61c3be86cc --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/common/CommandManager.java @@ -0,0 +1,246 @@ +/* + * 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. + * + */ + +package com.matter.controller.commands.common; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +public final class CommandManager { + private final ArrayList mCommandMgr = new ArrayList(); + private final Map> mClusters = + new HashMap>(); + + public final void register(String clusterName, ArrayList commandsList) { + mClusters.put(clusterName, commandsList); + } + + public final void run(String[] args) { + Command command; + + if (args.length < 1) { + System.out.println("Missing cluster name"); + showClusters(); + return; + } + + ArrayList commands = mClusters.get(args[0]); + if (commands == null) { + System.out.println("Unknown cluster: " + args[0]); + showClusters(); + return; + } + + if (args.length < 2) { + System.out.println("Missing command name"); + showCluster(args[0], commands); + return; + } + + if (!isGlobalCommand(args[0])) { + command = getCommand(commands, args[1]); + if (command == null) { + System.out.printf("Unknown command: %s", args[1]); + showCluster(args[0], commands); + throw new IllegalArgumentException(); + } + } else if (isEventCommand(args[1])) { + if (args.length < 3) { + System.out.println("Missing event name"); + showClusterEvents(args[0], args[1], commands); + throw new IllegalArgumentException(); + } + + command = getGlobalCommand(commands, args[1], args[2]); + if (command == null) { + System.out.println("Unknown event: " + args[2]); + showClusterEvents(args[0], args[1], commands); + throw new IllegalArgumentException(); + } + } else { + if (args.length < 3) { + System.out.println("Missing attribute name"); + showClusterAttributes(args[0], args[1], commands); + throw new IllegalArgumentException(); + } + + command = getGlobalCommand(commands, args[1], args[2]); + if (command == null) { + System.out.println("Unknown attribute: " + args[2]); + showClusterAttributes(args[0], args[1], commands); + throw new IllegalArgumentException(); + } + } + + String[] temp = Arrays.copyOfRange(args, 1, args.length); + + try { + command.initArguments(args.length - 1, temp); + command.run(); + } catch (IllegalArgumentException e) { + System.out.println("Arguments init failed with exception: " + e.getMessage()); + } catch (Exception e) { + System.out.println("Run command failed with exception: " + e.getMessage()); + } + } + + private boolean isAttributeCommand(String commandName) { + return commandName.equals("read") + || commandName.equals("write") + || commandName.equals("subscribe"); + } + + private boolean isEventCommand(String commandName) { + return commandName.equals("read-event") || commandName.equals("subscribe-event"); + } + + private boolean isGlobalCommand(String commandName) { + return isAttributeCommand(commandName) || isEventCommand(commandName); + } + + private Command getCommand(ArrayList commands, String commandName) { + for (Command command : commands) { + if (commandName.equals(command.getName())) { + return command; + } + } + + return null; + } + + private Command getGlobalCommand( + ArrayList commands, String commandName, String attributeName) { + for (Command command : commands) { + if (commandName.equals(command.getName()) && attributeName.equals(command.getAttribute())) { + return command; + } + } + + return null; + } + + private void showClusters() { + System.out.println("Usage:"); + System.out.println(" java-matter-controller cluster_name command_name [param1 param2 ...]"); + System.out.println("\n"); + System.out.println( + " +-------------------------------------------------------------------------------------+"); + System.out.println( + " | Clusters: |"); + System.out.println( + " +-------------------------------------------------------------------------------------+"); + + for (String key : mClusters.keySet()) { + System.out.printf(" | * %-82s|\n", key.toLowerCase()); + } + + System.out.println( + " +-------------------------------------------------------------------------------------+"); + } + + private void showCluster(String clusterName, ArrayList commands) { + System.out.println("Usage:"); + System.out.println( + " java-matter-controller " + clusterName + " command_name [param1 param2 ...]"); + System.out.println("\n"); + System.out.println( + " +-------------------------------------------------------------------------------------+"); + System.out.println( + " | Commands: |"); + System.out.println( + " +-------------------------------------------------------------------------------------+"); + boolean readCommand = false; + boolean writeCommand = false; + boolean subscribeCommand = false; + boolean readEventCommand = false; + boolean subscribeEventCommand = false; + + for (Command command : commands) { + boolean shouldPrint = true; + String cmdName = command.getName(); + if (isGlobalCommand(cmdName)) { + if (cmdName.equals("read") && !readCommand) { + readCommand = true; + } else if (cmdName.equals("write") && !writeCommand) { + writeCommand = true; + } else if (cmdName.equals("subscribe") && !subscribeCommand) { + subscribeCommand = true; + } else if (cmdName.equals("read-event") && !readEventCommand) { + readEventCommand = true; + } else if (cmdName.equals("subscribe-event") && !subscribeEventCommand) { + subscribeEventCommand = true; + } else { + shouldPrint = false; + } + } + + if (shouldPrint) { + System.out.printf(" | * %-82s|\n", cmdName); + } + } + System.out.println( + " +-------------------------------------------------------------------------------------+\n"); + } + + private void showClusterAttributes( + String clusterName, String commandName, ArrayList commands) { + System.out.println("Usage:"); + System.out.printf( + " java-matter-controller %s %s attribute-name [param1 param2 ...]\n", + clusterName, commandName); + System.out.println("\n"); + System.out.println( + " +-------------------------------------------------------------------------------------+"); + System.out.println( + " | Attributes: |"); + System.out.println( + " +-------------------------------------------------------------------------------------+"); + for (Command command : commands) { + if (commandName.equals(command.getName())) { + System.out.printf(" | * %-82s|\n", command.getAttribute().get()); + } + } + System.out.println( + " +-------------------------------------------------------------------------------------+"); + } + + private void showClusterEvents( + String clusterName, String commandName, ArrayList commands) { + System.out.println("Usage:"); + System.out.printf( + " java-matter-controller %s %s event-name [param1 param2 ...]\n", + clusterName, commandName); + System.out.println("\n"); + System.out.println( + " +-------------------------------------------------------------------------------------+"); + System.out.println( + " | Events: |"); + System.out.println( + " +-------------------------------------------------------------------------------------+"); + + for (Command command : commands) { + if (commandName.equals(command.getName())) { + System.out.printf(" | * %-82s|\n", command.getAttribute().get()); + } + } + System.out.println( + " +-------------------------------------------------------------------------------------+"); + } +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/On.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/discover/DiscoverCommand.java similarity index 73% rename from examples/java-matter-controller/java/src/com/matter/controller/On.java rename to examples/java-matter-controller/java/src/com/matter/controller/commands/discover/DiscoverCommand.java index 29fb65fbf97117..00c81d10d866a5 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/On.java +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/discover/DiscoverCommand.java @@ -1,37 +1,41 @@ -/* - * 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. - * - */ - -package com.matter.controller; - -import com.matter.controller.commands.common.CredentialsIssuer; -import com.matter.controller.commands.common.MatterCommand; -import java.util.concurrent.atomic.AtomicLong; - -public final class On extends MatterCommand { - private final AtomicLong mNodeId = new AtomicLong(); - private final AtomicLong mFabricId = new AtomicLong(); - - public On(CredentialsIssuer credIssuerCmds) { - super("on", credIssuerCmds); - addArgument("nodeid", 0, Long.MAX_VALUE, mNodeId, null); - addArgument("fabricid", 0, Long.MAX_VALUE, mFabricId, null); - } - - @Override - protected final void runCommand() {} -} +/* + * 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. + * + */ + +package com.matter.controller.commands.discover; + +import com.matter.controller.commands.common.CredentialsIssuer; +import com.matter.controller.commands.common.MatterCommand; +import java.util.concurrent.atomic.AtomicLong; + +public final class DiscoverCommand extends MatterCommand { + private final AtomicLong mNodeId = new AtomicLong(); + private final AtomicLong mFabricId = new AtomicLong(); + + public DiscoverCommand(CredentialsIssuer credsIssuer) { + super("resolve", credsIssuer); + addArgument("nodeid", 0, Long.MAX_VALUE, mNodeId, null); + addArgument("fabricid", 0, Long.MAX_VALUE, mFabricId, null); + } + + @Override + protected final void runCommand() { + runCommand(mNodeId.get(), mFabricId.get()); + } + + private final void runCommand(long remoteId, long fabricId) {} +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/Off.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/discover/DiscoverCommissionablesCommand.java similarity index 65% rename from examples/java-matter-controller/java/src/com/matter/controller/Off.java rename to examples/java-matter-controller/java/src/com/matter/controller/commands/discover/DiscoverCommissionablesCommand.java index 2eceb657222f50..cb128c41b005d4 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/Off.java +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/discover/DiscoverCommissionablesCommand.java @@ -16,20 +16,14 @@ * */ -package com.matter.controller; +package com.matter.controller.commands.discover; import com.matter.controller.commands.common.CredentialsIssuer; import com.matter.controller.commands.common.MatterCommand; -import java.util.concurrent.atomic.AtomicLong; -public final class Off extends MatterCommand { - private final AtomicLong mNodeId = new AtomicLong(); - private final AtomicLong mFabricId = new AtomicLong(); - - public Off(CredentialsIssuer credIssuerCmds) { - super("off", credIssuerCmds); - addArgument("nodeid", 0L, Long.MAX_VALUE, mNodeId, null); - addArgument("fabricid", 0L, Long.MAX_VALUE, mFabricId, null); +public final class DiscoverCommissionablesCommand extends MatterCommand { + public DiscoverCommissionablesCommand(CredentialsIssuer credsIssuer) { + super("commissionables", credsIssuer); } @Override diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/discover/DiscoverCommissionersCommand.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/discover/DiscoverCommissionersCommand.java new file mode 100644 index 00000000000000..a7a373683ae16c --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/discover/DiscoverCommissionersCommand.java @@ -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. + * + */ + +package com.matter.controller.commands.discover; + +import com.matter.controller.commands.common.CredentialsIssuer; +import com.matter.controller.commands.common.MatterCommand; + +public final class DiscoverCommissionersCommand extends MatterCommand { + public DiscoverCommissionersCommand(CredentialsIssuer credsIssuer) { + super("commissioners", credsIssuer); + } + + @Override + protected final void runCommand() { + // mCommissionableNodeController.DiscoverCommissioners(); + } +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/CloseSessionCommand.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/CloseSessionCommand.java new file mode 100644 index 00000000000000..f756f531746873 --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/CloseSessionCommand.java @@ -0,0 +1,43 @@ +/* + * 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. + * + */ + +package com.matter.controller.commands.pairing; + +import com.matter.controller.commands.common.CredentialsIssuer; +import com.matter.controller.commands.common.MatterCommand; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +public final class CloseSessionCommand extends MatterCommand { + private final AtomicLong mDestinationId = new AtomicLong(); + private final AtomicInteger mTimeoutSecs = new AtomicInteger(); + + public CloseSessionCommand(CredentialsIssuer credsIssuer) { + super("close-session", credsIssuer); + addArgument("destination-id", 0, Long.MAX_VALUE, mDestinationId, null); + addArgument( + "timeout", + (short) 0, + Short.MAX_VALUE, + mTimeoutSecs, + "Time, in seconds, before this command is considered to have timed out."); + } + + @Override + protected final void runCommand() {} +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/DiscoveryFilterType.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/DiscoveryFilterType.java new file mode 100644 index 00000000000000..1d614eb5b462d2 --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/DiscoveryFilterType.java @@ -0,0 +1,31 @@ +/* + * 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. + * + */ + +package com.matter.controller.commands.pairing; + +public enum DiscoveryFilterType { + NONE, + SHORT_DISCRIMINATOR, + LONG_DISCRIMINATOR, + VENDOR_ID, + DEVICE_TYPE, + COMMISSIONING_MODE, + INSTANCE_NAME, + COMMISSIONER, + COMPRESSED_FABRIC_ID, +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairCodeCommand.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairCodeCommand.java new file mode 100644 index 00000000000000..ceadf2ffed00c6 --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairCodeCommand.java @@ -0,0 +1,12 @@ +package com.matter.controller.commands.pairing; + +import com.matter.controller.commands.common.CredentialsIssuer; + +public final class PairCodeCommand extends PairingCommand { + public PairCodeCommand(CredentialsIssuer credsIssue) { + super("code", PairingModeType.CODE, PairingNetworkType.NONE, credsIssue); + } + + @Override + protected void runCommand() {} +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairCodePaseCommand.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairCodePaseCommand.java new file mode 100644 index 00000000000000..32a3bad4c14f93 --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairCodePaseCommand.java @@ -0,0 +1,12 @@ +package com.matter.controller.commands.pairing; + +import com.matter.controller.commands.common.CredentialsIssuer; + +public final class PairCodePaseCommand extends PairingCommand { + public PairCodePaseCommand(CredentialsIssuer credsIssue) { + super("code-paseonly", PairingModeType.CODE_PASE_ONLY, PairingNetworkType.NONE, credsIssue); + } + + @Override + protected void runCommand() {} +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairCodeThreadCommand.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairCodeThreadCommand.java new file mode 100644 index 00000000000000..8d036d2944beec --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairCodeThreadCommand.java @@ -0,0 +1,12 @@ +package com.matter.controller.commands.pairing; + +import com.matter.controller.commands.common.CredentialsIssuer; + +public final class PairCodeThreadCommand extends PairingCommand { + public PairCodeThreadCommand(CredentialsIssuer credsIssue) { + super("code-thread", PairingModeType.CODE, PairingNetworkType.THREAD, credsIssue); + } + + @Override + protected void runCommand() {} +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairCodeWifiCommand.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairCodeWifiCommand.java new file mode 100644 index 00000000000000..80c8098405d667 --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairCodeWifiCommand.java @@ -0,0 +1,12 @@ +package com.matter.controller.commands.pairing; + +import com.matter.controller.commands.common.CredentialsIssuer; + +public final class PairCodeWifiCommand extends PairingCommand { + public PairCodeWifiCommand(CredentialsIssuer credsIssue) { + super("code-wifi", PairingModeType.CODE, PairingNetworkType.WIFI, credsIssue); + } + + @Override + protected void runCommand() {} +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairEthernetCommand.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairEthernetCommand.java new file mode 100644 index 00000000000000..4296df73b9cef5 --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairEthernetCommand.java @@ -0,0 +1,12 @@ +package com.matter.controller.commands.pairing; + +import com.matter.controller.commands.common.CredentialsIssuer; + +public final class PairEthernetCommand extends PairingCommand { + public PairEthernetCommand(CredentialsIssuer credsIssue) { + super("ethernet", PairingModeType.ETHERNET, PairingNetworkType.ETHERNET, credsIssue); + } + + @Override + protected void runCommand() {} +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkCommand.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkCommand.java new file mode 100644 index 00000000000000..073e13fee7d2b8 --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkCommand.java @@ -0,0 +1,12 @@ +package com.matter.controller.commands.pairing; + +import com.matter.controller.commands.common.CredentialsIssuer; + +public final class PairOnNetworkCommand extends PairingCommand { + public PairOnNetworkCommand(CredentialsIssuer credsIssue) { + super("onnetwork", PairingModeType.ON_NETWORK, PairingNetworkType.NONE, credsIssue); + } + + @Override + protected void runCommand() {} +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkCommissionerCommand.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkCommissionerCommand.java new file mode 100644 index 00000000000000..6feb9d94670a81 --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkCommissionerCommand.java @@ -0,0 +1,17 @@ +package com.matter.controller.commands.pairing; + +import com.matter.controller.commands.common.CredentialsIssuer; + +public final class PairOnNetworkCommissionerCommand extends PairingCommand { + public PairOnNetworkCommissionerCommand(CredentialsIssuer credsIssue) { + super( + "onnetwork-commissioner", + PairingModeType.ON_NETWORK, + PairingNetworkType.NONE, + credsIssue, + DiscoveryFilterType.COMMISSIONER); + } + + @Override + protected void runCommand() {} +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkCommissioningModeCommand.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkCommissioningModeCommand.java new file mode 100644 index 00000000000000..4b44e5cd7896a2 --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkCommissioningModeCommand.java @@ -0,0 +1,17 @@ +package com.matter.controller.commands.pairing; + +import com.matter.controller.commands.common.CredentialsIssuer; + +public final class PairOnNetworkCommissioningModeCommand extends PairingCommand { + public PairOnNetworkCommissioningModeCommand(CredentialsIssuer credsIssue) { + super( + "onnetwork-commissioning-mode", + PairingModeType.ON_NETWORK, + PairingNetworkType.NONE, + credsIssue, + DiscoveryFilterType.COMMISSIONING_MODE); + } + + @Override + protected void runCommand() {} +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkDeviceTypeCommand.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkDeviceTypeCommand.java new file mode 100644 index 00000000000000..ad6e98fe57d45f --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkDeviceTypeCommand.java @@ -0,0 +1,17 @@ +package com.matter.controller.commands.pairing; + +import com.matter.controller.commands.common.CredentialsIssuer; + +public final class PairOnNetworkDeviceTypeCommand extends PairingCommand { + public PairOnNetworkDeviceTypeCommand(CredentialsIssuer credsIssue) { + super( + "onnetwork-device-type", + PairingModeType.ON_NETWORK, + PairingNetworkType.NONE, + credsIssue, + DiscoveryFilterType.DEVICE_TYPE); + } + + @Override + protected void runCommand() {} +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkFabricCommand.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkFabricCommand.java new file mode 100644 index 00000000000000..c430cd7da0cda5 --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkFabricCommand.java @@ -0,0 +1,18 @@ +package com.matter.controller.commands.pairing; + +import com.matter.controller.commands.common.CredentialsIssuer; +import java.net.UnknownHostException; + +public final class PairOnNetworkFabricCommand extends PairingCommand { + public PairOnNetworkFabricCommand(CredentialsIssuer credsIssue) throws UnknownHostException { + super( + "onnetwork-fabric", + PairingModeType.ON_NETWORK, + PairingNetworkType.NONE, + credsIssue, + DiscoveryFilterType.COMPRESSED_FABRIC_ID); + } + + @Override + protected void runCommand() {} +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkInstanceNameCommand.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkInstanceNameCommand.java new file mode 100644 index 00000000000000..c3dd7f7731047a --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkInstanceNameCommand.java @@ -0,0 +1,17 @@ +package com.matter.controller.commands.pairing; + +import com.matter.controller.commands.common.CredentialsIssuer; + +public final class PairOnNetworkInstanceNameCommand extends PairingCommand { + public PairOnNetworkInstanceNameCommand(CredentialsIssuer credsIssue) { + super( + "onnetwork-instance-name", + PairingModeType.ON_NETWORK, + PairingNetworkType.NONE, + credsIssue, + DiscoveryFilterType.INSTANCE_NAME); + } + + @Override + protected void runCommand() {} +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongCommand.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongCommand.java new file mode 100644 index 00000000000000..62ee8c03ccf8c9 --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongCommand.java @@ -0,0 +1,17 @@ +package com.matter.controller.commands.pairing; + +import com.matter.controller.commands.common.CredentialsIssuer; + +public final class PairOnNetworkLongCommand extends PairingCommand { + public PairOnNetworkLongCommand(CredentialsIssuer credsIssue) { + super( + "onnetwork-long", + PairingModeType.ON_NETWORK, + PairingNetworkType.NONE, + credsIssue, + DiscoveryFilterType.LONG_DISCRIMINATOR); + } + + @Override + protected void runCommand() {} +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkShortCommand.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkShortCommand.java new file mode 100644 index 00000000000000..e6af8dc6bd7f5a --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkShortCommand.java @@ -0,0 +1,17 @@ +package com.matter.controller.commands.pairing; + +import com.matter.controller.commands.common.CredentialsIssuer; + +public final class PairOnNetworkShortCommand extends PairingCommand { + public PairOnNetworkShortCommand(CredentialsIssuer credsIssue) { + super( + "onnetwork-short", + PairingModeType.ON_NETWORK, + PairingNetworkType.NONE, + credsIssue, + DiscoveryFilterType.SHORT_DISCRIMINATOR); + } + + @Override + protected void runCommand() {} +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkVendorCommand.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkVendorCommand.java new file mode 100644 index 00000000000000..398203d916d48a --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkVendorCommand.java @@ -0,0 +1,17 @@ +package com.matter.controller.commands.pairing; + +import com.matter.controller.commands.common.CredentialsIssuer; + +public final class PairOnNetworkVendorCommand extends PairingCommand { + public PairOnNetworkVendorCommand(CredentialsIssuer credsIssue) { + super( + "onnetwork-vendor", + PairingModeType.ON_NETWORK, + PairingNetworkType.NONE, + credsIssue, + DiscoveryFilterType.VENDOR_ID); + } + + @Override + protected void runCommand() {} +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.java new file mode 100644 index 00000000000000..151c88bf8bd2ca --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.java @@ -0,0 +1,149 @@ +/* + * 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. + * + */ + +package com.matter.controller.commands.pairing; + +import com.matter.controller.commands.common.CredentialsIssuer; +import com.matter.controller.commands.common.IPAddress; +import com.matter.controller.commands.common.MatterCommand; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +public abstract class PairingCommand extends MatterCommand { + private PairingModeType mPairingMode = PairingModeType.NONE; + private PairingNetworkType mNetworkType = PairingNetworkType.NONE; + private DiscoveryFilterType mFilterType = DiscoveryFilterType.NONE; + private final IPAddress mRemoteAddr; + private final AtomicLong mNodeId = new AtomicLong(); + private final AtomicLong mDiscoveryFilterCode = new AtomicLong(); + private final AtomicInteger mTimeout = new AtomicInteger(); + private final AtomicBoolean mDiscoverOnce = new AtomicBoolean(); + private final AtomicBoolean mUseOnlyOnNetworkDiscovery = new AtomicBoolean(); + private final AtomicInteger mRemotePort = new AtomicInteger(); + private final AtomicInteger mDiscriminator = new AtomicInteger(); + private final AtomicInteger mSetupPINCode = new AtomicInteger(); + private final StringBuffer mOperationalDataset = new StringBuffer(); + private final StringBuffer mSSID = new StringBuffer(); + private final StringBuffer mPassword = new StringBuffer(); + private final StringBuffer mOnboardingPayload = new StringBuffer(); + private final StringBuffer mDiscoveryFilterInstanceName = new StringBuffer(); + + public PairingCommand( + String commandName, + PairingModeType mode, + PairingNetworkType networkType, + CredentialsIssuer credsIssuer) { + this(commandName, mode, networkType, credsIssuer, DiscoveryFilterType.NONE); + } + + public PairingCommand( + String commandName, + PairingModeType mode, + PairingNetworkType networkType, + CredentialsIssuer credsIssuer, + DiscoveryFilterType filterType) { + super(commandName, credsIssuer); + this.mPairingMode = mode; + this.mNetworkType = networkType; + this.mFilterType = filterType; + + try { + this.mRemoteAddr = new IPAddress(InetAddress.getByName("0.0.0.0")); + } catch (UnknownHostException e) { + throw new RuntimeException(e); + } + + addArgument("node-id", 0, Long.MAX_VALUE, mNodeId, null); + + switch (networkType) { + case NONE: + case ETHERNET: + break; + case WIFI: + addArgument("ssid", mSSID, null); + addArgument("password", mPassword, null); + break; + case THREAD: + addArgument("operationalDataset", mOperationalDataset, null); + break; + } + + switch (mode) { + case NONE: + break; + case CODE: + case CODE_PASE_ONLY: + Only: + addArgument("payload", mOnboardingPayload, null); + addArgument("discover-once", mDiscoverOnce, null); + addArgument("use-only-onnetwork-discovery", mUseOnlyOnNetworkDiscovery, null); + break; + case BLE: + addArgument("setup-pin-code", 0, 134217727, mSetupPINCode, null); + addArgument("discriminator", (short) 0, (short) 4096, mDiscriminator, null); + break; + case ON_NETWORK: + addArgument("setup-pin-code", 0, 134217727, mSetupPINCode, null); + break; + case SOFT_AP: + AP: + addArgument("setup-pin-code", 0, 134217727, mSetupPINCode, null); + addArgument("discriminator", (short) 0, (short) 4096, mDiscriminator, null); + addArgument("device-remote-ip", mRemoteAddr); + addArgument("device-remote-port", (short) 0, Short.MAX_VALUE, mRemotePort, null); + break; + case ETHERNET: + addArgument("setup-pin-code", 0, 134217727, mSetupPINCode, null); + addArgument("discriminator", (short) 0, (short) 4096, mDiscriminator, null); + addArgument("device-remote-ip", mRemoteAddr); + addArgument("device-remote-port", (short) 0, Short.MAX_VALUE, mRemotePort, null); + break; + } + + switch (filterType) { + case NONE: + break; + case SHORT_DISCRIMINATOR: + addArgument("discriminator", (short) 0, (short) 4096, mDiscriminator, null); + break; + case LONG_DISCRIMINATOR: + addArgument("discriminator", (short) 0, (short) 4096, mDiscriminator, null); + break; + case VENDOR_ID: + addArgument("vendor-id", (short) 0, Short.MAX_VALUE, mDiscoveryFilterCode, null); + break; + case COMPRESSED_FABRIC_ID: + addArgument("fabric-id", 0, Long.MAX_VALUE, mDiscoveryFilterCode, null); + break; + case COMMISSIONING_MODE: + case COMMISSIONER: + break; + case DEVICE_TYPE: + addArgument("device-type", (short) 0, Short.MAX_VALUE, mDiscoveryFilterCode, null); + break; + case INSTANCE_NAME: + addArgument("name", mDiscoveryFilterInstanceName, null); + break; + } + + addArgument("timeout", (short) 0, Short.MAX_VALUE, mTimeout, null); + } +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingModeType.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingModeType.java new file mode 100644 index 00000000000000..015bb8005acc25 --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingModeType.java @@ -0,0 +1,29 @@ +/* + * 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. + * + */ + +package com.matter.controller.commands.pairing; + +public enum PairingModeType { + NONE, + CODE, + CODE_PASE_ONLY, + BLE, + SOFT_AP, + ETHERNET, + ON_NETWORK; +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingNetworkType.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingNetworkType.java new file mode 100644 index 00000000000000..1edbe327585577 --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingNetworkType.java @@ -0,0 +1,26 @@ +/* + * 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. + * + */ + +package com.matter.controller.commands.pairing; + +public enum PairingNetworkType { + NONE, + WIFI, + THREAD, + ETHERNET; +} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/UnpairCommand.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/UnpairCommand.java new file mode 100644 index 00000000000000..8cf1f844e1511d --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/UnpairCommand.java @@ -0,0 +1,12 @@ +package com.matter.controller.commands.pairing; + +import com.matter.controller.commands.common.CredentialsIssuer; + +public final class UnpairCommand extends PairingCommand { + public UnpairCommand(CredentialsIssuer credsIssue) { + super("unpair", PairingModeType.NONE, PairingNetworkType.NONE, credsIssue); + } + + @Override + protected void runCommand() {} +} diff --git a/examples/light-switch-app/telink/boards/tlsr9518adk80d.overlay b/examples/light-switch-app/telink/boards/tlsr9518adk80d.overlay deleted file mode 100644 index 613584d2908fba..00000000000000 --- a/examples/light-switch-app/telink/boards/tlsr9518adk80d.overlay +++ /dev/null @@ -1,35 +0,0 @@ -&flash { - /delete-node/ partitions; -}; - -&flash { - reg = <0x20000000 0x100000>; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - boot_partition: partition@0 { - label = "mcuboot"; - reg = <0x00000000 0x10000>; - }; - slot0_partition: partition@10000 { - label = "image-0"; - reg = <0x10000 0x70000>; - }; - slot1_partition: partition@80000 { - label = "image-1"; - reg = <0x80000 0x70000>; - }; - scratch_partition: partition@f0000 { - label = "image-scratch"; - reg = <0xf0000 0x4000>; - }; - storage_partition: partition@f4000 { - label = "storage"; - reg = <0xf4000 0x0000b000>; - /* region <0xff000 0x1000> is reserved for Telink B91 SDK's data */ - }; - }; -}; diff --git a/examples/light-switch-app/telink/include/AppTask.h b/examples/light-switch-app/telink/include/AppTask.h index 7fd67ff34abdad..6cf0a330cf2317 100755 --- a/examples/light-switch-app/telink/include/AppTask.h +++ b/examples/light-switch-app/telink/include/AppTask.h @@ -24,6 +24,10 @@ #include +#if CONFIG_CHIP_FACTORY_DATA +#include +#endif + #include struct k_timer; @@ -48,7 +52,6 @@ class AppTask private: friend AppTask & GetAppTask(void); - CHIP_ERROR Init(); static void ActionInitiated(AppTask::Action_t aAction, int32_t aActor); @@ -74,6 +77,11 @@ class AppTask static void ThreadProvisioningHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); static AppTask sAppTask; + +#if CONFIG_CHIP_FACTORY_DATA + // chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; + chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; +#endif }; inline AppTask & GetAppTask(void) diff --git a/examples/light-switch-app/telink/prj.conf b/examples/light-switch-app/telink/prj.conf index 05b92e9169eb6e..1366c5f0e952fb 100755 --- a/examples/light-switch-app/telink/prj.conf +++ b/examples/light-switch-app/telink/prj.conf @@ -54,4 +54,8 @@ CONFIG_CHIP_DEVICE_SOFTWARE_VERSION_STRING="2022" CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y # CHIP shell -CONFIG_CHIP_LIB_SHELL=n \ No newline at end of file +CONFIG_CHIP_LIB_SHELL=n + +# Disable factory data support. +CONFIG_CHIP_FACTORY_DATA=n +CONFIG_CHIP_FACTORY_DATA_BUILD=n \ No newline at end of file diff --git a/examples/light-switch-app/telink/src/AppTask.cpp b/examples/light-switch-app/telink/src/AppTask.cpp index e8d3d0049dc095..7e1c792018b885 100644 --- a/examples/light-switch-app/telink/src/AppTask.cpp +++ b/examples/light-switch-app/telink/src/AppTask.cpp @@ -23,27 +23,19 @@ #include "ButtonManager.h" #include "LEDWidget.h" #include "binding-handler.h" -#include -#include - -#include #include "ThreadUtil.h" +#include #include #include #include #include -#include - +#include +#include #include #include - -#include - #include -#include -#include #include #if CONFIG_CHIP_OTA_REQUESTOR @@ -57,12 +49,22 @@ LOG_MODULE_DECLARE(app); +using namespace ::chip; +using namespace ::chip::app; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; + namespace { constexpr int kAppEventQueueSize = 10; constexpr uint8_t kButtonPushEvent = 1; constexpr uint8_t kButtonReleaseEvent = 0; +// NOTE! This key is for test/certification only and should not be available in production devices! +// If CONFIG_CHIP_FACTORY_DATA is enabled, this value is read from the factory data. +uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; + K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); LEDWidget sStatusLED; @@ -112,15 +114,11 @@ Identify sIdentify = { } // namespace -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; -using namespace ::chip::DeviceLayer::Internal; - AppTask AppTask::sAppTask; CHIP_ERROR AppTask::Init() { - CHIP_ERROR ret; + CHIP_ERROR err; LOG_INF("Current Software Version: %u, %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION, CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); @@ -133,15 +131,30 @@ CHIP_ERROR AppTask::Init() InitButtons(); - // Init ZCL Data Model and start server - static chip::CommonCaseDeviceServerInitParams initParams; - (void) initParams.InitializeStaticResourcesBeforeServerInit(); - chip::Server::GetInstance().Init(initParams); - - // Initialize device attestation config + // Initialize CHIP server +#if CONFIG_CHIP_FACTORY_DATA + ReturnErrorOnFailure(mFactoryDataProvider.Init()); + SetDeviceInstanceInfoProvider(&mFactoryDataProvider); + SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); + SetCommissionableDataProvider(&mFactoryDataProvider); + // Read EnableKey from the factory data. + MutableByteSpan enableKey(sTestEventTriggerEnableKey); + err = mFactoryDataProvider.GetEnableKey(enableKey); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("mFactoryDataProvider.GetEnableKey() failed. Could not delegate a test event trigger"); + memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); + } +#else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif - gExampleDeviceInfoProvider.SetStorageDelegate(&chip::Server::GetInstance().GetPersistentStorage()); + static CommonCaseDeviceServerInitParams initParams; + // static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); + // initParams.testEventTriggerDelegate = &testEventTriggerDelegate; + ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); + gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); #if CONFIG_CHIP_OTA_REQUESTOR @@ -151,11 +164,11 @@ CHIP_ERROR AppTask::Init() ConfigurationMgr().LogDeviceConfig(); // Configure Bindings - ret = InitBindingHandler(); - if (ret != CHIP_NO_ERROR) + err = InitBindingHandler(); + if (err != CHIP_NO_ERROR) { LOG_ERR("InitBindingHandler() failed"); - return ret; + return err; } PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); @@ -165,14 +178,13 @@ CHIP_ERROR AppTask::Init() // between the main and the CHIP threads. PlatformMgr().AddEventHandler(ChipEventHandler, 0); - ret = ConnectivityMgr().SetBLEDeviceName("TelinkSwitch"); - if (ret != CHIP_NO_ERROR) + err = ConnectivityMgr().SetBLEDeviceName("TelinkSwitch"); + if (err != CHIP_NO_ERROR) { LOG_ERR("Fail to set BLE device name"); - return ret; } - return CHIP_NO_ERROR; + return err; } CHIP_ERROR AppTask::StartApp() @@ -255,7 +267,7 @@ void AppTask::StartThreadHandler(AppEvent * aEvent) if (!chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned()) { // Switch context from BLE to Thread - BLEManagerImpl sInstance; + Internal::BLEManagerImpl sInstance; sInstance.SwitchToIeee802154(); StartDefaultThreadNetwork(); LOG_INF("Device is not commissioned to a Thread network. Starting with the default configuration."); diff --git a/examples/lighting-app/qpg/include/AppTask.h b/examples/lighting-app/qpg/include/AppTask.h index f91eb971c2ca17..7651124669546d 100644 --- a/examples/lighting-app/qpg/include/AppTask.h +++ b/examples/lighting-app/qpg/include/AppTask.h @@ -64,6 +64,9 @@ class AppTask static void LightingActionEventHandler(AppEvent * aEvent); static void TimerEventHandler(chip::System::Layer * aLayer, void * aAppState); + static void MatterEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + static void UpdateLEDs(void); + void StartTimer(uint32_t aTimeoutMs); void CancelTimer(void); diff --git a/examples/lighting-app/qpg/src/AppTask.cpp b/examples/lighting-app/qpg/src/AppTask.cpp index 2f99b8e97edca3..27724b1f271329 100644 --- a/examples/lighting-app/qpg/src/AppTask.cpp +++ b/examples/lighting-app/qpg/src/AppTask.cpp @@ -57,7 +57,7 @@ using namespace ::chip::DeviceLayer; #define FACTORY_RESET_TRIGGER_TIMEOUT 3000 #define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 3000 -#define APP_TASK_STACK_SIZE (3 * 1024) +#define APP_TASK_STACK_SIZE (2 * 1024) #define APP_TASK_PRIORITY 2 #define APP_EVENT_QUEUE_SIZE 10 #define QPG_LIGHT_ENDPOINT_ID (1) @@ -260,6 +260,8 @@ CHIP_ERROR AppTask::Init() { CHIP_ERROR err = CHIP_NO_ERROR; + PlatformMgr().AddEventHandler(MatterEventHandler, 0); + ChipLogProgress(NotSpecified, "Current Software Version: %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); // Init ZCL Data Model and start server @@ -303,53 +305,12 @@ void AppTask::AppTaskMain(void * pvParameter) while (true) { - BaseType_t eventReceived = xQueueReceive(sAppEventQueue, &event, pdMS_TO_TICKS(10)); + BaseType_t eventReceived = xQueueReceive(sAppEventQueue, &event, portMAX_DELAY); while (eventReceived == pdTRUE) { sAppTask.DispatchEvent(&event); eventReceived = xQueueReceive(sAppEventQueue, &event, 0); } - - // Collect connectivity and configuration state from the CHIP stack. Because - // the CHIP event loop is being run in a separate task, the stack must be - // locked while these values are queried. However we use a non-blocking - // lock request (TryLockCHIPStack()) to avoid blocking other UI activities - // when the CHIP task is busy (e.g. with a long crypto operation). - if (PlatformMgr().TryLockChipStack()) - { - sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); - sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); - sHaveBLEConnections = (ConnectivityMgr().NumBLEConnections() != 0); - PlatformMgr().UnlockChipStack(); - } - - // Update the status LED if factory reset has not been initiated. - // - // If system has "full connectivity", keep the LED On constantly. - // - // If thread and service provisioned, but not attached to the thread network - // yet OR no connectivity to the service OR subscriptions are not fully - // established THEN blink the LED Off for a short period of time. - // - // If the system has ble connection(s) uptill the stage above, THEN blink - // the LEDs at an even rate of 100ms. - // - // Otherwise, blink the LED ON for a very short time. - if (sAppTask.mFunction != kFunction_FactoryReset) - { - if (sIsThreadProvisioned && sIsThreadEnabled) - { - qvIO_LedBlink(SYSTEM_STATE_LED, 950, 50); - } - else if (sHaveBLEConnections) - { - qvIO_LedBlink(SYSTEM_STATE_LED, 100, 100); - } - else - { - qvIO_LedBlink(SYSTEM_STATE_LED, 50, 950); - } - } } } @@ -621,3 +582,62 @@ void AppTask::UpdateClusterState(void) ChipLogError(NotSpecified, "ERR: updating level %x", status); } } + +void AppTask::UpdateLEDs(void) +{ + // If system has "full connectivity", keep the LED On constantly. + // + // If thread and service provisioned, but not attached to the thread network + // yet OR no connectivity to the service OR subscriptions are not fully + // established THEN blink the LED Off for a short period of time. + // + // If the system has ble connection(s) uptill the stage above, THEN blink + // the LEDs at an even rate of 100ms. + // + // Otherwise, blink the LED ON for a very short time. + if (sIsThreadProvisioned && sIsThreadEnabled) + { + qvIO_LedBlink(SYSTEM_STATE_LED, 950, 50); + } + else if (sHaveBLEConnections) + { + qvIO_LedBlink(SYSTEM_STATE_LED, 100, 100); + } + else + { + qvIO_LedBlink(SYSTEM_STATE_LED, 50, 950); + } +} + +void AppTask::MatterEventHandler(const ChipDeviceEvent * event, intptr_t) +{ + switch (event->Type) + { + case DeviceEventType::kServiceProvisioningChange: { + sIsThreadProvisioned = event->ServiceProvisioningChange.IsServiceProvisioned; + UpdateLEDs(); + break; + } + + case DeviceEventType::kThreadConnectivityChange: { + sIsThreadEnabled = (event->ThreadConnectivityChange.Result == kConnectivity_Established); + UpdateLEDs(); + break; + } + + case DeviceEventType::kCHIPoBLEConnectionEstablished: { + sHaveBLEConnections = true; + UpdateLEDs(); + break; + } + + case DeviceEventType::kCHIPoBLEConnectionClosed: { + sHaveBLEConnections = false; + UpdateLEDs(); + break; + } + + default: + break; + } +} diff --git a/examples/lighting-app/telink/boards/tlsr9518adk80d.overlay b/examples/lighting-app/telink/boards/tlsr9518adk80d.overlay deleted file mode 100644 index 613584d2908fba..00000000000000 --- a/examples/lighting-app/telink/boards/tlsr9518adk80d.overlay +++ /dev/null @@ -1,35 +0,0 @@ -&flash { - /delete-node/ partitions; -}; - -&flash { - reg = <0x20000000 0x100000>; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - boot_partition: partition@0 { - label = "mcuboot"; - reg = <0x00000000 0x10000>; - }; - slot0_partition: partition@10000 { - label = "image-0"; - reg = <0x10000 0x70000>; - }; - slot1_partition: partition@80000 { - label = "image-1"; - reg = <0x80000 0x70000>; - }; - scratch_partition: partition@f0000 { - label = "image-scratch"; - reg = <0xf0000 0x4000>; - }; - storage_partition: partition@f4000 { - label = "storage"; - reg = <0xf4000 0x0000b000>; - /* region <0xff000 0x1000> is reserved for Telink B91 SDK's data */ - }; - }; -}; diff --git a/examples/lighting-app/telink/include/AppTask.h b/examples/lighting-app/telink/include/AppTask.h index d926c5286f41f3..0b1b588654aa13 100644 --- a/examples/lighting-app/telink/include/AppTask.h +++ b/examples/lighting-app/telink/include/AppTask.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2022 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,6 +23,10 @@ #include +#if CONFIG_CHIP_FACTORY_DATA +#include +#endif + #include struct k_timer; @@ -38,7 +42,6 @@ class AppTask private: friend AppTask & GetAppTask(void); - CHIP_ERROR Init(); static void ActionInitiated(LightingManager::Action_t aAction, int32_t aActor); @@ -64,6 +67,11 @@ class AppTask static void ThreadProvisioningHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); static AppTask sAppTask; + +#if CONFIG_CHIP_FACTORY_DATA + // chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; + chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; +#endif }; inline AppTask & GetAppTask(void) diff --git a/examples/lighting-app/telink/prj.conf b/examples/lighting-app/telink/prj.conf index 3e94168f31df3d..3de670dd34bf07 100644 --- a/examples/lighting-app/telink/prj.conf +++ b/examples/lighting-app/telink/prj.conf @@ -54,4 +54,8 @@ CONFIG_CHIP_DEVICE_SOFTWARE_VERSION_STRING="2022" CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y # CHIP shell -CONFIG_CHIP_LIB_SHELL=n \ No newline at end of file +CONFIG_CHIP_LIB_SHELL=n + +# Disable factory data support. +CONFIG_CHIP_FACTORY_DATA=n +CONFIG_CHIP_FACTORY_DATA_BUILD=n \ No newline at end of file diff --git a/examples/lighting-app/telink/src/AppTask.cpp b/examples/lighting-app/telink/src/AppTask.cpp index fd9eabc82976e5..00db77cd01c89a 100644 --- a/examples/lighting-app/telink/src/AppTask.cpp +++ b/examples/lighting-app/telink/src/AppTask.cpp @@ -23,28 +23,20 @@ #include "ButtonManager.h" #include "LEDWidget.h" #include "LightingManager.h" -#include -#include - -#include #include "ThreadUtil.h" +#include #include #include #include #include #include -#include - +#include +#include #include #include - -#include - #include -#include -#include #include #if CONFIG_CHIP_OTA_REQUESTOR @@ -58,6 +50,11 @@ LOG_MODULE_DECLARE(app); +using namespace ::chip; +using namespace ::chip::app; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; + namespace { constexpr int kAppEventQueueSize = 10; @@ -66,6 +63,11 @@ constexpr uint8_t kButtonReleaseEvent = 0; constexpr uint8_t kDefaultMinLevel = 0; constexpr uint8_t kDefaultMaxLevel = 254; +// NOTE! This key is for test/certification only and should not be available in production devices! +// If CONFIG_CHIP_FACTORY_DATA is enabled, this value is read from the factory data. +uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; + K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); LEDWidget sStatusLED; @@ -115,18 +117,10 @@ Identify sIdentify = { } // namespace -using namespace ::chip; -using namespace ::chip::app; -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; -using namespace ::chip::DeviceLayer::Internal; - AppTask AppTask::sAppTask; CHIP_ERROR AppTask::Init() { - CHIP_ERROR ret; - LOG_INF("Current Software Version: %u, %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION, CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); @@ -145,23 +139,39 @@ CHIP_ERROR AppTask::Init() uint8_t maxLightLevel = kDefaultMaxLevel; Clusters::LevelControl::Attributes::MaxLevel::Get(1, &maxLightLevel); - ret = LightingMgr().Init(LIGHTING_PWM_DEVICE, LIGHTING_PWM_CHANNEL, minLightLevel, maxLightLevel, maxLightLevel); - if (ret != CHIP_NO_ERROR) + CHIP_ERROR err = LightingMgr().Init(LIGHTING_PWM_DEVICE, LIGHTING_PWM_CHANNEL, minLightLevel, maxLightLevel, maxLightLevel); + if (err != CHIP_NO_ERROR) { LOG_ERR("Failed to int lighting manager"); - return ret; + return err; } LightingMgr().SetCallbacks(ActionInitiated, ActionCompleted); - // Init ZCL Data Model and start server - static chip::CommonCaseDeviceServerInitParams initParams; - (void) initParams.InitializeStaticResourcesBeforeServerInit(); - chip::Server::GetInstance().Init(initParams); - - // Initialize device attestation config + // Initialize CHIP server +#if CONFIG_CHIP_FACTORY_DATA + ReturnErrorOnFailure(mFactoryDataProvider.Init()); + SetDeviceInstanceInfoProvider(&mFactoryDataProvider); + SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); + SetCommissionableDataProvider(&mFactoryDataProvider); + // Read EnableKey from the factory data. + MutableByteSpan enableKey(sTestEventTriggerEnableKey); + err = mFactoryDataProvider.GetEnableKey(enableKey); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("mFactoryDataProvider.GetEnableKey() failed. Could not delegate a test event trigger"); + memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); + } +#else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif + + static CommonCaseDeviceServerInitParams initParams; + // static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); + // initParams.testEventTriggerDelegate = &testEventTriggerDelegate; + ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); - gExampleDeviceInfoProvider.SetStorageDelegate(&chip::Server::GetInstance().GetPersistentStorage()); + gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); #if CONFIG_CHIP_OTA_REQUESTOR @@ -176,14 +186,13 @@ CHIP_ERROR AppTask::Init() // between the main and the CHIP threads. PlatformMgr().AddEventHandler(ChipEventHandler, 0); - ret = ConnectivityMgr().SetBLEDeviceName("TelinkLight"); - if (ret != CHIP_NO_ERROR) + err = ConnectivityMgr().SetBLEDeviceName("TelinkLight"); + if (err != CHIP_NO_ERROR) { LOG_ERR("Fail to set BLE device name"); - return ret; } - return CHIP_NO_ERROR; + return err; } CHIP_ERROR AppTask::StartApp() @@ -274,7 +283,7 @@ void AppTask::StartThreadHandler(AppEvent * aEvent) if (!chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned()) { // Switch context from BLE to Thread - BLEManagerImpl sInstance; + Internal::BLEManagerImpl sInstance; sInstance.SwitchToIeee802154(); StartDefaultThreadNetwork(); LOG_INF("Device is not commissioned to a Thread network. Starting with the default configuration."); diff --git a/examples/platform/efr32/LEDWidget.cpp b/examples/platform/efr32/LEDWidget.cpp index 960995545e6efb..10ffcac363520d 100644 --- a/examples/platform/efr32/LEDWidget.cpp +++ b/examples/platform/efr32/LEDWidget.cpp @@ -18,7 +18,10 @@ */ #include "LEDWidget.h" + +extern "C" { #include "sl_simple_led_instances.h" +} #include diff --git a/examples/platform/efr32/OTAConfig.cpp b/examples/platform/efr32/OTAConfig.cpp index 8f42f6951e1cdc..1056cf5a3533b4 100644 --- a/examples/platform/efr32/OTAConfig.cpp +++ b/examples/platform/efr32/OTAConfig.cpp @@ -18,9 +18,15 @@ #include "OTAConfig.h" -#include "platform/bootloader/api/application_properties.h" +#include "application_properties.h" #include +#if defined(SL_COMPONENT_CATALOG_PRESENT) +#include "sl_component_catalog.h" +#endif + +// Only include app properties if the Gecko SDK component that does it automatically isn't present +#if !defined(SL_CATALOG_GECKO_BOOTLOADER_INTERFACE_PRESENT) // Header used for building the image GBL file #define APP_PROPERTIES_VERSION 1 #define APP_PROPERTIES_ID \ @@ -65,6 +71,7 @@ __attribute__((used)) ApplicationProperties_t sl_app_properties = { /// Pointer to Long Token Data Section .longTokenSectionAddress = NULL, }; +#endif // SL_CATALOG_GECKO_BOOTLOADER_INTERFACE_PRESENT // Global OTA objects chip::DefaultOTARequestor gRequestorCore; diff --git a/examples/platform/efr32/matter_config.cpp b/examples/platform/efr32/matter_config.cpp index d4d651f73ab5d2..1102db5465f430 100644 --- a/examples/platform/efr32/matter_config.cpp +++ b/examples/platform/efr32/matter_config.cpp @@ -105,10 +105,12 @@ CHIP_ERROR EFR32MatterConfig::InitOpenThread(void) } #endif // CHIP_ENABLE_OPENTHREAD +#if EFR32_OTA_ENABLED void EFR32MatterConfig::InitOTARequestorHandler(System::Layer * systemLayer, void * appState) { OTAConfig::Init(); } +#endif void EFR32MatterConfig::ConnectivityEventCallback(const ChipDeviceEvent * event, intptr_t arg) { @@ -118,9 +120,11 @@ void EFR32MatterConfig::ConnectivityEventCallback(const ChipDeviceEvent * event, ((event->Type == DeviceEventType::kInternetConnectivityChange) && (event->InternetConnectivityChange.IPv6 == kConnectivity_Established))) { +#if EFR32_OTA_ENABLED EFR32_LOG("Scheduling OTA Requestor initialization") chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(OTAConfig::kInitOTARequestorDelaySec), InitOTARequestorHandler, nullptr); +#endif } } diff --git a/examples/tv-app/android/java/AppImpl.cpp b/examples/tv-app/android/java/AppImpl.cpp index 8139dba7a8c912..d03ebc2c908e52 100644 --- a/examples/tv-app/android/java/AppImpl.cpp +++ b/examples/tv-app/android/java/AppImpl.cpp @@ -403,6 +403,19 @@ Access::Privilege ContentAppFactoryImpl::GetVendorPrivilege(uint16_t vendorId) return Access::Privilege::kOperate; } +std::list ContentAppFactoryImpl::GetAllowedClusterListForStaticEndpoint(EndpointId endpointId, uint16_t vendorId, + uint16_t productId) +{ + if (endpointId == kLocalVideoPlayerEndpointId) + { + return { chip::app::Clusters::Descriptor::Id, chip::app::Clusters::OnOff::Id, + chip::app::Clusters::WakeOnLan::Id, chip::app::Clusters::MediaPlayback::Id, + chip::app::Clusters::LowPower::Id, chip::app::Clusters::KeypadInput::Id, + chip::app::Clusters::ContentLauncher::Id, chip::app::Clusters::AudioOutput::Id }; + } + return {}; +} + } // namespace AppPlatform } // namespace chip diff --git a/examples/tv-app/android/java/AppImpl.h b/examples/tv-app/android/java/AppImpl.h index 70ea36f452ac30..df257e081577dc 100644 --- a/examples/tv-app/android/java/AppImpl.h +++ b/examples/tv-app/android/java/AppImpl.h @@ -163,6 +163,11 @@ class DLL_EXPORT ContentAppFactoryImpl : public ContentAppFactory // When a vendor has admin privileges, it will get access to all clusters on ep1 Access::Privilege GetVendorPrivilege(uint16_t vendorId) override; + // Get the cluster list this vendorId/productId should have on static endpoints such as ep1 for casting video clients. + // When a vendor has admin privileges, it will get access to all clusters on ep1 + std::list GetAllowedClusterListForStaticEndpoint(EndpointId endpointId, uint16_t vendorId, + uint16_t productId) override; + void AddAdminVendorId(uint16_t vendorId); void setContentAppAttributeDelegate(ContentAppAttributeDelegate * attributeDelegate); diff --git a/examples/tv-app/android/java/TVApp-JNI.cpp b/examples/tv-app/android/java/TVApp-JNI.cpp index c59893106a8554..405554e073f950 100644 --- a/examples/tv-app/android/java/TVApp-JNI.cpp +++ b/examples/tv-app/android/java/TVApp-JNI.cpp @@ -41,9 +41,11 @@ #include #include #include +#include using namespace chip; using namespace chip::app; +using namespace chip::app::Clusters; using namespace chip::AppPlatform; using namespace chip::Credentials; @@ -201,9 +203,44 @@ class MyPostCommissioningListener : public PostCommissioningListener void CommissioningCompleted(uint16_t vendorId, uint16_t productId, NodeId nodeId, Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle) override { + // read current binding list + chip::Controller::BindingCluster cluster(exchangeMgr, sessionHandle, kTargetBindingClusterEndpointId); - ContentAppPlatform::GetInstance().ManageClientAccess( - exchangeMgr, sessionHandle, vendorId, GetDeviceCommissioner()->GetNodeId(), OnSuccessResponse, OnFailureResponse); + cacheContext(vendorId, productId, nodeId, exchangeMgr, sessionHandle); + + CHIP_ERROR err = + cluster.ReadAttribute(this, OnReadSuccessResponse, OnReadFailureResponse); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "Failed in reading binding. Error %s", ErrorStr(err)); + clearContext(); + } + } + + /* Callback when command results in success */ + static void + OnReadSuccessResponse(void * context, + const app::DataModel::DecodableList & responseData) + { + ChipLogProgress(Controller, "OnReadSuccessResponse - Binding Read Successfully"); + + MyPostCommissioningListener * listener = static_cast(context); + listener->finishTargetConfiguration(responseData); + } + + /* Callback when command results in failure */ + static void OnReadFailureResponse(void * context, CHIP_ERROR error) + { + ChipLogProgress(Controller, "OnReadFailureResponse - Binding Read Failed"); + + MyPostCommissioningListener * listener = static_cast(context); + listener->clearContext(); + + CommissionerDiscoveryController * cdc = GetCommissionerDiscoveryController(); + if (cdc != nullptr) + { + cdc->PostCommissioningFailed(error); + } } /* Callback when command results in success */ @@ -227,6 +264,60 @@ class MyPostCommissioningListener : public PostCommissioningListener cdc->PostCommissioningFailed(error); } } + + void + finishTargetConfiguration(const app::DataModel::DecodableList & responseList) + { + std::vector bindings; + NodeId localNodeId = GetDeviceCommissioner()->GetNodeId(); + + auto iter = responseList.begin(); + while (iter.Next()) + { + auto & binding = iter.GetValue(); + ChipLogProgress(Controller, "Binding found nodeId=0x" ChipLogFormatX64 " my nodeId=0x" ChipLogFormatX64, + ChipLogValueX64(binding.node.ValueOr(0)), ChipLogValueX64(localNodeId)); + if (binding.node.ValueOr(0) != localNodeId) + { + ChipLogProgress(Controller, "Found a binding for a different node, preserving"); + bindings.push_back(binding); + } + else + { + ChipLogProgress(Controller, "Found a binding for a matching node, dropping"); + } + } + + Optional opt = mSecureSession.Get(); + SessionHandle & sessionHandle = opt.Value(); + ContentAppPlatform::GetInstance().ManageClientAccess(*mExchangeMgr, sessionHandle, mVendorId, mProductId, localNodeId, + bindings, OnSuccessResponse, OnFailureResponse); + clearContext(); + } + + void cacheContext(uint16_t vendorId, uint16_t productId, NodeId nodeId, Messaging::ExchangeManager & exchangeMgr, + SessionHandle & sessionHandle) + { + mVendorId = vendorId; + mProductId = productId; + mNodeId = nodeId; + mExchangeMgr = &exchangeMgr; + mSecureSession.ShiftToSession(sessionHandle); + } + + void clearContext() + { + mVendorId = 0; + mProductId = 0; + mNodeId = 0; + mExchangeMgr = nullptr; + mSecureSession.SessionReleased(); + } + uint16_t mVendorId = 0; + uint16_t mProductId = 0; + NodeId mNodeId = 0; + Messaging::ExchangeManager * mExchangeMgr = nullptr; + SessionHolder mSecureSession; }; MyPostCommissioningListener gMyPostCommissioningListener; diff --git a/examples/tv-app/linux/AppImpl.cpp b/examples/tv-app/linux/AppImpl.cpp index 24231e5882ab33..544dbb8509e8f6 100644 --- a/examples/tv-app/linux/AppImpl.cpp +++ b/examples/tv-app/linux/AppImpl.cpp @@ -42,9 +42,11 @@ #include #include #include +#include using namespace chip; using namespace chip::AppPlatform; +using namespace chip::app::Clusters; #if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE class MyUserPrompter : public UserPrompter @@ -89,9 +91,44 @@ class MyPostCommissioningListener : public PostCommissioningListener void CommissioningCompleted(uint16_t vendorId, uint16_t productId, NodeId nodeId, Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle) override { + // read current binding list + chip::Controller::BindingCluster cluster(exchangeMgr, sessionHandle, kTargetBindingClusterEndpointId); - ContentAppPlatform::GetInstance().ManageClientAccess( - exchangeMgr, sessionHandle, vendorId, GetDeviceCommissioner()->GetNodeId(), OnSuccessResponse, OnFailureResponse); + cacheContext(vendorId, productId, nodeId, exchangeMgr, sessionHandle); + + CHIP_ERROR err = + cluster.ReadAttribute(this, OnReadSuccessResponse, OnReadFailureResponse); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "Failed in reading binding. Error %s", ErrorStr(err)); + clearContext(); + } + } + + /* Callback when command results in success */ + static void + OnReadSuccessResponse(void * context, + const app::DataModel::DecodableList & responseData) + { + ChipLogProgress(Controller, "OnReadSuccessResponse - Binding Read Successfully"); + + MyPostCommissioningListener * listener = static_cast(context); + listener->finishTargetConfiguration(responseData); + } + + /* Callback when command results in failure */ + static void OnReadFailureResponse(void * context, CHIP_ERROR error) + { + ChipLogProgress(Controller, "OnReadFailureResponse - Binding Read Failed"); + + MyPostCommissioningListener * listener = static_cast(context); + listener->clearContext(); + + CommissionerDiscoveryController * cdc = GetCommissionerDiscoveryController(); + if (cdc != nullptr) + { + cdc->PostCommissioningFailed(error); + } } /* Callback when command results in success */ @@ -115,6 +152,60 @@ class MyPostCommissioningListener : public PostCommissioningListener cdc->PostCommissioningFailed(error); } } + + void + finishTargetConfiguration(const app::DataModel::DecodableList & responseList) + { + std::vector bindings; + NodeId localNodeId = GetDeviceCommissioner()->GetNodeId(); + + auto iter = responseList.begin(); + while (iter.Next()) + { + auto & binding = iter.GetValue(); + ChipLogProgress(Controller, "Binding found nodeId=0x" ChipLogFormatX64 " my nodeId=0x" ChipLogFormatX64, + ChipLogValueX64(binding.node.ValueOr(0)), ChipLogValueX64(localNodeId)); + if (binding.node.ValueOr(0) != localNodeId) + { + ChipLogProgress(Controller, "Found a binding for a different node, preserving"); + bindings.push_back(binding); + } + else + { + ChipLogProgress(Controller, "Found a binding for a matching node, dropping"); + } + } + + Optional opt = mSecureSession.Get(); + SessionHandle & sessionHandle = opt.Value(); + ContentAppPlatform::GetInstance().ManageClientAccess(*mExchangeMgr, sessionHandle, mVendorId, mProductId, localNodeId, + bindings, OnSuccessResponse, OnFailureResponse); + clearContext(); + } + + void cacheContext(uint16_t vendorId, uint16_t productId, NodeId nodeId, Messaging::ExchangeManager & exchangeMgr, + SessionHandle & sessionHandle) + { + mVendorId = vendorId; + mProductId = productId; + mNodeId = nodeId; + mExchangeMgr = &exchangeMgr; + mSecureSession.ShiftToSession(sessionHandle); + } + + void clearContext() + { + mVendorId = 0; + mProductId = 0; + mNodeId = 0; + mExchangeMgr = nullptr; + mSecureSession.SessionReleased(); + } + uint16_t mVendorId = 0; + uint16_t mProductId = 0; + NodeId mNodeId = 0; + Messaging::ExchangeManager * mExchangeMgr = nullptr; + SessionHolder mSecureSession; }; MyPostCommissioningListener gMyPostCommissioningListener; @@ -407,6 +498,19 @@ Access::Privilege ContentAppFactoryImpl::GetVendorPrivilege(uint16_t vendorId) return Access::Privilege::kOperate; } +std::list ContentAppFactoryImpl::GetAllowedClusterListForStaticEndpoint(EndpointId endpointId, uint16_t vendorId, + uint16_t productId) +{ + if (endpointId == kLocalVideoPlayerEndpointId) + { + return { chip::app::Clusters::Descriptor::Id, chip::app::Clusters::OnOff::Id, + chip::app::Clusters::WakeOnLan::Id, chip::app::Clusters::MediaPlayback::Id, + chip::app::Clusters::LowPower::Id, chip::app::Clusters::KeypadInput::Id, + chip::app::Clusters::ContentLauncher::Id, chip::app::Clusters::AudioOutput::Id }; + } + return {}; +} + } // namespace AppPlatform } // namespace chip diff --git a/examples/tv-app/linux/AppImpl.h b/examples/tv-app/linux/AppImpl.h index 68c96d135e0630..46cdb650bd38c8 100644 --- a/examples/tv-app/linux/AppImpl.h +++ b/examples/tv-app/linux/AppImpl.h @@ -131,6 +131,11 @@ class DLL_EXPORT ContentAppFactoryImpl : public ContentAppFactory // When a vendor has admin privileges, it will get access to all clusters on ep1 Access::Privilege GetVendorPrivilege(uint16_t vendorId) override; + // Get the cluster list this vendorId/productId should have on static endpoints such as ep1 for casting video clients. + // When a vendor has admin privileges, it will get access to all clusters on ep1 + std::list GetAllowedClusterListForStaticEndpoint(EndpointId endpointId, uint16_t vendorId, + uint16_t productId) override; + void AddAdminVendorId(uint16_t vendorId); protected: diff --git a/examples/window-app/efr32/src/WindowAppImpl.cpp b/examples/window-app/efr32/src/WindowAppImpl.cpp index 7f9eeaca724f0d..2675b7398d50a1 100644 --- a/examples/window-app/efr32/src/WindowAppImpl.cpp +++ b/examples/window-app/efr32/src/WindowAppImpl.cpp @@ -26,6 +26,10 @@ #include #ifdef QR_CODE_ENABLED #include +#else +#include "EFR32DeviceDataProvider.h" +#include +#include #endif // QR_CODE_ENABLED #include @@ -54,6 +58,8 @@ SilabsLCD slLCD; #define LCD_ICON_TIMEOUT 1000 using namespace chip::app::Clusters::WindowCovering; +using namespace chip; +using namespace ::chip::DeviceLayer; #define APP_STATE_LED &sl_led_led0 #define APP_ACTION_LED &sl_led_led1 @@ -212,6 +218,21 @@ CHIP_ERROR WindowAppImpl::Init() slLCD.Init(); #endif +#ifndef QR_CODE_ENABLED + // Create buffer for QR code that can fit max size and null terminator. + char qrCodeBuffer[chip::QRCodeBasicSetupPayloadGenerator::kMaxQRCodeBase38RepresentationLength + 1]; + chip::MutableCharSpan QRCode(qrCodeBuffer); + + if (EFR32::EFR32DeviceDataProvider::GetDeviceDataProvider().GetSetupPayload(QRCode) == CHIP_NO_ERROR) + { + PrintQrCodeURL(QRCode); + } + else + { + EFR32_LOG("Getting QR code failed!"); + } +#endif // QR_CODE_ENABLED + return CHIP_NO_ERROR; } diff --git a/integrations/cloudbuild/build-all.yaml b/integrations/cloudbuild/build-all.yaml index 17c343b0b0b2b2..e0dbcfaa61467c 100644 --- a/integrations/cloudbuild/build-all.yaml +++ b/integrations/cloudbuild/build-all.yaml @@ -6,7 +6,7 @@ steps: - "--init" - "--recursive" id: Submodules - - name: "connectedhomeip/chip-build-vscode:0.6.05" + - name: "connectedhomeip/chip-build-vscode:0.6.06" env: - PW_ENVIRONMENT_ROOT=/pwenv args: @@ -21,7 +21,7 @@ steps: path: /pwenv timeout: 900s - - name: "connectedhomeip/chip-build-vscode:0.6.05" + - name: "connectedhomeip/chip-build-vscode:0.6.06" env: - PW_ENVIRONMENT_ROOT=/pwenv args: diff --git a/integrations/cloudbuild/chef.yaml b/integrations/cloudbuild/chef.yaml index d8cf8c82655b3b..7abdf02bf9d3c9 100644 --- a/integrations/cloudbuild/chef.yaml +++ b/integrations/cloudbuild/chef.yaml @@ -1,5 +1,5 @@ steps: - - name: "connectedhomeip/chip-build-vscode:0.6.05" + - name: "connectedhomeip/chip-build-vscode:0.6.06" env: - PW_ENVIRONMENT_ROOT=/pwenv args: @@ -12,7 +12,7 @@ steps: path: /pwenv timeout: 2700s - - name: "connectedhomeip/chip-build-vscode:0.6.05" + - name: "connectedhomeip/chip-build-vscode:0.6.06" env: - PW_ENVIRONMENT_ROOT=/pwenv args: @@ -26,7 +26,7 @@ steps: - name: pwenv path: /pwenv - - name: "connectedhomeip/chip-build-vscode:0.6.05" + - name: "connectedhomeip/chip-build-vscode:0.6.06" env: - PW_ENVIRONMENT_ROOT=/pwenv args: diff --git a/integrations/cloudbuild/smoke-test.yaml b/integrations/cloudbuild/smoke-test.yaml index 23cec5dec9f84a..a5d491519965b2 100644 --- a/integrations/cloudbuild/smoke-test.yaml +++ b/integrations/cloudbuild/smoke-test.yaml @@ -1,5 +1,5 @@ steps: - - name: "connectedhomeip/chip-build-vscode:0.6.05" + - name: "connectedhomeip/chip-build-vscode:0.6.06" entrypoint: "bash" args: - "-c" @@ -7,7 +7,7 @@ steps: git config --global --add safe.directory "*" git submodule update --init --recursive id: Submodules - - name: "connectedhomeip/chip-build-vscode:0.6.05" + - name: "connectedhomeip/chip-build-vscode:0.6.06" env: - PW_ENVIRONMENT_ROOT=/pwenv args: @@ -22,7 +22,7 @@ steps: path: /pwenv timeout: 900s - - name: "connectedhomeip/chip-build-vscode:0.6.05" + - name: "connectedhomeip/chip-build-vscode:0.6.06" id: ESP32 env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -41,7 +41,7 @@ steps: - name: pwenv path: /pwenv - - name: "connectedhomeip/chip-build-vscode:0.6.05" + - name: "connectedhomeip/chip-build-vscode:0.6.06" id: NRFConnect env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -62,7 +62,7 @@ steps: - name: pwenv path: /pwenv - - name: "connectedhomeip/chip-build-vscode:0.6.05" + - name: "connectedhomeip/chip-build-vscode:0.6.06" id: EFR32 env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -84,7 +84,7 @@ steps: - name: pwenv path: /pwenv - - name: "connectedhomeip/chip-build-vscode:0.6.05" + - name: "connectedhomeip/chip-build-vscode:0.6.06" id: Linux env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -142,7 +142,7 @@ steps: - name: pwenv path: /pwenv - - name: "connectedhomeip/chip-build-vscode:0.6.05" + - name: "connectedhomeip/chip-build-vscode:0.6.06" id: Android env: - PW_ENVIRONMENT_ROOT=/pwenv diff --git a/integrations/docker/images/chip-build/Dockerfile b/integrations/docker/images/chip-build/Dockerfile index 782aa74f64afea..d53978c727c8f3 100644 --- a/integrations/docker/images/chip-build/Dockerfile +++ b/integrations/docker/images/chip-build/Dockerfile @@ -49,6 +49,7 @@ RUN set -x \ libusb-dev \ libxml2-dev \ make \ + meson \ net-tools \ ninja-build \ openjdk-8-jdk \ @@ -131,3 +132,19 @@ RUN set -x \ && cd .. \ && rm -rf node_js \ && : # last line + +# Build glib-2.0 from source with enabled thread sanitizer. This is needed for +# running CHIP tests with TSAN enabled. When running applications with TSAN +# all shared libraries should be built with TSAN enabled, otherwise TSAN might +# report false positives. This case is most prominent with glib-2.0, which has +# a lot of threads-related APIs. +ENV LD_LIBRARY_PATH_TSAN=/usr/lib/x86_64-linux-gnu-tsan +RUN set -x \ + && mkdir -p $LD_LIBRARY_PATH_TSAN \ + && GLIB_VERSION=$(pkg-config --modversion glib-2.0) \ + && git clone --depth=1 --branch=$GLIB_VERSION https://github.com/GNOME/glib.git \ + && CFLAGS="-O2 -g -fsanitize=thread" meson glib/build glib \ + && DESTDIR=../build-image ninja -C glib/build install \ + && mv glib/build-image/usr/local/lib/x86_64-linux-gnu/lib* $LD_LIBRARY_PATH_TSAN \ + && rm -rf glib \ + && : # last line diff --git a/integrations/docker/images/chip-build/version b/integrations/docker/images/chip-build/version index 31a9e441a4fc04..00402354e9ff3b 100644 --- a/integrations/docker/images/chip-build/version +++ b/integrations/docker/images/chip-build/version @@ -1 +1 @@ -0.6.06 Version bump reason: [Telink] Update Telink Docker. +0.6.07 Version bump reason: Build glib-2.0 libs with TSAN diff --git a/scripts/tools/telink/generate_telink_chip_factory_data.py b/scripts/tools/telink/generate_telink_chip_factory_data.py new file mode 100644 index 00000000000000..2ec9b888accbc9 --- /dev/null +++ b/scripts/tools/telink/generate_telink_chip_factory_data.py @@ -0,0 +1,492 @@ +#!/usr/bin/env python3 +# +# 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. +# + +from os.path import exists +import os +import sys +import json +import jsonschema +import secrets +import argparse +import subprocess +import logging as log +import base64 +from collections import namedtuple +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives.serialization import load_der_private_key + +# A user can not change the factory data version and must be coherent with +# the factory data version set in the Telink platform Kconfig file (CHIP_FACTORY_DATA_VERSION). +FACTORY_DATA_VERSION = 1 + +MATTER_ROOT = os.path.dirname(os.path.realpath(__file__))[:-len("/scripts/tools/telink")] +HEX_PREFIX = "hex:" +PUB_KEY_PREFIX = b'\x04' +INVALID_PASSCODES = [00000000, 11111111, 22222222, 33333333, 44444444, + 55555555, 66666666, 77777777, 88888888, 99999999, 12345678, 87654321] + + +def get_raw_private_key_der(der_file: str, password: str): + """ Split given der file to get separated key pair consisting of public and private keys. + + Args: + der_file (str): Path to .der file containing public and private keys + password (str): Password to decrypt Keys. It can be None, and then KEY is not encrypted. + + Returns: + hex string: return a hex string containing extracted and decrypted private KEY from given .der file. + """ + try: + with open(der_file, 'rb') as file: + key_data = file.read() + if password is None: + log.warning("KEY password has not been provided. It means that DAC key is not encrypted.") + keys = load_der_private_key(key_data, password, backend=default_backend()) + private_key = keys.private_numbers().private_value.to_bytes(32, byteorder='big') + + return private_key + + except IOError or ValueError: + return None + + +def gen_test_certs(chip_cert_exe: str, + output: str, + vendor_id: int, + product_id: int, + device_name: str, + generate_cd: bool = False, + cd_type: int = 1, + paa_cert_path: str = None, + paa_key_path: str = None): + """ + Generate Matter certificates according to given Vendor ID and Product ID using the chip-cert executable. + To use own Product Attestation Authority certificate provide paa_cert_path and paa_key_path arguments. + Without providing these arguments a PAA certificate will be get from /credentials/test/attestation directory + in the Matter repository. + + Args: + chip_cert_exe (str): path to chip-cert executable + output (str): output path to store a newly generated certificates (CD, DAC, PAI) + vendor_id (int): an identification number specific to Vendor + product_id (int): an identification number specific to Product + device_name (str): human-readable device name + generate_cd (bool, optional): Generate Certificate Declaration and store it in thee output directory. Defaults to False. + paa_cert_path (str, optional): provide PAA certification path. Defaults to None - a path will be set to /credentials/test/attestation directory. + paa_key_path (str, optional): provide PAA key path. Defaults to None - a path will be set to /credentials/test/attestation directory. + + Returns: + dictionary: ["PAI_CERT": (str), + "DAC_CERT": (str), + "DAC_KEY": (str)] + """ + + CD_PATH = MATTER_ROOT + "/credentials/test/certification-declaration/Chip-Test-CD-Signing-Cert.pem" + CD_KEY_PATH = MATTER_ROOT + "/credentials/test/certification-declaration/Chip-Test-CD-Signing-Key.pem" + PAA_PATH = paa_cert_path if paa_cert_path != None else MATTER_ROOT + "/credentials/test/attestation/Chip-Test-PAA-NoVID-Cert.pem" + PAA_KEY_PATH = paa_key_path if paa_key_path != None else MATTER_ROOT + "/credentials/test/attestation/Chip-Test-PAA-NoVID-Key.pem" + + attestation_certs = namedtuple("attestation_certs", ["dac_cert", "dac_key", "pai_cert"]) + + log.info("Generating new certificates using chip-cert...") + + if generate_cd: + # generate Certification Declaration + cmd = [chip_cert_exe, "gen-cd", + "--key", CD_KEY_PATH, + "--cert", CD_PATH, + "--out", output + "/CD.der", + "--format-version", "1", + "--vendor-id", hex(vendor_id), + "--product-id", hex(product_id), + "--device-type-id", "0", + "--certificate-id", "FFFFFFFFFFFFFFFFFFF", + "--security-level", "0", + "--security-info", "0", + "--certification-type", str(cd_type), + "--version-number", "0xFFFF", + ] + subprocess.run(cmd) + + new_certificates = {"PAI_CERT": output + "/PAI_cert", + "PAI_KEY": output + "/PAI_key", + "DAC_CERT": output + "/DAC_cert", + "DAC_KEY": output + "/DAC_key" + } + + # generate PAI + cmd = [chip_cert_exe, "gen-att-cert", + "-t", "i", + "-c", device_name, + "-V", hex(vendor_id), + "-C", PAA_PATH, + "-K", PAA_KEY_PATH, + "-o", new_certificates["PAI_CERT"] + ".pem", + "-O", new_certificates["PAI_KEY"] + ".pem", + "-l", str(10000), + ] + subprocess.run(cmd) + + # generate DAC + cmd = [chip_cert_exe, "gen-att-cert", + "-t", "d", + "-c", device_name, + "-V", hex(vendor_id), + "-P", hex(product_id), + "-C", new_certificates["PAI_CERT"] + ".pem", + "-K", new_certificates["PAI_KEY"] + ".pem", + "-o", new_certificates["DAC_CERT"] + ".pem", + "-O", new_certificates["DAC_KEY"] + ".pem", + "-l", str(10000), + ] + subprocess.run(cmd) + + # convert to .der files + for cert_k, cert_v in new_certificates.items(): + action_type = "convert-cert" if cert_k.find("CERT") != -1 else "convert-key" + log.info(cert_v + ".der") + cmd = [chip_cert_exe, action_type, + cert_v + ".pem", + cert_v + ".der", + "--x509-der", + ] + subprocess.run(cmd) + + return attestation_certs(new_certificates["DAC_CERT"] + ".der", + new_certificates["DAC_KEY"] + ".der", + new_certificates["PAI_CERT"] + ".der") + + +def gen_spake2p_params(spake2p_path: str, passcode: int, it: int, salt: bytes) -> dict: + """ Generate Spake2+ params using external spake2p tool + + Args: + spake2p_path (str): path to spake2p executable + passcode (int): Pairing passcode using in Spake2+ + it (int): Iteration counter for Spake2+ verifier generation + salt (str): Salt used to generate Spake2+ verifier + + Returns: + dict: dictionary containing passcode, it, salt, and generated Verifier + """ + + cmd = [ + spake2p_path, 'gen-verifier', + '--iteration-count', str(it), + '--salt', base64.b64encode(salt), + '--pin-code', str(passcode), + '--out', '-', + ] + output = subprocess.check_output(cmd) + output = output.decode('utf-8').splitlines() + return dict(zip(output[0].split(','), output[1].split(','))) + + +class FactoryDataGenerator: + """ + Class to generate factory data from given arguments and generate a JSON file + + """ + + def __init__(self, arguments) -> None: + """ + Args: + arguments (any):All input arguments parsed using ArgParse + """ + self._args = arguments + self._factory_data = list() + self._user_data = dict() + + try: + self._validate_args() + except AssertionError as e: + log.error(e) + sys.exit(-1) + + def _validate_args(self): + if self._args.user: + try: + self._user_data = json.loads(self._args.user) + except json.decoder.JSONDecodeError as e: + raise AssertionError("Provided wrong user data, this is not a JSON format! {}".format(e)) + assert (self._args.spake2_verifier or (self._args.passcode and self._args.spake2p_path)), \ + "Cannot find Spake2+ verifier, to generate a new one please provide passcode (--passcode) and path to spake2p tool (--spake2p_path)" + assert (self._args.chip_cert_path or (self._args.dac_cert and self._args.pai_cert and self._args.dac_key)), \ + "Cannot find paths to DAC or PAI certificates .der files. To generate a new ones please provide a path to chip-cert executable (--chip_cert_path)" + assert self._args.output.endswith(".json"), \ + "Output path doesn't contain .json file path. ({})".format(self._args.output) + assert not (self._args.passcode in INVALID_PASSCODES), \ + "Provided invalid passcode!" + + def generate_json(self): + """ + This function generates JSON data, .json file and validates it. + + To validate generated JSON data a scheme must be provided within script's arguments. + + - In the first part, if the rotating device id unique id has been not provided + as an argument, it will be created. + - If user-provided passcode and Spake2+ verifier have been not provided + as an argument, it will be created using an external script + - Passcode is not stored in JSON by default. To store it for debugging purposes, add --include_passcode argument. + - Validating output JSON is not mandatory, but highly recommended. + + """ + # generate missing data if needed + if not self._args.rd_uid: + if self._args.generate_rd_uid: + rd_uid = self._generate_rotating_device_uid() + else: + # rotating device ID unique ID was not provided, so do not store it in factory data. + rd_uid = None + else: + rd_uid = HEX_PREFIX + self._args.rd_uid + + if not self._args.spake2_verifier: + spake_2_verifier = self._generate_spake2_verifier() + else: + spake_2_verifier = self._args.spake2_verifier + + # convert salt to bytestring to be coherent with Spake2+ verifier type + spake_2_salt = self._args.spake2_salt + + if self._args.chip_cert_path: + certs = gen_test_certs(self._args.chip_cert_path, + self._args.output[:self._args.output.rfind("/")], + self._args.vendor_id, + self._args.product_id, + self._args.vendor_name + "_" + self._args.product_name, + self._args.gen_cd, + self._args.cd_type, + self._args.paa_cert, + self._args.paa_key) + dac_cert = certs.dac_cert + pai_cert = certs.pai_cert + dac_key = certs.dac_key + else: + dac_cert = self._args.dac_cert + dac_key = self._args.dac_key + pai_cert = self._args.pai_cert + + # try to read DAC public and private keys + dac_priv_key = get_raw_private_key_der(dac_key, self._args.dac_key_password) + if dac_priv_key is None: + log.error("Cannot read DAC keys from : {}".format(dac_key)) + sys.exit(-1) + + try: + json_file = open(self._args.output, "w+") + except FileNotFoundError: + print("Cannot create JSON file in this location: {}".format(self._args.output)) + sys.exit(-1) + with json_file: + # serialize data + self._add_entry("version", FACTORY_DATA_VERSION) + self._add_entry("sn", self._args.sn) + self._add_entry("vendor_id", self._args.vendor_id) + self._add_entry("product_id", self._args.product_id) + self._add_entry("vendor_name", self._args.vendor_name) + self._add_entry("product_name", self._args.product_name) + self._add_entry("date", self._args.date) + self._add_entry("hw_ver", self._args.hw_ver) + self._add_entry("hw_ver_str", self._args.hw_ver_str) + self._add_entry("dac_cert", self._process_der(dac_cert)) + self._add_entry("dac_key", dac_priv_key) + self._add_entry("pai_cert", self._process_der(pai_cert)) + if self._args.include_passcode: + self._add_entry("passcode", self._args.passcode) + self._add_entry("spake2_it", self._args.spake2_it) + self._add_entry("spake2_salt", spake_2_salt) + self._add_entry("spake2_verifier", spake_2_verifier) + self._add_entry("discriminator", self._args.discriminator) + if rd_uid: + self._add_entry("rd_uid", rd_uid) + if self._args.enable_key: + self._add_entry("enable_key", HEX_PREFIX + self._args.enable_key) + if self._args.user: + self._add_entry("user", self._args.user) + + factory_data_dict = dict(self._factory_data) + + json_object = json.dumps(factory_data_dict) + is_json_valid = True + + if self._args.schema: + is_json_valid = self._validate_output_json(json_object) + else: + log.warning("JSON Schema file has not been provided, the output file can be wrong. Be aware of that.") + try: + if is_json_valid: + json_file.write(json_object) + except IOError as e: + log.error("Cannot save output file into directory: {}".format(self._args.output)) + + def _add_entry(self, name: str, value: any): + """ Add single entry to list of tuples ("key", "value") """ + if(isinstance(value, bytes) or isinstance(value, bytearray)): + value = HEX_PREFIX + value.hex() + if value or (isinstance(value, int) and value == 0): + log.debug("Adding entry '{}' with size {} and type {}".format(name, sys.getsizeof(value), type(value))) + self._factory_data.append((name, value)) + + def _generate_spake2_verifier(self): + """ If verifier has not been provided in arguments list it should be generated via external script """ + spake2_params = gen_spake2p_params(self._args.spake2p_path, self._args.passcode, + self._args.spake2_it, self._args.spake2_salt) + return base64.b64decode(spake2_params["Verifier"]) + + def _generate_rotating_device_uid(self): + """ If rotating device unique ID has not been provided it should be generated """ + log.warning("Cannot find rotating device UID in provided arguments list. A new one will be generated.") + rdu = secrets.token_bytes(16) + log.info("\n\nThe new rotate device UID: {}\n".format(rdu.hex())) + return rdu + + def _validate_output_json(self, output_json: str): + """ + Validate output JSON data with provided .scheme file + This function will raise error if JSON does not match schema. + + """ + try: + with open(self._args.schema) as schema_file: + log.info("Validating JSON with schema...") + schema = json.loads(schema_file.read()) + validator = jsonschema.Draft202012Validator(schema=schema) + validator.validate(instance=json.loads(output_json)) + except IOError as e: + log.error("Provided JSON schema file is wrong: {}".format(self._args.schema)) + return False + else: + log.info("Validate OK") + return True + + def _process_der(self, path: str): + log.debug("Processing der file...") + try: + with open(path, 'rb') as f: + data = f.read() + return data + except IOError as e: + log.error(e) + raise e + + +def main(): + parser = argparse.ArgumentParser(description="Telink Factory Data NVS generator tool") + + def allow_any_int(i): return int(i, 0) + def base64_str(s): return base64.b64decode(s) + + mandatory_arguments = parser.add_argument_group("Mandatory keys", "These arguments must be provided to generate JSON file") + optional_arguments = parser.add_argument_group( + "Optional keys", "These arguments are optional and they depend on the user-purpose") + parser.add_argument("-s", "--schema", type=str, + help="JSON schema file to validate JSON output data") + parser.add_argument("-o", "--output", type=str, required=True, + help="Output path to store .json file, e.g. my_dir/output.json") + parser.add_argument("-v", "--verbose", action="store_true", + help="Run this script with DEBUG logging level") + parser.add_argument("--include_passcode", action="store_true", + help="Include passcode in factory data. By default, it is used only for generating Spake2+ verifier.") + parser.add_argument("--overwrite", action="store_true", + help="If output JSON file exist this argument allows to generate new factory data and overwrite it.") + # Json known-keys values + # mandatory keys + mandatory_arguments.add_argument("--sn", type=str, required=True, + help="[ascii string] Serial number of a device which can be used to identify \ + the serial number field in the Matter certificate structure. \ + Maximum length of serial number is 20 bytes. \ + Strings longer than 20 bytes will be declined in script") + mandatory_arguments.add_argument("--vendor_id", type=allow_any_int, + help="[int | hex int] Provide Vendor Identification Number") + mandatory_arguments.add_argument("--product_id", type=allow_any_int, + help="[int | hex int] Provide Product Identification Number") + mandatory_arguments.add_argument("--vendor_name", type=str, + help="[string] provide human-readable vendor name") + mandatory_arguments.add_argument("--product_name", type=str, + help="[string] provide human-readable product name") + mandatory_arguments.add_argument("--date", type=str, required=True, + help="[ascii string] Provide manufacturing date \ + A manufacturing date specifies the date that the Node was manufactured. \ + Used format for providing a manufacturing date is ISO 8601 e.g. YYYY-MM-DD.") + mandatory_arguments.add_argument("--hw_ver", type=allow_any_int, required=True, + help="[int | hex int] Provide hardware version in int format.") + mandatory_arguments.add_argument("--hw_ver_str", type=str, required=True, + help="[ascii string] Provide hardware version in string format.") + mandatory_arguments.add_argument("--spake2_it", type=allow_any_int, required=True, + help="[int | hex int] Provide Spake2+ iteration count.") + mandatory_arguments.add_argument("--spake2_salt", type=base64_str, required=True, + help="[base64 string] Provide Spake2+ salt.") + mandatory_arguments.add_argument("--discriminator", type=allow_any_int, required=True, + help="[int] Provide BLE pairing discriminator. \ + A 12-bit value matching the field of the same name in \ + the setup code. Discriminator is used during a discovery process.") + + # optional keys + optional_arguments.add_argument("--chip_cert_path", type=str, + help="Generate DAC and PAI certificates instead giving a path to .der files. This option requires a path to chip-cert executable." + "By default You can find spake2p in connectedhomeip/src/tools/chip-cert directory and build it there.") + optional_arguments.add_argument("--dac_cert", type=str, + help="[.der] Provide the path to .der file containing DAC certificate.") + optional_arguments.add_argument("--dac_key", type=str, + help="[.der] Provide the path to .der file containing DAC keys.") + optional_arguments.add_argument("--generate_rd_uid", action="store_true", + help="Generate a new rotating device unique ID, print it out to console output and store it in factory data.") + optional_arguments.add_argument("--dac_key_password", type=str, + help="Provide a password to decode dac key. If dac key is not encrypted do not provide this argument.") + optional_arguments.add_argument("--pai_cert", type=str, + help="[.der] Provide the path to .der file containing PAI certificate.") + optional_arguments.add_argument("--rd_uid", type=str, + help="[hex string] [128-bit hex-encoded] Provide the rotating device unique ID. If this argument is not provided a new rotating device id unique id will be generated.") + optional_arguments.add_argument("--passcode", type=allow_any_int, + help="[int | hex] Default PASE session passcode. (This is mandatory to generate Spake2+ verifier).") + optional_arguments.add_argument("--spake2p_path", type=str, + help="[string] Provide a path to spake2p. By default You can find spake2p in connectedhomeip/src/tools/spake2p directory and build it there.") + optional_arguments.add_argument("--spake2_verifier", type=base64_str, + help="[base64 string] Provide Spake2+ verifier without generating it.") + optional_arguments.add_argument("--enable_key", type=str, + help="[hex string] [128-bit hex-encoded] The Enable Key is a 128-bit value that triggers manufacturer-specific action while invoking the TestEventTrigger Command." + "This value is used during Certification Tests, and should not be present on production devices.") + optional_arguments.add_argument("--user", type=str, + help="[string] Provide additional user-specific keys in JSON format: {'name_1': 'value_1', 'name_2': 'value_2', ... 'name_n', 'value_n'}.") + optional_arguments.add_argument("--gen_cd", action="store_true", default=False, + help="Generate a new Certificate Declaration in .der format according to used Vendor ID and Product ID. This certificate will not be included to the factory data.") + optional_arguments.add_argument("--cd_type", type=int, default=1, + help="[int] Type of generated Certification Declaration: 0 - development, 1 - provisional, 2 - official") + optional_arguments.add_argument("--paa_cert", type=str, + help="Provide a path to the Product Attestation Authority (PAA) certificate to generate the PAI certificate. Without providing it, a testing PAA stored in the Matter repository will be used.") + optional_arguments.add_argument("--paa_key", type=str, + help="Provide a path to the Product Attestation Authority (PAA) key to generate the PAI certificate. Without providing it, a testing PAA key stored in the Matter repository will be used.") + args = parser.parse_args() + + if args.verbose: + log.basicConfig(format='[%(asctime)s][%(levelname)s] %(message)s', level=log.DEBUG) + else: + log.basicConfig(format='[%(levelname)s] %(message)s', level=log.INFO) + + # check if json file already exist + if(exists(args.output) and not args.overwrite): + log.error("Output file: {} already exist, to create a new one add argument '--overwrite'. By default overwriting is disabled".format(args.output)) + return + + generator = FactoryDataGenerator(args) + generator.generate_json() + + +if __name__ == "__main__": + main() diff --git a/scripts/tools/telink/telink_factory_data.schema b/scripts/tools/telink/telink_factory_data.schema new file mode 100644 index 00000000000000..16ffcc68dbd47b --- /dev/null +++ b/scripts/tools/telink/telink_factory_data.schema @@ -0,0 +1,147 @@ +{ + "$id": "Telink_Factory_Data_schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "A representation of all factory data used in Matter's Telink device", + "type": "object", + "required": [ + "version", + "sn", + "vendor_id", + "product_id", + "vendor_name", + "product_name", + "date", + "hw_ver", + "hw_ver_str", + "dac_cert", + "dac_key", + "pai_cert", + "spake2_it", + "spake2_salt", + "spake2_verifier", + "discriminator" + ], + "properties": { + "version": { + "description": "Current version of the factory data set", + "type": "integer", + "minimum": 0, + "maximum": 255 + }, + "sn": { + "description": "Serial number of device", + "type": "string", + "maxLength": 32 + }, + "vendor_id": { + "description": "Vendor Identifier", + "type": "integer", + "minimum": 0, + "maximum": 65524 + }, + "product_id": { + "description": "Product Identifier", + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "vendor_name": { + "description": "human-readable vendor name", + "type": "string", + "maxLength": 32 + }, + "product_name": { + "description": "human-readable product name", + "type": "string", + "maxLength": 32 + }, + "date": { + "description": "Manufacturing date according to ISO 8601 in notation YYYY-MM-DD", + "type": "string", + "format": "date" + }, + "hw_ver": { + "description": "Hardware version - integer", + "type": "integer", + "minimum": 0, + "maximum": 65536 + }, + "hw_ver_str": { + "description": "A string representation of hardware version", + "type": "string", + "minLength": 1, + "maxLength": 64 + }, + "rd_uid": { + "description": "A randomly-generated 128-bit or longer octet string. Length has been expanded with 'hex:' prefix", + "type": "string", + "pattern:": "^hex:{1}", + "minLength": 20, + "minLength": 5, + "maxLength": 36 + }, + "dac_cert": { + "description": "DAC certificate in hex-string format", + "type": "string", + "pattern:": "^hex:{1}([0-9A-Fa-f]){2,}", + "minLength": 5, + "maxLength": 1204 + }, + "dac_key": { + "description": "DAC Private Key in hex-string format", + "type": "string", + "pattern:": "^hex:{1}([0-9A-Fa-f]){2,}", + "minLength": 68, + "maxLength": 68 + }, + "pai_cert": { + "description": "PAI certificate in hex-string format", + "type": "string", + "pattern:": "^hex:{1}([0-9A-Fa-f]){2,}", + "minLength": 5, + "maxLength": 1204 + }, + "passcode": { + "description": "A default PASE session passcode", + "type": "integer", + "minimum": 1, + "maximum": 99999998 + }, + "spake2_it": { + "description": "An Iteration counter for the Symmetric Password-Authenticated Key Exchange", + "type": "integer", + "minimum": 1000, + "maximum": 100000 + }, + "spake2_salt": { + "description": "A key-derivation function for the Symmetric Password-Authenticated Key Exchange.", + "type": "string", + "pattern:": "^hex:{1}([0-9A-Fa-f]){2,}", + "minLength": 36, + "maxLength": 68 + }, + "spake2_verifier": { + "description": "A verifier for the Symmetric Password-Authenticated Key Exchange", + "type": "string", + "pattern:": "^hex:{1}([0-9A-Fa-f]){2,}", + "minLength": 97 + }, + "discriminator": { + "description": "The Discriminator value helps to further identify potential devices during the setup process.", + "type": "integer", + "minimum": 0, + "maximum": 4095 + }, + "enable_key": { + "description": "The Enable Key is a 128-bit value that triggers manufacturer-specific action while invoking the TestEventTrigger Command", + "type": "string", + "pattern": "^hex:{1}([0-9A-Fa-f]){32}", + "minLength": 36, + "maxLength": 36 + }, + "user": { + "description": "A user-specific additional data which should be added to factory data. This should be a Json format.", + "type": "object" + } + } +} \ No newline at end of file diff --git a/scripts/tools/telink/telink_generate_partition.py b/scripts/tools/telink/telink_generate_partition.py new file mode 100644 index 00000000000000..ddd3b63acc4a7f --- /dev/null +++ b/scripts/tools/telink/telink_generate_partition.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python3 +# +# 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 codecs +import sys +from intelhex import IntelHex +import argparse +import json +import logging as log +import cbor2 as cbor + +HEX_PREFIX = "hex:" + + +class PartitionCreator: + """ + Class to create telink partition containing FactoryData + + :param offset: This is a partition offset where data will be stored in device's flash memory + :param length: This is a maximum partition size + :param input: This is a path to input JSON file + :param output: This is a path to output directory + + """ + + def __init__(self, offset: int, length: int, input: str, output: str) -> None: + self._ih = IntelHex() + self._length = length + self._offset = offset + self._data_ready = False + self._output = output + self._input = input + try: + self.__data_to_save = self._convert_to_dict(self._load_json()) + except IOError: + sys.exit(-1) + + def generate_cbor(self): + """ + Generates .cbor file using cbor2 library. + It generate a CBORTag 55799 which is user-specific tag + + """ + if self.__data_to_save: + # prepare raw data from Json + cbor_data = cbor.dumps(self.__data_to_save) + return cbor_data + + def create_hex(self, data: bytes): + """ + Creates .hex file from CBOR. + This file can be write directly to device. + + """ + if len(data) > self._length: + raise ValueError("generated CBOR file exceeds declared maximum partition size! {} > {}".format(len(data), self._length)) + self._ih.putsz(self._offset, data) + self._ih.write_hex_file(self._output + ".hex", True) + self._data_ready = True + return True + + def create_bin(self): + """ + Creates raw binary data of created previously .hex file + + """ + if not self._data_ready: + log.error("Please create hex file first!") + return False + self._ih.tobinfile(self._output + ".bin") + return True + + @staticmethod + def _convert_to_dict(data): + """ + Converts a list containing tuples ("key_name", "key_value") to a dictionary + + If "key_value" of data entry is a string-type variable and contains a HEX_PREFIX algorithm decodes it + to hex format to be sure that a cbor file will contain proper bytes. + + If "key_value" of data entry is a dictionary, algorithm appends it to the created dictionary. + """ + output_dict = dict() + for entry in data: + if not isinstance(entry, dict): + log.debug("Processing entry {}".format(entry)) + if isinstance(data[entry], str) and data[entry].startswith(HEX_PREFIX): + output_dict[entry] = codecs.decode(data[entry][len(HEX_PREFIX):], "hex") + elif isinstance(data[entry], str): + output_dict[entry] = data[entry].encode("utf-8") + else: + output_dict[entry] = data[entry] + else: + output_dict[entry] = entry + return output_dict + + def _load_json(self): + """ + Loads file containing a JSON data and converts it to JSON format + + :raises IOError: if provided JSON file can not be read out. + """ + try: + with open(self._input, "rb") as json_file: + return json.loads(json_file.read()) + except IOError as e: + log.error("Can not read Json file {}".format(self._input)) + raise e + + +def print_flashing_help(): + print("\nTo flash the generated hex/bin containing factory data, use BDT tool") + + +def main(): + + def allow_any_int(i): return int(i, 0) + + parser = argparse.ArgumentParser(description="Telink Factory Data NVS partition generator tool") + parser.add_argument("-i", "--input", type=str, required=True, + help="Path to input .json file") + parser.add_argument("-o", "--output", type=str, required=True, + help="Prefix for output file paths, e.g. setting dir/output causes creation of the following files: dir/output.hex, and dir/output.bin") + parser.add_argument("--offset", type=allow_any_int, required=True, + help="Partition offset - an address in device's NVM memory, where factory data will be stored") + parser.add_argument("--size", type=allow_any_int, required=True, + help="The maximum partition size") + parser.add_argument("-v", "--verbose", action="store_true", + help="Run this script with DEBUG logging level") + parser.add_argument("-r", "--raw", action="store_true", + help="Do not print flashing help and other logs, only generate a .hex file. It can be useful when the script is used by other script.") + args = parser.parse_args() + + if args.verbose: + log.basicConfig(format='[%(asctime)s][%(levelname)s] %(message)s', level=log.DEBUG) + elif args.raw: + log.basicConfig(format='%(message)s', level=log.ERROR) + else: + log.basicConfig(format='[%(asctime)s] %(message)s', level=log.INFO) + + partition_creator = PartitionCreator(args.offset, args.size, args.input, args.output) + cbor_data = partition_creator.generate_cbor() + try: + if not args.raw: + print("Generating .hex file: {}.hex with offset: {} and size: {}".format(args.output, hex(args.offset), hex(args.size))) + if partition_creator.create_hex(cbor_data) and partition_creator.create_bin(): + if not args.raw: + print_flashing_help() + except ValueError as e: + log.error(e) + sys.exit(-1) + + +if __name__ == "__main__": + main() diff --git a/src/app/app-platform/ContentAppPlatform.cpp b/src/app/app-platform/ContentAppPlatform.cpp index 6555e55b04aaba..736cf164fdfede 100644 --- a/src/app/app-platform/ContentAppPlatform.cpp +++ b/src/app/app-platform/ContentAppPlatform.cpp @@ -510,27 +510,11 @@ CHIP_ERROR ContentAppPlatform::GetACLEntryIndex(size_t * foundIndex, FabricIndex return CHIP_ERROR_NOT_FOUND; } -constexpr EndpointId kTargetBindingClusterEndpointId = 0; -constexpr EndpointId kLocalVideoPlayerEndpointId = 1; -constexpr EndpointId kLocalSpeakerEndpointId = 2; -constexpr ClusterId kClusterIdDescriptor = 0x001d; -constexpr ClusterId kClusterIdOnOff = 0x0006; -constexpr ClusterId kClusterIdWakeOnLAN = 0x0503; -// constexpr ClusterId kClusterIdChannel = 0x0504; -// constexpr ClusterId kClusterIdTargetNavigator = 0x0505; -constexpr ClusterId kClusterIdMediaPlayback = 0x0506; -// constexpr ClusterId kClusterIdMediaInput = 0x0507; -constexpr ClusterId kClusterIdLowPower = 0x0508; -constexpr ClusterId kClusterIdKeypadInput = 0x0509; -constexpr ClusterId kClusterIdContentLauncher = 0x050a; -constexpr ClusterId kClusterIdAudioOutput = 0x050b; -// constexpr ClusterId kClusterIdApplicationLauncher = 0x050c; -// constexpr ClusterId kClusterIdAccountLogin = 0x050e; - // Add ACLs on this device for the given client, // and create bindings on the given client so that it knows what it has access to. CHIP_ERROR ContentAppPlatform::ManageClientAccess(Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle, - uint16_t targetVendorId, NodeId localNodeId, + uint16_t targetVendorId, uint16_t targetProductId, NodeId localNodeId, + std::vector bindings, Controller::WriteResponseSuccessCallback successCb, Controller::WriteResponseFailureCallback failureCb) { @@ -564,8 +548,6 @@ CHIP_ERROR ContentAppPlatform::ManageClientAccess(Messaging::ExchangeManager & e ReturnErrorOnFailure(entry.SetPrivilege(vendorPrivilege)); ReturnErrorOnFailure(entry.AddSubject(nullptr, subjectNodeId)); - std::vector bindings; - /** * Here we are creating a single ACL entry containing: * a) selection of clusters on video player endpoint (8 targets) @@ -588,6 +570,7 @@ CHIP_ERROR ContentAppPlatform::ManageClientAccess(Messaging::ExchangeManager & e ChipLogProgress(Controller, "Create video player endpoint ACL and binding"); { + bool hasClusterAccess = false; if (vendorPrivilege == Access::Privilege::kAdminister) { ChipLogProgress(Controller, "ContentAppPlatform::ManageClientAccess Admin privilege granted"); @@ -595,14 +578,14 @@ CHIP_ERROR ContentAppPlatform::ManageClientAccess(Messaging::ExchangeManager & e Access::AccessControl::Entry::Target target = { .flags = Access::AccessControl::Entry::Target::kEndpoint, .endpoint = kLocalVideoPlayerEndpointId }; ReturnErrorOnFailure(entry.AddTarget(nullptr, target)); + hasClusterAccess = true; } else { ChipLogProgress(Controller, "ContentAppPlatform::ManageClientAccess non-Admin privilege granted"); // a vendor with non-admin privilege gets access to select clusters on ep1 - std::list allowedClusterList = { kClusterIdDescriptor, kClusterIdOnOff, kClusterIdWakeOnLAN, - kClusterIdMediaPlayback, kClusterIdLowPower, kClusterIdKeypadInput, - kClusterIdContentLauncher, kClusterIdAudioOutput }; + std::list allowedClusterList = mContentAppFactory->GetAllowedClusterListForStaticEndpoint( + kLocalVideoPlayerEndpointId, targetVendorId, targetProductId); for (const auto & clusterId : allowedClusterList) { @@ -611,16 +594,21 @@ CHIP_ERROR ContentAppPlatform::ManageClientAccess(Messaging::ExchangeManager & e .cluster = clusterId, .endpoint = kLocalVideoPlayerEndpointId }; ReturnErrorOnFailure(entry.AddTarget(nullptr, target)); + hasClusterAccess = true; } } - bindings.push_back(Binding::Structs::TargetStruct::Type{ - .node = MakeOptional(localNodeId), - .group = NullOptional, - .endpoint = MakeOptional(kLocalVideoPlayerEndpointId), - .cluster = NullOptional, - .fabricIndex = kUndefinedFabricIndex, - }); + if (hasClusterAccess) + { + ChipLogProgress(Controller, "ContentAppPlatform::ManageClientAccess adding a binding on ep1"); + bindings.push_back(Binding::Structs::TargetStruct::Type{ + .node = MakeOptional(localNodeId), + .group = NullOptional, + .endpoint = MakeOptional(kLocalVideoPlayerEndpointId), + .cluster = NullOptional, + .fabricIndex = kUndefinedFabricIndex, + }); + } } ChipLogProgress(Controller, "Create speaker endpoint ACL and binding"); diff --git a/src/app/app-platform/ContentAppPlatform.h b/src/app/app-platform/ContentAppPlatform.h index 3744a0fa0edf1d..69248cd431e3c7 100644 --- a/src/app/app-platform/ContentAppPlatform.h +++ b/src/app/app-platform/ContentAppPlatform.h @@ -38,6 +38,10 @@ using BindingListType = chip::app::Clusters::Binding::Attributes::Binding::TypeI namespace chip { namespace AppPlatform { +constexpr EndpointId kTargetBindingClusterEndpointId = 0; +constexpr EndpointId kLocalVideoPlayerEndpointId = 1; +constexpr EndpointId kLocalSpeakerEndpointId = 2; + class DLL_EXPORT ContentAppFactory { public: @@ -63,6 +67,11 @@ class DLL_EXPORT ContentAppFactory // and for voice agents, this may be Access::Privilege::kAdminister // When a vendor has admin privileges, it will get access to all clusters on ep1 virtual Access::Privilege GetVendorPrivilege(uint16_t vendorId) = 0; + + // Get the cluster list this vendorId/productId should have on static endpoints such as ep1 for casting video clients. + // When a vendor has admin privileges, it will get access to all clusters on ep1 + virtual std::list GetAllowedClusterListForStaticEndpoint(EndpointId endpointId, uint16_t vendorId, + uint16_t productId) = 0; }; class DLL_EXPORT ContentAppPlatform @@ -146,14 +155,18 @@ class DLL_EXPORT ContentAppPlatform * @param[in] exchangeMgr Exchange manager to be used to get an exchange context. * @param[in] sessionHandle Reference to an established session. * @param[in] targetVendorId Vendor ID for the target device. + * @param[in] targetProductId Product ID for the target device. * @param[in] localNodeId The NodeId for the local device. + * @param[in] bindings Any additional bindings to include. This may include current bindings. * @param[in] successCb The function to be called on success of adding the binding. * @param[in] failureCb The function to be called on failure of adding the binding. * * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error */ CHIP_ERROR ManageClientAccess(Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle, uint16_t targetVendorId, - NodeId localNodeId, Controller::WriteResponseSuccessCallback successCb, + uint16_t targetProductId, NodeId localNodeId, + std::vector bindings, + Controller::WriteResponseSuccessCallback successCb, Controller::WriteResponseFailureCallback failureCb); protected: diff --git a/src/app/clusters/door-lock-server/door-lock-server.cpp b/src/app/clusters/door-lock-server/door-lock-server.cpp index 4b46b80ffe6f5f..a1e5307b66169d 100644 --- a/src/app/clusters/door-lock-server/door-lock-server.cpp +++ b/src/app/clusters/door-lock-server/door-lock-server.cpp @@ -3234,10 +3234,10 @@ bool DoorLockServer::HandleRemoteLockOperation(chip::app::CommandHandler * comma EndpointId endpoint = commandPath.mEndpointId; DlOperationError reason = DlOperationError::kUnspecified; - uint16_t pinUserIdx = 0; - uint16_t pinCredIdx = 0; - bool success = false; - bool sendEvent = true; + Nullable pinUserIdx; // Will get set to non-null if we find a user for the PIN. + Optional pinCredIdx; // Will get set to a value if the PIN is one we know about. + bool success = false; + bool sendEvent = true; auto currentTime = chip::System::SystemClock().GetMonotonicTimestamp(); @@ -3253,9 +3253,9 @@ bool DoorLockServer::HandleRemoteLockOperation(chip::app::CommandHandler * comma VerifyOrExit(nullptr != endpointContext, ChipLogError(Zcl, "Failed to get endpoint index for cluster [endpoint=%d]", endpoint)); if (endpointContext->lockoutEndTimestamp >= currentTime) { - emberAfDoorLockClusterPrintln("Rejecting unlock command -- lockout is in action [endpoint=%d,lockoutEnd=%u,currentTime=%u]", - endpoint, static_cast(endpointContext->lockoutEndTimestamp.count()), - static_cast(currentTime.count())); + emberAfDoorLockClusterPrintln( + "Rejecting remote lock operation -- lockout is in action [endpoint=%d,lockoutEnd=%u,currentTime=%u]", endpoint, + static_cast(endpointContext->lockoutEndTimestamp.count()), static_cast(currentTime.count())); sendEvent = false; goto exit; } @@ -3272,14 +3272,27 @@ bool DoorLockServer::HandleRemoteLockOperation(chip::app::CommandHandler * comma // Look up the user index and credential index -- it should be used in the Lock Operation event EmberAfPluginDoorLockUserInfo user; - findUserIndexByCredential(endpoint, DlCredentialType::kPin, pinCode.Value(), pinUserIdx, pinCredIdx, user); + uint16_t userIdx; + uint16_t credIdx; + if (findUserIndexByCredential(endpoint, DlCredentialType::kPin, pinCode.Value(), userIdx, credIdx, user)) + { + pinUserIdx.SetNonNull(userIdx); + pinCredIdx.Emplace(credIdx); + } + else + { + emberAfDoorLockClusterPrintln("Rejecting lock operation: unknown PIN provided [endpoint=%d, lock_op=%d]", endpoint, + to_underlying(opType)); + reason = DlOperationError::kInvalidCredential; + goto exit; + } // If the user status is OccupiedDisabled we should deny the access and send out the appropriate event VerifyOrExit(user.userStatus != DlUserStatus::kOccupiedDisabled, { reason = DlOperationError::kDisabledUserDenied; emberAfDoorLockClusterPrintln( "Unable to perform remote lock operation: user is disabled [endpoint=%d, lock_op=%d, userIndex=%d]", endpoint, - to_underlying(opType), pinUserIdx); + to_underlying(opType), userIdx); }); } else @@ -3306,12 +3319,13 @@ bool DoorLockServer::HandleRemoteLockOperation(chip::app::CommandHandler * comma // credentials check succeeded, try to lock/unlock door success = opHandler(endpoint, pinCode, reason); + // The app should trigger the lock state change as it may take a while before the lock actually locks/unlocks +exit: if (!success && reason == DlOperationError::kInvalidCredential) { TrackWrongCodeEntry(endpoint); } - // The app should trigger the lock state change as it may take a while before the lock actually locks/unlocks -exit: + // Send command response emberAfSendImmediateDefaultResponse(success ? EMBER_ZCL_STATUS_SUCCESS : EMBER_ZCL_STATUS_FAILURE); @@ -3321,20 +3335,22 @@ bool DoorLockServer::HandleRemoteLockOperation(chip::app::CommandHandler * comma return success; } - // Send LockOperation/LockOperationError event - LockOpCredentials foundCred[] = { { DlCredentialType::kPin, pinCredIdx } }; + // Send LockOperation/LockOperationError event. The credential index in + // foundCred will be filled in if we actually have a value to fill in. + LockOpCredentials foundCred[] = { { DlCredentialType::kPin, UINT16_MAX } }; LockOpCredentials * credList = nullptr; size_t credListSize = 0; // appclusters.pdf 5.3.5.3, 5.3.5.4: // The list of credentials used in performing the lock operation. This SHALL be null if no credentials were involved. - if (pinCode.HasValue()) + if (pinCode.HasValue() && pinCredIdx.HasValue()) { - credList = foundCred; - credListSize = 1; + foundCred[0].credentialIndex = pinCredIdx.Value(); + credList = foundCred; + credListSize = 1; } - SendLockOperationEvent(endpoint, opType, DlOperationSource::kRemote, reason, Nullable(pinUserIdx), + SendLockOperationEvent(endpoint, opType, DlOperationSource::kRemote, reason, pinUserIdx, Nullable(getFabricIndex(commandObj)), Nullable(getNodeId(commandObj)), credList, credListSize, success); return success; diff --git a/src/app/clusters/door-lock-server/door-lock-server.h b/src/app/clusters/door-lock-server/door-lock-server.h index c7ddf369f8871a..67314c63a158f6 100644 --- a/src/app/clusters/door-lock-server/door-lock-server.h +++ b/src/app/clusters/door-lock-server/door-lock-server.h @@ -571,12 +571,12 @@ struct EmberAfPluginDoorLockCredentialInfo */ struct EmberAfPluginDoorLockUserInfo { - chip::CharSpan userName; /**< Name of the user. */ - chip::Span credentials; /**< Credentials that are associated with user (without data).*/ - uint32_t userUniqueId; /**< Unique user identifier. */ - DlUserStatus userStatus; /**< Status of the user slot (available/occupied). */ - DlUserType userType; /**< Type of the user. */ - DlCredentialRule credentialRule; /**< Number of supported credentials. */ + chip::CharSpan userName; /**< Name of the user. */ + chip::Span credentials; /**< Credentials that are associated with user (without data).*/ + uint32_t userUniqueId; /**< Unique user identifier. */ + DlUserStatus userStatus = DlUserStatus::kAvailable; /**< Status of the user slot (available/occupied). */ + DlUserType userType; /**< Type of the user. */ + DlCredentialRule credentialRule; /**< Number of supported credentials. */ DlAssetSource creationSource; chip::FabricIndex createdBy; /**< ID of the fabric that created the user. */ diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h b/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h index 2f874547e6948b..c4527c8a3e5edc 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h @@ -55,9 +55,6 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic, assign, readonly) chip::NodeId nodeID; -/** - * Controllers are created via the MTRControllerFactory object. - */ - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.h b/src/darwin/Framework/CHIP/MTRDeviceController.h index 6515c4742f2987..76f51a18b2b9f7 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.h +++ b/src/darwin/Framework/CHIP/MTRDeviceController.h @@ -31,7 +31,7 @@ typedef void (^MTRDeviceConnectionCallback)(MTRBaseDevice * _Nullable device, NS @interface MTRDeviceController : NSObject -@property (readonly, nonatomic) BOOL isRunning; +@property (readonly, nonatomic, getter=isRunning) BOOL running; /** * Return the Node ID assigned to the controller. Will return nil if the @@ -139,7 +139,7 @@ typedef void (^MTRDeviceConnectionCallback)(MTRBaseDevice * _Nullable device, NS error:(NSError * __autoreleasing *)error; /** - * Controllers are created via the MTRControllerFactory object. + * Controllers are created via the MTRDeviceControllerFactory object. */ - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm index 6ee251571a775d..07e77b8b34398c 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm @@ -20,7 +20,7 @@ #import "MTRBaseDevice_Internal.h" #import "MTRCommissioningParameters.h" -#import "MTRControllerFactory_Internal.h" +#import "MTRDeviceControllerFactory_Internal.h" #import "MTRDeviceControllerStartupParams.h" #import "MTRDeviceControllerStartupParams_Internal.h" #import "MTRDevicePairingDelegateBridge.h" @@ -87,14 +87,14 @@ @interface MTRDeviceController () @property (readonly) MTRP256KeypairBridge signingKeypairBridge; @property (readonly) MTRP256KeypairBridge operationalKeypairBridge; @property (readonly) MTRDeviceAttestationDelegateBridge * deviceAttestationDelegateBridge; -@property (readonly) MTRControllerFactory * factory; +@property (readonly) MTRDeviceControllerFactory * factory; @property (readonly) NSMutableDictionary * nodeIDToDeviceMap; @property (readonly) os_unfair_lock deviceMapLock; // protects nodeIDToDeviceMap @end @implementation MTRDeviceController -- (instancetype)initWithFactory:(MTRControllerFactory *)factory queue:(dispatch_queue_t)queue +- (instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory queue:(dispatch_queue_t)queue { if (self = [super init]) { _chipWorkQueue = queue; @@ -143,7 +143,7 @@ - (void)cleanupAfterStartup } // Part of cleanupAfterStartup that has to interact with the Matter work queue -// in a very specific way that only MTRControllerFactory knows about. +// in a very specific way that only MTRDeviceControllerFactory knows about. - (void)shutDownCppController { if (_cppCommissioner) { diff --git a/src/darwin/Framework/CHIP/MTRControllerFactory.h b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.h similarity index 66% rename from src/darwin/Framework/CHIP/MTRControllerFactory.h rename to src/darwin/Framework/CHIP/MTRDeviceControllerFactory.h index efb2edd36670c0..97e7ca28749050 100644 --- a/src/darwin/Framework/CHIP/MTRControllerFactory.h +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.h @@ -32,7 +32,8 @@ NS_ASSUME_NONNULL_BEGIN @class MTRDeviceController; @class MTRDeviceControllerStartupParams; -@interface MTRControllerFactoryParams : NSObject +MTR_NEWLY_AVAILABLE +@interface MTRDeviceControllerFactoryParams : NSObject /* * Storage delegate must be provided for correct functioning of Matter * controllers. It is used to store persistent information for the fabrics the @@ -67,44 +68,47 @@ NS_ASSUME_NONNULL_BEGIN * Whether to run a server capable of accepting incoming CASE * connections. Defaults to NO. */ -@property (nonatomic, assign) BOOL startServer; +@property (nonatomic, assign) BOOL shouldStartServer MTR_NEWLY_AVAILABLE; - (instancetype)init NS_UNAVAILABLE; - (instancetype)initWithStorage:(id)storage; @end -@interface MTRControllerFactory : NSObject - -@property (readonly, nonatomic) BOOL isRunning; +@interface MTRDeviceControllerFactory : NSObject -- (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; +/** + * If true, the factory is in a state where it can create controllers: + * startControllerFactory has been called, but stopControllerFactory has not been called + * since then. + */ +@property (readonly, nonatomic, getter=isRunning) BOOL running; /** - * Return the single MTRControllerFactory we support existing. It starts off + * Return the single MTRDeviceControllerFactory we support existing. It starts off * in a "not started" state. */ + (instancetype)sharedInstance; /** - * Start the controller factory. Repeated calls to startup without calls to - * shutdown in between are NO-OPs. Use the isRunning property to check whether - * the controller factory needs to be started up. + * Start the controller factory. Repeated calls to startControllerFactory + * without calls to stopControllerFactory in between are NO-OPs. Use the + * isRunning property to check whether the controller factory needs to be + * started up. * * @param[in] startupParams data needed to start up the controller factory. * * @return Whether startup succeded. */ -- (BOOL)startup:(MTRControllerFactoryParams *)startupParams; +- (BOOL)startControllerFactory:(MTRDeviceControllerFactoryParams *)startupParams error:(NSError * __autoreleasing *)error; /** - * Shut down the controller factory. This will shut down any outstanding - * controllers as part of the factory shutdown. + * Stop the controller factory. This will shut down any outstanding + * controllers as part of the factory stopping. * - * Repeated calls to shutdown without calls to startup in between are - * NO-OPs. + * Repeated calls to stopControllerFactory without calls to + * startControllerFactory in between are NO-OPs. */ -- (void)shutdown; +- (void)stopControllerFactory; /** * Create a MTRDeviceController on an existing fabric. Returns nil on failure. @@ -115,7 +119,8 @@ NS_ASSUME_NONNULL_BEGIN * The fabric is identified by the root public key and fabric id in * the startupParams. */ -- (MTRDeviceController * _Nullable)startControllerOnExistingFabric:(MTRDeviceControllerStartupParams *)startupParams; +- (MTRDeviceController * _Nullable)createControllerOnExistingFabric:(MTRDeviceControllerStartupParams *)startupParams + error:(NSError * __autoreleasing *)error; /** * Create a MTRDeviceController on a new fabric. Returns nil on failure. @@ -125,13 +130,31 @@ NS_ASSUME_NONNULL_BEGIN * The fabric is identified by the root public key and fabric id in * the startupParams. */ -- (MTRDeviceController * _Nullable)startControllerOnNewFabric:(MTRDeviceControllerStartupParams *)startupParams; +- (MTRDeviceController * _Nullable)createControllerOnNewFabric:(MTRDeviceControllerStartupParams *)startupParams + error:(NSError * __autoreleasing *)error; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; @end -@interface MTRControllerFactoryParams (Deprecated) +MTR_NEWLY_DEPRECATED("Please use MTRDeviceControllerFactoryParams") +@interface MTRControllerFactoryParams : MTRDeviceControllerFactoryParams @property (nonatomic, strong, readonly) id storageDelegate MTR_NEWLY_DEPRECATED( "Please use the storage property"); +@property (nonatomic, assign) BOOL startServer; +@end + +MTR_NEWLY_DEPRECATED("Please use MTRDeviceControllerFactory") +@interface MTRControllerFactory : NSObject +@property (readonly, nonatomic) BOOL isRunning; ++ (instancetype)sharedInstance; +- (BOOL)startup:(MTRControllerFactoryParams *)startupParams; +- (void)shutdown; +- (MTRDeviceController * _Nullable)startControllerOnExistingFabric:(MTRDeviceControllerStartupParams *)startupParams; +- (MTRDeviceController * _Nullable)startControllerOnNewFabric:(MTRDeviceControllerStartupParams *)startupParams; +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; @end NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRControllerFactory.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm similarity index 84% rename from src/darwin/Framework/CHIP/MTRControllerFactory.mm rename to src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm index 0b6926e08ad4b1..9167cd047c1209 100644 --- a/src/darwin/Framework/CHIP/MTRControllerFactory.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm @@ -14,8 +14,8 @@ * limitations under the License. */ -#import "MTRControllerFactory.h" -#import "MTRControllerFactory_Internal.h" +#import "MTRDeviceControllerFactory.h" +#import "MTRDeviceControllerFactory_Internal.h" #import "MTRAttestationTrustStoreBridge.h" #import "MTRCertificates.h" @@ -24,6 +24,7 @@ #import "MTRDeviceControllerStartupParams.h" #import "MTRDeviceControllerStartupParams_Internal.h" #import "MTRDeviceController_Internal.h" +#import "MTRError_Internal.h" #import "MTRLogging.h" #import "MTRMemory.h" #import "MTROTAProviderDelegateBridge.h" @@ -58,7 +59,7 @@ static NSString * const kErrorCDCertStoreInit = @"Init failure while initializing Certificate Declaration Signing Keys store"; static NSString * const kErrorOtaProviderInit = @"Init failure while creating an OTA provider delegate"; -@interface MTRControllerFactory () +@interface MTRDeviceControllerFactory () @property (atomic, readonly) dispatch_queue_t chipWorkQueue; @property (readonly) DeviceControllerFactory * controllerFactory; @@ -82,15 +83,15 @@ - (BOOL)findMatchingFabric:(FabricTable &)fabricTable - (MTRDeviceController * _Nullable)maybeInitializeOTAProvider:(MTRDeviceController * _Nonnull)controller; @end -@implementation MTRControllerFactory +@implementation MTRDeviceControllerFactory + (instancetype)sharedInstance { - static MTRControllerFactory * factory = nil; + static MTRDeviceControllerFactory * factory = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ // initialize the factory. - factory = [[MTRControllerFactory alloc] init]; + factory = [[MTRDeviceControllerFactory alloc] init]; }); return factory; } @@ -101,7 +102,7 @@ - (instancetype)init return nil; } - _isRunning = NO; + _running = NO; _chipWorkQueue = DeviceLayer::PlatformMgrImpl().GetWorkQueue(); _controllerFactory = &DeviceControllerFactory::GetInstance(); [MTRMemory ensureInit]; @@ -133,10 +134,23 @@ - (instancetype)init - (void)dealloc { - [self shutdown]; + [self stopControllerFactory]; [self cleanupInitObjects]; } +- (BOOL)checkIsRunning:(NSError * __autoreleasing *)error +{ + if ([self isRunning]) { + return YES; + } + + if (error != nil) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + + return NO; +} + - (BOOL)checkForInitError:(BOOL)condition logMsg:(NSString *)logMsg { if (condition) { @@ -201,7 +215,7 @@ - (void)cleanupStartupObjects } } -- (BOOL)startup:(MTRControllerFactoryParams *)startupParams +- (BOOL)startControllerFactory:(MTRDeviceControllerFactoryParams *)startupParams error:(NSError * __autoreleasing *)error; { if ([self isRunning]) { MTR_LOG_DEBUG("Ignoring duplicate call to startup, Matter controller factory already started..."); @@ -221,6 +235,7 @@ - (BOOL)startup:(MTRControllerFactoryParams *)startupParams _persistentStorageDelegateBridge = new MTRPersistentStorageDelegateBridge(startupParams.storage); if (_persistentStorageDelegateBridge == nil) { MTR_LOG_ERROR("Error: %@", kErrorPersistentStorageInit); + errorCode = CHIP_ERROR_NO_MEMORY; return; } @@ -271,6 +286,7 @@ - (BOOL)startup:(MTRControllerFactoryParams *)startupParams _otaProviderDelegateBridge = new MTROTAProviderDelegateBridge(startupParams.otaProviderDelegate); if (_otaProviderDelegateBridge == nil) { MTR_LOG_ERROR("Error: %@", kErrorOtaProviderInit); + errorCode = CHIP_ERROR_NO_MEMORY; return; } } @@ -279,6 +295,7 @@ - (BOOL)startup:(MTRControllerFactoryParams *)startupParams _keystore = new PersistentStorageOperationalKeystore(); if (_keystore == nullptr) { MTR_LOG_ERROR("Error: %@", kErrorKeystoreInit); + errorCode = CHIP_ERROR_NO_MEMORY; return; } @@ -292,6 +309,7 @@ - (BOOL)startup:(MTRControllerFactoryParams *)startupParams _opCertStore = new Credentials::PersistentStorageOpCertStore(); if (_opCertStore == nullptr) { MTR_LOG_ERROR("Error: %@", kErrorCertStoreInit); + errorCode = CHIP_ERROR_NO_MEMORY; return; } @@ -307,6 +325,7 @@ - (BOOL)startup:(MTRControllerFactoryParams *)startupParams _attestationTrustStoreBridge = new MTRAttestationTrustStoreBridge(startupParams.paaCerts); if (_attestationTrustStoreBridge == nullptr) { MTR_LOG_ERROR("Error: %@", kErrorAttestationTrustStoreInit); + errorCode = CHIP_ERROR_NO_MEMORY; return; } trustStore = _attestationTrustStoreBridge; @@ -317,6 +336,7 @@ - (BOOL)startup:(MTRControllerFactoryParams *)startupParams _deviceAttestationVerifier = new Credentials::DefaultDACVerifier(trustStore); if (_deviceAttestationVerifier == nullptr) { MTR_LOG_ERROR("Error: %@", kErrorDACVerifierInit); + errorCode = CHIP_ERROR_NO_MEMORY; return; } @@ -324,6 +344,7 @@ - (BOOL)startup:(MTRControllerFactoryParams *)startupParams auto cdTrustStore = _deviceAttestationVerifier->GetCertificationDeclarationTrustStore(); if (cdTrustStore == nullptr) { MTR_LOG_ERROR("Error: %@", kErrorCDCertStoreInit); + errorCode = CHIP_ERROR_INCORRECT_STATE; return; } @@ -340,7 +361,7 @@ - (BOOL)startup:(MTRControllerFactoryParams *)startupParams if (startupParams.port != nil) { params.listenPort = [startupParams.port unsignedShortValue]; } - if (startupParams.startServer == YES) { + if (startupParams.shouldStartServer == YES) { params.enableServerInteractions = true; } @@ -367,7 +388,7 @@ - (BOOL)startup:(MTRControllerFactoryParams *)startupParams _controllerFactory->RetainSystemState(); _controllerFactory->ReleaseSystemState(); - self->_isRunning = YES; + self->_running = YES; }); // Make sure to stop the event loop again before returning, so we are not running it while we don't have any controllers. @@ -375,12 +396,15 @@ - (BOOL)startup:(MTRControllerFactoryParams *)startupParams if (![self isRunning]) { [self cleanupStartupObjects]; + if (error != nil) { + *error = [MTRError errorForCHIPErrorCode:errorCode]; + } } return [self isRunning]; } -- (void)shutdown +- (void)stopControllerFactory { if (![self isRunning]) { return; @@ -399,12 +423,13 @@ - (void)shutdown // that does not re-create the objects that we create inside init. // Maybe we should be creating them in startup? - _isRunning = NO; + _running = NO; } -- (MTRDeviceController * _Nullable)startControllerOnExistingFabric:(MTRDeviceControllerStartupParams *)startupParams +- (MTRDeviceController * _Nullable)createControllerOnExistingFabric:(MTRDeviceControllerStartupParams *)startupParams + error:(NSError * __autoreleasing *)error { - if (![self isRunning]) { + if (![self checkIsRunning:error]) { MTR_LOG_ERROR("Trying to start controller while Matter controller factory is not running"); return nil; } @@ -413,10 +438,14 @@ - (MTRDeviceController * _Nullable)startControllerOnExistingFabric:(MTRDeviceCon // our fabric table operations there. auto * controller = [self createController]; if (controller == nil) { + if (error != nil) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_NO_MEMORY]; + } return nil; } __block MTRDeviceControllerStartupParamsInternal * params = nil; + __block CHIP_ERROR fabricError = CHIP_NO_ERROR; // We want the block to end up with just a pointer to the fabric table, // since we know our on-stack instance will outlive the block. FabricTable fabricTableInstance; @@ -426,11 +455,13 @@ - (MTRDeviceController * _Nullable)startControllerOnExistingFabric:(MTRDeviceCon BOOL ok = [self findMatchingFabric:*fabricTable params:startupParams fabric:&fabric]; if (!ok) { MTR_LOG_ERROR("Can't start on existing fabric: fabric matching failed"); + fabricError = CHIP_ERROR_INTERNAL; return; } if (fabric == nullptr) { MTR_LOG_ERROR("Can't start on existing fabric: fabric not found"); + fabricError = CHIP_ERROR_NOT_FOUND; return; } @@ -439,11 +470,13 @@ - (MTRDeviceController * _Nullable)startControllerOnExistingFabric:(MTRDeviceCon if ([existing isRunningOnFabric:fabricTable fabricIndex:fabric->GetFabricIndex() isRunning:&isRunning] != CHIP_NO_ERROR) { MTR_LOG_ERROR("Can't tell what fabric a controller is running on. Not safe to start."); + fabricError = CHIP_ERROR_INTERNAL; return; } if (isRunning) { MTR_LOG_ERROR("Can't start on existing fabric: another controller is running on it"); + fabricError = CHIP_ERROR_INCORRECT_STATE; return; } } @@ -452,22 +485,39 @@ - (MTRDeviceController * _Nullable)startControllerOnExistingFabric:(MTRDeviceCon fabricIndex:fabric->GetFabricIndex() keystore:_keystore params:startupParams]; + if (params == nil) { + fabricError = CHIP_ERROR_NO_MEMORY; + } }); if (params == nil) { [self controllerShuttingDown:controller]; + if (error != nil) { + *error = [MTRError errorForCHIPErrorCode:fabricError]; + } return nil; } BOOL ok = [controller startup:params]; if (ok == NO) { + // TODO: get error from controller's startup. + if (error != nil) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INTERNAL]; + } return nil; } - return [self maybeInitializeOTAProvider:controller]; + controller = [self maybeInitializeOTAProvider:controller]; + if (controller == nil) { + if (error != nil) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INTERNAL]; + } + } + return controller; } -- (MTRDeviceController * _Nullable)startControllerOnNewFabric:(MTRDeviceControllerStartupParams *)startupParams +- (MTRDeviceController * _Nullable)createControllerOnNewFabric:(MTRDeviceControllerStartupParams *)startupParams + error:(NSError * __autoreleasing *)error { if (![self isRunning]) { MTR_LOG_ERROR("Trying to start controller while Matter controller factory is not running"); @@ -488,10 +538,14 @@ - (MTRDeviceController * _Nullable)startControllerOnNewFabric:(MTRDeviceControll // our fabric table operations there. auto * controller = [self createController]; if (controller == nil) { + if (error != nil) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_NO_MEMORY]; + } return nil; } __block MTRDeviceControllerStartupParamsInternal * params = nil; + __block CHIP_ERROR fabricError = CHIP_NO_ERROR; // We want the block to end up with just a pointer to the fabric table, // since we know our on-stack instance will outlive the block. FabricTable fabricTableInstance; @@ -501,30 +555,49 @@ - (MTRDeviceController * _Nullable)startControllerOnNewFabric:(MTRDeviceControll BOOL ok = [self findMatchingFabric:*fabricTable params:startupParams fabric:&fabric]; if (!ok) { MTR_LOG_ERROR("Can't start on new fabric: fabric matching failed"); + fabricError = CHIP_ERROR_INTERNAL; return; } if (fabric != nullptr) { MTR_LOG_ERROR("Can't start on new fabric that matches existing fabric"); + fabricError = CHIP_ERROR_INCORRECT_STATE; return; } params = [[MTRDeviceControllerStartupParamsInternal alloc] initForNewFabric:fabricTable keystore:_keystore params:startupParams]; + if (params == nil) { + fabricError = CHIP_ERROR_NO_MEMORY; + } }); if (params == nil) { [self controllerShuttingDown:controller]; + if (error != nil) { + *error = [MTRError errorForCHIPErrorCode:fabricError]; + } return nil; } BOOL ok = [controller startup:params]; if (ok == NO) { + // TODO: get error from controller's startup. + if (error != nil) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INTERNAL]; + } return nil; } - return [self maybeInitializeOTAProvider:controller]; + // TODO: Need better error propagation. + controller = [self maybeInitializeOTAProvider:controller]; + if (controller == nil) { + if (error != nil) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INTERNAL]; + } + } + return controller; } - (MTRDeviceController * _Nullable)createController @@ -611,7 +684,7 @@ - (MTRDeviceController * _Nullable)maybeInitializeOTAProvider:(MTRDeviceControll @end -@implementation MTRControllerFactory (InternalMethods) +@implementation MTRDeviceControllerFactory (InternalMethods) - (void)controllerShuttingDown:(MTRDeviceController *)controller { @@ -678,7 +751,7 @@ - (MTRPersistentStorageDelegateBridge *)storageDelegateBridge @end -@implementation MTRControllerFactoryParams +@implementation MTRDeviceControllerFactoryParams - (instancetype)initWithStorage:(id)storage { @@ -691,14 +764,58 @@ - (instancetype)initWithStorage:(id)storage _paaCerts = nil; _cdCerts = nil; _port = nil; - _startServer = NO; + _shouldStartServer = NO; return self; } @end -@implementation MTRControllerFactoryParams (Deprecated) +@implementation MTRControllerFactory +- (BOOL)isRunning +{ + return [[MTRDeviceControllerFactory sharedInstance] isRunning]; +} + ++ (instancetype)sharedInstance +{ + // We could try to delegate to MTRDeviceControllerFactory's sharedInstance + // here, but then we would have to add the backwards-compar selectors to + // MTRDeviceControllerFactory, etc. Just forward things along instead. + // This works because we never accept an MTRControllerFactory as an argument + // in any of our public APIs. + static MTRControllerFactory * factory = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + // initialize the factory. + factory = [[MTRControllerFactory alloc] init]; + }); + return factory; +} + +- (BOOL)startup:(MTRControllerFactoryParams *)startupParams +{ + return [[MTRDeviceControllerFactory sharedInstance] startControllerFactory:startupParams error:nil]; +} + +- (void)shutdown +{ + return [[MTRDeviceControllerFactory sharedInstance] stopControllerFactory]; +} + +- (MTRDeviceController * _Nullable)startControllerOnExistingFabric:(MTRDeviceControllerStartupParams *)startupParams +{ + return [[MTRDeviceControllerFactory sharedInstance] createControllerOnExistingFabric:startupParams error:nil]; +} + +- (MTRDeviceController * _Nullable)startControllerOnNewFabric:(MTRDeviceControllerStartupParams *)startupParams +{ + return [[MTRDeviceControllerFactory sharedInstance] createControllerOnNewFabric:startupParams error:nil]; +} + +@end + +@implementation MTRControllerFactoryParams - (id)storageDelegate { @@ -708,4 +825,14 @@ @implementation MTRControllerFactoryParams (Deprecated) return static_cast>(self.storage); } +- (BOOL)startServer +{ + return self.shouldStartServer; +} + +- (void)setStartServer:(BOOL)startServer +{ + self.shouldStartServer = startServer; +} + @end diff --git a/src/darwin/Framework/CHIP/MTRControllerFactory_Internal.h b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory_Internal.h similarity index 89% rename from src/darwin/Framework/CHIP/MTRControllerFactory_Internal.h rename to src/darwin/Framework/CHIP/MTRDeviceControllerFactory_Internal.h index e976aea01609af..a92d00b1c1e8b3 100644 --- a/src/darwin/Framework/CHIP/MTRControllerFactory_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory_Internal.h @@ -15,13 +15,13 @@ */ /** - * Parts of MTRControllerFactory that are not part of the framework API. + * Parts of MTRDeviceControllerFactory that are not part of the framework API. * Mostly for use from MTRDeviceController. */ #import -#import "MTRControllerFactory.h" +#import "MTRDeviceControllerFactory.h" #include @@ -38,7 +38,7 @@ namespace Credentials { NS_ASSUME_NONNULL_BEGIN -@interface MTRControllerFactory (InternalMethods) +@interface MTRDeviceControllerFactory (InternalMethods) - (void)controllerShuttingDown:(MTRDeviceController *)controller; diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.h b/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.h index c9733f08701bcc..dfafee444916aa 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.h +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.h @@ -28,9 +28,10 @@ NS_ASSUME_NONNULL_BEGIN * if not using an intermediate CA, the intermediate CA's keypair otherwise. * * Allowed to be nil if this controller will not be issuing operational - * certificates. In that case, the MTRDeviceControllerStartupParams object - * must be initialized using initWithOperationalKeypair (to provide the - * operational credentials for the controller itself). + * certificates. In that case, the MTRDeviceControllerStartupParams object must + * be initialized using + * initWithIPK:operationalKeypair:operationalCertificate:intermediateCertificate:rootCertificate: + * (to provide the operational credentials for the controller itself). */ @property (nonatomic, copy, readonly, nullable) id nocSigner; /** @@ -99,8 +100,6 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic, copy, nullable) NSNumber * nodeID MTR_NEWLY_AVAILABLE; -// TODO: Add something here for CATs? - /** * Root certificate, in X.509 DER form, to use. * @@ -198,16 +197,14 @@ NS_ASSUME_NONNULL_BEGIN * * ipk must be 16 bytes in length */ -- (instancetype)initWithSigningKeypair:(id)nocSigner - fabricID:(NSNumber *)fabricID - ipk:(NSData *)ipk MTR_NEWLY_AVAILABLE; +- (instancetype)initWithIPK:(NSData *)ipk fabricID:(NSNumber *)fabricID nocSigner:(id)nocSigner MTR_NEWLY_AVAILABLE; /** * Prepare to initialize a controller with a complete operational certificate * chain. This initialization method should be used when none of the * certificate-signing private keys are available locally. * - * The fabric id and node if to use will be derived from the provided + * The fabric id and node id to use will be derived from the provided * operationalCertificate. * * intermediateCertificate may be nil if operationalCertificate is signed by @@ -215,11 +212,11 @@ NS_ASSUME_NONNULL_BEGIN * * ipk must be 16 bytes in length. */ -- (instancetype)initWithOperationalKeypair:(id)operationalKeypair - operationalCertificate:(MTRCertificateDERBytes)operationalCertificate - intermediateCertificate:(MTRCertificateDERBytes _Nullable)intermediateCertificate - rootCertificate:(MTRCertificateDERBytes)rootCertificate - ipk:(NSData *)ipk; +- (instancetype)initWithIPK:(NSData *)ipk + operationalKeypair:(id)operationalKeypair + operationalCertificate:(MTRCertificateDERBytes)operationalCertificate + intermediateCertificate:(MTRCertificateDERBytes _Nullable)intermediateCertificate + rootCertificate:(MTRCertificateDERBytes)rootCertificate MTR_NEWLY_AVAILABLE; @end @@ -231,7 +228,14 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithSigningKeypair:(id)nocSigner fabricId:(uint64_t)fabricId - ipk:(NSData *)ipk MTR_NEWLY_DEPRECATED("Please use initWithSigningKeypair:fabricID:ipk:"); + ipk:(NSData *)ipk MTR_NEWLY_DEPRECATED("Please use initWithIPK:fabricID:nocSigner:"); +- (instancetype)initWithOperationalKeypair:(id)operationalKeypair + operationalCertificate:(MTRCertificateDERBytes)operationalCertificate + intermediateCertificate:(MTRCertificateDERBytes _Nullable)intermediateCertificate + rootCertificate:(MTRCertificateDERBytes)rootCertificate + ipk:(NSData *)ipk + MTR_NEWLY_DEPRECATED( + "Please use initWithIPK:operationalKeypair:operationalCertificate:intermediateCertificate:rootCertificate:"); @end diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.mm index dd5512929b2aab..c2f0242d6ffc20 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.mm @@ -30,7 +30,7 @@ @implementation MTRDeviceControllerStartupParams -- (instancetype)initWithSigningKeypair:(id)nocSigner fabricID:(NSNumber *)fabricID ipk:(NSData *)ipk +- (instancetype)initWithIPK:(NSData *)ipk fabricID:(NSNumber *)fabricID nocSigner:(id)nocSigner { if (!(self = [super init])) { return nil; @@ -48,11 +48,11 @@ - (instancetype)initWithSigningKeypair:(id)nocSigner fabricID:(NSNum return self; } -- (instancetype)initWithOperationalKeypair:(id)operationalKeypair - operationalCertificate:(MTRCertificateDERBytes)operationalCertificate - intermediateCertificate:(MTRCertificateDERBytes _Nullable)intermediateCertificate - rootCertificate:(MTRCertificateDERBytes)rootCertificate - ipk:(NSData *)ipk +- (instancetype)initWithIPK:(NSData *)ipk + operationalKeypair:(id)operationalKeypair + operationalCertificate:(MTRCertificateDERBytes)operationalCertificate + intermediateCertificate:(MTRCertificateDERBytes _Nullable)intermediateCertificate + rootCertificate:(MTRCertificateDERBytes)rootCertificate { if (!(self = [super init])) { return nil; @@ -152,7 +152,20 @@ - (void)setNodeId:(nullable NSNumber *)nodeId - (instancetype)initWithSigningKeypair:(id)nocSigner fabricId:(uint64_t)fabricId ipk:(NSData *)ipk { - return [self initWithSigningKeypair:nocSigner fabricID:@(fabricId) ipk:ipk]; + return [self initWithIPK:ipk fabricID:@(fabricId) nocSigner:nocSigner]; +} + +- (instancetype)initWithOperationalKeypair:(id)operationalKeypair + operationalCertificate:(MTRCertificateDERBytes)operationalCertificate + intermediateCertificate:(MTRCertificateDERBytes _Nullable)intermediateCertificate + rootCertificate:(MTRCertificateDERBytes)rootCertificate + ipk:(NSData *)ipk +{ + return [self initWithIPK:ipk + operationalKeypair:operationalKeypair + operationalCertificate:operationalCertificate + intermediateCertificate:intermediateCertificate + rootCertificate:rootCertificate]; } @end diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams_Internal.h b/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams_Internal.h index 9a4d3ead0359a6..79751cc95362e8 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams_Internal.h @@ -83,12 +83,16 @@ NS_ASSUME_NONNULL_BEGIN keystore:(chip::Crypto::OperationalKeystore *)keystore params:(MTRDeviceControllerStartupParams *)params; -- (instancetype)initWithSigningKeypair:(id)nocSigner fabricID:(NSNumber *)fabricID ipk:(NSData *)ipk NS_UNAVAILABLE; -- (instancetype)initWithOperationalKeypair:(id)operationalKeypair - operationalCertificate:(MTRCertificateDERBytes)operationalCertificate - intermediateCertificate:(MTRCertificateDERBytes _Nullable)intermediateCertificate - rootCertificate:(MTRCertificateDERBytes)rootCertificate - ipk:(NSData *)ipk NS_UNAVAILABLE; +/** + * Should use initForExistingFabric or initForNewFabric to initialize + * internally. + */ +- (instancetype)initWithIPK:(NSData *)ipk fabricID:(NSNumber *)fabricID nocSigner:(id)nocSigner NS_UNAVAILABLE; +- (instancetype)initWithIPK:(NSData *)ipk + operationalKeypair:(id)operationalKeypair + operationalCertificate:(MTRCertificateDERBytes)operationalCertificate + intermediateCertificate:(MTRCertificateDERBytes _Nullable)intermediateCertificate + rootCertificate:(MTRCertificateDERBytes)rootCertificate NS_UNAVAILABLE; @end NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRDeviceController_Internal.h b/src/darwin/Framework/CHIP/MTRDeviceController_Internal.h index bb20c6b397c38a..d787aa02c329b1 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDeviceController_Internal.h @@ -16,7 +16,7 @@ /** * Parts of MTRDeviceController that are not part of the framework API. Mostly - * for use from MTRControllerFactory. + * for use from MTRDeviceControllerFactory. */ #import @@ -31,7 +31,7 @@ #import "MTRDeviceController.h" @class MTRDeviceControllerStartupParamsInternal; -@class MTRControllerFactory; +@class MTRDeviceControllerFactory; @class MTRDevice; namespace chip { @@ -46,17 +46,17 @@ NS_ASSUME_NONNULL_BEGIN @interface MTRDeviceController (InternalMethods) -#pragma mark - MTRControllerFactory methods +#pragma mark - MTRDeviceControllerFactory methods /** * Start a new controller. Returns whether startup succeeded. If this fails, * it guarantees that it has called controllerShuttingDown on the - * MTRControllerFactory. + * MTRDeviceControllerFactory. * * The return value will always match [controller isRunning] for this * controller. * - * Only MTRControllerFactory should be calling this. + * Only MTRDeviceControllerFactory should be calling this. */ - (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams; @@ -69,9 +69,9 @@ NS_ASSUME_NONNULL_BEGIN /** * Init a newly created controller. * - * Only MTRControllerFactory should be calling this. + * Only MTRDeviceControllerFactory should be calling this. */ -- (instancetype)initWithFactory:(MTRControllerFactory *)factory queue:(dispatch_queue_t)queue; +- (instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory queue:(dispatch_queue_t)queue; /** * Check whether this controller is running on the given fabric, as represented @@ -82,7 +82,7 @@ NS_ASSUME_NONNULL_BEGIN * Might return failure, in which case we don't know whether it's running on the * given fabric. Otherwise it will set *isRunning to the right boolean value. * - * Only MTRControllerFactory should be calling this. + * Only MTRDeviceControllerFactory should be calling this. */ - (CHIP_ERROR)isRunningOnFabric:(chip::FabricTable *)fabricTable fabricIndex:(chip::FabricIndex)fabricIndex @@ -92,16 +92,16 @@ NS_ASSUME_NONNULL_BEGIN * Shut down the underlying C++ controller. Must be called on the Matter work * queue or after the Matter work queue has been shut down. * - * Only MTRControllerFactory should be calling this. + * Only MTRDeviceControllerFactory should be calling this. */ - (void)shutDownCppController; /** - * Notification that the MTRControllerFactory has finished shutting down + * Notification that the MTRDeviceControllerFactory has finished shutting down * this controller and will not be touching it anymore. This is guaranteed to * be called after initWithFactory succeeds. * - * Only MTRControllerFactory should be calling this. + * Only MTRDeviceControllerFactory should be calling this. */ - (void)deinitFromFactory; diff --git a/src/darwin/Framework/CHIP/MTROTAProviderDelegateBridge.mm b/src/darwin/Framework/CHIP/MTROTAProviderDelegateBridge.mm index 8d82a33d6940df..c2ce1b39548b47 100644 --- a/src/darwin/Framework/CHIP/MTROTAProviderDelegateBridge.mm +++ b/src/darwin/Framework/CHIP/MTROTAProviderDelegateBridge.mm @@ -16,7 +16,7 @@ */ #import "MTROTAProviderDelegateBridge.h" -#import "MTRControllerFactory_Internal.h" +#import "MTRDeviceControllerFactory_Internal.h" #import "NSDataSpanConversion.h" #import "NSStringSpanConversion.h" @@ -149,7 +149,7 @@ CHIP_ERROR OnTransferSessionBegin(TransferSession::OutputEvent & event) }); }; - auto * controller = [[MTRControllerFactory sharedInstance] runningControllerForFabricIndex:mFabricIndex.Value()]; + auto * controller = [[MTRDeviceControllerFactory sharedInstance] runningControllerForFabricIndex:mFabricIndex.Value()]; VerifyOrReturnError(controller != nil, CHIP_ERROR_INCORRECT_STATE); auto nodeId = @(mNodeId.Value()); @@ -186,7 +186,7 @@ CHIP_ERROR OnTransferSessionEnd(TransferSession::OutputEvent & event) error = CHIP_ERROR_INTERNAL; } - auto * controller = [[MTRControllerFactory sharedInstance] runningControllerForFabricIndex:mFabricIndex.Value()]; + auto * controller = [[MTRDeviceControllerFactory sharedInstance] runningControllerForFabricIndex:mFabricIndex.Value()]; VerifyOrReturnError(controller != nil, CHIP_ERROR_INCORRECT_STATE); auto nodeId = @(mNodeId.Value()); @@ -236,7 +236,7 @@ CHIP_ERROR OnBlockQuery(TransferSession::OutputEvent & event) // TODO Handle MaxLength - auto * controller = [[MTRControllerFactory sharedInstance] runningControllerForFabricIndex:mFabricIndex.Value()]; + auto * controller = [[MTRDeviceControllerFactory sharedInstance] runningControllerForFabricIndex:mFabricIndex.Value()]; VerifyOrReturnError(controller != nil, CHIP_ERROR_INCORRECT_STATE); auto nodeId = @(mNodeId.Value()); @@ -387,7 +387,7 @@ bool GetPeerNodeInfo(CommandHandler * commandHandler, const ConcreteCommandPath } auto * controller = - [[MTRControllerFactory sharedInstance] runningControllerForFabricIndex:commandHandler->GetAccessingFabricIndex()]; + [[MTRDeviceControllerFactory sharedInstance] runningControllerForFabricIndex:commandHandler->GetAccessingFabricIndex()]; if (controller == nil) { commandHandler->AddStatus(commandPath, Status::Failure); return false; diff --git a/src/darwin/Framework/CHIP/Matter.h b/src/darwin/Framework/CHIP/Matter.h index c42a242c6b1859..dc71d1cb998dd5 100644 --- a/src/darwin/Framework/CHIP/Matter.h +++ b/src/darwin/Framework/CHIP/Matter.h @@ -37,11 +37,11 @@ #import #import #import -#import #import #import #import #import +#import #import #import #import diff --git a/src/darwin/Framework/CHIPTests/MTRControllerTests.m b/src/darwin/Framework/CHIPTests/MTRControllerTests.m index 9a0a551ab34eb5..78169202dd9a94 100644 --- a/src/darwin/Framework/CHIPTests/MTRControllerTests.m +++ b/src/darwin/Framework/CHIPTests/MTRControllerTests.m @@ -37,27 +37,73 @@ @implementation MTRControllerTests - (void)testFactoryLifecycle { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); XCTAssertFalse([factory isRunning]); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); // Now try to restart the factory. - XCTAssertTrue([factory startup:factoryParams]); + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerLifecycle +{ + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; + XCTAssertNotNil(factory); + + __auto_type * storage = [[MTRTestStorage alloc] init]; + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); + XCTAssertTrue([factory isRunning]); + + __auto_type * testKeys = [[MTRTestKeys alloc] init]; + XCTAssertNotNil(testKeys); + + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:testKeys.ipk fabricID:@(1) nocSigner:testKeys]; + XCTAssertNotNil(params); + + params.vendorID = @(kTestVendorId); + + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; + XCTAssertNotNil(controller); + XCTAssertTrue([controller isRunning]); + + [controller shutdown]; + XCTAssertFalse([controller isRunning]); + + // now try to restart the controller + controller = [factory createControllerOnExistingFabric:params error:nil]; + XCTAssertNotNil(controller); + XCTAssertTrue([controller isRunning]); + + [controller shutdown]; + XCTAssertFalse([controller isRunning]); + + // now try to restart the controller without providing a vendor id. + params.vendorID = nil; + controller = [factory createControllerOnExistingFabric:params error:nil]; + XCTAssertNotNil(controller); + XCTAssertTrue([controller isRunning]); + + [controller shutdown]; + XCTAssertFalse([controller isRunning]); + + [factory stopControllerFactory]; + XCTAssertFalse([factory isRunning]); +} + +- (void)testDeprecatedControllerLifecycle { __auto_type * factory = [MTRControllerFactory sharedInstance]; XCTAssertNotNil(factory); @@ -70,9 +116,7 @@ - (void)testControllerLifecycle __auto_type * testKeys = [[MTRTestKeys alloc] init]; XCTAssertNotNil(testKeys); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:testKeys - fabricID:@(1) - ipk:testKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:testKeys.ipk fabricID:@(1) nocSigner:testKeys]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); @@ -107,145 +151,135 @@ - (void)testControllerLifecycle - (void)testFactoryShutdownShutsDownController { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * testKeys = [[MTRTestKeys alloc] init]; XCTAssertNotNil(testKeys); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:testKeys - fabricID:@(1) - ipk:testKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:testKeys.ipk fabricID:@(1) nocSigner:testKeys]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); XCTAssertFalse([controller isRunning]); } - (void)testControllerMultipleShutdown { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * testKeys = [[MTRTestKeys alloc] init]; XCTAssertNotNil(testKeys); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:testKeys - fabricID:@(1) - ipk:testKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:testKeys.ipk fabricID:@(1) nocSigner:testKeys]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertTrue([controller isRunning]); for (int i = 0; i < 5; i++) { [controller shutdown]; XCTAssertFalse([controller isRunning]); } - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerWithOTAProviderDelegate { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * otaProvider = [[MTRTestOTAProvider alloc] init]; __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; factoryParams.otaProviderDelegate = otaProvider; - XCTAssertTrue([factory startup:factoryParams]); + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * testKeys = [[MTRTestKeys alloc] init]; XCTAssertNotNil(testKeys); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:testKeys - fabricID:@(1) - ipk:testKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:testKeys.ipk fabricID:@(1) nocSigner:testKeys]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertTrue([controller isRunning]); [controller shutdown]; // OTA Provider depends on the system state maintained by CHIPDeviceControllerFactory that is destroyed when // the controller count goes down to 0. Make sure that a new controller can still be started successfully onto the // same fabric. - MTRDeviceController * controller2 = [factory startControllerOnExistingFabric:params]; + MTRDeviceController * controller2 = [factory createControllerOnExistingFabric:params error:nil]; XCTAssertTrue([controller2 isRunning]); [controller2 shutdown]; // Check that a new controller can be started on a different fabric too. - __auto_type * params2 = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:testKeys - fabricID:@(2) - ipk:testKeys.ipk]; + __auto_type * params2 = [[MTRDeviceControllerStartupParams alloc] initWithIPK:testKeys.ipk fabricID:@(2) nocSigner:testKeys]; XCTAssertNotNil(params2); params2.vendorID = @(kTestVendorId); - MTRDeviceController * controller3 = [factory startControllerOnNewFabric:params2]; + MTRDeviceController * controller3 = [factory createControllerOnNewFabric:params2 error:nil]; XCTAssertTrue([controller3 isRunning]); [controller3 shutdown]; // Stop the factory, start it up again and create a controller to ensure that no dead state from the previous // ota provider delegate is staying around. - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); - XCTAssertTrue([factory startup:factoryParams]); + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); - MTRDeviceController * controller4 = [factory startControllerOnExistingFabric:params2]; + MTRDeviceController * controller4 = [factory createControllerOnExistingFabric:params2 error:nil]; XCTAssertTrue([controller4 isRunning]); [controller4 shutdown]; - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerInvalidAccess { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * testKeys = [[MTRTestKeys alloc] init]; XCTAssertNotNil(testKeys); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:testKeys - fabricID:@(1) - ipk:testKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:testKeys.ipk fabricID:@(1) nocSigner:testKeys]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertTrue([controller isRunning]); [controller shutdown]; @@ -256,31 +290,29 @@ - (void)testControllerInvalidAccess XCTAssertEqual(error.code, MTRErrorCodeInvalidState); }]); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerNewFabricMatchesOldFabric { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * testKeys = [[MTRTestKeys alloc] init]; XCTAssertNotNil(testKeys); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:testKeys - fabricID:@(1) - ipk:testKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:testKeys.ipk fabricID:@(1) nocSigner:testKeys]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -289,88 +321,82 @@ - (void)testControllerNewFabricMatchesOldFabric // now try to start a new controller on a new fabric but using the // same params; this should fail. - XCTAssertNil([factory startControllerOnNewFabric:params]); + XCTAssertNil([factory createControllerOnNewFabric:params error:nil]); XCTAssertFalse([controller isRunning]); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerExistingFabricMatchesRunningController { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * testKeys = [[MTRTestKeys alloc] init]; XCTAssertNotNil(testKeys); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:testKeys - fabricID:@(1) - ipk:testKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:testKeys.ipk fabricID:@(1) nocSigner:testKeys]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); // Now try to start a new controller on the same fabric. This should fail. - XCTAssertNil([factory startControllerOnExistingFabric:params]); + XCTAssertNil([factory createControllerOnExistingFabric:params error:nil]); XCTAssertTrue([controller isRunning]); [controller shutdown]; XCTAssertFalse([controller isRunning]); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerStartControllersOnTwoFabricIds { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * testKeys = [[MTRTestKeys alloc] init]; XCTAssertNotNil(testKeys); - __auto_type * params1 = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:testKeys - fabricID:@(1) - ipk:testKeys.ipk]; + __auto_type * params1 = [[MTRDeviceControllerStartupParams alloc] initWithIPK:testKeys.ipk fabricID:@(1) nocSigner:testKeys]; XCTAssertNotNil(params1); params1.vendorID = @(kTestVendorId); - MTRDeviceController * controller1 = [factory startControllerOnNewFabric:params1]; + MTRDeviceController * controller1 = [factory createControllerOnNewFabric:params1 error:nil]; XCTAssertNotNil(controller1); XCTAssertTrue([controller1 isRunning]); // Now try to start a new controller with the same root but a // different fabric id. - __auto_type * params2 = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:testKeys - fabricID:@(2) - ipk:testKeys.ipk]; + __auto_type * params2 = [[MTRDeviceControllerStartupParams alloc] initWithIPK:testKeys.ipk fabricID:@(2) nocSigner:testKeys]; XCTAssertNotNil(params2); params2.vendorID = @(kTestVendorId); - MTRDeviceController * controller2 = [factory startControllerOnNewFabric:params2]; + MTRDeviceController * controller2 = [factory createControllerOnNewFabric:params2 error:nil]; XCTAssertNotNil(controller2); XCTAssertTrue([controller2 isRunning]); - XCTAssertNil([factory startControllerOnExistingFabric:params2]); + XCTAssertNil([factory createControllerOnExistingFabric:params2 error:nil]); [controller1 shutdown]; XCTAssertFalse([controller1 isRunning]); @@ -378,18 +404,18 @@ - (void)testControllerStartControllersOnTwoFabricIds [controller2 shutdown]; XCTAssertFalse([controller2 isRunning]); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerStartControllerSameFabricWrongSubject { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * testKeys = [[MTRTestKeys alloc] init]; @@ -404,15 +430,13 @@ - (void)testControllerStartControllerSameFabricWrongSubject __auto_type * root3 = [MTRCertificates createRootCertificate:testKeys issuerID:@2 fabricID:@1 error:nil]; XCTAssertNotNil(root3); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:testKeys - fabricID:@(1) - ipk:testKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:testKeys.ipk fabricID:@(1) nocSigner:testKeys]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); params.rootCertificate = root1; - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -422,7 +446,7 @@ - (void)testControllerStartControllerSameFabricWrongSubject // Now try to start a new controller on the same fabric with what should be // a compatible root certificate. params.rootCertificate = root2; - controller = [factory startControllerOnExistingFabric:params]; + controller = [factory createControllerOnExistingFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -436,7 +460,7 @@ - (void)testControllerStartControllerSameFabricWrongSubject // reasons, including our existing operational certificate not matching this // root. params.rootCertificate = root3; - controller = [factory startControllerOnExistingFabric:params]; + controller = [factory createControllerOnExistingFabric:params error:nil]; XCTAssertNil(controller); // Now try to start a new controller on the same fabric but with a root @@ -445,21 +469,21 @@ - (void)testControllerStartControllerSameFabricWrongSubject // the fabric would change if we allowed this. params.rootCertificate = root3; params.nodeID = nodeId; - controller = [factory startControllerOnExistingFabric:params]; + controller = [factory createControllerOnExistingFabric:params error:nil]; XCTAssertNil(controller); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerFabricIdRootCertMismatch { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * testKeys = [[MTRTestKeys alloc] init]; @@ -471,21 +495,19 @@ - (void)testControllerFabricIdRootCertMismatch __auto_type * root2 = [MTRCertificates createRootCertificate:testKeys issuerID:@1 fabricID:@2 error:nil]; XCTAssertNotNil(root2); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:testKeys - fabricID:@(1) - ipk:testKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:testKeys.ipk fabricID:@(1) nocSigner:testKeys]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); // Try to start controller when fabric id in root cert subject does not match provided fabric id. params.rootCertificate = root2; - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNil(controller); // Start controller when the fabric ids do match. params.rootCertificate = root1; - controller = [factory startControllerOnNewFabric:params]; + controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -493,7 +515,7 @@ - (void)testControllerFabricIdRootCertMismatch XCTAssertFalse([controller isRunning]); // Re-start controller on the new fabric. - controller = [factory startControllerOnExistingFabric:params]; + controller = [factory createControllerOnExistingFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -503,21 +525,21 @@ - (void)testControllerFabricIdRootCertMismatch // Now try to restart controller on the fabric, but with the wrong fabric id // in the root cert. params.rootCertificate = root2; - controller = [factory startControllerOnExistingFabric:params]; + controller = [factory createControllerOnExistingFabric:params error:nil]; XCTAssertNil(controller); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerSignerDoesNotMatchRoot { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * rootKeys = [[MTRTestKeys alloc] init]; @@ -529,9 +551,7 @@ - (void)testControllerSignerDoesNotMatchRoot __auto_type * root = [MTRCertificates createRootCertificate:rootKeys issuerID:nil fabricID:nil error:nil]; XCTAssertNotNil(root); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:signerKeys - fabricID:@(1) - ipk:rootKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:rootKeys.ipk fabricID:@(1) nocSigner:signerKeys]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); @@ -539,21 +559,21 @@ - (void)testControllerSignerDoesNotMatchRoot // Try to start controller when there is no ICA and root cert does not match signing key. params.rootCertificate = root; - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNil(controller); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerSignerKeyWithIntermediate { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * rootKeys = [[MTRTestKeys alloc] init]; @@ -573,9 +593,7 @@ - (void)testControllerSignerKeyWithIntermediate error:nil]; XCTAssertNotNil(intermediate); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:rootKeys - fabricID:@(1) - ipk:rootKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:rootKeys.ipk fabricID:@(1) nocSigner:rootKeys]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); @@ -583,97 +601,91 @@ - (void)testControllerSignerKeyWithIntermediate // Try to start controller when there is an ICA and the ICA cert does not match signing key. params.rootCertificate = root; params.intermediateCertificate = intermediate; - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNil(controller); // Now start controller with the signing key matching the intermediate cert. - params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:intermediateKeys fabricID:@(1) ipk:rootKeys.ipk]; + params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:rootKeys.ipk fabricID:@(1) nocSigner:intermediateKeys]; params.vendorID = @(kTestVendorId); params.rootCertificate = root; params.intermediateCertificate = intermediate; - controller = [factory startControllerOnNewFabric:params]; + controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); [controller shutdown]; XCTAssertFalse([controller isRunning]); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerStartupParamsInvalidFabric { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * rootKeys = [[MTRTestKeys alloc] init]; XCTAssertNotNil(rootKeys); // Invalid fabric ID. - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:rootKeys - fabricID:@(0) - ipk:rootKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:rootKeys.ipk fabricID:@(0) nocSigner:rootKeys]; XCTAssertNil(params); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerStartupParamsInvalidVendor { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * rootKeys = [[MTRTestKeys alloc] init]; XCTAssertNotNil(rootKeys); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:rootKeys - fabricID:@(1) - ipk:rootKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:rootKeys.ipk fabricID:@(1) nocSigner:rootKeys]; XCTAssertNotNil(params); // Invalid vendor ID ("standard"). params.vendorID = @(0); - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNil(controller); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerStartupNodeIdPreserved { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * rootKeys = [[MTRTestKeys alloc] init]; XCTAssertNotNil(rootKeys); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:rootKeys - fabricID:@(1) - ipk:rootKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:rootKeys.ipk fabricID:@(1) nocSigner:rootKeys]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -682,7 +694,7 @@ - (void)testControllerStartupNodeIdPreserved [controller shutdown]; XCTAssertFalse([controller isRunning]); - controller = [factory startControllerOnExistingFabric:params]; + controller = [factory createControllerOnExistingFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -691,33 +703,31 @@ - (void)testControllerStartupNodeIdPreserved [controller shutdown]; XCTAssertFalse([controller isRunning]); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerStartupNodeIdUsed { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * rootKeys = [[MTRTestKeys alloc] init]; XCTAssertNotNil(rootKeys); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:rootKeys - fabricID:@(1) - ipk:rootKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:rootKeys.ipk fabricID:@(1) nocSigner:rootKeys]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); // Bring up with node id 17. params.nodeID = @17; - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -728,7 +738,7 @@ - (void)testControllerStartupNodeIdUsed // Bring up with a different node id (18). params.nodeID = @18; - controller = [factory startControllerOnExistingFabric:params]; + controller = [factory createControllerOnExistingFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -739,7 +749,7 @@ - (void)testControllerStartupNodeIdUsed // Verify the new node id has been stored. params.nodeID = nil; - controller = [factory startControllerOnExistingFabric:params]; + controller = [factory createControllerOnExistingFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -748,43 +758,41 @@ - (void)testControllerStartupNodeIdUsed [controller shutdown]; XCTAssertFalse([controller isRunning]); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerStartupNodeIdValidation { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * rootKeys = [[MTRTestKeys alloc] init]; XCTAssertNotNil(rootKeys); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:rootKeys - fabricID:@(1) - ipk:rootKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:rootKeys.ipk fabricID:@(1) nocSigner:rootKeys]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); // Try to bring up with node id 0. params.nodeID = @0; - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNil(controller); // Try to bring up with node id that is outside of the operational range. params.nodeID = @(0xFFFFFFFF00000000ULL); - controller = [factory startControllerOnNewFabric:params]; + controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNil(controller); // Verify that we can indeed bring up a controller for this fabric, with a valid node id. params.nodeID = @17; - controller = [factory startControllerOnNewFabric:params]; + controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -793,19 +801,19 @@ - (void)testControllerStartupNodeIdValidation [controller shutdown]; XCTAssertFalse([controller isRunning]); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerRotateToICA { // Tests that we can switch a fabric from not using an ICA to using an ICA. - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * rootKeys = [[MTRTestKeys alloc] init]; @@ -825,16 +833,14 @@ - (void)testControllerRotateToICA error:nil]; XCTAssertNotNil(intermediate); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:rootKeys - fabricID:@(1) - ipk:rootKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:rootKeys.ipk fabricID:@(1) nocSigner:rootKeys]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); // Create a new fabric without the ICA. params.rootCertificate = root; - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -844,11 +850,11 @@ - (void)testControllerRotateToICA XCTAssertFalse([controller isRunning]); // Now start controller on the same fabric but using the ICA. - params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:intermediateKeys fabricID:@(1) ipk:rootKeys.ipk]; + params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:rootKeys.ipk fabricID:@(1) nocSigner:intermediateKeys]; params.vendorID = @(kTestVendorId); params.rootCertificate = root; params.intermediateCertificate = intermediate; - controller = [factory startControllerOnExistingFabric:params]; + controller = [factory createControllerOnExistingFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -857,19 +863,19 @@ - (void)testControllerRotateToICA [controller shutdown]; XCTAssertFalse([controller isRunning]); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerRotateFromICA { // Tests that we can switch a fabric from using an ICA to not using an ICA. - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * rootKeys = [[MTRTestKeys alloc] init]; @@ -889,9 +895,9 @@ - (void)testControllerRotateFromICA error:nil]; XCTAssertNotNil(intermediate); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:intermediateKeys - fabricID:@(1) - ipk:rootKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:rootKeys.ipk + fabricID:@(1) + nocSigner:intermediateKeys]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); @@ -899,7 +905,7 @@ - (void)testControllerRotateFromICA // Create a new fabric without the ICA. params.rootCertificate = root; params.intermediateCertificate = intermediate; - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -909,10 +915,10 @@ - (void)testControllerRotateFromICA XCTAssertFalse([controller isRunning]); // Now start controller on the same fabric but without using the ICA. - params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:rootKeys fabricID:@(1) ipk:rootKeys.ipk]; + params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:rootKeys.ipk fabricID:@(1) nocSigner:rootKeys]; params.vendorID = @(kTestVendorId); params.rootCertificate = root; - controller = [factory startControllerOnExistingFabric:params]; + controller = [factory createControllerOnExistingFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -921,19 +927,19 @@ - (void)testControllerRotateFromICA [controller shutdown]; XCTAssertFalse([controller isRunning]); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerRotateICA { // Tests that we can change the ICA being used for a fabric. - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * rootKeys = [[MTRTestKeys alloc] init]; @@ -964,9 +970,9 @@ - (void)testControllerRotateICA error:nil]; XCTAssertNotNil(intermediate2); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:intermediateKeys1 - fabricID:@(1) - ipk:rootKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:rootKeys.ipk + fabricID:@(1) + nocSigner:intermediateKeys1]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); @@ -974,7 +980,7 @@ - (void)testControllerRotateICA // Create a new fabric without the first ICA. params.rootCertificate = root; params.intermediateCertificate = intermediate1; - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -984,11 +990,11 @@ - (void)testControllerRotateICA XCTAssertFalse([controller isRunning]); // Now start controller on the same fabric but using the second ICA. - params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:intermediateKeys2 fabricID:@(1) ipk:rootKeys.ipk]; + params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:rootKeys.ipk fabricID:@(1) nocSigner:intermediateKeys2]; params.vendorID = @(kTestVendorId); params.rootCertificate = root; params.intermediateCertificate = intermediate2; - controller = [factory startControllerOnExistingFabric:params]; + controller = [factory createControllerOnExistingFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -997,18 +1003,18 @@ - (void)testControllerRotateICA [controller shutdown]; XCTAssertFalse([controller isRunning]); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerICAWithoutRoot { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * rootKeys = [[MTRTestKeys alloc] init]; @@ -1028,30 +1034,30 @@ - (void)testControllerICAWithoutRoot error:nil]; XCTAssertNotNil(intermediate); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:intermediateKeys - fabricID:@(1) - ipk:rootKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:rootKeys.ipk + fabricID:@(1) + nocSigner:intermediateKeys]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); // Pass in an intermediate but no root. Should fail. params.intermediateCertificate = intermediate; - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNil(controller); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerProvideFullCertChain { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * rootKeys = [[MTRTestKeys alloc] init]; @@ -1083,16 +1089,16 @@ - (void)testControllerProvideFullCertChain error:nil]; XCTAssertNotNil(operational); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithOperationalKeypair:operationalKeys - operationalCertificate:operational - intermediateCertificate:intermediate - rootCertificate:root - ipk:rootKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:rootKeys.ipk + operationalKeypair:operationalKeys + operationalCertificate:operational + intermediateCertificate:intermediate + rootCertificate:root]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -1102,11 +1108,11 @@ - (void)testControllerProvideFullCertChain XCTAssertFalse([controller isRunning]); // Trying to bring up another new fabric with the same root and NOC should fail. - controller = [factory startControllerOnNewFabric:params]; + controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNil(controller); // Trying to bring up the same fabric should succeed. - controller = [factory startControllerOnExistingFabric:params]; + controller = [factory createControllerOnExistingFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -1115,18 +1121,18 @@ - (void)testControllerProvideFullCertChain [controller shutdown]; XCTAssertFalse([controller isRunning]); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerProvideCertChainNoICA { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * rootKeys = [[MTRTestKeys alloc] init]; @@ -1147,16 +1153,16 @@ - (void)testControllerProvideCertChainNoICA error:nil]; XCTAssertNotNil(operational); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithOperationalKeypair:operationalKeys - operationalCertificate:operational - intermediateCertificate:nil - rootCertificate:root - ipk:rootKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:rootKeys.ipk + operationalKeypair:operationalKeys + operationalCertificate:operational + intermediateCertificate:nil + rootCertificate:root]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -1165,18 +1171,18 @@ - (void)testControllerProvideCertChainNoICA [controller shutdown]; XCTAssertFalse([controller isRunning]); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerCertChainFabricMismatchRoot { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * rootKeys = [[MTRTestKeys alloc] init]; @@ -1197,30 +1203,30 @@ - (void)testControllerCertChainFabricMismatchRoot error:nil]; XCTAssertNotNil(operational); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithOperationalKeypair:operationalKeys - operationalCertificate:operational - intermediateCertificate:nil - rootCertificate:root - ipk:rootKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:rootKeys.ipk + operationalKeypair:operationalKeys + operationalCertificate:operational + intermediateCertificate:nil + rootCertificate:root]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNil(controller); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerCertChainFabricMismatchIntermediate { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * rootKeys = [[MTRTestKeys alloc] init]; @@ -1252,30 +1258,30 @@ - (void)testControllerCertChainFabricMismatchIntermediate error:nil]; XCTAssertNotNil(operational); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithOperationalKeypair:operationalKeys - operationalCertificate:operational - intermediateCertificate:intermediate - rootCertificate:root - ipk:rootKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:rootKeys.ipk + operationalKeypair:operationalKeys + operationalCertificate:operational + intermediateCertificate:intermediate + rootCertificate:root]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNil(controller); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } - (void)testControllerExternallyProvidedOperationalKey { - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; - XCTAssertTrue([factory startup:factoryParams]); + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; + XCTAssertTrue([factory startControllerFactory:factoryParams error:nil]); XCTAssertTrue([factory isRunning]); __auto_type * rootKeys = [[MTRTestKeys alloc] init]; @@ -1284,15 +1290,13 @@ - (void)testControllerExternallyProvidedOperationalKey __auto_type * operationalKeys = [[MTRTestKeys alloc] init]; XCTAssertNotNil(operationalKeys); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:rootKeys - fabricID:@(1) - ipk:rootKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:rootKeys.ipk fabricID:@(1) nocSigner:rootKeys]; XCTAssertNotNil(params); params.vendorID = @(kTestVendorId); params.operationalKeypair = operationalKeys; - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -1305,13 +1309,13 @@ - (void)testControllerExternallyProvidedOperationalKey // keypair should now fail, because we won't know what operational keys to // use. params.operationalKeypair = nil; - controller = [factory startControllerOnExistingFabric:params]; + controller = [factory createControllerOnExistingFabric:params error:nil]; XCTAssertNil(controller); // But bringing up the controller with provided operational keys should // work, and have the same node id. params.operationalKeypair = operationalKeys; - controller = [factory startControllerOnExistingFabric:params]; + controller = [factory createControllerOnExistingFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -1326,7 +1330,7 @@ - (void)testControllerExternallyProvidedOperationalKey XCTAssertNotNil(newOperationalKeys); params.operationalKeypair = newOperationalKeys; - controller = [factory startControllerOnExistingFabric:params]; + controller = [factory createControllerOnExistingFabric:params error:nil]; XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); @@ -1335,7 +1339,7 @@ - (void)testControllerExternallyProvidedOperationalKey [controller shutdown]; XCTAssertFalse([controller isRunning]); - [factory shutdown]; + [factory stopControllerFactory]; XCTAssertFalse([factory isRunning]); } diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m index a0ea3163cec7c3..a01e9b87a4467d 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m @@ -161,14 +161,14 @@ - (void)initStack { XCTestExpectation * expectation = [self expectationWithDescription:@"Pairing Complete"]; - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; factoryParams.port = @(kLocalPort); - BOOL ok = [factory startup:factoryParams]; + BOOL ok = [factory startControllerFactory:factoryParams error:nil]; XCTAssertTrue(ok); __auto_type * testKeys = [[MTRTestKeys alloc] init]; @@ -178,12 +178,10 @@ - (void)initStack // Needs to match what startControllerOnExistingFabric calls elsewhere in // this file do. - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:testKeys - fabricID:@(1) - ipk:testKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:testKeys.ipk fabricID:@(1) nocSigner:testKeys]; params.vendorID = @(kTestVendorId); - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:nil]; XCTAssertNotNil(controller); sController = controller; @@ -222,7 +220,7 @@ - (void)shutdownStack [controller shutdown]; XCTAssertFalse([controller isRunning]); - [[MTRControllerFactory sharedInstance] shutdown]; + [[MTRDeviceControllerFactory sharedInstance] stopControllerFactory]; } - (void)waitForCommissionee diff --git a/src/darwin/Framework/CHIPTests/MTRXPCListenerSampleTests.m b/src/darwin/Framework/CHIPTests/MTRXPCListenerSampleTests.m index 15239cc92bde81..df9006b277fd4f 100644 --- a/src/darwin/Framework/CHIPTests/MTRXPCListenerSampleTests.m +++ b/src/darwin/Framework/CHIPTests/MTRXPCListenerSampleTests.m @@ -528,26 +528,27 @@ - (void)initStack { XCTestExpectation * expectation = [self expectationWithDescription:@"Pairing Complete"]; - __auto_type * factory = [MTRControllerFactory sharedInstance]; + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); __auto_type * storage = [[MTRTestStorage alloc] init]; - __auto_type * factoryParams = [[MTRControllerFactoryParams alloc] initWithStorage:storage]; + __auto_type * factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; factoryParams.port = @(kLocalPort); - BOOL ok = [factory startup:factoryParams]; + NSError * error; + BOOL ok = [factory startControllerFactory:factoryParams error:&error]; XCTAssertTrue(ok); + XCTAssertNil(error); __auto_type * testKeys = [[MTRTestKeys alloc] init]; XCTAssertNotNil(testKeys); - __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithSigningKeypair:testKeys - fabricID:@(1) - ipk:testKeys.ipk]; + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:testKeys.ipk fabricID:@(1) nocSigner:testKeys]; params.vendorID = @(kTestVendorId); - MTRDeviceController * controller = [factory startControllerOnNewFabric:params]; + MTRDeviceController * controller = [factory createControllerOnNewFabric:params error:&error]; XCTAssertNotNil(controller); + XCTAssertNil(error); sController = controller; @@ -557,7 +558,6 @@ - (void)initStack [controller setPairingDelegate:pairing queue:callbackQueue]; - NSError * error; __auto_type * payload = [MTRSetupPayload setupPayloadWithOnboardingPayload:kOnboardingPayload error:&error]; XCTAssertNotNil(payload); XCTAssertNil(error); @@ -593,7 +593,7 @@ - (void)shutdownStack [controller shutdown]; XCTAssertFalse([controller isRunning]); - [[MTRControllerFactory sharedInstance] shutdown]; + [[MTRDeviceControllerFactory sharedInstance] stopControllerFactory]; mDeviceController = nil; } diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index 6501179acc3b6e..0cf5642bf40f9b 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -43,9 +43,9 @@ 511913FC28C100EF009235E9 /* MTRBaseSubscriptionCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 511913FA28C100EF009235E9 /* MTRBaseSubscriptionCallback.h */; }; 5129BCFD26A9EE3300122DDF /* MTRError.h in Headers */ = {isa = PBXBuildFile; fileRef = 5129BCFC26A9EE3300122DDF /* MTRError.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5136661328067D550025EDAE /* MTRDeviceController_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5136660F28067D540025EDAE /* MTRDeviceController_Internal.h */; }; - 5136661428067D550025EDAE /* MTRControllerFactory.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5136661028067D540025EDAE /* MTRControllerFactory.mm */; }; - 5136661528067D550025EDAE /* MTRControllerFactory_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5136661128067D540025EDAE /* MTRControllerFactory_Internal.h */; }; - 5136661628067D550025EDAE /* MTRControllerFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 5136661228067D550025EDAE /* MTRControllerFactory.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5136661428067D550025EDAE /* MTRDeviceControllerFactory.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5136661028067D540025EDAE /* MTRDeviceControllerFactory.mm */; }; + 5136661528067D550025EDAE /* MTRDeviceControllerFactory_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5136661128067D540025EDAE /* MTRDeviceControllerFactory_Internal.h */; }; + 5136661628067D550025EDAE /* MTRDeviceControllerFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 5136661228067D550025EDAE /* MTRDeviceControllerFactory.h */; settings = {ATTRIBUTES = (Public, ); }; }; 513DDB862761F69300DAA01A /* MTRAttributeTLVValueDecoder_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 513DDB852761F69300DAA01A /* MTRAttributeTLVValueDecoder_Internal.h */; }; 513DDB8A2761F6F900DAA01A /* MTRAttributeTLVValueDecoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 513DDB892761F6F900DAA01A /* MTRAttributeTLVValueDecoder.mm */; }; 514304202914CED9004DC7FE /* generic-callback-stubs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5143041F2914CED9004DC7FE /* generic-callback-stubs.cpp */; }; @@ -184,9 +184,9 @@ 511913FA28C100EF009235E9 /* MTRBaseSubscriptionCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRBaseSubscriptionCallback.h; sourceTree = ""; }; 5129BCFC26A9EE3300122DDF /* MTRError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRError.h; sourceTree = ""; }; 5136660F28067D540025EDAE /* MTRDeviceController_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRDeviceController_Internal.h; sourceTree = ""; }; - 5136661028067D540025EDAE /* MTRControllerFactory.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRControllerFactory.mm; sourceTree = ""; }; - 5136661128067D540025EDAE /* MTRControllerFactory_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRControllerFactory_Internal.h; sourceTree = ""; }; - 5136661228067D550025EDAE /* MTRControllerFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRControllerFactory.h; sourceTree = ""; }; + 5136661028067D540025EDAE /* MTRDeviceControllerFactory.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRDeviceControllerFactory.mm; sourceTree = ""; }; + 5136661128067D540025EDAE /* MTRDeviceControllerFactory_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRDeviceControllerFactory_Internal.h; sourceTree = ""; }; + 5136661228067D550025EDAE /* MTRDeviceControllerFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRDeviceControllerFactory.h; sourceTree = ""; }; 513DDB852761F69300DAA01A /* MTRAttributeTLVValueDecoder_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRAttributeTLVValueDecoder_Internal.h; sourceTree = ""; }; 513DDB892761F6F900DAA01A /* MTRAttributeTLVValueDecoder.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MTRAttributeTLVValueDecoder.mm; path = "zap-generated/MTRAttributeTLVValueDecoder.mm"; sourceTree = ""; }; 5143041F2914CED9004DC7FE /* generic-callback-stubs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "generic-callback-stubs.cpp"; path = "../../../app/util/generic-callback-stubs.cpp"; sourceTree = ""; }; @@ -426,12 +426,12 @@ 991DC0822475F45400C13860 /* MTRDeviceController.h */, 991DC0872475F47D00C13860 /* MTRDeviceController.mm */, 5136660F28067D540025EDAE /* MTRDeviceController_Internal.h */, - 5136661128067D540025EDAE /* MTRControllerFactory_Internal.h */, + 5136661128067D540025EDAE /* MTRDeviceControllerFactory_Internal.h */, 51E51FBD282AD37A00FC978D /* MTRDeviceControllerStartupParams_Internal.h */, 51E51FBC282AD37A00FC978D /* MTRDeviceControllerStartupParams.h */, 51E51FBE282AD37A00FC978D /* MTRDeviceControllerStartupParams.mm */, - 5136661228067D550025EDAE /* MTRControllerFactory.h */, - 5136661028067D540025EDAE /* MTRControllerFactory.mm */, + 5136661228067D550025EDAE /* MTRDeviceControllerFactory.h */, + 5136661028067D540025EDAE /* MTRDeviceControllerFactory.mm */, 5A7947E227C0101200434CF2 /* MTRDeviceController+XPC.h */, 517BF3EE282B62B800A8B7DB /* MTRCertificates.h */, 517BF3EF282B62B800A8B7DB /* MTRCertificates.mm */, @@ -502,7 +502,7 @@ files = ( 517BF3F0282B62B800A8B7DB /* MTRCertificates.h in Headers */, 51E51FBF282AD37A00FC978D /* MTRDeviceControllerStartupParams.h in Headers */, - 5136661628067D550025EDAE /* MTRControllerFactory.h in Headers */, + 5136661628067D550025EDAE /* MTRDeviceControllerFactory.h in Headers */, 7596A84B287636C1004DAE0E /* MTRDevice_Internal.h in Headers */, 5A6FEC9927B5C88900F25F42 /* MTRDeviceOverXPC.h in Headers */, 51B22C222740CB1D008D5055 /* MTRCommandPayloadsObjc.h in Headers */, @@ -513,7 +513,7 @@ 2C1B027B2641DB4E00780EF1 /* MTROperationalCredentialsDelegate.h in Headers */, 7596A85728788557004DAE0E /* MTRClusters.h in Headers */, 99D466E12798936D0089A18F /* MTRCommissioningParameters.h in Headers */, - 5136661528067D550025EDAE /* MTRControllerFactory_Internal.h in Headers */, + 5136661528067D550025EDAE /* MTRDeviceControllerFactory_Internal.h in Headers */, 515C1C70284F9FFB00A48F0C /* MTRMemory.h in Headers */, 7534F12928BFF20300390851 /* MTRDeviceAttestationDelegate_Internal.h in Headers */, D4772A46285AE98400383630 /* MTRClusterConstants.h in Headers */, @@ -694,7 +694,7 @@ 515C1C6F284F9FFB00A48F0C /* MTRMemory.mm in Sources */, 27A53C1827FBC6920053F131 /* MTRAttestationTrustStoreBridge.mm in Sources */, 998F287126D56940001846C6 /* MTRP256KeypairBridge.mm in Sources */, - 5136661428067D550025EDAE /* MTRControllerFactory.mm in Sources */, + 5136661428067D550025EDAE /* MTRDeviceControllerFactory.mm in Sources */, 51B22C2A2740CB47008D5055 /* MTRCommandPayloadsObjc.mm in Sources */, AF5F90FF2878D351005503FA /* MTROTAProviderDelegateBridge.mm in Sources */, 7534F12828BFF20300390851 /* MTRDeviceAttestationDelegate.mm in Sources */, diff --git a/src/platform/EFR32/OTAImageProcessorImpl.cpp b/src/platform/EFR32/OTAImageProcessorImpl.cpp index c8c717e191837a..70b1349ce378b6 100644 --- a/src/platform/EFR32/OTAImageProcessorImpl.cpp +++ b/src/platform/EFR32/OTAImageProcessorImpl.cpp @@ -21,8 +21,8 @@ #include extern "C" { -#include "platform/bootloader/api/btl_interface.h" -#include "platform/emlib/inc/em_bus.h" // For CORE_CRITICAL_SECTION +#include "btl_interface.h" +#include "em_bus.h" // For CORE_CRITICAL_SECTION } #include "EFR32Config.h" diff --git a/src/platform/Linux/PlatformManagerImpl.cpp b/src/platform/Linux/PlatformManagerImpl.cpp index 9daa120976dfd4..e29f04bd1d0383 100644 --- a/src/platform/Linux/PlatformManagerImpl.cpp +++ b/src/platform/Linux/PlatformManagerImpl.cpp @@ -288,6 +288,14 @@ CHIP_ERROR PlatformManagerImpl::RunOnGLibMainLoopThread(GSourceFunc callback, vo VerifyOrReturnError(context != nullptr, (ChipLogDetail(DeviceLayer, "Failed to get GLib main loop context"), CHIP_ERROR_INTERNAL)); + // If we've been called from the GLib main loop thread itself, there is no reason to wait + // for the callback, as it will be executed immediately by the g_main_context_invoke() call + // below. Using a callback indirection in this case would cause a deadlock. + if (g_main_context_is_owner(context)) + { + wait = false; + } + if (wait) { std::unique_lock lock(mGLibMainLoopCallbackIndirectionMutex); diff --git a/src/platform/Linux/PlatformManagerImpl.h b/src/platform/Linux/PlatformManagerImpl.h index bc5bc7c10c4e4a..2b1bad0ea7fd2c 100644 --- a/src/platform/Linux/PlatformManagerImpl.h +++ b/src/platform/Linux/PlatformManagerImpl.h @@ -70,7 +70,7 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener * @brief Convenience method to require less casts to void pointers. */ template - CHIP_ERROR ScheduleOnGLibMainLoopThread(int (*callback)(T *), T * userData, bool wait = false) + CHIP_ERROR ScheduleOnGLibMainLoopThread(gboolean (*callback)(T *), T * userData, bool wait = false) { return RunOnGLibMainLoopThread(G_SOURCE_FUNC(callback), userData, wait); } diff --git a/src/platform/android/CHIPPlatformConfig.h b/src/platform/android/CHIPPlatformConfig.h index 245d61b0589c9d..19ba3d113517ef 100644 --- a/src/platform/android/CHIPPlatformConfig.h +++ b/src/platform/android/CHIPPlatformConfig.h @@ -32,7 +32,7 @@ using CHIP_CONFIG_PERSISTED_STORAGE_KEY_TYPE = const char *; #define CHIP_CONFIG_LIFETIIME_PERSISTED_COUNTER_KEY "life-count" -#define CHIP_CONFIG_ERROR_FORMAT_AS_STRING 0 +#define CHIP_CONFIG_ERROR_FORMAT_AS_STRING 1 #define CHIP_CONFIG_ERROR_SOURCE 1 // ==================== Security Adaptations ==================== diff --git a/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java b/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java index a3a4ecfa4822d2..11b6241d2deb85 100644 --- a/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java +++ b/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java @@ -25,9 +25,13 @@ import android.os.Handler; import android.os.Looper; import android.util.Log; +import androidx.annotation.Nullable; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; public class NsdManagerServiceResolver implements ServiceResolver { private static final String TAG = NsdManagerServiceResolver.class.getSimpleName(); @@ -37,8 +41,15 @@ public class NsdManagerServiceResolver implements ServiceResolver { private Handler mainThreadHandler; private List registrationListeners = new ArrayList<>(); private final CopyOnWriteArrayList mMFServiceName = new CopyOnWriteArrayList<>(); + @Nullable private final NsdManagerResolverAvailState nsdManagerResolverAvailState; - public NsdManagerServiceResolver(Context context) { + /** + * @param context application context + * @param nsdManagerResolverAvailState Passing NsdManagerResolverAvailState allows + * NsdManagerServiceResolver to synchronize on the usage of NsdManager's resolveService() API + */ + public NsdManagerServiceResolver( + Context context, @Nullable NsdManagerResolverAvailState nsdManagerResolverAvailState) { this.nsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE); this.mainThreadHandler = new Handler(Looper.getMainLooper()); @@ -46,6 +57,11 @@ public NsdManagerServiceResolver(Context context) { ((WifiManager) context.getSystemService(Context.WIFI_SERVICE)) .createMulticastLock("chipMulticastLock"); this.multicastLock.setReferenceCounted(true); + this.nsdManagerResolverAvailState = nsdManagerResolverAvailState; + } + + public NsdManagerServiceResolver(Context context) { + this(context, null); } @Override @@ -78,10 +94,18 @@ public void run() { Log.d(TAG, "resolve: Timing out"); if (multicastLock.isHeld()) { multicastLock.release(); + + if (nsdManagerResolverAvailState != null) { + nsdManagerResolverAvailState.signalFree(); + } } } }; + if (nsdManagerResolverAvailState != null) { + nsdManagerResolverAvailState.acquireResolver(); + } + this.nsdManager.resolveService( serviceInfo, new NsdManager.ResolveListener() { @@ -95,6 +119,10 @@ public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { if (multicastLock.isHeld()) { multicastLock.release(); + + if (nsdManagerResolverAvailState != null) { + nsdManagerResolverAvailState.signalFree(); + } } mainThreadHandler.removeCallbacks(timeoutRunnable); } @@ -120,10 +148,15 @@ public void onServiceResolved(NsdServiceInfo serviceInfo) { if (multicastLock.isHeld()) { multicastLock.release(); + + if (nsdManagerResolverAvailState != null) { + nsdManagerResolverAvailState.signalFree(); + } } mainThreadHandler.removeCallbacks(timeoutRunnable); } }); + mainThreadHandler.postDelayed(timeoutRunnable, RESOLVE_SERVICE_TIMEOUT); } @@ -223,4 +256,51 @@ public void removeServices() { registrationListeners.clear(); mMFServiceName.clear(); } + + /** + * The Android NsdManager calls back on the NsdManager.ResolveListener with a + * FAILURE_ALREADY_ACTIVE(3) if any application code calls resolveService() on it while the + * resolve operation is already active (from another call made previously). An object of + * NsdManagerResolverAvailState allows NsdManagerServiceResolver to synchronize on the usage of + * NsdManager's resolveService() API + */ + public static class NsdManagerResolverAvailState { + private static final String TAG = NsdManagerResolverAvailState.class.getSimpleName(); + + private Lock lock = new ReentrantLock(); + private Condition condition = lock.newCondition(); + private boolean busy = false; + + /** + * Waits if the NsdManager is already busy with resolving a service. Otherwise, it marks it as + * busy and returns + */ + public void acquireResolver() { + lock.lock(); + try { + while (busy) { + Log.d(TAG, "Found NsdManager Resolver busy, waiting"); + condition.await(); + } + Log.d(TAG, "Found NsdManager Resolver free, using it and marking it as busy"); + busy = true; + } catch (InterruptedException e) { + Log.e(TAG, "Failure while waiting for condition: " + e); + } finally { + lock.unlock(); + } + } + + /** Signals the NsdManager resolver as free */ + public void signalFree() { + lock.lock(); + try { + Log.d(TAG, "Signaling NsdManager Resolver as free"); + busy = false; + condition.signal(); + } finally { + lock.unlock(); + } + } + } } diff --git a/src/platform/qpg/BLEManagerImpl.cpp b/src/platform/qpg/BLEManagerImpl.cpp index 0b4fe14ee0bf9e..f466491ff724c8 100644 --- a/src/platform/qpg/BLEManagerImpl.cpp +++ b/src/platform/qpg/BLEManagerImpl.cpp @@ -201,8 +201,12 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) break; case DeviceEventType::kCHIPoBLEUnsubscribe: { + ChipDeviceEvent connClosedEvent; + ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEUnsubscribe"); HandleUnsubscribeReceived(event->CHIPoBLEUnsubscribe.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX); + connClosedEvent.Type = DeviceEventType::kCHIPoBLEConnectionClosed; + PlatformMgr().PostEventOrDie(&connClosedEvent); } break; diff --git a/src/platform/telink/BUILD.gn b/src/platform/telink/BUILD.gn index d5644b09f5ceb0..b13a9d185ee8dd 100644 --- a/src/platform/telink/BUILD.gn +++ b/src/platform/telink/BUILD.gn @@ -16,6 +16,7 @@ import("//build_overrides/chip.gni") import("//build_overrides/telink.gni") import("${chip_root}/src/platform/device.gni") +import("${chip_root}/src/platform/telink/args.gni") assert(chip_device_platform == "telink") @@ -48,11 +49,26 @@ static_library("telink") { deps = [] + public = [ + "${chip_root}/src/credentials/CHIPCert.h", + "${chip_root}/src/credentials/CertificationDeclaration.h", + "${chip_root}/src/credentials/DeviceAttestationCredsProvider.h", + ] + public_deps = [ "${chip_root}/src/platform:platform_base", "${telink_sdk_build_root}", ] + if (chip_enable_factory_data) { + sources += [ + "FactoryDataParser.c", + "FactoryDataParser.h", + "FactoryDataProvider.cpp", + "FactoryDataProvider.h", + ] + } + if (chip_enable_openthread) { sources += [ "../OpenThread/OpenThreadUtils.cpp", diff --git a/src/platform/telink/CHIPDevicePlatformConfig.h b/src/platform/telink/CHIPDevicePlatformConfig.h index 8241a10bc534f8..4f45252aa2865b 100644 --- a/src/platform/telink/CHIPDevicePlatformConfig.h +++ b/src/platform/telink/CHIPDevicePlatformConfig.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2021 Project CHIP Authors + * 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. @@ -27,6 +27,42 @@ // ==================== Platform Adaptations ==================== +#ifndef CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER +#define CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER CONFIG_CHIP_DEVICE_SERIAL_NUMBER +#endif + +#ifndef CHIP_DEVICE_CONFIG_TEST_MANUFACTURING_DATE +#define CHIP_DEVICE_CONFIG_TEST_MANUFACTURING_DATE CONFIG_CHIP_DEVICE_MANUFACTURING_DATE +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION +#define CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION CONFIG_CHIP_DEVICE_HARDWARE_VERSION +#endif + +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE CONFIG_CHIP_DEVICE_PAIRING_PASSCODE +#endif + +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR CONFIG_CHIP_DEVICE_DISCRIMINATOR +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING CONFIG_CHIP_DEVICE_HARDWARE_VERSION_STRING +#endif + +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT +#define CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT CONFIG_CHIP_DEVICE_SPAKE2_IT +#endif + +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_SALT +#define CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_SALT CONFIG_CHIP_DEVICE_SPAKE2_SALT +#endif + +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_VERIFIER +#define CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_VERIFIER CONFIG_CHIP_DEVICE_SPAKE2_TEST_VERIFIER +#endif + #ifndef CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID #define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID CONFIG_CHIP_DEVICE_VENDOR_ID #endif @@ -35,8 +71,12 @@ #define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID CONFIG_CHIP_DEVICE_PRODUCT_ID #endif -#ifdef CONFIG_CHIP_DEVICE_TYPE -#define CHIP_DEVICE_CONFIG_DEVICE_TYPE CONFIG_CHIP_DEVICE_TYPE +#ifndef CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME CONFIG_CHIP_DEVICE_VENDOR_NAME +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME CONFIG_CHIP_DEVICE_PRODUCT_NAME #endif #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION @@ -80,6 +120,58 @@ #endif // !defined(CONFIG_CHIP_MALLOC_SYS_HEAP) && defined(CONFIG_NEWLIB_LIBC) #endif // CHIP_DEVICE_CONFIG_HEAP_STATISTICS_MALLINFO +#ifndef CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION +//-> format_version = 1 +//-> vendor_id = 0xFFF1 +//-> product_id_array = [ 0x8000, 0x8001, 0x8002, 0x8003, 0x8004, 0x8005, 0x8006, 0x8007, 0x8008, 0x8009, 0x800A, 0x800B, +// 0x800C, 0x800D, 0x800E, 0x800F, 0x8010, 0x8011, 0x8012, 0x8013, 0x8014, 0x8015, 0x8016, 0x8017, 0x8018, 0x8019, 0x801A, +// 0x801B, 0x801C, 0x801D, 0x801E, 0x801F, 0x8020, 0x8021, 0x8022, 0x8023, 0x8024, 0x8025, 0x8026, 0x8027, 0x8028, 0x8029, +// 0x802A, 0x802B, 0x802C, 0x802D, 0x802E, 0x802F, 0x8030, 0x8031, 0x8032, 0x8033, 0x8034, 0x8035, 0x8036, 0x8037, 0x8038, +// 0x8039, 0x803A, 0x803B, 0x803C, 0x803D, 0x803E, 0x803F, 0x8040, 0x8041, 0x8042, 0x8043, 0x8044, 0x8045, 0x8046, 0x8047, +// 0x8048, 0x8049, 0x804A, 0x804B, 0x804C, 0x804D, 0x804E, 0x804F, 0x8050, 0x8051, 0x8052, 0x8053, 0x8054, 0x8055, 0x8056, +// 0x8057, 0x8058, 0x8059, 0x805A, 0x805B, 0x805C, 0x805D, 0x805E, 0x805F, 0x8060, 0x8061, 0x8062, 0x8063 ] +//-> device_type_id = 0x0016 +//-> certificate_id = "ZIG20142ZB330003-24" +//-> security_level = 0 +//-> security_information = 0 +//-> version_number = 0x2694 +//-> certification_type = 0 +//-> dac_origin_vendor_id is not present +//-> dac_origin_product_id is not present +#define CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION \ + { \ + 0x30, 0x82, 0x02, 0x19, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0x0a, 0x30, \ + 0x82, 0x02, 0x06, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, \ + 0x02, 0x01, 0x30, 0x82, 0x01, 0x71, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, \ + 0x01, 0x62, 0x04, 0x82, 0x01, 0x5e, 0x15, 0x24, 0x00, 0x01, 0x25, 0x01, 0xf1, 0xff, 0x36, 0x02, 0x05, 0x00, 0x80, \ + 0x05, 0x01, 0x80, 0x05, 0x02, 0x80, 0x05, 0x03, 0x80, 0x05, 0x04, 0x80, 0x05, 0x05, 0x80, 0x05, 0x06, 0x80, 0x05, \ + 0x07, 0x80, 0x05, 0x08, 0x80, 0x05, 0x09, 0x80, 0x05, 0x0a, 0x80, 0x05, 0x0b, 0x80, 0x05, 0x0c, 0x80, 0x05, 0x0d, \ + 0x80, 0x05, 0x0e, 0x80, 0x05, 0x0f, 0x80, 0x05, 0x10, 0x80, 0x05, 0x11, 0x80, 0x05, 0x12, 0x80, 0x05, 0x13, 0x80, \ + 0x05, 0x14, 0x80, 0x05, 0x15, 0x80, 0x05, 0x16, 0x80, 0x05, 0x17, 0x80, 0x05, 0x18, 0x80, 0x05, 0x19, 0x80, 0x05, \ + 0x1a, 0x80, 0x05, 0x1b, 0x80, 0x05, 0x1c, 0x80, 0x05, 0x1d, 0x80, 0x05, 0x1e, 0x80, 0x05, 0x1f, 0x80, 0x05, 0x20, \ + 0x80, 0x05, 0x21, 0x80, 0x05, 0x22, 0x80, 0x05, 0x23, 0x80, 0x05, 0x24, 0x80, 0x05, 0x25, 0x80, 0x05, 0x26, 0x80, \ + 0x05, 0x27, 0x80, 0x05, 0x28, 0x80, 0x05, 0x29, 0x80, 0x05, 0x2a, 0x80, 0x05, 0x2b, 0x80, 0x05, 0x2c, 0x80, 0x05, \ + 0x2d, 0x80, 0x05, 0x2e, 0x80, 0x05, 0x2f, 0x80, 0x05, 0x30, 0x80, 0x05, 0x31, 0x80, 0x05, 0x32, 0x80, 0x05, 0x33, \ + 0x80, 0x05, 0x34, 0x80, 0x05, 0x35, 0x80, 0x05, 0x36, 0x80, 0x05, 0x37, 0x80, 0x05, 0x38, 0x80, 0x05, 0x39, 0x80, \ + 0x05, 0x3a, 0x80, 0x05, 0x3b, 0x80, 0x05, 0x3c, 0x80, 0x05, 0x3d, 0x80, 0x05, 0x3e, 0x80, 0x05, 0x3f, 0x80, 0x05, \ + 0x40, 0x80, 0x05, 0x41, 0x80, 0x05, 0x42, 0x80, 0x05, 0x43, 0x80, 0x05, 0x44, 0x80, 0x05, 0x45, 0x80, 0x05, 0x46, \ + 0x80, 0x05, 0x47, 0x80, 0x05, 0x48, 0x80, 0x05, 0x49, 0x80, 0x05, 0x4a, 0x80, 0x05, 0x4b, 0x80, 0x05, 0x4c, 0x80, \ + 0x05, 0x4d, 0x80, 0x05, 0x4e, 0x80, 0x05, 0x4f, 0x80, 0x05, 0x50, 0x80, 0x05, 0x51, 0x80, 0x05, 0x52, 0x80, 0x05, \ + 0x53, 0x80, 0x05, 0x54, 0x80, 0x05, 0x55, 0x80, 0x05, 0x56, 0x80, 0x05, 0x57, 0x80, 0x05, 0x58, 0x80, 0x05, 0x59, \ + 0x80, 0x05, 0x5a, 0x80, 0x05, 0x5b, 0x80, 0x05, 0x5c, 0x80, 0x05, 0x5d, 0x80, 0x05, 0x5e, 0x80, 0x05, 0x5f, 0x80, \ + 0x05, 0x60, 0x80, 0x05, 0x61, 0x80, 0x05, 0x62, 0x80, 0x05, 0x63, 0x80, 0x18, 0x24, 0x03, 0x16, 0x2c, 0x04, 0x13, \ + 0x5a, 0x49, 0x47, 0x32, 0x30, 0x31, 0x34, 0x32, 0x5a, 0x42, 0x33, 0x33, 0x30, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x34, \ + 0x24, 0x05, 0x00, 0x24, 0x06, 0x00, 0x25, 0x07, 0x94, 0x26, 0x24, 0x08, 0x00, 0x18, 0x31, 0x7d, 0x30, 0x7b, 0x02, \ + 0x01, 0x03, 0x80, 0x14, 0x62, 0xfa, 0x82, 0x33, 0x59, 0xac, 0xfa, 0xa9, 0x96, 0x3e, 0x1c, 0xfa, 0x14, 0x0a, 0xdd, \ + 0xf5, 0x04, 0xf3, 0x71, 0x60, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, \ + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02, 0x20, 0x24, 0xe5, \ + 0xd1, 0xf4, 0x7a, 0x7d, 0x7b, 0x0d, 0x20, 0x6a, 0x26, 0xef, 0x69, 0x9b, 0x7c, 0x97, 0x57, 0xb7, 0x2d, 0x46, 0x90, \ + 0x89, 0xde, 0x31, 0x92, 0xe6, 0x78, 0xc7, 0x45, 0xe7, 0xf6, 0x0c, 0x02, 0x21, 0x00, 0xf8, 0xaa, 0x2f, 0xa7, 0x11, \ + 0xfc, 0xb7, 0x9b, 0x97, 0xe3, 0x97, 0xce, 0xda, 0x66, 0x7b, 0xae, 0x46, 0x4e, 0x2b, 0xd3, 0xff, 0xdf, 0xc3, 0xcc, \ + 0xed, 0x7a, 0xa8, 0xca, 0x5f, 0x4c, 0x1a, 0x7c \ + } +#endif + // ========== Platform-specific Configuration Overrides ========= #ifndef CHIP_DEVICE_CONFIG_CHIP_TASK_PRIORITY @@ -111,3 +203,11 @@ #define CHIP_DEVICE_CONFIG_ENABLE_THREAD_COMMISSIONABLE_DISCOVERY 1 #endif // CONFIG_CHIP_ENABLE_DNS_CLIENT #endif // CONFIG_CHIP_ENABLE_DNSSD_SRP + +#ifdef CONFIG_CHIP_DEVICE_TYPE +#define CHIP_DEVICE_CONFIG_DEVICE_TYPE CONFIG_CHIP_DEVICE_TYPE +#endif // CONFIG_CHIP_DEVICE_TYPE + +#ifdef CONFIG_CHIP_EXTENDED_DISCOVERY +#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 +#endif // CONFIG_CHIP_EXTENDED_DISCOVERY diff --git a/src/platform/telink/FactoryDataParser.c b/src/platform/telink/FactoryDataParser.c new file mode 100644 index 00000000000000..e89cf3b85d4c95 --- /dev/null +++ b/src/platform/telink/FactoryDataParser.c @@ -0,0 +1,167 @@ +/* + * + * 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 "FactoryDataParser.h" + +#include +#include + +#include +#include + +#define MAX_FACTORY_DATA_NESTING_LEVEL 3 + +LOG_MODULE_DECLARE(app, CONFIG_MATTER_LOG_LEVEL); + +static inline bool uint16_decode(zcbor_state_t * states, uint16_t * value) +{ + uint32_t u32; + + if (zcbor_uint32_decode(states, &u32)) + { + *value = (uint16_t) u32; + return true; + } + + return false; +} + +bool ParseFactoryData(uint8_t * buffer, uint16_t bufferSize, struct FactoryData * factoryData) +{ + memset(factoryData, 0, sizeof(*factoryData)); + ZCBOR_STATE_D(states, MAX_FACTORY_DATA_NESTING_LEVEL, buffer, bufferSize, 1); + + bool res = zcbor_map_start_decode(states); + struct zcbor_string currentString; + + while (res) + { + res = zcbor_tstr_decode(states, ¤tString); + + if (!res) + { + res = true; + break; + } + + if (strncmp("version", (const char *) currentString.value, currentString.len) == 0) + { + res = res && uint16_decode(states, &factoryData->version); + } + else if (strncmp("hw_ver", (const char *) currentString.value, currentString.len) == 0) + { + res = res && uint16_decode(states, &factoryData->hw_ver); + factoryData->hwVerPresent = res; + } + else if (strncmp("spake2_it", (const char *) currentString.value, currentString.len) == 0) + { + res = res && zcbor_uint32_decode(states, &factoryData->spake2_it); + } + else if (strncmp("vendor_id", (const char *) currentString.value, currentString.len) == 0) + { + res = res && uint16_decode(states, &factoryData->vendor_id); + factoryData->vendorIdPresent = res; + } + else if (strncmp("product_id", (const char *) currentString.value, currentString.len) == 0) + { + res = res && uint16_decode(states, &factoryData->product_id); + factoryData->productIdPresent = res; + } + else if (strncmp("discriminator", (const char *) currentString.value, currentString.len) == 0) + { + res = res && uint16_decode(states, &factoryData->discriminator); + factoryData->discriminatorPresent = res; + } + else if (strncmp("passcode", (const char *) currentString.value, currentString.len) == 0) + { + res = res && zcbor_uint32_decode(states, &factoryData->passcode); + } + else if (strncmp("sn", (const char *) currentString.value, currentString.len) == 0) + { + res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->sn); + } + else if (strncmp("date", (const char *) currentString.value, currentString.len) == 0) + { + // Date format is YYYY-MM-DD, so format needs to be validated and string parse to integer parts. + struct zcbor_string date; + res = res && zcbor_bstr_decode(states, &date); + if (date.len == 10 && isdigit(date.value[0]) && isdigit(date.value[1]) && isdigit(date.value[2]) && + isdigit(date.value[3]) && date.value[4] == '-' && isdigit(date.value[5]) && isdigit(date.value[6]) && + date.value[7] == '-' && isdigit(date.value[8]) && isdigit(date.value[9])) + { + factoryData->date_year = + 1000 * (date.value[0] - '0') + 100 * (date.value[1] - '0') + 10 * (date.value[2] - '0') + date.value[3] - '0'; + factoryData->date_month = 10 * (date.value[5] - '0') + date.value[6] - '0'; + factoryData->date_day = 10 * (date.value[8] - '0') + date.value[9] - '0'; + } + else + { + LOG_ERR("Parsing error - wrong date format"); + } + } + else if (strncmp("hw_ver_str", (const char *) currentString.value, currentString.len) == 0) + { + res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->hw_ver_str); + } + else if (strncmp("rd_uid", (const char *) currentString.value, currentString.len) == 0) + { + res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->rd_uid); + } + else if (strncmp("dac_cert", (const char *) currentString.value, currentString.len) == 0) + { + res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->dac_cert); + } + else if (strncmp("dac_key", (const char *) currentString.value, currentString.len) == 0) + { + res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->dac_priv_key); + } + else if (strncmp("pai_cert", (const char *) currentString.value, currentString.len) == 0) + { + res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->pai_cert); + } + else if (strncmp("spake2_salt", (const char *) currentString.value, currentString.len) == 0) + { + res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->spake2_salt); + } + else if (strncmp("spake2_verifier", (const char *) currentString.value, currentString.len) == 0) + { + res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->spake2_verifier); + } + else if (strncmp("vendor_name", (const char *) currentString.value, currentString.len) == 0) + { + res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->vendor_name); + } + else if (strncmp("product_name", (const char *) currentString.value, currentString.len) == 0) + { + res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->product_name); + } + else if (strncmp("enable_key", (const char *) currentString.value, currentString.len) == 0) + { + res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->enable_key); + } + else if (strncmp("user", (const char *) currentString.value, currentString.len) == 0) + { + res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->user); + } + else + { + res = res && zcbor_any_skip(states, NULL); + } + } + + return res && zcbor_list_map_end_force_decode(states); +} diff --git a/src/platform/telink/FactoryDataParser.h b/src/platform/telink/FactoryDataParser.h new file mode 100644 index 00000000000000..156010ab66c527 --- /dev/null +++ b/src/platform/telink/FactoryDataParser.h @@ -0,0 +1,78 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct FactoryDataString +{ + void * data; + size_t len; +}; + +struct FactoryData +{ + uint16_t version; + struct FactoryDataString sn; + uint16_t date_year; + uint8_t date_month; + uint8_t date_day; + uint16_t vendor_id; + uint16_t product_id; + struct FactoryDataString vendor_name; + struct FactoryDataString product_name; + uint16_t hw_ver; + struct FactoryDataString hw_ver_str; + struct FactoryDataString rd_uid; + struct FactoryDataString dac_cert; + struct FactoryDataString dac_priv_key; + struct FactoryDataString pai_cert; + uint32_t spake2_it; + struct FactoryDataString spake2_salt; + struct FactoryDataString spake2_verifier; + uint16_t discriminator; + uint32_t passcode; + struct FactoryDataString enable_key; + struct FactoryDataString user; + + bool vendorIdPresent; + bool productIdPresent; + bool hwVerPresent; + bool discriminatorPresent; +}; + +/** + * @brief Parses raw factory data into the factory data structure. + * + * @param[in] buffer Buffer containing raw factory data. + * @param[in] bufferSize Size of factory data. + * @param[out] factoryData address of object to be filled with parsed factory data. + * + * @returns true on success, false otherwise. + */ +bool ParseFactoryData(uint8_t * buffer, uint16_t bufferSize, struct FactoryData * factoryData); + +#ifdef __cplusplus +} +#endif diff --git a/src/platform/telink/FactoryDataProvider.cpp b/src/platform/telink/FactoryDataProvider.cpp new file mode 100644 index 00000000000000..38592270b1f4a0 --- /dev/null +++ b/src/platform/telink/FactoryDataProvider.cpp @@ -0,0 +1,341 @@ +/* + * + * 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 "FactoryDataProvider.h" +#include "CHIPDevicePlatformConfig.h" +#include + +#if CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE +#include +#include +#endif + +#include + +namespace chip { +namespace { + +CHIP_ERROR LoadKeypairFromRaw(ByteSpan privateKey, ByteSpan publicKey, Crypto::P256Keypair & keypair) +{ + Crypto::P256SerializedKeypair serializedKeypair; + ReturnErrorOnFailure(serializedKeypair.SetLength(privateKey.size() + publicKey.size())); + memcpy(serializedKeypair.Bytes(), publicKey.data(), publicKey.size()); + memcpy(serializedKeypair.Bytes() + publicKey.size(), privateKey.data(), privateKey.size()); + return keypair.Deserialize(serializedKeypair); +} +} // namespace + +namespace DeviceLayer { + +template +CHIP_ERROR FactoryDataProvider::Init() +{ + uint8_t * factoryData = nullptr; + size_t factoryDataSize; + + CHIP_ERROR error = mFlashFactoryData.ProtectFactoryDataPartitionAgainstWrite(); + + // Protection against write for external storage is not supported. + if (error == CHIP_ERROR_NOT_IMPLEMENTED) + { + ChipLogProgress(DeviceLayer, "The device does not support hardware protection against write."); + error = CHIP_NO_ERROR; + } + else if (error != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to protect the factory data partition."); + return error; + } + + error = mFlashFactoryData.GetFactoryDataPartition(factoryData, factoryDataSize); + + if (error != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to read factory data partition"); + return error; + } + + if (!ParseFactoryData(factoryData, factoryDataSize, &mFactoryData)) + { + ChipLogError(DeviceLayer, "Failed to parse factory data"); + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + // Check if factory data version is correct + if (mFactoryData.version != CONFIG_CHIP_FACTORY_DATA_VERSION) + { + ChipLogError(DeviceLayer, "Factory data version mismatch. Flash version: %d vs code version: %d", mFactoryData.version, + CONFIG_CHIP_FACTORY_DATA_VERSION); + return CHIP_ERROR_VERSION_MISMATCH; + } + + return CHIP_NO_ERROR; +} + +template +CHIP_ERROR FactoryDataProvider::GetCertificationDeclaration(MutableByteSpan & outBuffer) +{ +#if CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE + size_t cdLen = 0; + + if (Internal::ZephyrConfig::ReadConfigValueBin(Internal::ZephyrConfig::kConfigKey_CertificationDeclaration, + reinterpret_cast(outBuffer.data()), outBuffer.size(), + cdLen) == CHIP_NO_ERROR) + { + outBuffer.reduce_size(cdLen); + return CHIP_NO_ERROR; + } +#endif + constexpr uint8_t kCdForAllExamples[] = CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION; + + return CopySpanToMutableSpan(ByteSpan{ kCdForAllExamples }, outBuffer); +} + +template +CHIP_ERROR FactoryDataProvider::GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) +{ + out_firmware_info_buffer.reduce_size(0); + + return CHIP_NO_ERROR; +} + +template +CHIP_ERROR FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & outBuffer) +{ + ReturnErrorCodeIf(outBuffer.size() < mFactoryData.dac_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); + ReturnErrorCodeIf(!mFactoryData.dac_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + + memcpy(outBuffer.data(), mFactoryData.dac_cert.data, mFactoryData.dac_cert.len); + + outBuffer.reduce_size(mFactoryData.dac_cert.len); + + return CHIP_NO_ERROR; +} + +template +CHIP_ERROR FactoryDataProvider::GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) +{ + ReturnErrorCodeIf(outBuffer.size() < mFactoryData.pai_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); + ReturnErrorCodeIf(!mFactoryData.pai_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + + memcpy(outBuffer.data(), mFactoryData.pai_cert.data, mFactoryData.pai_cert.len); + + outBuffer.reduce_size(mFactoryData.pai_cert.len); + + return CHIP_NO_ERROR; +} + +template +CHIP_ERROR FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & messageToSign, + MutableByteSpan & outSignBuffer) +{ + Crypto::P256ECDSASignature signature; + Crypto::P256Keypair keypair; + + VerifyOrReturnError(outSignBuffer.size() >= signature.Capacity(), CHIP_ERROR_BUFFER_TOO_SMALL); + ReturnErrorCodeIf(!mFactoryData.dac_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + ReturnErrorCodeIf(!mFactoryData.dac_priv_key.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + + // Extract public key from DAC cert. + ByteSpan dacCertSpan{ reinterpret_cast(mFactoryData.dac_cert.data), mFactoryData.dac_cert.len }; + chip::Crypto::P256PublicKey dacPublicKey; + + ReturnErrorOnFailure(chip::Crypto::ExtractPubkeyFromX509Cert(dacCertSpan, dacPublicKey)); + ReturnErrorOnFailure( + LoadKeypairFromRaw(ByteSpan(reinterpret_cast(mFactoryData.dac_priv_key.data), mFactoryData.dac_priv_key.len), + ByteSpan(dacPublicKey.Bytes(), dacPublicKey.Length()), keypair)); + ReturnErrorOnFailure(keypair.ECDSA_sign_msg(messageToSign.data(), messageToSign.size(), signature)); + + return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, outSignBuffer); +} + +template +CHIP_ERROR FactoryDataProvider::GetSetupDiscriminator(uint16_t & setupDiscriminator) +{ + VerifyOrReturnError(mFactoryData.discriminatorPresent, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + setupDiscriminator = mFactoryData.discriminator; + return CHIP_NO_ERROR; +} + +template +CHIP_ERROR FactoryDataProvider::SetSetupDiscriminator(uint16_t setupDiscriminator) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +template +CHIP_ERROR FactoryDataProvider::GetSpake2pIterationCount(uint32_t & iterationCount) +{ + ReturnErrorCodeIf(mFactoryData.spake2_it == 0, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + iterationCount = mFactoryData.spake2_it; + return CHIP_NO_ERROR; +} + +template +CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) +{ + ReturnErrorCodeIf(saltBuf.size() < mFactoryData.spake2_salt.len, CHIP_ERROR_BUFFER_TOO_SMALL); + ReturnErrorCodeIf(!mFactoryData.spake2_salt.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + + memcpy(saltBuf.data(), mFactoryData.spake2_salt.data, mFactoryData.spake2_salt.len); + + saltBuf.reduce_size(mFactoryData.spake2_salt.len); + + return CHIP_NO_ERROR; +} + +template +CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) +{ + ReturnErrorCodeIf(verifierBuf.size() < mFactoryData.spake2_verifier.len, CHIP_ERROR_BUFFER_TOO_SMALL); + ReturnErrorCodeIf(!mFactoryData.spake2_verifier.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + + memcpy(verifierBuf.data(), mFactoryData.spake2_verifier.data, mFactoryData.spake2_verifier.len); + + verifierLen = mFactoryData.spake2_verifier.len; + + verifierBuf.reduce_size(verifierLen); + + return CHIP_NO_ERROR; +} + +template +CHIP_ERROR FactoryDataProvider::GetSetupPasscode(uint32_t & setupPasscode) +{ + ReturnErrorCodeIf(mFactoryData.passcode == 0, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + setupPasscode = mFactoryData.passcode; + return CHIP_NO_ERROR; +} + +template +CHIP_ERROR FactoryDataProvider::SetSetupPasscode(uint32_t setupPasscode) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +template +CHIP_ERROR FactoryDataProvider::GetVendorName(char * buf, size_t bufSize) +{ + ReturnErrorCodeIf(bufSize < mFactoryData.vendor_name.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); + ReturnErrorCodeIf(!mFactoryData.vendor_name.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + + memcpy(buf, mFactoryData.vendor_name.data, mFactoryData.vendor_name.len); + buf[mFactoryData.vendor_name.len] = 0; + + return CHIP_NO_ERROR; +} + +template +CHIP_ERROR FactoryDataProvider::GetVendorId(uint16_t & vendorId) +{ + VerifyOrReturnError(mFactoryData.vendorIdPresent, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + vendorId = mFactoryData.vendor_id; + return CHIP_NO_ERROR; +} + +template +CHIP_ERROR FactoryDataProvider::GetProductName(char * buf, size_t bufSize) +{ + ReturnErrorCodeIf(bufSize < mFactoryData.product_name.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); + ReturnErrorCodeIf(!mFactoryData.product_name.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + + memcpy(buf, mFactoryData.product_name.data, mFactoryData.product_name.len); + buf[mFactoryData.product_name.len] = 0; + + return CHIP_NO_ERROR; +} + +template +CHIP_ERROR FactoryDataProvider::GetProductId(uint16_t & productId) +{ + VerifyOrReturnError(mFactoryData.productIdPresent, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + productId = mFactoryData.product_id; + return CHIP_NO_ERROR; +} + +template +CHIP_ERROR FactoryDataProvider::GetSerialNumber(char * buf, size_t bufSize) +{ + ReturnErrorCodeIf(bufSize < mFactoryData.sn.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); + ReturnErrorCodeIf(!mFactoryData.sn.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + + memcpy(buf, mFactoryData.sn.data, mFactoryData.sn.len); + buf[mFactoryData.sn.len] = 0; + + return CHIP_NO_ERROR; +} + +template +CHIP_ERROR FactoryDataProvider::GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) +{ + VerifyOrReturnError(mFactoryData.date_year != 0, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + year = mFactoryData.date_year; + month = mFactoryData.date_month; + day = mFactoryData.date_day; + return CHIP_NO_ERROR; +} + +template +CHIP_ERROR FactoryDataProvider::GetHardwareVersion(uint16_t & hardwareVersion) +{ + VerifyOrReturnError(mFactoryData.hwVerPresent, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + hardwareVersion = mFactoryData.hw_ver; + return CHIP_NO_ERROR; +} + +template +CHIP_ERROR FactoryDataProvider::GetHardwareVersionString(char * buf, size_t bufSize) +{ + ReturnErrorCodeIf(bufSize < mFactoryData.hw_ver_str.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); + ReturnErrorCodeIf(!mFactoryData.hw_ver_str.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + + memcpy(buf, mFactoryData.hw_ver_str.data, mFactoryData.hw_ver_str.len); + buf[mFactoryData.hw_ver_str.len] = 0; + + return CHIP_NO_ERROR; +} + +template +CHIP_ERROR FactoryDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) +{ + ReturnErrorCodeIf(uniqueIdSpan.size() < mFactoryData.rd_uid.len, CHIP_ERROR_BUFFER_TOO_SMALL); + ReturnErrorCodeIf(!mFactoryData.rd_uid.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + + memcpy(uniqueIdSpan.data(), mFactoryData.rd_uid.data, mFactoryData.rd_uid.len); + + return CHIP_NO_ERROR; +} + +template +CHIP_ERROR FactoryDataProvider::GetEnableKey(MutableByteSpan & enableKey) +{ + ReturnErrorCodeIf(!mFactoryData.enable_key.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + ReturnErrorCodeIf(enableKey.size() < mFactoryData.enable_key.len, CHIP_ERROR_BUFFER_TOO_SMALL); + + memcpy(enableKey.data(), mFactoryData.enable_key.data, mFactoryData.enable_key.len); + + enableKey.reduce_size(mFactoryData.enable_key.len); + + return CHIP_NO_ERROR; +} + +// Fully instantiate the template class in whatever compilation unit includes this file. +// template class FactoryDataProvider; +template class FactoryDataProvider; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/telink/FactoryDataProvider.h b/src/platform/telink/FactoryDataProvider.h new file mode 100644 index 00000000000000..79d34a6b9fdd84 --- /dev/null +++ b/src/platform/telink/FactoryDataProvider.h @@ -0,0 +1,117 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +#include +#include +#include + +#include "FactoryDataParser.h" + +namespace chip { +namespace DeviceLayer { + +struct InternalFlashFactoryData +{ + CHIP_ERROR GetFactoryDataPartition(uint8_t *& data, size_t & dataSize) + { + data = reinterpret_cast(FLASH_AREA_OFFSET(factory_data)); + dataSize = FLASH_AREA_SIZE(factory_data); + return CHIP_NO_ERROR; + } + + CHIP_ERROR ProtectFactoryDataPartitionAgainstWrite() { return CHIP_ERROR_NOT_IMPLEMENTED; } +}; + +struct ExternalFlashFactoryData +{ + CHIP_ERROR GetFactoryDataPartition(uint8_t *& data, size_t & dataSize) + { + int ret = flash_read(mFlashDevice, FLASH_AREA_OFFSET(factory_data), mFactoryDataBuffer, FLASH_AREA_SIZE(factory_data)); + + if (ret != 0) + { + return CHIP_ERROR_READ_FAILED; + } + + data = mFactoryDataBuffer; + dataSize = FLASH_AREA_SIZE(factory_data); + + return CHIP_NO_ERROR; + } + + CHIP_ERROR ProtectFactoryDataPartitionAgainstWrite() { return CHIP_ERROR_NOT_IMPLEMENTED; } + + const struct device * mFlashDevice = DEVICE_DT_GET(DT_CHOSEN(zephyr_flash_controller)); + uint8_t mFactoryDataBuffer[FLASH_AREA_SIZE(factory_data)]; +}; + +template +class FactoryDataProvider : public chip::Credentials::DeviceAttestationCredentialsProvider, + public CommissionableDataProvider, + public DeviceInstanceInfoProvider +{ +public: + CHIP_ERROR Init(); + + // ===== Members functions that implement the DeviceAttestationCredentialsProvider + CHIP_ERROR GetCertificationDeclaration(MutableByteSpan & outBuffer) override; + CHIP_ERROR GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) override; + CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & outBuffer) override; + CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) override; + CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) override; + + // ===== Members functions that implement the CommissionableDataProvider + CHIP_ERROR GetSetupDiscriminator(uint16_t & setupDiscriminator) override; + CHIP_ERROR SetSetupDiscriminator(uint16_t setupDiscriminator) override; + CHIP_ERROR GetSpake2pIterationCount(uint32_t & iterationCount) override; + CHIP_ERROR GetSpake2pSalt(MutableByteSpan & saltBuf) override; + CHIP_ERROR GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) override; + CHIP_ERROR GetSetupPasscode(uint32_t & setupPasscode) override; + CHIP_ERROR SetSetupPasscode(uint32_t setupPasscode) override; + + // ===== Members functions that implement the DeviceInstanceInfoProvider + CHIP_ERROR GetVendorName(char * buf, size_t bufSize) override; + CHIP_ERROR GetVendorId(uint16_t & vendorId) override; + CHIP_ERROR GetProductName(char * buf, size_t bufSize) override; + CHIP_ERROR GetProductId(uint16_t & productId) override; + CHIP_ERROR GetSerialNumber(char * buf, size_t bufSize) override; + CHIP_ERROR GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) override; + CHIP_ERROR GetHardwareVersion(uint16_t & hardwareVersion) override; + CHIP_ERROR GetHardwareVersionString(char * buf, size_t bufSize) override; + CHIP_ERROR GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) override; + + // ===== Members functions that are platform-specific + CHIP_ERROR GetEnableKey(MutableByteSpan & enableKey); + +private: + static constexpr uint16_t kFactoryDataPartitionSize = FLASH_AREA_SIZE(factory_data); + static constexpr uint32_t kFactoryDataPartitionAddress = FLASH_AREA_OFFSET(factory_data); + static constexpr uint8_t kDACPrivateKeyLength = 32; + static constexpr uint8_t kDACPublicKeyLength = 65; + + struct FactoryData mFactoryData; + FlashFactoryData mFlashFactoryData; +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/telink/args.gni b/src/platform/telink/args.gni index 1ff86d0b38c074..a8307083a7d217 100644 --- a/src/platform/telink/args.gni +++ b/src/platform/telink/args.gni @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Project CHIP Authors +# 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. @@ -15,3 +15,8 @@ chip_device_platform = "telink" chip_inet_config_enable_ipv4 = false + +declare_args() { + # Enable factory data support + chip_enable_factory_data = false +} diff --git a/src/platform/telink/telink-mbedtls-config.h b/src/platform/telink/telink-mbedtls-config.h index d0de1d19734a4f..0a37b4a632e274 100644 --- a/src/platform/telink/telink-mbedtls-config.h +++ b/src/platform/telink/telink-mbedtls-config.h @@ -1,20 +1,25 @@ -/****************************************************************************** - * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") - * 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 + * Copyright (c) 2022 Project CHIP Authors * - * http://www.apache.org/licenses/LICENSE-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 * - * 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. + * 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 + * Telink mbedtls configuration file. + * + */ #ifndef MBEDTLS_TSLR9_CONF_H #define MBEDTLS_TSLR9_CONF_H diff --git a/third_party/openthread/ot-nxp b/third_party/openthread/ot-nxp index 24bf5d185d039e..aa5d627e8cd880 160000 --- a/third_party/openthread/ot-nxp +++ b/third_party/openthread/ot-nxp @@ -1 +1 @@ -Subproject commit 24bf5d185d039e89f651310c7f690f3cc72a55ff +Subproject commit aa5d627e8cd8808b34d8403e71b9954498e9aea6 diff --git a/third_party/openthread/repo b/third_party/openthread/repo index 2ce3d3bf021856..ba826ffb2ac7e2 160000 --- a/third_party/openthread/repo +++ b/third_party/openthread/repo @@ -1 +1 @@ -Subproject commit 2ce3d3bf0218566484be2e9943b95c755cefebe3 +Subproject commit ba826ffb2ac7e2d366ebd553b92a912434ff603d