diff --git a/.flake8 b/.flake8 index 599ac08c7b63a3..c53238a9262656 100644 --- a/.flake8 +++ b/.flake8 @@ -47,31 +47,6 @@ exclude = third_party scripts/tools/zap_convert_all.py src/app/ota_image_tool.py src/app/zap_cluster_list.py - src/controller/python/build-chip-wheel.py - src/controller/python/chip-device-ctrl.py - src/controller/python/chip/CertificateAuthority.py - src/controller/python/chip/ChipBleUtility.py - src/controller/python/chip/ChipBluezMgr.py - src/controller/python/chip/ChipCommissionableNodeCtrl.py - src/controller/python/chip/ChipCoreBluetoothMgr.py - src/controller/python/chip/ChipDeviceCtrl.py - src/controller/python/chip/ChipReplStartup.py - src/controller/python/chip/ChipStack.py - src/controller/python/chip/ChipUtility.py - src/controller/python/chip/FabricAdmin.py - src/controller/python/chip/ble/scan_devices.py - src/controller/python/chip/clusters/Attribute.py - src/controller/python/chip/clusters/ClusterObjects.py - src/controller/python/chip/clusters/Command.py - src/controller/python/chip/clusters/__init__.py - src/controller/python/chip/discovery/__init__.py - src/controller/python/chip/interaction_model/__init__.py - src/controller/python/chip/interaction_model/delegate.py - src/controller/python/chip/internal/commissioner.py - src/controller/python/chip/setup_payload/setup_payload.py - src/controller/python/chip/storage/__init__.py - src/controller/python/chip/tlv/__init__.py - src/controller/python/chip/utils/CommissioningBuildingBlocks.py src/controller/python/chip/yaml/__init__.py src/controller/python/chip/yaml/format_converter.py src/controller/python/chip/yaml/runner.py diff --git a/.github/actions/checkout-submodules/action.yaml b/.github/actions/checkout-submodules/action.yaml index d5d4709ed3f37c..429fb1a5427011 100644 --- a/.github/actions/checkout-submodules/action.yaml +++ b/.github/actions/checkout-submodules/action.yaml @@ -11,6 +11,9 @@ inputs: runs: using: "composite" steps: - - name: Checkout submodules - shell: bash - run: scripts/checkout_submodules.py --allow-changing-global-git-config --shallow --platform ${{ inputs.platform }} ${{ inputs.extra-parameters }} + - uses: Wandalen/wretry.action@v1.3.0 + name: Checkout submodules + with: + command: scripts/checkout_submodules.py --allow-changing-global-git-config --shallow --platform ${{ inputs.platform }} ${{ inputs.extra-parameters }} + attempt_limit: 3 + attempt_delay: 2000 diff --git a/.github/workflows/darwin-tests.yaml b/.github/workflows/darwin-tests.yaml index 0920d90438c979..cedc306cbeaf45 100644 --- a/.github/workflows/darwin-tests.yaml +++ b/.github/workflows/darwin-tests.yaml @@ -60,7 +60,7 @@ jobs: uses: ./.github/actions/checkout-submodules-and-bootstrap with: platform: darwin - bootstrap-log-name: bootstrap-logs-darwin-${{ matrix.build_variant }}${{ matrix.chip_tool }} + bootstrap-log-name: bootstrap-logs-darwin-${{ matrix.build_variant }} - name: Run macOS Darwin Framework Tool Build Debug working-directory: src/darwin/Framework @@ -126,7 +126,7 @@ jobs: uses: actions/upload-artifact@v3 if: ${{ failure() && !env.ACT }} with: - name: crash-core-darwin-${{ matrix.build_variant }}${{ matrix.chip_tool }} + name: crash-core-darwin-${{ matrix.build_variant }} path: /cores/ # Cores are big; don't hold on to them too long. retention-days: 5 @@ -134,13 +134,19 @@ jobs: uses: actions/upload-artifact@v3 if: ${{ failure() && !env.ACT }} with: - name: crash-log-darwin-${{ matrix.build_variant }}${{ matrix.chip_tool }} + name: crash-log-darwin-${{ matrix.build_variant }} path: ~/Library/Logs/DiagnosticReports/ + - name: Uploading framework build log + uses: actions/upload-artifact@v3 + if: ${{ failure() && !env.ACT }} + with: + name: framework-build-log-darwin-${{ matrix.build_variant }} + path: out/darwin-x64-darwin-framework-tool-${{ matrix.build_variant }}/darwin_framework_build.log - name: Uploading objdir for debugging uses: actions/upload-artifact@v3 if: ${{ failure() && !env.ACT }} with: - name: crash-objdir-darwin-${{ matrix.build_variant }}${{ matrix.chip_tool }} + name: crash-objdir-darwin-${{ matrix.build_variant }} path: objdir-clone/ # objdirs are big; don't hold on to them too long. retention-days: 5 diff --git a/.github/workflows/darwin.yaml b/.github/workflows/darwin.yaml index a422c2066a8d98..27e850824bc2c1 100644 --- a/.github/workflows/darwin.yaml +++ b/.github/workflows/darwin.yaml @@ -80,7 +80,10 @@ jobs: # Disable -Wunguarded-availability-new because we internally use # APIs we added after our deployment target version. Maybe we # should change the deployment target version instead? - run: xcodebuild -target "Matter" -sdk macosx OTHER_CFLAGS='${inherited} -Werror -Wconversion -Wno-unguarded-availability-new' + # + # Disable BLE because the app does not have the permission to use + # it and that may crash the CI. + run: xcodebuild -target "Matter" -sdk macosx OTHER_CFLAGS='${inherited} -Werror -Wconversion -Wno-unguarded-availability-new' CHIP_IS_BLE=NO working-directory: src/darwin/Framework - name: Clean Build run: xcodebuild clean @@ -121,10 +124,10 @@ jobs: ../../../out/debug/chip-ota-requestor-app --interface-id -1 --secured-device-port 5543 --discriminator 1112 --KVS /tmp/chip-ota-requestor-kvs2 --otaDownloadPath /tmp/chip-ota-requestor-downloaded-image2 --autoApplyImage > >(tee /tmp/darwin/framework-tests/ota-requestor-app-2.log) 2> >(tee /tmp/darwin/framework-tests/ota-requestor-app-err-2.log >&2) & # -enableUndefinedBehaviorSanitizer instruments the code in Matter.framework, # but to instrument the code in the underlying libCHIP we need to pass CHIP_IS_UBSAN=YES - TEST_RUNNER_ASAN_OPTIONS=__CURRENT_VALUE__:detect_stack_use_after_return=1 xcodebuild test -target "Matter" -scheme "Matter Framework Tests" -sdk macosx -enableAddressSanitizer YES -enableUndefinedBehaviorSanitizer YES OTHER_CFLAGS='${inherited} -Werror -Wconversion -Wno-unguarded-availability-new' CHIP_IS_UBSAN=YES > >(tee /tmp/darwin/framework-tests/darwin-tests-asan.log) 2> >(tee /tmp/darwin/framework-tests/darwin-tests-asan-err.log >&2) + TEST_RUNNER_ASAN_OPTIONS=__CURRENT_VALUE__:detect_stack_use_after_return=1 xcodebuild test -target "Matter" -scheme "Matter Framework Tests" -sdk macosx -enableAddressSanitizer YES -enableUndefinedBehaviorSanitizer YES OTHER_CFLAGS='${inherited} -Werror -Wconversion -Wno-unguarded-availability-new' CHIP_IS_UBSAN=YES CHIP_IS_BLE=NO > >(tee /tmp/darwin/framework-tests/darwin-tests-asan.log) 2> >(tee /tmp/darwin/framework-tests/darwin-tests-asan-err.log >&2) # -enableThreadSanitizer instruments the code in Matter.framework, # but to instrument the code in the underlying libCHIP we need to pass CHIP_IS_TSAN=YES - xcodebuild test -target "Matter" -scheme "Matter Framework Tests" -sdk macosx -enableThreadSanitizer YES OTHER_CFLAGS='${inherited} -Werror -Wconversion -Wno-unguarded-availability-new' CHIP_IS_TSAN=YES > >(tee /tmp/darwin/framework-tests/darwin-tests-tsan.log) 2> >(tee /tmp/darwin/framework-tests/darwin-tests-tsan-err.log >&2) + xcodebuild test -target "Matter" -scheme "Matter Framework Tests" -sdk macosx -enableThreadSanitizer YES OTHER_CFLAGS='${inherited} -Werror -Wconversion -Wno-unguarded-availability-new' CHIP_IS_TSAN=YES CHIP_IS_BLE=NO > >(tee /tmp/darwin/framework-tests/darwin-tests-tsan.log) 2> >(tee /tmp/darwin/framework-tests/darwin-tests-tsan-err.log >&2) working-directory: src/darwin/Framework - name: Build Matter TV Casting Bridge run: | diff --git a/.github/workflows/examples-efr32.yaml b/.github/workflows/examples-efr32.yaml index 5f384b4542d899..9a3840a9ff55e7 100644 --- a/.github/workflows/examples-efr32.yaml +++ b/.github/workflows/examples-efr32.yaml @@ -38,7 +38,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-efr32:0.7.3 + image: connectedhomeip/chip-build-efr32:0.7.25 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/kotlin-style.yaml b/.github/workflows/kotlin-style.yaml new file mode 100644 index 00000000000000..3df657b810849e --- /dev/null +++ b/.github/workflows/kotlin-style.yaml @@ -0,0 +1,64 @@ +name: Kotlin + +on: + pull_request: + paths: + - "**/*.kt" + - ".github/workflows/kotlin-style.yaml" + - "kotlin-detect-config.yaml" + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }}-${{ (github.event_name == 'pull_request' && github.event.number) || (github.event_name == 'workflow_dispatch' && github.run_number) || github.sha }} + cancel-in-progress: true + + +jobs: + detekt: + name: Static code analysis + runs-on: ubuntu-latest + + steps: + - name: "checkout" + uses: actions/checkout@v2 + + - name: "detekt" + uses: natiginfo/action-detekt-all@1.23.0 + # Detekt seems not to like circular symlinks, so we set up + # explicit paths below + with: + args: --parallel --build-upon-default-config --config kotlin-detect-config.yaml --input examples/android/CHIPTest,examples/android/CHIPTool,examples/java-matter-controller/java,src/controller/java + + ktlint: + name: "Format check" + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - uses: actions/setup-java@v2 + with: + distribution: 'adopt' + java-version: '17' + + - name: Download ktfmt + run: | + cd /tmp + wget "https://repo1.maven.org/maven2/com/facebook/ktfmt/0.44/ktfmt-0.44-jar-with-dependencies.jar" + + - name: Format kotlin files + run: | + find src examples -name '*.kt' \ + | xargs java -jar /tmp/ktfmt-0.44-jar-with-dependencies.jar --google-style + + - name: Ensure git works in current working directory + run: git config --global --add safe.directory `pwd` + + - name: Check for uncommited changes + run: | + git add . + # Show the full diff + git diff-index -p HEAD -- + # Also show just the files that are different, to make it easy + # to tell at a glance what might be going on. And throw in + # --exit-code to make this job fail if there is a difference. + git diff-index --exit-code HEAD -- diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index a44b72f81262c8..dff906bc08feb5 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -212,6 +212,8 @@ jobs: " - name: Run Tests using the python parser sending commands to chip-tool + # https://github.com/project-chip/connectedhomeip/issues/27673 + if: matrix.build_variant != 'no-ble-tsan-clang' run: | ./scripts/run_in_build_env.sh \ "./scripts/tests/run_test_suite.py \ @@ -286,7 +288,8 @@ jobs: strategy: matrix: - build_variant: [no-ble-tsan-clang, no-ble-asan-clang] + build_variant: [no-ble-asan-clang] + # Since no-ble-tsan-clang doesn't run any tests, this is just wasted CI time for now chip_tool: [""] env: BUILD_VARIANT: ${{matrix.build_variant}} @@ -350,6 +353,8 @@ jobs: " - name: Run Tests using the python parser sending commands to chip-tool + # https://github.com/project-chip/connectedhomeip/issues/27673 + if: matrix.build_variant != 'no-ble-tsan-clang' run: | ./scripts/run_in_build_env.sh \ "./scripts/tests/run_test_suite.py \ diff --git a/BUILD.gn b/BUILD.gn index 6cc0d55261ff2b..5b3a9e480b6336 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -54,6 +54,7 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { "${chip_root}/src/credentials/tests:fuzz-chip-cert", "${chip_root}/src/lib/core/tests:fuzz-tlv-reader", "${chip_root}/src/lib/dnssd/minimal_mdns/tests:fuzz-minmdns-packet-parsing", + "${chip_root}/src/lib/format/tests:fuzz-payload-decoder", ] } } diff --git a/build/chip/chip_codegen.gni b/build/chip/chip_codegen.gni index 64c0642da29e65..1a6927bf4686f4 100644 --- a/build/chip/chip_codegen.gni +++ b/build/chip/chip_codegen.gni @@ -53,9 +53,19 @@ template("_chip_build_time_codegen") { rebase_path(target_gen_dir, root_build_dir), "--expected-outputs", rebase_path(_expected_outputs, root_build_dir), - rebase_path(_idl_file, root_build_dir), ] + if (defined(invoker.options)) { + foreach(option, invoker.options) { + args += [ + "--option", + option, + ] + } + } + + args += [ rebase_path(_idl_file, root_build_dir) ] + inputs = [ _idl_file, _expected_outputs, @@ -313,12 +323,15 @@ template("chip_codegen") { "generator", "input", "outputs", + "options", "public_configs", ]) } } else { _name = target_name + not_needed(invoker, [ "options" ]) + # This constructs a path like: # FROM all-clusters-app.matter (inside examples/all-clusters-app/all-clusters-common/) # USING "cpp-app" for generator: diff --git a/docs/guides/esp32/README.md b/docs/guides/esp32/README.md index a77fa0ca970384..89d9225cf65dd8 100644 --- a/docs/guides/esp32/README.md +++ b/docs/guides/esp32/README.md @@ -16,4 +16,4 @@ example on ESP32 series of SoCs - [Flash and NVS encryption for securing factory data](flash_nvs_encryption.md) - [RPC Console and Device Tracing](rpc_console.md) - [Matter OTA](ota.md) -- [Generating and Using ESP Secure Cert Parttiton](secure_cert_partition.md) +- [Generating and Using ESP Secure Cert Partition](secure_cert_partition.md) diff --git a/docs/guides/repl/Matter_Multi_Fabric_Commissioning.ipynb b/docs/guides/repl/Matter_Multi_Fabric_Commissioning.ipynb index d987196f2b1dbf..fe60b08a1c709c 100644 --- a/docs/guides/repl/Matter_Multi_Fabric_Commissioning.ipynb +++ b/docs/guides/repl/Matter_Multi_Fabric_Commissioning.ipynb @@ -24,7 +24,7 @@ "source": [ "## FabricAdmins and Controllers\n", "\n", - "The `FabricAdmin` class (present in the `chip.FabricAdmin` package) is responsible for adminstering a fabric. It houses the Fabric ID and Index, as well as an RCAC and ICAC that provides the certificate material grounding that fabric.\n", + "The `FabricAdmin` class (present in the `chip.FabricAdmin` package) is responsible for administering a fabric. It houses the Fabric ID and Index, as well as an RCAC and ICAC that provides the certificate material grounding that fabric.\n", "\n", "The `FabricAdmin` can be used to vend `ChipDeviceController` objects that represent a controller instance with a specific identity grounded in the admin's fabric. This controller can then be used to commission and interact with devices." ] diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter index 4319327b7dd87d..9e867f1be026a7 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter @@ -1939,6 +1939,146 @@ server cluster EthernetNetworkDiagnostics = 55 { command ResetCounts(): DefaultSuccess = 0; } +/** Accurate time is required for a number of reasons, including scheduling, display and validating security materials. */ +server cluster TimeSynchronization = 56 { + enum GranularityEnum : ENUM8 { + kNoTimeGranularity = 0; + kMinutesGranularity = 1; + kSecondsGranularity = 2; + kMillisecondsGranularity = 3; + kMicrosecondsGranularity = 4; + } + + enum StatusCode : ENUM8 { + kTimeNotAccepted = 2; + } + + enum TimeSourceEnum : ENUM8 { + kNone = 0; + kUnknown = 1; + kAdmin = 2; + kNodeTimeCluster = 3; + kNonMatterSNTP = 4; + kNonMatterNTP = 5; + kMatterSNTP = 6; + kMatterNTP = 7; + kMixedNTP = 8; + kNonMatterSNTPNTS = 9; + kNonMatterNTPNTS = 10; + kMatterSNTPNTS = 11; + kMatterNTPNTS = 12; + kMixedNTPNTS = 13; + kCloudSource = 14; + kPTP = 15; + kGNSS = 16; + } + + enum TimeZoneDatabaseEnum : ENUM8 { + kFull = 0; + kPartial = 1; + kNone = 2; + } + + bitmap Feature : BITMAP32 { + kTimeZone = 0x1; + kNTPClient = 0x2; + kNTPServer = 0x4; + kTimeSyncClient = 0x8; + } + + struct DSTOffsetStruct { + int32s offset = 0; + epoch_us validStarting = 1; + nullable epoch_us validUntil = 2; + } + + struct FabricScopedTrustedTimeSourceStruct { + node_id nodeID = 0; + endpoint_no endpoint = 1; + } + + struct TimeZoneStruct { + int32s offset = 0; + epoch_us validAt = 1; + optional char_string<64> name = 2; + } + + struct TrustedTimeSourceStruct { + fabric_idx fabricIndex = 0; + node_id nodeID = 1; + endpoint_no endpoint = 2; + } + + info event DSTTableEmpty = 0 { + } + + info event DSTStatus = 1 { + boolean DSTOffsetActive = 0; + } + + info event TimeZoneStatus = 2 { + INT32S offset = 0; + optional CHAR_STRING name = 1; + } + + info event TimeFailure = 3 { + } + + info event MissingTrustedTimeSource = 4 { + } + + readonly attribute nullable epoch_us UTCTime = 0; + readonly attribute GranularityEnum granularity = 1; + readonly attribute TimeSourceEnum timeSource = 2; + readonly attribute nullable TrustedTimeSourceStruct trustedTimeSource = 3; + readonly attribute nullable char_string<128> defaultNTP = 4; + readonly attribute TimeZoneStruct timeZone[] = 5; + readonly attribute DSTOffsetStruct DSTOffset[] = 6; + readonly attribute nullable epoch_us localTime = 7; + readonly attribute TimeZoneDatabaseEnum timeZoneDatabase = 8; + readonly attribute int8u timeZoneListMaxSize = 10; + readonly attribute int8u DSTOffsetListMaxSize = 11; + readonly attribute boolean supportsDNSResolve = 12; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct SetUTCTimeRequest { + epoch_us UTCTime = 0; + GranularityEnum granularity = 1; + optional TimeSourceEnum timeSource = 2; + } + + request struct SetTrustedTimeSourceRequest { + nullable FabricScopedTrustedTimeSourceStruct trustedTimeSource = 0; + } + + request struct SetTimeZoneRequest { + TimeZoneStruct timeZone[] = 0; + } + + request struct SetDSTOffsetRequest { + DSTOffsetStruct DSTOffset[] = 0; + } + + request struct SetDefaultNTPRequest { + nullable CHAR_STRING<128> defaultNTP = 0; + } + + response struct SetTimeZoneResponse = 3 { + boolean DSTOffsetRequired = 0; + } + + command access(invoke: administer) SetUTCTime(SetUTCTimeRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) SetTrustedTimeSource(SetTrustedTimeSourceRequest): DefaultSuccess = 1; + command access(invoke: manage) SetTimeZone(SetTimeZoneRequest): SetTimeZoneResponse = 2; + command access(invoke: manage) SetDSTOffset(SetDSTOffsetRequest): DefaultSuccess = 4; + command access(invoke: administer) SetDefaultNTP(SetDefaultNTPRequest): DefaultSuccess = 5; +} + /** This cluster exposes interactions with a switch device, for the purpose of using those interactions by other devices. Two types of switch devices are supported: latching switch (e.g. rocker switch) and momentary switch (e.g. push button), distinguished with their feature flags. Interactions with the switch device are exposed as attributes (for the latching switch) and as events (for both types of switches). An interested party MAY subscribe to these attributes/events and thus be informed of the interactions, and can perform actions based on this, for example by sending commands to perform an action such as controlling a light or a window shade. */ @@ -2365,6 +2505,7 @@ server cluster RefrigeratorAlarm = 87 { readonly attribute AlarmMap mask = 0; readonly attribute AlarmMap state = 2; + readonly attribute AlarmMap supported = 3; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -5929,6 +6070,32 @@ endpoint 0 { ram attribute clusterRevision default = 1; } + server cluster TimeSynchronization { + emits event DSTTableEmpty; + emits event DSTStatus; + emits event TimeZoneStatus; + emits event TimeFailure; + emits event MissingTrustedTimeSource; + callback attribute UTCTime; + callback attribute granularity default = 0x00; + ram attribute timeSource default = 0x00; + callback attribute trustedTimeSource; + callback attribute defaultNTP; + callback attribute timeZone default = 1; + callback attribute DSTOffset; + callback attribute localTime default = 1; + ram attribute timeZoneDatabase default = 0; + callback attribute timeZoneListMaxSize default = 3; + callback attribute DSTOffsetListMaxSize; + ram attribute supportsDNSResolve default = false; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0x0B; + ram attribute clusterRevision default = 2; + } + server cluster AdministratorCommissioning { callback attribute windowStatus default = 0; callback attribute adminFabricIndex default = 1; @@ -6155,6 +6322,7 @@ endpoint 1 { emits event Notify; ram attribute mask default = 1; ram attribute state default = 0; + ram attribute supported default = 1; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap index 0f19686c8795de..518c6e563eaa70 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap @@ -5434,6 +5434,451 @@ } ] }, + { + "name": "Time Synchronization", + "code": 56, + "mfgCode": null, + "define": "TIME_SYNCHRONIZATION_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "SetUTCTime", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "SetTrustedTimeSource", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "SetTimeZone", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "SetDSTOffset", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "SetDefaultNTP", + "code": 5, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "client", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Time Synchronization", + "code": 56, + "mfgCode": null, + "define": "TIME_SYNCHRONIZATION_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "SetTimeZoneResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "UTCTime", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "epoch_us", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Granularity", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "GranularityEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TimeSource", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "TimeSourceEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TrustedTimeSource", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "TrustedTimeSourceStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "DefaultNTP", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TimeZone", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "DSTOffset", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LocalTime", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "epoch_us", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TimeZoneDatabase", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "TimeZoneDatabaseEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "NTPServerAvailable", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TimeZoneListMaxSize", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "DSTOffsetListMaxSize", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportsDNSResolve", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "false", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0B", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "DSTTableEmpty", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "DSTStatus", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "TimeZoneStatus", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "TimeFailure", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "MissingTrustedTimeSource", + "code": 4, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, { "name": "Switch", "code": 59, @@ -13158,6 +13603,22 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "Supported", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "AlarmMap", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "GeneratedCommandList", "code": 65528, diff --git a/examples/all-clusters-app/asr/BUILD.gn b/examples/all-clusters-app/asr/BUILD.gn index d639d658589519..7d0b089b657b87 100755 --- a/examples/all-clusters-app/asr/BUILD.gn +++ b/examples/all-clusters-app/asr/BUILD.gn @@ -73,13 +73,13 @@ asr_executable("clusters_app") { sources = [ "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", + "${examples_plat_dir}/ButtonHandler.cpp", "${examples_plat_dir}/CHIPDeviceManager.cpp", "${examples_plat_dir}/LEDWidget.cpp", "${examples_plat_dir}/init_Matter.cpp", "${examples_plat_dir}/init_asrPlatform.cpp", "${examples_plat_dir}/shell/matter_shell.cpp", "src/AppTask.cpp", - "src/ButtonHandler.cpp", "src/DeviceCallbacks.cpp", "src/main.cpp", ] diff --git a/examples/all-clusters-app/asr/README.md b/examples/all-clusters-app/asr/README.md index 287da141fc0e24..bde062feab4445 100755 --- a/examples/all-clusters-app/asr/README.md +++ b/examples/all-clusters-app/asr/README.md @@ -6,20 +6,12 @@ control on ASR platform. --- - [Matter ASR All Clusters Example](#matter-asr-all-clusters-example) - - [Supported Chips](#supported-chips) - [Building and Commissioning](#building-and-commissioning) - [Cluster Control](#cluster-control) - [Light switch press button and light status LED](#light-switch-press-button-and-light-status-led) --- -## Supported Chips - -The Matter demo application is supported on: - -- ASR582X -- ASR595X - ## Building and Commissioning Please refer diff --git a/examples/all-clusters-app/asr/include/AppConfig.h b/examples/all-clusters-app/asr/include/AppConfig.h old mode 100644 new mode 100755 index 40abc79020f59e..3f2e1a80b4df84 --- a/examples/all-clusters-app/asr/include/AppConfig.h +++ b/examples/all-clusters-app/asr/include/AppConfig.h @@ -28,18 +28,6 @@ #define MATTER_DEVICE_NAME "ASR-Clusters" -#define GPIO_TASK_NAME "gpio" -#define GPIO_TASK_STACK_SIZE 1024 - -#define APP_BUTTON_PRESSED 0 -#define APP_BUTTON_RELEASED 1 - -#define SWITCH1_BUTTON GPIO12_INDEX -#define SWITCH2_BUTTON GPIO13_INDEX - -#define LIGHT1_LED PWM_OUTPUT_CH4 -#define LIGHT2_LED PWM_OUTPUT_CH6 - // Time it takes in ms for the simulated actuator to move from one // state to another. #define ACTUATOR_MOVEMENT_PERIOS_MS 2000 diff --git a/examples/all-clusters-app/asr/include/AppTask.h b/examples/all-clusters-app/asr/include/AppTask.h old mode 100644 new mode 100755 index 184e309af5eeba..210fd5a6fc7032 --- a/examples/all-clusters-app/asr/include/AppTask.h +++ b/examples/all-clusters-app/asr/include/AppTask.h @@ -40,7 +40,7 @@ class AppTask CHIP_ERROR StartAppTask(); static void AppTaskMain(void * pvParameter); static void AppEventHandler(AppEvent * aEvent); - void PostButtonEvent(uint8_t btnIdx, uint8_t btnAction); + void ButtonEventHandler(uint8_t btnIdx, uint8_t btnAction); void PostEvent(const AppEvent * event); /** * Use internally for registration of the ChipDeviceEvents diff --git a/examples/all-clusters-app/asr/src/AppTask.cpp b/examples/all-clusters-app/asr/src/AppTask.cpp old mode 100644 new mode 100755 index d55ef713dde3f2..3efb22ffcc338b --- a/examples/all-clusters-app/asr/src/AppTask.cpp +++ b/examples/all-clusters-app/asr/src/AppTask.cpp @@ -47,7 +47,6 @@ using namespace ::chip::DeviceManager; using namespace ::chip::DeviceLayer; using namespace ::chip::System; -LEDWidget sStatusLED; LEDWidget sLightLED; namespace { @@ -119,7 +118,11 @@ CHIP_ERROR AppTask::Init() ConfigurationMgr().LogDeviceConfig(); // Print setup info +#if CONFIG_NETWORK_LAYER_BLE PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kBLE)); +#else + PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kOnNetwork)); +#endif /* CONFIG_NETWORK_LAYER_BLE */ return CHIP_NO_ERROR; } @@ -131,8 +134,7 @@ void AppTask::AppTaskMain(void * pvParameter) ButtonHandler::Init(); - sLightLED.Init(LIGHT1_LED); // embedded board light - sStatusLED.Init(LIGHT2_LED); + sLightLED.Init(LIGHT_LED); lega_rtos_start_timer(&sAppTimer); @@ -186,7 +188,6 @@ void AppTask::AppEventHandler(AppEvent * aEvent) if (lightState) { sLightLED.Set(1); - sLightLED.SetBrightness(100); } else { @@ -213,9 +214,9 @@ void AppTask::AppTimerCallback(void * params) sAppTask.PostEvent(&timer_event); } -void AppTask::PostButtonEvent(uint8_t btnIdx, uint8_t btnAction) +void AppTask::ButtonEventHandler(uint8_t btnIdx, uint8_t btnAction) { - ASR_LOG("%s %s\n", btnIdx == SWITCH1_BUTTON ? "btn1" : "btn2", btnAction == APP_BUTTON_PRESSED ? "Pressed" : "Released"); + ASR_LOG("%s %s\n", btnIdx == SWITCH1_BUTTON ? "btn1" : "btn2", btnAction == BUTTON_PRESSED ? "Pressed" : "Released"); if (btnIdx != SWITCH1_BUTTON && btnIdx != SWITCH2_BUTTON) { @@ -227,7 +228,7 @@ void AppTask::PostButtonEvent(uint8_t btnIdx, uint8_t btnAction) button_event.ButtonEvent.ButtonIdx = btnIdx; button_event.ButtonEvent.Action = btnAction; - if (btnAction == APP_BUTTON_RELEASED) + if (btnAction == BUTTON_RELEASED) { button_event.Handler = AppEventHandler; sAppTask.PostEvent(&button_event); diff --git a/examples/all-clusters-app/asr/src/ButtonHandler.cpp b/examples/all-clusters-app/asr/src/ButtonHandler.cpp deleted file mode 100644 index 1faa7f7f56fbe1..00000000000000 --- a/examples/all-clusters-app/asr/src/ButtonHandler.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * - * Copyright (c) 2022 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ButtonHandler.h" -#include "AppConfig.h" -#include "AppTask.h" -#include - -#ifdef CFG_PLF_RV32 -#define duet_gpio_dev_t asr_gpio_dev_t -#define duet_gpio_init asr_gpio_init -#define duet_gpio_input_get asr_gpio_input_get -#define DUET_INPUT_PULL_UP ASR_INPUT_PULL_UP -#endif - -TaskHandle_t sGpioTaskHandle; -ButtonHandler::KeyInformation ButtonHandler::keyInfo = { 0 }; - -static void GpioTaskMain(void * pvParameter); - -void ButtonHandler::Init(void) -{ - GpioInit(); - - xTaskCreate(GpioTaskMain, GPIO_TASK_NAME, GPIO_TASK_STACK_SIZE, 0, 2, &sGpioTaskHandle); -} - -// port pin -duet_gpio_dev_t switch1_btn; -duet_gpio_dev_t switch2_btn; - -void ButtonHandler::GpioInit(void) -{ - // light switch1 button - switch1_btn.port = SWITCH1_BUTTON; - switch1_btn.config = DUET_INPUT_PULL_UP; - switch1_btn.priv = NULL; - duet_gpio_init(&switch1_btn); - - switch2_btn.port = SWITCH2_BUTTON; - switch2_btn.config = DUET_INPUT_PULL_UP; - switch2_btn.priv = NULL; - duet_gpio_init(&switch2_btn); -} - -void GpioTaskMain(void * pvParameter) -{ - ASR_LOG("GPIO Task started"); - uint32_t btnValue; - uint8_t currentKeys = 0; - - for (;;) - { - vTaskDelay(50 / portTICK_PERIOD_MS); - - duet_gpio_input_get(&switch1_btn, &btnValue); - - if (!btnValue) - { - currentKeys |= 0x01; - } - else - { - currentKeys &= ~0x01; - } - - duet_gpio_input_get(&switch2_btn, &btnValue); - - if (!btnValue) - { - currentKeys |= 0x02; - } - else - { - currentKeys &= ~0x02; - } - - ButtonHandler::keyInfo.keyImPulse = (ButtonHandler::keyInfo.keyDown ^ currentKeys) & ~ButtonHandler::keyInfo.keyDown; - ButtonHandler::keyInfo.keyReleasePulse = (ButtonHandler::keyInfo.keyDown ^ currentKeys) & ButtonHandler::keyInfo.keyDown; - ButtonHandler::keyInfo.keyDown = currentKeys; - - if (ButtonHandler::keyInfo.keyImPulse & 0x01) - { - GetAppTask().PostButtonEvent(SWITCH1_BUTTON, APP_BUTTON_PRESSED); - } - - if (ButtonHandler::keyInfo.keyImPulse & 0x02) - { - GetAppTask().PostButtonEvent(SWITCH2_BUTTON, APP_BUTTON_PRESSED); - } - - if (ButtonHandler::keyInfo.keyReleasePulse & 0x01) - { - GetAppTask().PostButtonEvent(SWITCH1_BUTTON, APP_BUTTON_RELEASED); - } - - if (ButtonHandler::keyInfo.keyReleasePulse & 0x02) - { - GetAppTask().PostButtonEvent(SWITCH2_BUTTON, APP_BUTTON_RELEASED); - } - } -} diff --git a/examples/all-clusters-app/asr/src/DeviceCallbacks.cpp b/examples/all-clusters-app/asr/src/DeviceCallbacks.cpp old mode 100644 new mode 100755 index 7b284250787382..859e3fb1043430 --- a/examples/all-clusters-app/asr/src/DeviceCallbacks.cpp +++ b/examples/all-clusters-app/asr/src/DeviceCallbacks.cpp @@ -54,7 +54,6 @@ using namespace ::chip::DeviceManager; using namespace ::chip::Logging; extern LEDWidget sLightLED; -extern LEDWidget sStatusLED; uint32_t identifyTimerCount; constexpr uint32_t kIdentifyTimerDelayMS = 250; @@ -191,7 +190,6 @@ void DeviceCallbacks::OnLevelPostAttributeChangeCallback(EndpointId endpointId, { uint8_t tmp = *value; ChipLogProgress(Zcl, "New level: %u ", tmp); - sLightLED.SetBrightness(tmp); } else { diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt index e2311a75f51f76..86249f3d81df0a 100644 --- a/examples/all-clusters-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt @@ -90,6 +90,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/pump-configuration-and-control-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/power-source-configuration-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/power-source-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/time-synchronization-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/src" ) diff --git a/examples/all-clusters-minimal-app/asr/README.md b/examples/all-clusters-minimal-app/asr/README.md index 8926066fccece9..5160ef5d4d5cf8 100755 --- a/examples/all-clusters-minimal-app/asr/README.md +++ b/examples/all-clusters-minimal-app/asr/README.md @@ -6,20 +6,11 @@ control on ASR platform. --- - [Matter ASR All Clusters Example](#matter-asr-all-clusters-example) - - [Supported Chips](#supported-chips) - [Building and Commissioning](#building-and-commissioning) - [Cluster Control](#cluster-control) - - [Light switch press button and light status LED](#light-switch-press-button-and-light-status-led) --- -## Supported Chips - -The Matter demo application is supported on: - -- ASR582X -- ASR595X - ## Building and Commissioning Please refer @@ -42,13 +33,3 @@ For example,control the OnOff Cluster attribute: ./chip-tool onoff off 1 ./chip-tool onoff toggle 1 ``` - -## Light switch press button and light status LED - -This demo uses button to test changing the light states and LED to show the -state of these changes. - -| Name | Pin | -| :----: | :---: | -| LED | PAD6 | -| BUTTON | PAD12 | diff --git a/examples/all-clusters-minimal-app/asr/include/AppConfig.h b/examples/all-clusters-minimal-app/asr/include/AppConfig.h old mode 100644 new mode 100755 index 6a633267878a8d..46f0a9a00128ea --- a/examples/all-clusters-minimal-app/asr/include/AppConfig.h +++ b/examples/all-clusters-minimal-app/asr/include/AppConfig.h @@ -28,12 +28,6 @@ #define MATTER_DEVICE_NAME "ASR-Clusters-m" -#define APP_LIGHT_BUTTON_IDX 0 -#define APP_BUTTON_DEBOUNCE_PERIOD_MS 50 - -#define APP_BUTTON_PRESSED 0 -#define APP_BUTTON_RELEASED 1 - // Time it takes in ms for the simulated actuator to move from one // state to another. #define ACTUATOR_MOVEMENT_PERIOS_MS 2000 diff --git a/examples/all-clusters-minimal-app/asr/src/AppTask.cpp b/examples/all-clusters-minimal-app/asr/src/AppTask.cpp index 6b97d430953867..ac9dfe7ba5d8d0 100644 --- a/examples/all-clusters-minimal-app/asr/src/AppTask.cpp +++ b/examples/all-clusters-minimal-app/asr/src/AppTask.cpp @@ -21,6 +21,7 @@ #include "AppTask.h" #include "AppConfig.h" #include "AppEvent.h" +#include "ButtonHandler.h" #include "CHIPDeviceManager.h" #include "DeviceCallbacks.h" #include "LEDWidget.h" @@ -50,9 +51,7 @@ using namespace ::chip::DeviceManager; using namespace ::chip::DeviceLayer; using namespace ::chip::System; -LEDWidget sStatusLED; LEDWidget sLightLED; -LEDWidget sClusterLED; namespace { TaskHandle_t sAppTaskHandle; @@ -112,7 +111,13 @@ CHIP_ERROR AppTask::Init() ConfigurationMgr().LogDeviceConfig(); // Print setup info +#if CONFIG_NETWORK_LAYER_BLE PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kBLE)); +#else + PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kOnNetwork)); +#endif /* CONFIG_NETWORK_LAYER_BLE */ + + sLightLED.Init(LIGHT_LED); return CHIP_NO_ERROR; } @@ -150,7 +155,7 @@ void AppTask::LightActionEventHandler(AppEvent * aEvent) void AppTask::ButtonEventHandler(uint8_t btnIdx, uint8_t btnAction) { - if (btnIdx != APP_LIGHT_BUTTON_IDX) + if (btnIdx != SWITCH1_BUTTON) { return; } @@ -160,7 +165,7 @@ void AppTask::ButtonEventHandler(uint8_t btnIdx, uint8_t btnAction) button_event.ButtonEvent.ButtonIdx = btnIdx; button_event.ButtonEvent.Action = btnAction; - if ((btnIdx == APP_LIGHT_BUTTON_IDX) && (btnAction == APP_BUTTON_RELEASED)) + if (btnAction == BUTTON_RELEASED) { button_event.Handler = LightActionEventHandler; sAppTask.PostEvent(&button_event); diff --git a/examples/all-clusters-minimal-app/asr/src/DeviceCallbacks.cpp b/examples/all-clusters-minimal-app/asr/src/DeviceCallbacks.cpp old mode 100644 new mode 100755 index 269d1a8c7623a2..a7be66c3fbef2c --- a/examples/all-clusters-minimal-app/asr/src/DeviceCallbacks.cpp +++ b/examples/all-clusters-minimal-app/asr/src/DeviceCallbacks.cpp @@ -52,6 +52,8 @@ using namespace ::chip::DeviceLayer; using namespace ::chip::DeviceManager; using namespace ::chip::Logging; +extern LEDWidget sLightLED; + uint32_t identifyTimerCount; constexpr uint32_t kIdentifyTimerDelayMS = 250; #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR @@ -151,9 +153,27 @@ void DeviceCallbacks::OnOnOffPostAttributeChangeCallback(EndpointId endpointId, VerifyOrExit(endpointId == 1 || endpointId == 2, ChipLogError(DeviceLayer, TAG, "Unexpected EndPoint ID: `0x%02x'", endpointId)); - // At this point we can assume that value points to a bool value. - // statusLED1.Set(*value); + switch (attributeId) + { + case chip::app::Clusters::OnOff::Attributes::OnOff::Id: { + ChipLogProgress(Zcl, "ON/OFF level: %u ", *value); + // At this point we can assume that value points to a bool value. + sLightLED.Set(*value); + } + break; + + case chip::app::Clusters::OnOff::Attributes::OnTime::Id: + case chip::app::Clusters::OnOff::Attributes::OffWaitTime::Id: + case chip::app::Clusters::OnOff::Attributes::StartUpOnOff::Id: + case chip::app::Clusters::OnOff::Attributes::GlobalSceneControl::Id: { + ChipLogProgress(Zcl, "Unprocessed attribute ID: %" PRIx32, attributeId); + } + break; + default: + ChipLogProgress(Zcl, "Unknown attribute ID: %" PRIx32, attributeId); + return; + } // switch (attributeId) exit: return; } diff --git a/examples/android/CHIPTest/app/src/androidTest/java/com/tcl/chip/chiptest/ExampleInstrumentedTest.kt b/examples/android/CHIPTest/app/src/androidTest/java/com/tcl/chip/chiptest/ExampleInstrumentedTest.kt index 0b4a921e467b9b..816d452a6efe00 100644 --- a/examples/android/CHIPTest/app/src/androidTest/java/com/tcl/chip/chiptest/ExampleInstrumentedTest.kt +++ b/examples/android/CHIPTest/app/src/androidTest/java/com/tcl/chip/chiptest/ExampleInstrumentedTest.kt @@ -1,13 +1,11 @@ package com.tcl.chip.chiptest -import androidx.test.platform.app.InstrumentationRegistry import androidx.test.ext.junit.runners.AndroidJUnit4 - +import androidx.test.platform.app.InstrumentationRegistry +import org.junit.Assert.* import org.junit.Test import org.junit.runner.RunWith -import org.junit.Assert.* - /** * Instrumented test, which will execute on an Android device. * @@ -15,10 +13,10 @@ import org.junit.Assert.* */ @RunWith(AndroidJUnit4::class) class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("com.tcl.chip.chiptest", appContext.packageName) - } -} \ No newline at end of file + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.tcl.chip.chiptest", appContext.packageName) + } +} diff --git a/examples/android/CHIPTest/app/src/main/java/com/tcl/chip/chiptest/MainActivity.kt b/examples/android/CHIPTest/app/src/main/java/com/tcl/chip/chiptest/MainActivity.kt index 0b914a1745fe99..c29cee70364cd4 100644 --- a/examples/android/CHIPTest/app/src/main/java/com/tcl/chip/chiptest/MainActivity.kt +++ b/examples/android/CHIPTest/app/src/main/java/com/tcl/chip/chiptest/MainActivity.kt @@ -9,50 +9,60 @@ import androidx.appcompat.app.AppCompatActivity import chip.platform.* import com.tcl.chip.chiptest.databinding.ActivityMainBinding - class MainActivity : AppCompatActivity() { - private val msgShowLog = 1 + private val msgShowLog = 1 - private lateinit var binding: ActivityMainBinding - private val mainHandler: Handler = object : Handler(Looper.getMainLooper()) { - override fun handleMessage(msg: Message) { - super.handleMessage(msg) - when (msg.what) { - msgShowLog -> { - binding.testLog.append(msg.obj.toString()) - } - } + private lateinit var binding: ActivityMainBinding + private val mainHandler: Handler = + object : Handler(Looper.getMainLooper()) { + override fun handleMessage(msg: Message) { + super.handleMessage(msg) + when (msg.what) { + msgShowLog -> { + binding.testLog.append(msg.obj.toString()) + } } + } } - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) - binding = ActivityMainBinding.inflate(layoutInflater) - setContentView(binding.root) + binding = ActivityMainBinding.inflate(layoutInflater) + setContentView(binding.root) - binding.testLog.movementMethod = ScrollingMovementMethod(); - TestEngine.setListener { log -> - var msg = mainHandler.obtainMessage(msgShowLog, log) - mainHandler.sendMessage(msg) - } + binding.testLog.movementMethod = ScrollingMovementMethod() + TestEngine.setListener { log -> + var msg = mainHandler.obtainMessage(msgShowLog, log) + mainHandler.sendMessage(msg) + } - binding.runButton.setOnClickListener { - binding.testLog.text = "" - Thread{ - var ret = TestEngine.runTest(); - - var log:String = if (ret == 0) { - getString(R.string.test_finished) - } else { - getString(R.string.test_failed,ret) - } - var msg = mainHandler.obtainMessage(msgShowLog, log) - mainHandler.sendMessage(msg) - }.start() - } + binding.runButton.setOnClickListener { + binding.testLog.text = "" + Thread { + var ret = TestEngine.runTest() - AndroidChipPlatform(AndroidBleManager(), PreferencesKeyValueStoreManager(this), PreferencesConfigurationManager(this), NsdManagerServiceResolver(this), NsdManagerServiceBrowser(this), ChipMdnsCallbackImpl(), DiagnosticDataProviderImpl(this)) + var log: String = + if (ret == 0) { + getString(R.string.test_finished) + } else { + getString(R.string.test_failed, ret) + } + var msg = mainHandler.obtainMessage(msgShowLog, log) + mainHandler.sendMessage(msg) + } + .start() } + + AndroidChipPlatform( + AndroidBleManager(), + PreferencesKeyValueStoreManager(this), + PreferencesConfigurationManager(this), + NsdManagerServiceResolver(this), + NsdManagerServiceBrowser(this), + ChipMdnsCallbackImpl(), + DiagnosticDataProviderImpl(this) + ) + } } diff --git a/examples/android/CHIPTest/app/src/test/java/com/tcl/chip/chiptest/ExampleUnitTest.kt b/examples/android/CHIPTest/app/src/test/java/com/tcl/chip/chiptest/ExampleUnitTest.kt index 803f71dcf64930..a33a8805de2146 100644 --- a/examples/android/CHIPTest/app/src/test/java/com/tcl/chip/chiptest/ExampleUnitTest.kt +++ b/examples/android/CHIPTest/app/src/test/java/com/tcl/chip/chiptest/ExampleUnitTest.kt @@ -1,8 +1,7 @@ package com.tcl.chip.chiptest -import org.junit.Test - import org.junit.Assert.* +import org.junit.Test /** * Example local unit test, which will execute on the development machine (host). @@ -10,8 +9,8 @@ import org.junit.Assert.* * See [testing documentation](http://d.android.com/tools/testing). */ class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} \ No newline at end of file + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/CHIPToolActivity.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/CHIPToolActivity.kt index 07bde0bf7dac57..0284b007fe60ec 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/CHIPToolActivity.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/CHIPToolActivity.kt @@ -60,16 +60,15 @@ class CHIPToolActivity : if (savedInstanceState == null) { val fragment = SelectActionFragment.newInstance() supportFragmentManager - .beginTransaction() - .add(R.id.nav_host_fragment, fragment, fragment.javaClass.simpleName) - .commit() + .beginTransaction() + .add(R.id.nav_host_fragment, fragment, fragment.javaClass.simpleName) + .commit() } else { networkType = - ProvisionNetworkType.fromName(savedInstanceState.getString(ARG_PROVISION_NETWORK_TYPE)) + ProvisionNetworkType.fromName(savedInstanceState.getString(ARG_PROVISION_NETWORK_TYPE)) } - if (intent?.action == NfcAdapter.ACTION_NDEF_DISCOVERED) - onNfcIntent(intent) + if (intent?.action == NfcAdapter.ACTION_NDEF_DISCOVERED) onNfcIntent(intent) if (Intent.ACTION_VIEW == intent?.action) { onReturnIntent(intent) @@ -97,10 +96,8 @@ class CHIPToolActivity : override fun onCommissioningComplete(code: Int) { runOnUiThread { - Toast.makeText( - this, - getString(R.string.commissioning_completed, code), - Toast.LENGTH_SHORT).show() + Toast.makeText(this, getString(R.string.commissioning_completed, code), Toast.LENGTH_SHORT) + .show() } ChipClient.getDeviceController(this).close() showFragment(SelectActionFragment.newInstance(), false) @@ -128,7 +125,8 @@ class CHIPToolActivity : } private fun showFragment(fragment: Fragment, showOnBack: Boolean = true) { - val fragmentTransaction = supportFragmentManager + val fragmentTransaction = + supportFragmentManager .beginTransaction() .replace(R.id.nav_host_fragment, fragment, fragment.javaClass.simpleName) @@ -153,8 +151,7 @@ class CHIPToolActivity : lateinit var setupPayload: OnboardingPayload try { - setupPayload = - OnboardingPayloadParser().parseQrCode(uri.toString().toUpperCase()) + setupPayload = OnboardingPayloadParser().parseQrCode(uri.toString().toUpperCase()) } catch (ex: UnrecognizedQrCodeException) { Log.e(TAG, "Unrecognized QR Code", ex) Toast.makeText(this, "Unrecognized QR Code", Toast.LENGTH_SHORT).show() @@ -163,23 +160,26 @@ class CHIPToolActivity : val deviceInfo = CHIPDeviceInfo.fromSetupPayload(setupPayload) - val buttons = arrayOf( + val buttons = + arrayOf( getString(R.string.nfc_tag_action_show), getString(R.string.nfc_tag_action_wifi), - getString(R.string.nfc_tag_action_thread)) + getString(R.string.nfc_tag_action_thread) + ) AlertDialog.Builder(this) - .setTitle(R.string.nfc_tag_action_title) - .setItems(buttons) { _, which -> - this.networkType = when (which) { + .setTitle(R.string.nfc_tag_action_title) + .setItems(buttons) { _, which -> + this.networkType = + when (which) { 1 -> ProvisionNetworkType.WIFI 2 -> ProvisionNetworkType.THREAD else -> null } - onCHIPDeviceInfoReceived(deviceInfo) - } - .create() - .show() + onCHIPDeviceInfoReceived(deviceInfo) + } + .create() + .show() } private fun onReturnIntent(intent: Intent) { @@ -222,18 +222,13 @@ class CHIPToolActivity : setupPayload.setupPinCode = payload.getLong("setupPinCode") val deviceInfo = CHIPDeviceInfo.fromSetupPayload(setupPayload) - val buttons = arrayOf( - getString(R.string.nfc_tag_action_show) - ) + val buttons = arrayOf(getString(R.string.nfc_tag_action_show)) AlertDialog.Builder(this) .setTitle(R.string.provision_custom_flow_alert_title) - .setItems(buttons) { _, _ -> - onCHIPDeviceInfoReceived(deviceInfo) - } + .setItems(buttons) { _, _ -> onCHIPDeviceInfoReceived(deviceInfo) } .create() .show() - } catch (ex: UnrecognizedQrCodeException) { Log.e(TAG, "Unrecognized Payload", ex) Toast.makeText(this, "Unrecognized Setup Payload", Toast.LENGTH_SHORT).show() diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/ChipClient.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/ChipClient.kt index 84a14de4714e13..d57f63a69a9bee 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/ChipClient.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/ChipClient.kt @@ -47,11 +47,14 @@ object ChipClient { getAndroidChipPlatform(context) if (!this::chipDeviceController.isInitialized) { - chipDeviceController = ChipDeviceController(ControllerParams.newBuilder().setControllerVendorId(VENDOR_ID).build()) + chipDeviceController = + ChipDeviceController(ControllerParams.newBuilder().setControllerVendorId(VENDOR_ID).build()) // Set delegate for attestation trust store for device attestation verifier. // It will replace the default attestation trust store. - chipDeviceController.setAttestationTrustStoreDelegate(ExampleAttestationTrustStoreDelegate(chipDeviceController)) + chipDeviceController.setAttestationTrustStoreDelegate( + ExampleAttestationTrustStoreDelegate(chipDeviceController) + ) } return chipDeviceController @@ -59,9 +62,18 @@ object ChipClient { fun getAndroidChipPlatform(context: Context?): AndroidChipPlatform { if (!this::androidPlatform.isInitialized && context != null) { - //force ChipDeviceController load jni + // force ChipDeviceController load jni ChipDeviceController.loadJni() - androidPlatform = AndroidChipPlatform(AndroidBleManager(context), PreferencesKeyValueStoreManager(context), PreferencesConfigurationManager(context), NsdManagerServiceResolver(context), NsdManagerServiceBrowser(context), ChipMdnsCallbackImpl(), DiagnosticDataProviderImpl(context)) + androidPlatform = + AndroidChipPlatform( + AndroidBleManager(context), + PreferencesKeyValueStoreManager(context), + PreferencesConfigurationManager(context), + NsdManagerServiceResolver(context), + NsdManagerServiceBrowser(context), + ChipMdnsCallbackImpl(), + DiagnosticDataProviderImpl(context) + ) } return androidPlatform @@ -71,25 +83,30 @@ object ChipClient { * Wrapper around [ChipDeviceController.getConnectedDevicePointer] to return the value directly. */ suspend fun getConnectedDevicePointer(context: Context, nodeId: Long): Long { - // TODO (#21539) This is a memory leak because we currently never call releaseConnectedDevicePointer - // once we are done with the returned device pointer. Memory leak was introduced since the refactor - // that introduced it was very large in order to fix a use after free, which was considered to be + // TODO (#21539) This is a memory leak because we currently never call + // releaseConnectedDevicePointer + // once we are done with the returned device pointer. Memory leak was introduced since the + // refactor + // that introduced it was very large in order to fix a use after free, which was considered + // to be // worse than the memory leak that was introduced. return suspendCancellableCoroutine { continuation -> - getDeviceController(context).getConnectedDevicePointer( - nodeId, - object : GetConnectedDeviceCallback { - override fun onDeviceConnected(devicePointer: Long) { - Log.d(TAG, "Got connected device pointer") - continuation.resume(devicePointer) - } + getDeviceController(context) + .getConnectedDevicePointer( + nodeId, + object : GetConnectedDeviceCallback { + override fun onDeviceConnected(devicePointer: Long) { + Log.d(TAG, "Got connected device pointer") + continuation.resume(devicePointer) + } - override fun onConnectionFailure(nodeId: Long, error: Exception) { - val errorMessage = "Unable to get connected device with nodeId $nodeId" - Log.e(TAG, errorMessage, error) - continuation.resumeWithException(IllegalStateException(errorMessage)) + override fun onConnectionFailure(nodeId: Long, error: Exception) { + val errorMessage = "Unable to get connected device with nodeId $nodeId" + Log.e(TAG, errorMessage, error) + continuation.resumeWithException(IllegalStateException(errorMessage)) + } } - }) + ) } } } diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/GenericChipDeviceListener.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/GenericChipDeviceListener.kt index 4ccf1ba6e6a836..1d62115547e305 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/GenericChipDeviceListener.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/GenericChipDeviceListener.kt @@ -23,7 +23,12 @@ open class GenericChipDeviceListener : ChipDeviceController.CompletionListener { // No op } - override fun onReadCommissioningInfo(vendorId: Int,productId: Int, wifiEndpointId: Int, threadEndpointId: Int) { + override fun onReadCommissioningInfo( + vendorId: Int, + productId: Int, + wifiEndpointId: Int, + threadEndpointId: Int + ) { // No op } diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/NetworkCredentialsParcelable.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/NetworkCredentialsParcelable.kt index 4f5d5ffafdeb52..a3295e96fc66cf 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/NetworkCredentialsParcelable.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/NetworkCredentialsParcelable.kt @@ -17,20 +17,19 @@ */ package com.google.chip.chiptool -import android.os.Parcelable import android.os.Parcel +import android.os.Parcelable import android.os.Parcelable.Creator -/** Class for holding WiFi or Thread credentials, but not both. */ +/** Class for holding WiFi or Thread credentials, but not both. */ class NetworkCredentialsParcelable : Parcelable { var wiFiCredentials: WiFiCredentials? private set + var threadCredentials: ThreadCredentials? private set - private constructor( - wifiCredentials: WiFiCredentials?, threadCredentials: ThreadCredentials? - ) { + private constructor(wifiCredentials: WiFiCredentials?, threadCredentials: ThreadCredentials?) { this.wiFiCredentials = wifiCredentials this.threadCredentials = threadCredentials } @@ -136,14 +135,15 @@ class NetworkCredentialsParcelable : Parcelable { } @JvmField - val CREATOR = object : Parcelable.Creator { - override fun createFromParcel(parcel: Parcel): NetworkCredentialsParcelable? { - return NetworkCredentialsParcelable(parcel) + val CREATOR = + object : Parcelable.Creator { + override fun createFromParcel(parcel: Parcel): NetworkCredentialsParcelable? { + return NetworkCredentialsParcelable(parcel) + } + + override fun newArray(size: Int): Array { + return arrayOfNulls(size) + } } - - override fun newArray(size: Int): Array { - return arrayOfNulls(size) - } - } } } diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/SelectActionFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/SelectActionFragment.kt index 38cc5d7fb5cec3..5932acb648d8a5 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/SelectActionFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/SelectActionFragment.kt @@ -40,12 +40,13 @@ import com.google.chip.chiptool.util.FragmentUtil /** Fragment to select from various options to interact with a CHIP device. */ class SelectActionFragment : Fragment() { private var _binding: SelectActionFragmentBinding? = null - private val binding get() = _binding!! + private val binding + get() = _binding!! override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? ): View { _binding = SelectActionFragmentBinding.inflate(inflater, container, false) @@ -67,9 +68,9 @@ class SelectActionFragment : Fragment() { binding.basicClusterBtn.setOnClickListener { handleBasicClicked() } binding.attestationTestBtn.setOnClickListener { handleAttestationTestClicked() } binding.clusterInteractionBtn.setOnClickListener { handleClusterInteractionClicked() } - binding.provisionCustomFlowBtn.setOnClickListener{ handleProvisionCustomFlowClicked() } + binding.provisionCustomFlowBtn.setOnClickListener { handleProvisionCustomFlowClicked() } binding.wildcardBtn.setOnClickListener { handleWildcardClicked() } - binding.unpairDeviceBtn.setOnClickListener{ handleUnpairDeviceClicked() } + binding.unpairDeviceBtn.setOnClickListener { handleUnpairDeviceClicked() } return binding.root } @@ -153,9 +154,10 @@ class SelectActionFragment : Fragment() { } private fun showFragment(fragment: Fragment, showOnBack: Boolean = true) { - val fragmentTransaction = parentFragmentManager - .beginTransaction() - .replace(R.id.nav_host_fragment, fragment, fragment.javaClass.simpleName) + val fragmentTransaction = + parentFragmentManager + .beginTransaction() + .replace(R.id.nav_host_fragment, fragment, fragment.javaClass.simpleName) if (showOnBack) { fragmentTransaction.addToBackStack(null) @@ -164,95 +166,69 @@ class SelectActionFragment : Fragment() { fragmentTransaction.commit() } - /** - * Notifies listener of Scan QR code button click. - */ + /** Notifies listener of Scan QR code button click. */ private fun handleScanQrCodeClicked() { showFragment(BarcodeFragment.newInstance(), false) } - /** - * Notifies listener of Light On/Off & Level Cluster button click. - */ + /** Notifies listener of Light On/Off & Level Cluster button click. */ private fun handleOnOffClicked() { showFragment(OnOffClientFragment.newInstance()) } - /** - * Notifies listener of Sensor Clusters button click. - */ + /** Notifies listener of Sensor Clusters button click. */ private fun handleSensorClicked() { showFragment(SensorClientFragment.newInstance()) } - /** - * Notifies listener of Multi-admin Clusters button click. - */ + /** Notifies listener of Multi-admin Clusters button click. */ private fun handleMultiAdminClicked() { showFragment(MultiAdminClientFragment.newInstance()) } - /** - * Notifies listener of Operational Credentials Clusters button click. - */ + /** Notifies listener of Operational Credentials Clusters button click. */ private fun handleOpCredClicked() { showFragment(OpCredClientFragment.newInstance()) } - /** - * Notifies listener of Basic Clusters button click. - */ + /** Notifies listener of Basic Clusters button click. */ private fun handleBasicClicked() { showFragment(BasicClientFragment.newInstance()) } - /** - * Notifies listener of attestation command button clicked. - */ + /** Notifies listener of attestation command button clicked. */ private fun handleAttestationTestClicked() { showFragment(AttestationTestFragment.newInstance()) } - /** - * Notifies listener of cluster interaction button click. - */ + /** Notifies listener of cluster interaction button click. */ private fun handleClusterInteractionClicked() { showFragment(ClusterInteractionFragment.newInstance()) } - /** - * Notifies listener of wildcard button click. - */ + /** Notifies listener of wildcard button click. */ private fun handleWildcardClicked() { showFragment(WildcardFragment.newInstance()) } - /** - * Notifies listener of unpair button click. - */ + /** Notifies listener of unpair button click. */ private fun handleUnpairDeviceClicked() { showFragment(UnpairDeviceFragment.newInstance()) } - /** - * Notifies listener of provision-WiFi-credentials button click. - */ + /** Notifies listener of provision-WiFi-credentials button click. */ private fun handleProvisionWiFiCredentialsClicked() { getCallback()?.SetNetworkType(ProvisionNetworkType.WIFI) showFragment(BarcodeFragment.newInstance(), false) } - /** - * Notifies listener of provision-Thread-credentials button click. - */ + /** Notifies listener of provision-Thread-credentials button click. */ private fun handleProvisionThreadCredentialsClicked() { getCallback()?.SetNetworkType(ProvisionNetworkType.THREAD) showFragment(BarcodeFragment.newInstance(), false) } - /** - * Notifies listener of provision-custom-flow button click. - */ + /** Notifies listener of provision-custom-flow button click. */ private fun handleProvisionCustomFlowClicked() { showFragment(BarcodeFragment.newInstance(), false) } diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/attestation/AttestationAppLauncher.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/attestation/AttestationAppLauncher.kt index 3cb19cb4f99437..e3185f34917d30 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/attestation/AttestationAppLauncher.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/attestation/AttestationAppLauncher.kt @@ -16,7 +16,8 @@ object AttestationAppLauncher { caller: ActivityResultCaller, block: (String?) -> Unit ): ActivityResultLauncher { - return caller.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> + return caller.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + result -> val data = result.data if (result.resultCode == Activity.RESULT_OK && data != null) { val chipResult = data.getStringExtra(CHIP_RESULT_KEY) @@ -30,9 +31,8 @@ object AttestationAppLauncher { fun getAttestationIntent(context: Context): Intent? { val packageManager = context.packageManager as PackageManager val attestationActivityIntent = Intent(CHIP_ACTION) - val attestationAppInfo = packageManager - .queryIntentActivities(attestationActivityIntent, 0) - .firstOrNull() + val attestationAppInfo = + packageManager.queryIntentActivities(attestationActivityIntent, 0).firstOrNull() return if (attestationAppInfo != null) { attestationActivityIntent.setClassName( diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/attestation/AttestationTestFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/attestation/AttestationTestFragment.kt index d4ff86d3719293..35c50e5384dc54 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/attestation/AttestationTestFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/attestation/AttestationTestFragment.kt @@ -11,7 +11,8 @@ import com.google.chip.chiptool.databinding.AttestationTestFragmentBinding /** Fragment for launching external attestation apps */ class AttestationTestFragment : Fragment() { private var _binding: AttestationTestFragmentBinding? = null - private val binding get() = _binding!! + private val binding + get() = _binding!! override fun onCreateView( inflater: LayoutInflater, @@ -23,8 +24,7 @@ class AttestationTestFragment : Fragment() { binding.attestationText.text = context!!.getString(R.string.attestation_fetching_status) val appIntent = AttestationAppLauncher.getAttestationIntent(requireContext()) if (appIntent != null) { - AttestationAppLauncher - .getLauncher(this@AttestationTestFragment) { result -> + AttestationAppLauncher.getLauncher(this@AttestationTestFragment) { result -> binding.attestationText.text = result } .launch(appIntent) @@ -41,7 +41,6 @@ class AttestationTestFragment : Fragment() { } companion object { - @JvmStatic - fun newInstance(): AttestationTestFragment = AttestationTestFragment() + @JvmStatic fun newInstance(): AttestationTestFragment = AttestationTestFragment() } } diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/attestation/ExampleAttestationTrustStoreDelegate.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/attestation/ExampleAttestationTrustStoreDelegate.kt index c94a64d1b8d00f..f62be2ce7dbbc6 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/attestation/ExampleAttestationTrustStoreDelegate.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/attestation/ExampleAttestationTrustStoreDelegate.kt @@ -1,7 +1,6 @@ package com.google.chip.chiptool.attestation import android.util.Base64 -import android.util.Log import chip.devicecontroller.AttestationTrustStoreDelegate import chip.devicecontroller.ChipDeviceController import java.util.* @@ -14,7 +13,9 @@ class ExampleAttestationTrustStoreDelegate(val chipDeviceController: ChipDeviceC override fun getProductAttestationAuthorityCert(skid: ByteArray): ByteArray? { return paaCerts .map { Base64.decode(it, Base64.DEFAULT) } - .firstOrNull { cert -> Arrays.equals(chipDeviceController.extractSkidFromPaaCert(cert), skid) } + .firstOrNull { cert -> + Arrays.equals(chipDeviceController.extractSkidFromPaaCert(cert), skid) + } } companion object { diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/bluetooth/BluetoothManager.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/bluetooth/BluetoothManager.kt index 4618a0591f9044..16d0f745b5f70f 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/bluetooth/BluetoothManager.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/bluetooth/BluetoothManager.kt @@ -39,14 +39,16 @@ class BluetoothManager : BleCallback { val version = 0 val versionDiscriminator = ((version and 0xf) shl 12) or (discriminator and 0xfff) return intArrayOf(opcode, versionDiscriminator, versionDiscriminator shr 8) - .map { it.toByte() } - .toByteArray() + .map { it.toByte() } + .toByteArray() } private fun getServiceDataMask(isShortDiscriminator: Boolean): ByteArray { - val shortDiscriminatorMask = when(isShortDiscriminator) { - true -> 0x00 false -> 0xff - } + val shortDiscriminatorMask = + when (isShortDiscriminator) { + true -> 0x00 + false -> 0xff + } return intArrayOf(0xff, shortDiscriminatorMask, 0xff).map { it.toByte() }.toByteArray() } @@ -54,52 +56,59 @@ class BluetoothManager : BleCallback { return getBluetoothDevice(context, discriminator, false) } - suspend fun getBluetoothDevice(context: Context, discriminator: Int, isShortDiscriminator: Boolean): BluetoothDevice? { - if (! bluetoothAdapter.isEnabled) { - bluetoothAdapter.enable(); + suspend fun getBluetoothDevice( + context: Context, + discriminator: Int, + isShortDiscriminator: Boolean + ): BluetoothDevice? { + if (!bluetoothAdapter.isEnabled) { + bluetoothAdapter.enable() } - val scanner = bluetoothAdapter.bluetoothLeScanner ?: run { - Log.e(TAG, "No bluetooth scanner found") - return null - } + val scanner = + bluetoothAdapter.bluetoothLeScanner + ?: run { + Log.e(TAG, "No bluetooth scanner found") + return null + } return withTimeoutOrNull(10000) { callbackFlow { - val scanCallback = object : ScanCallback() { - override fun onScanResult(callbackType: Int, result: ScanResult) { - val device = result.device - Log.i(TAG, "Bluetooth Device Scanned Addr: ${device.address}, Name ${device.name}") - - val producerScope: ProducerScope = this@callbackFlow - if (producerScope.channel.isClosedForSend) { - Log.w(TAG, "Bluetooth device was scanned, but channel is already closed") - } else { - offer(device) + val scanCallback = + object : ScanCallback() { + override fun onScanResult(callbackType: Int, result: ScanResult) { + val device = result.device + Log.i(TAG, "Bluetooth Device Scanned Addr: ${device.address}, Name ${device.name}") + + val producerScope: ProducerScope = this@callbackFlow + if (producerScope.channel.isClosedForSend) { + Log.w(TAG, "Bluetooth device was scanned, but channel is already closed") + } else { + offer(device) + } + } + + override fun onScanFailed(errorCode: Int) { + Log.e(TAG, "Scan failed $errorCode") + } } - } - override fun onScanFailed(errorCode: Int) { - Log.e(TAG, "Scan failed $errorCode") - } - } - - val serviceData = getServiceData(discriminator) - val serviceDataMask = getServiceDataMask(isShortDiscriminator) + val serviceData = getServiceData(discriminator) + val serviceDataMask = getServiceDataMask(isShortDiscriminator) - val scanFilter = + val scanFilter = ScanFilter.Builder() - .setServiceData(ParcelUuid(UUID.fromString(CHIP_UUID)), serviceData, serviceDataMask) - .build() + .setServiceData(ParcelUuid(UUID.fromString(CHIP_UUID)), serviceData, serviceDataMask) + .build() - val scanSettings = ScanSettings.Builder() - .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) - .build() + val scanSettings = + ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build() - Log.i(TAG, "Starting Bluetooth scan") - scanner.startScan(listOf(scanFilter), scanSettings, scanCallback) - awaitClose { scanner.stopScan(scanCallback) } - }.first() + Log.i(TAG, "Starting Bluetooth scan") + scanner.startScan(listOf(scanFilter), scanSettings, scanCallback) + awaitClose { scanner.stopScan(scanCallback) } + } + .first() } } @@ -125,16 +134,16 @@ class BluetoothManager : BleCallback { continuation: CancellableContinuation ): BluetoothGattCallback { return object : BluetoothGattCallback() { - private val wrappedCallback = ChipClient.getAndroidChipPlatform(context).bleManager.callback; + private val wrappedCallback = ChipClient.getAndroidChipPlatform(context).bleManager.callback + private val coroutineContinuation = continuation - override fun onConnectionStateChange( - gatt: BluetoothGatt?, - status: Int, - newState: Int - ) { + override fun onConnectionStateChange(gatt: BluetoothGatt?, status: Int, newState: Int) { super.onConnectionStateChange(gatt, status, newState) - Log.i(TAG, "${gatt?.device?.name}.onConnectionStateChange status = $status, newState=$newState") + Log.i( + TAG, + "${gatt?.device?.name}.onConnectionStateChange status = $status, newState=$newState" + ) wrappedCallback.onConnectionStateChange(gatt, status, newState) if (newState == BluetoothProfile.STATE_CONNECTED && status == BluetoothGatt.GATT_SUCCESS) { @@ -148,7 +157,7 @@ class BluetoothManager : BleCallback { wrappedCallback.onServicesDiscovered(gatt, status) Log.i("$TAG|onServicesDiscovered", "Services Discovered") - gatt?.requestMtu(247); + gatt?.requestMtu(247) } override fun onMtuChanged(gatt: BluetoothGatt?, mtu: Int, status: Int) { @@ -161,44 +170,44 @@ class BluetoothManager : BleCallback { } override fun onCharacteristicChanged( - gatt: BluetoothGatt, - characteristic: BluetoothGattCharacteristic + gatt: BluetoothGatt, + characteristic: BluetoothGattCharacteristic ) { Log.d(TAG, "${gatt.device.name}.onCharacteristicChanged: ${characteristic.uuid}") wrappedCallback.onCharacteristicChanged(gatt, characteristic) } override fun onCharacteristicRead( - gatt: BluetoothGatt, - characteristic: BluetoothGattCharacteristic, - status: Int + gatt: BluetoothGatt, + characteristic: BluetoothGattCharacteristic, + status: Int ) { Log.d(TAG, "${gatt.device.name}.onCharacteristicRead: ${characteristic.uuid} -> $status") wrappedCallback.onCharacteristicRead(gatt, characteristic, status) } override fun onCharacteristicWrite( - gatt: BluetoothGatt, - characteristic: BluetoothGattCharacteristic, - status: Int + gatt: BluetoothGatt, + characteristic: BluetoothGattCharacteristic, + status: Int ) { Log.d(TAG, "${gatt.device.name}.onCharacteristicWrite: ${characteristic.uuid} -> $status") wrappedCallback.onCharacteristicWrite(gatt, characteristic, status) } override fun onDescriptorRead( - gatt: BluetoothGatt, - descriptor: BluetoothGattDescriptor, - status: Int + gatt: BluetoothGatt, + descriptor: BluetoothGattDescriptor, + status: Int ) { Log.d(TAG, "${gatt.device.name}.onDescriptorRead: ${descriptor.uuid} -> $status") wrappedCallback.onDescriptorRead(gatt, descriptor, status) } override fun onDescriptorWrite( - gatt: BluetoothGatt, - descriptor: BluetoothGattDescriptor, - status: Int + gatt: BluetoothGatt, + descriptor: BluetoothGattDescriptor, + status: Int ) { Log.d(TAG, "${gatt.device.name}.onDescriptorWrite: ${descriptor.uuid} -> $status") wrappedCallback.onDescriptorWrite(gatt, descriptor, status) @@ -227,7 +236,7 @@ class BluetoothManager : BleCallback { } override fun onNotifyChipConnectionClosed(connId: Int) { - bleGatt?.close(); + bleGatt?.close() connectionId = 0 Log.d(TAG, "onNotifyChipConnectionClosed") } diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/AddressUpdateFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/AddressUpdateFragment.kt index 9b69bf751bf9ee..2fc03050bfc2f1 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/AddressUpdateFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/AddressUpdateFragment.kt @@ -11,19 +11,22 @@ import com.google.chip.chiptool.databinding.AddressUpdateFragmentBinding import com.google.chip.chiptool.util.DeviceIdUtil /** Fragment for updating the address of a device given its fabric and node ID. */ -class AddressUpdateFragment: Fragment() { +class AddressUpdateFragment : Fragment() { private val deviceController: ChipDeviceController get() = ChipClient.getDeviceController(requireContext()) val deviceId: Long get() = binding.deviceIdEd.text.toString().toULong().toLong() - var endpointId : Int + + var endpointId: Int get() = binding.epIdEd.text.toString().toInt() set(value) { binding.epIdEd.setText(value.toString()) } + private var _binding: AddressUpdateFragmentBinding? = null - private val binding get() = _binding!! + private val binding + get() = _binding!! override fun onCreateView( inflater: LayoutInflater, @@ -47,4 +50,4 @@ class AddressUpdateFragment: Fragment() { super.onDestroyView() _binding = null } -} \ No newline at end of file +} diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/BasicClientFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/BasicClientFragment.kt index 3f1692f6720795..4d19a56c10c5c5 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/BasicClientFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/BasicClientFragment.kt @@ -10,6 +10,7 @@ import android.widget.ArrayAdapter import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import chip.devicecontroller.ChipDeviceController +import chip.devicecontroller.ClusterIDMapping.* import chip.devicecontroller.ReportCallback import chip.devicecontroller.WriteAttributesCallback import chip.devicecontroller.model.AttributeWriteRequest @@ -21,11 +22,9 @@ import com.google.chip.chiptool.GenericChipDeviceListener import com.google.chip.chiptool.R import com.google.chip.chiptool.databinding.BasicClientFragmentBinding import com.google.chip.chiptool.util.TlvParseUtil +import java.util.Optional import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch -import java.util.Optional - -import chip.devicecontroller.ClusterIDMapping.* class BasicClientFragment : Fragment() { private val deviceController: ChipDeviceController @@ -36,7 +35,8 @@ class BasicClientFragment : Fragment() { private lateinit var addressUpdateFragment: AddressUpdateFragment private var _binding: BasicClientFragmentBinding? = null - private val binding get() = _binding!! + private val binding + get() = _binding!! override fun onCreateView( inflater: LayoutInflater, @@ -50,25 +50,38 @@ class BasicClientFragment : Fragment() { addressUpdateFragment = childFragmentManager.findFragmentById(R.id.addressUpdateFragment) as AddressUpdateFragment - binding.writeNodeLabelBtn.setOnClickListener { scope.launch { - // TODO : Need to be implement poj-to-tlv - sendWriteAttribute(BasicInformation.Attribute.NodeLabel, TlvParseUtil.encode(binding.nodeLabelEd.text.toString())) - binding.nodeLabelEd.onEditorAction(EditorInfo.IME_ACTION_DONE) - }} - binding.writeLocationBtn.setOnClickListener { scope.launch { - // TODO : Need to be implement poj-to-tlv - sendWriteAttribute(BasicInformation.Attribute.Location, TlvParseUtil.encode(binding.locationEd.text.toString())) - binding.locationEd.onEditorAction(EditorInfo.IME_ACTION_DONE) - }} + binding.writeNodeLabelBtn.setOnClickListener { + scope.launch { + // TODO : Need to be implement poj-to-tlv + sendWriteAttribute( + BasicInformation.Attribute.NodeLabel, + TlvParseUtil.encode(binding.nodeLabelEd.text.toString()) + ) + binding.nodeLabelEd.onEditorAction(EditorInfo.IME_ACTION_DONE) + } + } + binding.writeLocationBtn.setOnClickListener { + scope.launch { + // TODO : Need to be implement poj-to-tlv + sendWriteAttribute( + BasicInformation.Attribute.Location, + TlvParseUtil.encode(binding.locationEd.text.toString()) + ) + binding.locationEd.onEditorAction(EditorInfo.IME_ACTION_DONE) + } + } binding.writeLocalConfigDisabledSwitch.setOnCheckedChangeListener { _, isChecked -> scope.launch { // TODO : Need to be implement poj-to-tlv - sendWriteAttribute(BasicInformation.Attribute.LocalConfigDisabled, TlvParseUtil.encode(isChecked)) + sendWriteAttribute( + BasicInformation.Attribute.LocalConfigDisabled, + TlvParseUtil.encode(isChecked) + ) } } makeAttributeList() binding.attributeNameSpinner.adapter = makeAttributeNamesAdapter() - binding.readAttributeBtn.setOnClickListener { scope.launch { readAttributeButtonClick() }} + binding.readAttributeBtn.setOnClickListener { scope.launch { readAttributeButtonClick() } } return binding.root } @@ -98,15 +111,13 @@ class BasicClientFragment : Fragment() { } } - private fun makeAttributeNamesAdapter(): ArrayAdapter { return ArrayAdapter( - requireContext(), - android.R.layout.simple_spinner_dropdown_item, - ATTRIBUTES.toList() - ).apply { - setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) - } + requireContext(), + android.R.layout.simple_spinner_dropdown_item, + ATTRIBUTES.toList() + ) + .apply { setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) } } private suspend fun readAttributeButtonClick() { @@ -123,21 +134,39 @@ class BasicClientFragment : Fragment() { val attributeName = ATTRIBUTES[itemIndex] val attributeId = BasicInformation.Attribute.valueOf(attributeName).id - val devicePtr = ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) - - ChipClient.getDeviceController(requireContext()).readPath(object: ReportCallback { - override fun onError(attributePath: ChipAttributePath?, eventPath: ChipEventPath?, ex: java.lang.Exception) { - showMessage("Read $attributeName failure $ex") - Log.e(TAG, "Read $attributeName failure", ex) - } - - override fun onReport(nodeState: NodeState?) { - val value = nodeState?.getEndpointState(endpointId)?.getClusterState(clusterId)?.getAttributeState(attributeId)?.value ?: "null" - Log.i(TAG,"[Read Success] $attributeName: $value") - showMessage("[Read Success] $attributeName: $value") - } - - }, devicePtr, listOf(ChipAttributePath.newInstance(endpointId, clusterId, attributeId)), null, false, 0 /* imTimeoutMs */) + val devicePtr = + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + + ChipClient.getDeviceController(requireContext()) + .readPath( + object : ReportCallback { + override fun onError( + attributePath: ChipAttributePath?, + eventPath: ChipEventPath?, + ex: java.lang.Exception + ) { + showMessage("Read $attributeName failure $ex") + Log.e(TAG, "Read $attributeName failure", ex) + } + + override fun onReport(nodeState: NodeState?) { + val value = + nodeState + ?.getEndpointState(endpointId) + ?.getClusterState(clusterId) + ?.getAttributeState(attributeId) + ?.value + ?: "null" + Log.i(TAG, "[Read Success] $attributeName: $value") + showMessage("[Read Success] $attributeName: $value") + } + }, + devicePtr, + listOf(ChipAttributePath.newInstance(endpointId, clusterId, attributeId)), + null, + false, + 0 /* imTimeoutMs */ + ) } private fun makeAttributeList() { @@ -148,25 +177,38 @@ class BasicClientFragment : Fragment() { private suspend fun sendWriteAttribute(attribute: BasicInformation.Attribute, tlv: ByteArray) { val clusterId = BasicInformation.ID - val devicePtr = ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) - - ChipClient.getDeviceController(requireContext()).write(object: WriteAttributesCallback { - override fun onError(attributePath: ChipAttributePath?, ex: java.lang.Exception?) { - showMessage("Write ${attribute.name} failure $ex") - Log.e(TAG, "Write ${attribute.name} failure", ex) - } - - override fun onResponse(attributePath: ChipAttributePath?) { - showMessage("Write ${attribute.name} success") - } - - }, devicePtr, listOf(AttributeWriteRequest.newInstance(addressUpdateFragment.endpointId, clusterId, attribute.id, tlv, Optional.empty())), 0, 0) + val devicePtr = + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + + ChipClient.getDeviceController(requireContext()) + .write( + object : WriteAttributesCallback { + override fun onError(attributePath: ChipAttributePath?, ex: java.lang.Exception?) { + showMessage("Write ${attribute.name} failure $ex") + Log.e(TAG, "Write ${attribute.name} failure", ex) + } + + override fun onResponse(attributePath: ChipAttributePath?) { + showMessage("Write ${attribute.name} success") + } + }, + devicePtr, + listOf( + AttributeWriteRequest.newInstance( + addressUpdateFragment.endpointId, + clusterId, + attribute.id, + tlv, + Optional.empty() + ) + ), + 0, + 0 + ) } private fun showMessage(msg: String) { - requireActivity().runOnUiThread { - binding.basicClusterCommandStatus.text = msg - } + requireActivity().runOnUiThread { binding.basicClusterCommandStatus.text = msg } } override fun onResume() { diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/MultiAdminClientFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/MultiAdminClientFragment.kt index ed7ba6f4f692f0..4df9d2a1a1d230 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/MultiAdminClientFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/MultiAdminClientFragment.kt @@ -33,7 +33,8 @@ class MultiAdminClientFragment : Fragment() { private lateinit var addressUpdateFragment: AddressUpdateFragment private var _binding: MultiAdminClientFragmentBinding? = null - private val binding get() = _binding!! + private val binding + get() = _binding!! override fun onCreateView( inflater: LayoutInflater, @@ -48,12 +49,34 @@ class MultiAdminClientFragment : Fragment() { addressUpdateFragment = childFragmentManager.findFragmentById(R.id.addressUpdateFragment) as AddressUpdateFragment - binding.basicCommissioningMethodBtn.setOnClickListener { scope.launch { sendBasicCommissioningCommandClick() } } - binding.enhancedCommissioningMethodBtn.setOnClickListener { scope.launch { sendEnhancedCommissioningCommandClick() } } + binding.basicCommissioningMethodBtn.setOnClickListener { + scope.launch { sendBasicCommissioningCommandClick() } + } + binding.enhancedCommissioningMethodBtn.setOnClickListener { + scope.launch { sendEnhancedCommissioningCommandClick() } + } binding.revokeBtn.setOnClickListener { scope.launch { sendRevokeCommandClick() } } - binding.readWindowStatusBtn.setOnClickListener { scope.launch { readAdministratorCommissioningClusterAttributeClick(AdministratorCommissioning.Attribute.WindowStatus) } } - binding.readAdminFabricIndexBtn.setOnClickListener { scope.launch { readAdministratorCommissioningClusterAttributeClick(AdministratorCommissioning.Attribute.AdminFabricIndex) } } - binding.readAdminVendorIdBtn.setOnClickListener { scope.launch { readAdministratorCommissioningClusterAttributeClick(AdministratorCommissioning.Attribute.AdminVendorId) } } + binding.readWindowStatusBtn.setOnClickListener { + scope.launch { + readAdministratorCommissioningClusterAttributeClick( + AdministratorCommissioning.Attribute.WindowStatus + ) + } + } + binding.readAdminFabricIndexBtn.setOnClickListener { + scope.launch { + readAdministratorCommissioningClusterAttributeClick( + AdministratorCommissioning.Attribute.AdminFabricIndex + ) + } + } + binding.readAdminVendorIdBtn.setOnClickListener { + scope.launch { + readAdministratorCommissioningClusterAttributeClick( + AdministratorCommissioning.Attribute.AdminVendorId + ) + } + } return binding.root } @@ -97,11 +120,9 @@ class MultiAdminClientFragment : Fragment() { private suspend fun sendBasicCommissioningCommandClick() { val testDuration = binding.timeoutEd.text.toString().toInt() deviceController.openPairingWindowCallback( - ChipClient.getConnectedDevicePointer( - requireContext(), - addressUpdateFragment.deviceId - ), testDuration, - object:OpenCommissioningCallback { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), + testDuration, + object : OpenCommissioningCallback { override fun onError(status: Int, deviceId: Long) { showMessage("OpenBasicCommissioning Fail! \nDevice ID : $deviceId\nErrorCode : $status") } @@ -124,15 +145,20 @@ class MultiAdminClientFragment : Fragment() { setupPinCode = binding.setupPinCodeEd.text.toString().toULong().toLong() } deviceController.openPairingWindowWithPINCallback( - devicePointer, testDuration, testIteration.toLong(), - binding.discriminatorEd.text.toString().toInt(), setupPinCode, - object:OpenCommissioningCallback { + devicePointer, + testDuration, + testIteration.toLong(), + binding.discriminatorEd.text.toString().toInt(), + setupPinCode, + object : OpenCommissioningCallback { override fun onError(status: Int, deviceId: Long) { showMessage("OpenCommissioning Fail! \nDevice ID : $deviceId\nErrorCode : $status") } override fun onSuccess(deviceId: Long, manualPairingCode: String?, qrCode: String?) { - showMessage("OpenCommissioning Success! \n Node ID: $deviceId\n\tManual : $manualPairingCode\n\tQRCode : $qrCode") + showMessage( + "OpenCommissioning Success! \n Node ID: $deviceId\n\tManual : $manualPairingCode\n\tQRCode : $qrCode" + ) } } ) @@ -144,42 +170,68 @@ class MultiAdminClientFragment : Fragment() { val tlvWriter = TlvWriter() tlvWriter.startStructure(AnonymousTag) tlvWriter.endStructure() - val invokeElement = InvokeElement.newInstance(ADMINISTRATOR_COMMISSIONING_CLUSTER_ENDPOINT_ID - , AdministratorCommissioning.ID - , AdministratorCommissioning.Command.RevokeCommissioning.id - , tlvWriter.getEncoded(), null) - - deviceController.invoke(object: InvokeCallback { - override fun onError(ex: Exception?) { - showMessage("Revoke Commissioning failure $ex") - Log.e(TAG, "Revoke Commissioning failure", ex) - } - - override fun onResponse(invokeElement: InvokeElement?, successCode: Long) { - Log.e(TAG, "onResponse : $invokeElement, Code : $successCode") - showMessage("Revoke Commissioning success") - } + val invokeElement = + InvokeElement.newInstance( + ADMINISTRATOR_COMMISSIONING_CLUSTER_ENDPOINT_ID, + AdministratorCommissioning.ID, + AdministratorCommissioning.Command.RevokeCommissioning.id, + tlvWriter.getEncoded(), + null + ) + + deviceController.invoke( + object : InvokeCallback { + override fun onError(ex: Exception?) { + showMessage("Revoke Commissioning failure $ex") + Log.e(TAG, "Revoke Commissioning failure", ex) + } - }, getConnectedDevicePointer(), invokeElement, timedInvokeTimeout, 0) + override fun onResponse(invokeElement: InvokeElement?, successCode: Long) { + Log.e(TAG, "onResponse : $invokeElement, Code : $successCode") + showMessage("Revoke Commissioning success") + } + }, + getConnectedDevicePointer(), + invokeElement, + timedInvokeTimeout, + 0 + ) } - private suspend fun readAdministratorCommissioningClusterAttributeClick(attribute: AdministratorCommissioning.Attribute) { + private suspend fun readAdministratorCommissioningClusterAttributeClick( + attribute: AdministratorCommissioning.Attribute + ) { val endpointId = ADMINISTRATOR_COMMISSIONING_CLUSTER_ENDPOINT_ID val clusterId = AdministratorCommissioning.ID val attributeId = attribute.id val attributeName = attribute.name val attributePath = ChipAttributePath.newInstance(endpointId, clusterId, attributeId) - deviceController.readAttributePath(object: ReportCallback { - override fun onReport(nodeState: NodeState?) { - val value = nodeState?.getEndpointState(endpointId)?.getClusterState(clusterId)?.getAttributeState(attributeId)?.value ?: "null" - Log.i(TAG,"read $attributeName: $value") - showMessage("read $attributeName: $value") - } + deviceController.readAttributePath( + object : ReportCallback { + override fun onReport(nodeState: NodeState?) { + val value = + nodeState + ?.getEndpointState(endpointId) + ?.getClusterState(clusterId) + ?.getAttributeState(attributeId) + ?.value + ?: "null" + Log.i(TAG, "read $attributeName: $value") + showMessage("read $attributeName: $value") + } - override fun onError(attributePath: ChipAttributePath?, eventPath: ChipEventPath?, e: Exception) { - showMessage("read $attributeName - error : ${e?.message}") - } - }, getConnectedDevicePointer(), listOf(attributePath), 0) + override fun onError( + attributePath: ChipAttributePath?, + eventPath: ChipEventPath?, + e: Exception + ) { + showMessage("read $attributeName - error : ${e?.message}") + } + }, + getConnectedDevicePointer(), + listOf(attributePath), + 0 + ) } private suspend fun getConnectedDevicePointer(): Long { @@ -187,14 +239,13 @@ class MultiAdminClientFragment : Fragment() { } private fun showMessage(msg: String) { - requireActivity().runOnUiThread { - binding.multiAdminClusterCommandStatus.text = msg - } + requireActivity().runOnUiThread { binding.multiAdminClusterCommandStatus.text = msg } } companion object { private const val TAG = "MultiAdminClientFragment" private const val ADMINISTRATOR_COMMISSIONING_CLUSTER_ENDPOINT_ID = 0 + fun newInstance(): MultiAdminClientFragment = MultiAdminClientFragment() } } diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OnOffClientFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OnOffClientFragment.kt index 5088cd05036d76..b4bc72c103c986 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OnOffClientFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OnOffClientFragment.kt @@ -13,6 +13,7 @@ import android.widget.Toast import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import chip.devicecontroller.ChipDeviceController +import chip.devicecontroller.ClusterIDMapping.* import chip.devicecontroller.InvokeCallback import chip.devicecontroller.ReportCallback import chip.devicecontroller.ResubscriptionAttemptCallback @@ -21,6 +22,8 @@ import chip.devicecontroller.model.ChipAttributePath import chip.devicecontroller.model.ChipEventPath import chip.devicecontroller.model.InvokeElement import chip.devicecontroller.model.NodeState +import chip.tlv.AnonymousTag +import chip.tlv.ContextSpecificTag import chip.tlv.TlvWriter import com.google.chip.chiptool.ChipClient import com.google.chip.chiptool.GenericChipDeviceListener @@ -33,10 +36,6 @@ import java.util.Locale import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch -import chip.devicecontroller.ClusterIDMapping.* -import chip.tlv.AnonymousTag -import chip.tlv.ContextSpecificTag - class OnOffClientFragment : Fragment() { private val deviceController: ChipDeviceController get() = ChipClient.getDeviceController(requireContext()) @@ -46,7 +45,8 @@ class OnOffClientFragment : Fragment() { private lateinit var addressUpdateFragment: AddressUpdateFragment private var _binding: OnOffClientFragmentBinding? = null - private val binding get() = _binding!! + private val binding + get() = _binding!! override fun onCreateView( inflater: LayoutInflater, @@ -62,28 +62,32 @@ class OnOffClientFragment : Fragment() { childFragmentManager.findFragmentById(R.id.addressUpdateFragment) as AddressUpdateFragment binding.onBtn.setOnClickListener { scope.launch { sendOnOffClusterCommand(OnOff.Command.On) } } - binding.offBtn.setOnClickListener { scope.launch { sendOnOffClusterCommand(OnOff.Command.Off) } } - binding.toggleBtn.setOnClickListener { scope.launch { sendOnOffClusterCommand(OnOff.Command.Toggle) } } + binding.offBtn.setOnClickListener { + scope.launch { sendOnOffClusterCommand(OnOff.Command.Off) } + } + binding.toggleBtn.setOnClickListener { + scope.launch { sendOnOffClusterCommand(OnOff.Command.Toggle) } + } binding.readBtn.setOnClickListener { scope.launch { sendReadOnOffClick() } } binding.showSubscribeDialogBtn.setOnClickListener { showSubscribeDialog() } - binding.levelBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { - override fun onProgressChanged(seekBar: SeekBar, i: Int, b: Boolean) { - - } + binding.levelBar.setOnSeekBarChangeListener( + object : SeekBar.OnSeekBarChangeListener { + override fun onProgressChanged(seekBar: SeekBar, i: Int, b: Boolean) {} - override fun onStartTrackingTouch(seekBar: SeekBar?) { - } + override fun onStartTrackingTouch(seekBar: SeekBar?) {} - override fun onStopTrackingTouch(seekBar: SeekBar?) { - Toast.makeText( - requireContext(), - "Level is: " + binding.levelBar.progress, - Toast.LENGTH_SHORT - ).show() - scope.launch { sendLevelCommandClick() } + override fun onStopTrackingTouch(seekBar: SeekBar?) { + Toast.makeText( + requireContext(), + "Level is: " + binding.levelBar.progress, + Toast.LENGTH_SHORT + ) + .show() + scope.launch { sendLevelCommandClick() } + } } - }) + ) return binding.root } @@ -100,25 +104,40 @@ class OnOffClientFragment : Fragment() { val attributePath = ChipAttributePath.newInstance(endpointId, clusterId, attributeId) - ChipClient.getDeviceController(requireContext()).readPath(object: ReportCallback { - override fun onError(attributePath: ChipAttributePath?, eventPath: ChipEventPath?, ex: java.lang.Exception) { - Log.e(TAG, "Error reading onOff attribute", ex) - } - - override fun onReport(nodeState: NodeState?) { - val value = nodeState?.getEndpointState(endpointId)?.getClusterState(clusterId)?.getAttributeState(attributeId)?.value ?: "null" - Log.v(TAG, "On/Off attribute value: $value") - showMessage("On/Off attribute value: $value") - } - - }, getConnectedDevicePointer(), listOf(attributePath), null, false, 0 /* imTimeoutMs */) + ChipClient.getDeviceController(requireContext()) + .readPath( + object : ReportCallback { + override fun onError( + attributePath: ChipAttributePath?, + eventPath: ChipEventPath?, + ex: java.lang.Exception + ) { + Log.e(TAG, "Error reading onOff attribute", ex) + } + + override fun onReport(nodeState: NodeState?) { + val value = + nodeState + ?.getEndpointState(endpointId) + ?.getClusterState(clusterId) + ?.getAttributeState(attributeId) + ?.value + ?: "null" + Log.v(TAG, "On/Off attribute value: $value") + showMessage("On/Off attribute value: $value") + } + }, + getConnectedDevicePointer(), + listOf(attributePath), + null, + false, + 0 /* imTimeoutMs */ + ) } private fun showSubscribeDialog() { val dialogView = requireActivity().layoutInflater.inflate(R.layout.subscribe_dialog, null) - val dialog = AlertDialog.Builder(requireContext()).apply { - setView(dialogView) - }.create() + val dialog = AlertDialog.Builder(requireContext()).apply { setView(dialogView) }.create() val minIntervalEd = dialogView.findViewById(R.id.minIntervalEd) val maxIntervalEd = dialogView.findViewById(R.id.maxIntervalEd) @@ -128,13 +147,12 @@ class OnOffClientFragment : Fragment() { minIntervalEd.text.toString().toInt(), maxIntervalEd.text.toString().toInt() ) - requireActivity().runOnUiThread { - dialog.dismiss() - } + requireActivity().runOnUiThread { dialog.dismiss() } } } dialog.show() } + private suspend fun sendSubscribeOnOffClick(minInterval: Int, maxInterval: Int) { val endpointId = addressUpdateFragment.endpointId val clusterId = OnOff.ID @@ -142,46 +160,65 @@ class OnOffClientFragment : Fragment() { val attributePath = ChipAttributePath.newInstance(endpointId, clusterId, attributeId) - val subscriptionEstablishedCallback = - SubscriptionEstablishedCallback { - subscriptionId -> - Log.i(TAG, "Subscription to device established : ${subscriptionId.toULong()}") - requireActivity().runOnUiThread { - Toast.makeText(requireActivity(), "${getString(R.string.wildcard_subscribe_established_toast_message)} : $subscriptionId", Toast.LENGTH_SHORT).show() - } - } + val subscriptionEstablishedCallback = SubscriptionEstablishedCallback { subscriptionId -> + Log.i(TAG, "Subscription to device established : ${subscriptionId.toULong()}") + requireActivity().runOnUiThread { + Toast.makeText( + requireActivity(), + "${getString(R.string.wildcard_subscribe_established_toast_message)} : $subscriptionId", + Toast.LENGTH_SHORT + ) + .show() + } + } val resubscriptionAttemptCallback = - ResubscriptionAttemptCallback { terminationCause, nextResubscribeIntervalMsec - -> Log.i(TAG, "ResubscriptionAttempt terminationCause:$terminationCause, nextResubscribeIntervalMsec:$nextResubscribeIntervalMsec") } - - deviceController.subscribeToPath(subscriptionEstablishedCallback, - resubscriptionAttemptCallback, - object: ReportCallback { - override fun onError(attributePath: ChipAttributePath?, eventPath: ChipEventPath?, ex: Exception) { - Log.e(TAG, "Error configuring on/off attribute", ex) - } - - override fun onReport(nodeState: NodeState?) { - val tlv = nodeState?.getEndpointState(endpointId)?.getClusterState(clusterId)?.getAttributeState(attributeId)?.tlv ?: return - // TODO : Need to be implement poj-to-tlv - val value = TlvParseUtil.decodeBoolean(tlv) - val formatter = SimpleDateFormat("HH:mm:ss", Locale.getDefault()) - val time = formatter.format(Calendar.getInstance(Locale.getDefault()).time) - val message = "Subscribed on/off value at $time: ${if (value) "ON" else "OFF"}" - - Log.v(TAG, message) - showReportMessage(message) - } - }, - getConnectedDevicePointer(), - listOf(attributePath), - null, - minInterval, - maxInterval, - false, - false, - /* imTimeoutMs= */ 0) + ResubscriptionAttemptCallback { terminationCause, nextResubscribeIntervalMsec -> + Log.i( + TAG, + "ResubscriptionAttempt terminationCause:$terminationCause, nextResubscribeIntervalMsec:$nextResubscribeIntervalMsec" + ) + } + + deviceController.subscribeToPath( + subscriptionEstablishedCallback, + resubscriptionAttemptCallback, + object : ReportCallback { + override fun onError( + attributePath: ChipAttributePath?, + eventPath: ChipEventPath?, + ex: Exception + ) { + Log.e(TAG, "Error configuring on/off attribute", ex) + } + + override fun onReport(nodeState: NodeState?) { + val tlv = + nodeState + ?.getEndpointState(endpointId) + ?.getClusterState(clusterId) + ?.getAttributeState(attributeId) + ?.tlv + ?: return + // TODO : Need to be implement poj-to-tlv + val value = TlvParseUtil.decodeBoolean(tlv) + val formatter = SimpleDateFormat("HH:mm:ss", Locale.getDefault()) + val time = formatter.format(Calendar.getInstance(Locale.getDefault()).time) + val message = "Subscribed on/off value at $time: ${if (value) "ON" else "OFF"}" + + Log.v(TAG, message) + showReportMessage(message) + } + }, + getConnectedDevicePointer(), + listOf(attributePath), + null, + minInterval, + maxInterval, + false, + false, + /* imTimeoutMs= */ 0 + ) } inner class ChipControllerCallback : GenericChipDeviceListener() { @@ -209,29 +246,41 @@ class OnOffClientFragment : Fragment() { // TODO : Need to be implement poj-to-tlv val tlvWriter = TlvWriter() tlvWriter.startStructure(AnonymousTag) - tlvWriter.put(ContextSpecificTag(LevelControl.MoveToLevelCommandField.Level.id), binding.levelBar.progress.toUInt()) + tlvWriter.put( + ContextSpecificTag(LevelControl.MoveToLevelCommandField.Level.id), + binding.levelBar.progress.toUInt() + ) tlvWriter.put(ContextSpecificTag(LevelControl.MoveToLevelCommandField.OptionsMask.id), 0u) tlvWriter.put(ContextSpecificTag(LevelControl.MoveToLevelCommandField.OptionsOverride.id), 0u) tlvWriter.put(ContextSpecificTag(LevelControl.MoveToLevelCommandField.TransitionTime.id), 0u) tlvWriter.endStructure() - val invokeElement = InvokeElement.newInstance(addressUpdateFragment.endpointId - , LevelControl.ID - , LevelControl.Command.MoveToLevel.id - , tlvWriter.getEncoded(), null) - - deviceController.invoke(object: InvokeCallback { - override fun onError(ex: Exception?) { - showMessage("MoveToLevel command failure $ex") - Log.e(TAG, "MoveToLevel command failure", ex) - } - - override fun onResponse(invokeElement: InvokeElement?, successCode: Long) { - Log.e(TAG, "onResponse : $invokeElement, Code : $successCode") - showMessage("MoveToLevel command success") - } + val invokeElement = + InvokeElement.newInstance( + addressUpdateFragment.endpointId, + LevelControl.ID, + LevelControl.Command.MoveToLevel.id, + tlvWriter.getEncoded(), + null + ) + + deviceController.invoke( + object : InvokeCallback { + override fun onError(ex: Exception?) { + showMessage("MoveToLevel command failure $ex") + Log.e(TAG, "MoveToLevel command failure", ex) + } - }, getConnectedDevicePointer(), invokeElement, 0, 0) + override fun onResponse(invokeElement: InvokeElement?, successCode: Long) { + Log.e(TAG, "onResponse : $invokeElement, Code : $successCode") + showMessage("MoveToLevel command success") + } + }, + getConnectedDevicePointer(), + invokeElement, + 0, + 0 + ) } private suspend fun sendOnOffClusterCommand(commandId: OnOff.Command) { @@ -239,23 +288,32 @@ class OnOffClientFragment : Fragment() { val tlvWriter = TlvWriter() tlvWriter.startStructure(AnonymousTag) tlvWriter.endStructure() - val invokeElement = InvokeElement.newInstance(addressUpdateFragment.endpointId - , OnOff.ID - , commandId.id - , tlvWriter.getEncoded(), null) - - deviceController.invoke(object: InvokeCallback { - override fun onError(ex: Exception?) { - showMessage("${commandId.name} command failure $ex") - Log.e(TAG, "${commandId.name} command failure", ex) - } - - override fun onResponse(invokeElement: InvokeElement?, successCode: Long) { - Log.e(TAG, "onResponse : $invokeElement, Code : $successCode") - showMessage("${commandId.name} command success") - } + val invokeElement = + InvokeElement.newInstance( + addressUpdateFragment.endpointId, + OnOff.ID, + commandId.id, + tlvWriter.getEncoded(), + null + ) + + deviceController.invoke( + object : InvokeCallback { + override fun onError(ex: Exception?) { + showMessage("${commandId.name} command failure $ex") + Log.e(TAG, "${commandId.name} command failure", ex) + } - }, getConnectedDevicePointer(), invokeElement, 0, 0) + override fun onResponse(invokeElement: InvokeElement?, successCode: Long) { + Log.e(TAG, "onResponse : $invokeElement, Code : $successCode") + showMessage("${commandId.name} command success") + } + }, + getConnectedDevicePointer(), + invokeElement, + 0, + 0 + ) } private suspend fun getConnectedDevicePointer(): Long { @@ -263,21 +321,16 @@ class OnOffClientFragment : Fragment() { } private fun showMessage(msg: String) { - requireActivity().runOnUiThread { - binding.commandStatusTv.text = msg - } + requireActivity().runOnUiThread { binding.commandStatusTv.text = msg } } private fun showReportMessage(msg: String) { - requireActivity().runOnUiThread { - binding.reportStatusTv.text = msg - } + requireActivity().runOnUiThread { binding.reportStatusTv.text = msg } } override fun onResume() { super.onResume() addressUpdateFragment.endpointId = ON_OFF_CLUSTER_ENDPOINT - } companion object { diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OpCredClientFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OpCredClientFragment.kt index 02dc9912c5597f..734ce12c6810bb 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OpCredClientFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OpCredClientFragment.kt @@ -8,13 +8,6 @@ import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import chip.devicecontroller.ChipDeviceController -import com.google.chip.chiptool.ChipClient -import com.google.chip.chiptool.GenericChipDeviceListener -import com.google.chip.chiptool.R -import com.google.chip.chiptool.databinding.OpCredClientFragmentBinding -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch - import chip.devicecontroller.ClusterIDMapping.OperationalCredentials import chip.devicecontroller.InvokeCallback import chip.devicecontroller.ReportCallback @@ -25,6 +18,12 @@ import chip.devicecontroller.model.NodeState import chip.tlv.AnonymousTag import chip.tlv.ContextSpecificTag import chip.tlv.TlvWriter +import com.google.chip.chiptool.ChipClient +import com.google.chip.chiptool.GenericChipDeviceListener +import com.google.chip.chiptool.R +import com.google.chip.chiptool.databinding.OpCredClientFragmentBinding +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch class OpCredClientFragment : Fragment() { private val deviceController: ChipDeviceController @@ -35,7 +34,8 @@ class OpCredClientFragment : Fragment() { private lateinit var addressUpdateFragment: AddressUpdateFragment private var _binding: OpCredClientFragmentBinding? = null - private val binding get() = _binding!! + private val binding + get() = _binding!! override fun onCreateView( inflater: LayoutInflater, @@ -50,10 +50,18 @@ class OpCredClientFragment : Fragment() { addressUpdateFragment = childFragmentManager.findFragmentById(R.id.addressUpdateFragment) as AddressUpdateFragment - binding.readSupportedFabricBtn.setOnClickListener { scope.launch { readClusterAttribute(OperationalCredentials.Attribute.SupportedFabrics) } } - binding.readCommissionedFabricBtn.setOnClickListener { scope.launch { readClusterAttribute(OperationalCredentials.Attribute.CommissionedFabrics) } } - binding.readFabricsBtn.setOnClickListener { scope.launch { readClusterAttribute(OperationalCredentials.Attribute.Fabrics) } } - binding.removeFabricsBtn.setOnClickListener { scope.launch { sendRemoveFabricsBtnClick(binding.fabricIndexEd.text.toString().toUInt()) } } + binding.readSupportedFabricBtn.setOnClickListener { + scope.launch { readClusterAttribute(OperationalCredentials.Attribute.SupportedFabrics) } + } + binding.readCommissionedFabricBtn.setOnClickListener { + scope.launch { readClusterAttribute(OperationalCredentials.Attribute.CommissionedFabrics) } + } + binding.readFabricsBtn.setOnClickListener { + scope.launch { readClusterAttribute(OperationalCredentials.Attribute.Fabrics) } + } + binding.removeFabricsBtn.setOnClickListener { + scope.launch { sendRemoveFabricsBtnClick(binding.fabricIndexEd.text.toString().toUInt()) } + } return binding.root } @@ -89,53 +97,82 @@ class OpCredClientFragment : Fragment() { val attributeName = attribute.name val attributeId = attribute.id - val devicePtr = ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) - - ChipClient.getDeviceController(requireContext()).readPath(object: ReportCallback { - override fun onError(attributePath: ChipAttributePath?, eventPath: ChipEventPath?, ex: java.lang.Exception) { - showMessage("Read $attributeName failure $ex") - Log.e(TAG, "Read $attributeName failure", ex) - } - - override fun onReport(nodeState: NodeState?) { - val value = nodeState?.getEndpointState(endpointId)?.getClusterState(clusterId)?.getAttributeState(attributeId)?.value ?: "null" - Log.i(TAG,"OpCred $attributeName value: $value") - showMessage("OpCred $attributeName value: $value") - } - - }, devicePtr, listOf(ChipAttributePath.newInstance(endpointId, clusterId, attributeId)), null, false, 0 /* imTimeoutMs */) + val devicePtr = + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + + ChipClient.getDeviceController(requireContext()) + .readPath( + object : ReportCallback { + override fun onError( + attributePath: ChipAttributePath?, + eventPath: ChipEventPath?, + ex: java.lang.Exception + ) { + showMessage("Read $attributeName failure $ex") + Log.e(TAG, "Read $attributeName failure", ex) + } + + override fun onReport(nodeState: NodeState?) { + val value = + nodeState + ?.getEndpointState(endpointId) + ?.getClusterState(clusterId) + ?.getAttributeState(attributeId) + ?.value + ?: "null" + Log.i(TAG, "OpCred $attributeName value: $value") + showMessage("OpCred $attributeName value: $value") + } + }, + devicePtr, + listOf(ChipAttributePath.newInstance(endpointId, clusterId, attributeId)), + null, + false, + 0 /* imTimeoutMs */ + ) } private suspend fun sendRemoveFabricsBtnClick(fabricIndex: UInt) { - val devicePtr = ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + val devicePtr = + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) // TODO : Need to be implement poj-to-tlv val tlvWriter = TlvWriter() tlvWriter.startStructure(AnonymousTag) - tlvWriter.put(ContextSpecificTag(OperationalCredentials.RemoveFabricCommandField.FabricIndex.id), fabricIndex) + tlvWriter.put( + ContextSpecificTag(OperationalCredentials.RemoveFabricCommandField.FabricIndex.id), + fabricIndex + ) tlvWriter.endStructure() - val invokeElement = InvokeElement.newInstance(addressUpdateFragment.endpointId - , OperationalCredentials.ID - , OperationalCredentials.Command.RemoveFabric.id - , tlvWriter.getEncoded(), null) - - deviceController.invoke(object: InvokeCallback { - override fun onError(ex: Exception?) { - showMessage("RemoveFabric failure $ex") - Log.e(TAG, "RemoveFabric failure", ex) - } - - override fun onResponse(invokeElement: InvokeElement?, successCode: Long) { - Log.e(TAG, "onResponse : $invokeElement, Code : $successCode") - showMessage("RemoveFabric success") - } - - }, devicePtr, invokeElement, 0, 0) + val invokeElement = + InvokeElement.newInstance( + addressUpdateFragment.endpointId, + OperationalCredentials.ID, + OperationalCredentials.Command.RemoveFabric.id, + tlvWriter.getEncoded(), + null + ) + + deviceController.invoke( + object : InvokeCallback { + override fun onError(ex: Exception?) { + showMessage("RemoveFabric failure $ex") + Log.e(TAG, "RemoveFabric failure", ex) + } + + override fun onResponse(invokeElement: InvokeElement?, successCode: Long) { + Log.e(TAG, "onResponse : $invokeElement, Code : $successCode") + showMessage("RemoveFabric success") + } + }, + devicePtr, + invokeElement, + 0, + 0 + ) } private fun showMessage(msg: String) { - requireActivity().runOnUiThread { - binding.opCredClusterCommandStatus.text = msg - } + requireActivity().runOnUiThread { binding.opCredClusterCommandStatus.text = msg } } override fun onResume() { @@ -146,6 +183,7 @@ class OpCredClientFragment : Fragment() { companion object { private const val TAG = "OpCredClientFragment" private const val OPERATIONAL_CREDENTIALS_ENDPOINT_ID = 0 + fun newInstance(): OpCredClientFragment = OpCredClientFragment() } } diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/SensorClientFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/SensorClientFragment.kt index 8abe61329a9727..53294c8037f981 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/SensorClientFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/SensorClientFragment.kt @@ -12,6 +12,7 @@ import android.widget.Toast import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import chip.devicecontroller.ChipDeviceController +import chip.devicecontroller.ClusterIDMapping.* import chip.devicecontroller.ReportCallback import chip.devicecontroller.model.ChipAttributePath import chip.devicecontroller.model.ChipEventPath @@ -30,7 +31,6 @@ import java.util.Calendar import java.util.Date import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch -import chip.devicecontroller.ClusterIDMapping.* class SensorClientFragment : Fragment() { private val deviceController: ChipDeviceController @@ -45,12 +45,13 @@ class SensorClientFragment : Fragment() { private var subscribedDevicePtr = 0L private var _binding: SensorClientFragmentBinding? = null - private val binding get() = _binding!! + private val binding + get() = _binding!! override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? ): View { _binding = SensorClientFragmentBinding.inflate(inflater, container, false) scope = viewLifecycleOwner.lifecycleScope @@ -76,12 +77,14 @@ class SensorClientFragment : Fragment() { } binding.clusterNameSpinner.adapter = makeClusterNamesAdapter() - binding.clusterNameSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { - override fun onNothingSelected(parent: AdapterView<*>?) = Unit - override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { - resetSensorGraph() // reset the graph on cluster change + binding.clusterNameSpinner.onItemSelectedListener = + object : AdapterView.OnItemSelectedListener { + override fun onNothingSelected(parent: AdapterView<*>?) = Unit + + override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { + resetSensorGraph() // reset the graph on cluster change + } } - } binding.readSensorBtn.setOnClickListener { scope.launch { readSensorCluster() } } binding.watchSensorBtn.setOnCheckedChangeListener { _, isChecked -> @@ -96,20 +99,22 @@ class SensorClientFragment : Fragment() { binding.sensorGraph.addSeries(sensorData) binding.sensorGraph.viewport.isXAxisBoundsManual = true binding.sensorGraph.viewport.setMinX(currentTime.toDouble()) - binding.sensorGraph.viewport.setMaxX(currentTime.toDouble() + MIN_REFRESH_PERIOD_S * 1000 * MAX_DATA_POINTS) + binding.sensorGraph.viewport.setMaxX( + currentTime.toDouble() + MIN_REFRESH_PERIOD_S * 1000 * MAX_DATA_POINTS + ) binding.sensorGraph.gridLabelRenderer.padding = 30 binding.sensorGraph.gridLabelRenderer.numHorizontalLabels = 4 binding.sensorGraph.gridLabelRenderer.setHorizontalLabelsAngle(150) - binding.sensorGraph.gridLabelRenderer.labelFormatter = object : LabelFormatter { - override fun setViewport(viewport: Viewport?) = Unit - override fun formatLabel(value: Double, isValueX: Boolean): String { - if (isValueX) - return SimpleDateFormat("H:mm:ss").format(Date(value.toLong())).toString() - if (value >= 100.0) - return "%.1f".format(value) - return "%.2f".format(value) + binding.sensorGraph.gridLabelRenderer.labelFormatter = + object : LabelFormatter { + override fun setViewport(viewport: Viewport?) = Unit + + override fun formatLabel(value: Double, isValueX: Boolean): String { + if (isValueX) return SimpleDateFormat("H:mm:ss").format(Date(value.toLong())).toString() + if (value >= 100.0) return "%.1f".format(value) + return "%.2f".format(value) + } } - } } override fun onStart() { @@ -138,9 +143,8 @@ class SensorClientFragment : Fragment() { requireContext(), android.R.layout.simple_spinner_dropdown_item, CLUSTERS.keys.toList() - ).apply { - setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) - } + ) + .apply { setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) } } private suspend fun readSensorCluster() { @@ -153,7 +157,12 @@ class SensorClientFragment : Fragment() { val device = ChipClient.getConnectedDevicePointer(requireContext(), deviceId) val callback = makeReadCallback(clusterName, false) - deviceController.readAttributePath(callback, device, listOf(ChipAttributePath.newInstance(endpointId, clusterId, attributeId)), 0) + deviceController.readAttributePath( + callback, + device, + listOf(ChipAttributePath.newInstance(endpointId, clusterId, attributeId)), + 0 + ) } catch (ex: Exception) { Log.d(TAG, "Failed to read the sensor : ", ex) showMessage(R.string.sensor_client_read_error_text, ex.toString()) @@ -170,7 +179,15 @@ class SensorClientFragment : Fragment() { val device = ChipClient.getConnectedDevicePointer(requireContext(), deviceId) val callback = makeReadCallback(clusterName, true) - deviceController.subscribeToAttributePath({ Log.d(TAG, "onSubscriptionEstablished") }, callback, device, listOf(ChipAttributePath.newInstance(endpointId, clusterId, attributeId)), MIN_REFRESH_PERIOD_S, MAX_REFRESH_PERIOD_S, 0) + deviceController.subscribeToAttributePath( + { Log.d(TAG, "onSubscriptionEstablished") }, + callback, + device, + listOf(ChipAttributePath.newInstance(endpointId, clusterId, attributeId)), + MIN_REFRESH_PERIOD_S, + MAX_REFRESH_PERIOD_S, + 0 + ) subscribedDevicePtr = device } catch (ex: Exception) { Log.d(TAG, "Failed to subscribe", ex) @@ -179,8 +196,7 @@ class SensorClientFragment : Fragment() { } private fun unsubscribeSensorCluster() { - if (subscribedDevicePtr == 0L) - return + if (subscribedDevicePtr == 0L) return try { ChipClient.getDeviceController(requireContext()).shutdownSubscriptions() @@ -198,21 +214,31 @@ class SensorClientFragment : Fragment() { val attributeId = clusterConfig["attributeId"] as Long override fun onReport(nodeState: NodeState?) { - val tlv = nodeState?.getEndpointState(endpointId)?.getClusterState(clusterId)?.getAttributeState(attributeId)?.tlv ?: return + val tlv = + nodeState + ?.getEndpointState(endpointId) + ?.getClusterState(clusterId) + ?.getAttributeState(attributeId) + ?.tlv + ?: return // TODO : Need to be implement poj-to-tlv val value = - try { - TlvParseUtil.decodeInt(tlv) - } catch (ex: Exception) { - showMessage(R.string.sensor_client_read_error_text, "value is null") - return - } + try { + TlvParseUtil.decodeInt(tlv) + } catch (ex: Exception) { + showMessage(R.string.sensor_client_read_error_text, "value is null") + return + } val unitValue = clusterConfig["unitValue"] as Double val unitSymbol = clusterConfig["unitSymbol"] as String consumeSensorValue(value * unitValue, unitSymbol, addToGraph) } - override fun onError(attributePath: ChipAttributePath?, eventPath: ChipEventPath?, ex: Exception) { + override fun onError( + attributePath: ChipAttributePath?, + eventPath: ChipEventPath?, + ex: Exception + ) { showMessage(R.string.sensor_client_read_error_text, ex.toString()) } } @@ -220,16 +246,16 @@ class SensorClientFragment : Fragment() { private fun consumeSensorValue(value: Double, unitSymbol: String, addToGraph: Boolean) { requireActivity().runOnUiThread { - binding.lastValueTv.text = requireContext().getString( - R.string.sensor_client_last_value_text, value, unitSymbol - ) + binding.lastValueTv.text = + requireContext().getString(R.string.sensor_client_last_value_text, value, unitSymbol) if (addToGraph) { val isFirstSample = sensorData.isEmpty val dataPoint = DataPoint(Calendar.getInstance().time, value) sensorData.appendData(dataPoint, true, MAX_DATA_POINTS) if (isFirstSample) { - // Make the graph visible on the first sample. Also, workaround a bug in graphview + // Make the graph visible on the first sample. Also, workaround a bug in + // graphview // related to calculating the viewport when there is only one data point by // duplicating the first sample. sensorData.appendData(dataPoint, true, MAX_DATA_POINTS) @@ -253,26 +279,30 @@ class SensorClientFragment : Fragment() { private const val MIN_REFRESH_PERIOD_S = 2 private const val MAX_REFRESH_PERIOD_S = 10 private const val MAX_DATA_POINTS = 60 - private val CLUSTERS = mapOf( - "Temperature" to mapOf( + private val CLUSTERS = + mapOf( + "Temperature" to + mapOf( "clusterId" to TemperatureMeasurement.ID, "attributeId" to TemperatureMeasurement.Attribute.MeasuredValue.id, "unitValue" to 0.01, "unitSymbol" to "\u00B0C" - ), - "Pressure" to mapOf( + ), + "Pressure" to + mapOf( "clusterId" to PressureMeasurement.ID, "attributeId" to PressureMeasurement.Attribute.MeasuredValue.id, "unitValue" to 1.0, "unitSymbol" to "hPa" - ), - "Relative Humidity" to mapOf( + ), + "Relative Humidity" to + mapOf( "clusterId" to RelativeHumidityMeasurement.ID, "attributeId" to RelativeHumidityMeasurement.Attribute.MeasuredValue.id, "unitValue" to 0.01, "unitSymbol" to "%" - ) - ) + ) + ) fun newInstance(): SensorClientFragment = SensorClientFragment() } diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/WildcardFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/WildcardFragment.kt index cff6d0f81cff66..a755b1a441f03a 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/WildcardFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/WildcardFragment.kt @@ -34,17 +34,17 @@ import chip.tlv.TlvWriter import com.google.chip.chiptool.ChipClient import com.google.chip.chiptool.R import com.google.chip.chiptool.databinding.WildcardFragmentBinding -import com.google.protobuf.ByteString import java.lang.StringBuilder import java.util.Optional -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch class WildcardFragment : Fragment() { private var _binding: WildcardFragmentBinding? = null - private val binding get() = _binding!! + private val binding + get() = _binding!! private val deviceController: ChipDeviceController get() = ChipClient.getDeviceController(requireContext()) @@ -57,58 +57,62 @@ class WildcardFragment : Fragment() { private val eventPath = ArrayList() private val subscribeIdList = ArrayList() - private val reportCallback = object : ReportCallback { - override fun onError(attributePath: ChipAttributePath?, eventPath: ChipEventPath?, ex: Exception) { - if (attributePath != null) - { - Log.e(TAG, "Report error for $attributePath: $ex") - } - if (eventPath != null) - { - Log.e(TAG, "Report error for $eventPath: $ex") + private val reportCallback = + object : ReportCallback { + override fun onError( + attributePath: ChipAttributePath?, + eventPath: ChipEventPath?, + ex: Exception + ) { + if (attributePath != null) { + Log.e(TAG, "Report error for $attributePath: $ex") + } + if (eventPath != null) { + Log.e(TAG, "Report error for $eventPath: $ex") + } } - } - override fun onReport(nodeState: NodeState) { - Log.i(TAG, "Received wildcard report") + override fun onReport(nodeState: NodeState) { + Log.i(TAG, "Received wildcard report") - val debugString = nodeStateToDebugString(nodeState) - Log.i(TAG, debugString) - requireActivity().runOnUiThread { binding.outputTv.text = debugString } - } + val debugString = nodeStateToDebugString(nodeState) + Log.i(TAG, debugString) + requireActivity().runOnUiThread { binding.outputTv.text = debugString } + } - override fun onDone() { - Log.i(TAG, "wildcard report Done") + override fun onDone() { + Log.i(TAG, "wildcard report Done") + } } - } - private val writeAttributeCallback = object : WriteAttributesCallback { - override fun onError(attributePath: ChipAttributePath?, ex: Exception?) { - Log.e(TAG, "Report error for $attributePath: $ex") - } + private val writeAttributeCallback = + object : WriteAttributesCallback { + override fun onError(attributePath: ChipAttributePath?, ex: Exception?) { + Log.e(TAG, "Report error for $attributePath: $ex") + } - override fun onResponse(attributePath: ChipAttributePath?) { - val text = "$attributePath : Write Success" - requireActivity().runOnUiThread { binding.outputTv.text = text } - } + override fun onResponse(attributePath: ChipAttributePath?) { + val text = "$attributePath : Write Success" + requireActivity().runOnUiThread { binding.outputTv.text = text } + } - override fun onDone() { - Log.i(TAG, "write attribute Done") + override fun onDone() { + Log.i(TAG, "write attribute Done") + } } - } - private val invokeCallback = object : InvokeCallback { - override fun onError(e: java.lang.Exception?) { - Log.e(TAG, "Report error", e) - } + private val invokeCallback = + object : InvokeCallback { + override fun onError(e: java.lang.Exception?) { + Log.e(TAG, "Report error", e) + } - override fun onResponse(invokeElement: InvokeElement?, successCode: Long) { - val text = "Invoke Response : $invokeElement, $successCode" - requireActivity().runOnUiThread { binding.outputTv.text = text } + override fun onResponse(invokeElement: InvokeElement?, successCode: Long) { + val text = "Invoke Response : $invokeElement, $successCode" + requireActivity().runOnUiThread { binding.outputTv.text = text } + } } - } - override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -159,8 +163,12 @@ class WildcardFragment : Fragment() { return binding.root } - private fun getVisibility(isShowing: Boolean) : Int { - return if (isShowing) { View.VISIBLE } else { View.GONE } + private fun getVisibility(isShowing: Boolean): Int { + return if (isShowing) { + View.VISIBLE + } else { + View.GONE + } } private fun addPathList(type: Int) { @@ -169,7 +177,9 @@ class WildcardFragment : Fragment() { val attributeId = getChipPathIdForText(binding.attributeIdEd.text.toString()) val eventId = getChipPathIdForText(binding.eventIdEd.text.toString()) // Only Subscribe used - val isUrgent = (binding.subscribeRadioBtn.isChecked) && (binding.isUrgentSp.selectedItem.toString().toBoolean()) + val isUrgent = + (binding.subscribeRadioBtn.isChecked) && + (binding.isUrgentSp.selectedItem.toString().toBoolean()) if (type == ATTRIBUTE) { attributePath.add(ChipAttributePath.newInstance(endpointId, clusterId, attributeId)) @@ -212,8 +222,7 @@ class WildcardFragment : Fragment() { stringBuilder.append("\t\t$attributeName: ${attributeState.value}\n") } clusterState.eventStates.forEach { (eventId, events) -> - for (event in events) - { + for (event in events) { stringBuilder.append("\t\teventNumber: ${event.eventNumber}\n") stringBuilder.append("\t\tpriorityLevel: ${event.priorityLevel}\n") stringBuilder.append("\t\tsystemTimeStamp: ${event.systemTimeStamp}\n") @@ -229,48 +238,69 @@ class WildcardFragment : Fragment() { return stringBuilder.toString() } - private suspend fun subscribe(minInterval: Int, maxInterval: Int, keepSubscriptions: Boolean, isFabricFiltered: Boolean, eventMin: Long?) { - val subscriptionEstablishedCallback = - SubscriptionEstablishedCallback { - subscriptionId -> - Log.i(TAG, "Subscription to device established : ${subscriptionId.toULong()}") - subscribeIdList.add(subscriptionId.toULong()) - requireActivity().runOnUiThread { - Toast.makeText(requireActivity(), "${getString(R.string.wildcard_subscribe_established_toast_message)} : $subscriptionId", Toast.LENGTH_SHORT).show() - } + private suspend fun subscribe( + minInterval: Int, + maxInterval: Int, + keepSubscriptions: Boolean, + isFabricFiltered: Boolean, + eventMin: Long? + ) { + val subscriptionEstablishedCallback = SubscriptionEstablishedCallback { subscriptionId -> + Log.i(TAG, "Subscription to device established : ${subscriptionId.toULong()}") + subscribeIdList.add(subscriptionId.toULong()) + requireActivity().runOnUiThread { + Toast.makeText( + requireActivity(), + "${getString(R.string.wildcard_subscribe_established_toast_message)} : $subscriptionId", + Toast.LENGTH_SHORT + ) + .show() } + } val resubscriptionAttemptCallback = - ResubscriptionAttemptCallback { terminationCause, nextResubscribeIntervalMsec - -> Log.i(TAG, "ResubscriptionAttempt terminationCause:$terminationCause, nextResubscribeIntervalMsec:$nextResubscribeIntervalMsec") } - - deviceController.subscribeToPath(subscriptionEstablishedCallback, - resubscriptionAttemptCallback, - reportCallback, - ChipClient.getConnectedDevicePointer(requireContext(), - addressUpdateFragment.deviceId), - attributePath.ifEmpty { null }, - eventPath.ifEmpty { null }, - minInterval, - maxInterval, - keepSubscriptions, - isFabricFiltered, - /* imTimeoutMs= */ 0, - eventMin) + ResubscriptionAttemptCallback { terminationCause, nextResubscribeIntervalMsec -> + Log.i( + TAG, + "ResubscriptionAttempt terminationCause:$terminationCause, nextResubscribeIntervalMsec:$nextResubscribeIntervalMsec" + ) + } + + deviceController.subscribeToPath( + subscriptionEstablishedCallback, + resubscriptionAttemptCallback, + reportCallback, + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), + attributePath.ifEmpty { null }, + eventPath.ifEmpty { null }, + minInterval, + maxInterval, + keepSubscriptions, + isFabricFiltered, + /* imTimeoutMs= */ 0, + eventMin + ) } private suspend fun read(isFabricFiltered: Boolean, eventMin: Long?) { - deviceController.readPath(reportCallback, - ChipClient.getConnectedDevicePointer(requireContext(), - addressUpdateFragment.deviceId), - attributePath.ifEmpty { null }, - eventPath.ifEmpty { null }, - isFabricFiltered, - /* imTimeoutMs= */ 0, - eventMin) + deviceController.readPath( + reportCallback, + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), + attributePath.ifEmpty { null }, + eventPath.ifEmpty { null }, + isFabricFiltered, + /* imTimeoutMs= */ 0, + eventMin + ) } - private suspend fun write(writeValueType: String, writeValue: String, dataVersion: Int?, timedRequestTimeoutMs: Int, imTimeoutMs: Int) { + private suspend fun write( + writeValueType: String, + writeValue: String, + dataVersion: Int?, + timedRequestTimeoutMs: Int, + imTimeoutMs: Int + ) { val endpointId = getChipPathIdForText(binding.endpointIdEd.text.toString()) val clusterId = getChipPathIdForText(binding.clusterIdEd.text.toString()) val attributeId = getChipPathIdForText(binding.attributeIdEd.text.toString()) @@ -288,15 +318,28 @@ class WildcardFragment : Fragment() { } if (values.size > 1) tlvWriter.endArray() - val version = if (dataVersion == null) { Optional.empty() } else { Optional.of(dataVersion) } + val version = + if (dataVersion == null) { + Optional.empty() + } else { + Optional.of(dataVersion) + } - val writeRequest = AttributeWriteRequest.newInstance(endpointId, clusterId, attributeId, tlvWriter.getEncoded(), version) - deviceController.write(writeAttributeCallback, - ChipClient.getConnectedDevicePointer(requireContext(), - addressUpdateFragment.deviceId), - listOf(writeRequest), - timedRequestTimeoutMs, - imTimeoutMs) + val writeRequest = + AttributeWriteRequest.newInstance( + endpointId, + clusterId, + attributeId, + tlvWriter.getEncoded(), + version + ) + deviceController.write( + writeAttributeCallback, + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), + listOf(writeRequest), + timedRequestTimeoutMs, + imTimeoutMs + ) } private suspend fun invoke(invokeField: String, timedRequestTimeoutMs: Int, imTimeoutMs: Int) { @@ -305,7 +348,12 @@ class WildcardFragment : Fragment() { val commandId = getChipPathIdForText(binding.commandIdEd.text.toString()) val tlvWriter = TlvWriter() - val fields = if (invokeField.isEmpty()) { listOf() } else { invokeField.split(",") } + val fields = + if (invokeField.isEmpty()) { + listOf() + } else { + invokeField.split(",") + } var count = 0 tlvWriter.startStructure(AnonymousTag) for (field in fields) { @@ -321,33 +369,43 @@ class WildcardFragment : Fragment() { } } tlvWriter.endStructure() - val invokeElement = InvokeElement.newInstance(endpointId, clusterId, commandId, tlvWriter.getEncoded(), null) - deviceController.invoke(invokeCallback, - ChipClient.getConnectedDevicePointer(requireContext(), - addressUpdateFragment.deviceId), - invokeElement, - timedRequestTimeoutMs, - imTimeoutMs) + val invokeElement = + InvokeElement.newInstance(endpointId, clusterId, commandId, tlvWriter.getEncoded(), null) + deviceController.invoke( + invokeCallback, + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), + invokeElement, + timedRequestTimeoutMs, + imTimeoutMs + ) } private fun showReadDialog() { if (attributePath.isEmpty() && eventPath.isEmpty()) { requireActivity().runOnUiThread { - Toast.makeText(requireActivity(), R.string.wildcard_empty_error_toast_message, Toast.LENGTH_SHORT).show() + Toast.makeText( + requireActivity(), + R.string.wildcard_empty_error_toast_message, + Toast.LENGTH_SHORT + ) + .show() } return } val dialogView = requireActivity().layoutInflater.inflate(R.layout.read_dialog, null) val eventMinEd = dialogView.findViewById(R.id.eventMinEd) - eventMinEd.visibility = if (eventPath.isNotEmpty()) { View.VISIBLE } else { View.GONE } - val dialog = AlertDialog.Builder(requireContext()).apply { - setView(dialogView) - }.create() + eventMinEd.visibility = + if (eventPath.isNotEmpty()) { + View.VISIBLE + } else { + View.GONE + } + val dialog = AlertDialog.Builder(requireContext()).apply { setView(dialogView) }.create() val isFabricFilteredEd = dialogView.findViewById(R.id.isFabricFilteredSp) dialogView.findViewById